Skip to content

Commit

Permalink
Playwright (#1609)
Browse files Browse the repository at this point in the history
  • Loading branch information
leightkt authored May 8, 2023
1 parent 22428ce commit 3de448a
Show file tree
Hide file tree
Showing 13 changed files with 12,217 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
"build": "yarn wsrun --serial build",
"type-check": "yarn wsrun type-check",
"file-check": "yarn install --check-files",
"check-all": "yarn build && yarn file-check && yarn type-check"
"check-all": "yarn build && yarn file-check && yarn type-check",
"test-playwright": "cd test && yarn && yarn playwright test"
},
"devDependencies": {
"prettier": "^2.4.1",
Expand Down
12 changes: 8 additions & 4 deletions packages/demo/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@
<button on:click={() => onboard.setChain({ chainId: '0x89' })}
>Set Chain to Matic</button
>
<button on:click={() => onboard.updateChain({ chainId: 10 })}
<button on:click={() => onboard.setChain({ chainId: 10 })}
>Set Chain to Optimism</button
>
</div>
Expand All @@ -670,13 +670,15 @@
</div>
{#if $wallets$}
{#each $wallets$ as { icon, label, accounts, chains, provider, instance }}
<div class="connected-wallet">
<div class="connected-wallet" data-testid="connected-wallet">
<div class="flex-centered" style="width: 10rem;">
<div style="width: 2rem; height: 2rem">{@html icon}</div>
<span>{label}</span>
<span data-testid={label}>{label}</span>
</div>
<div>Chains: {JSON.stringify(chains, null, 2)}</div>
<div data-testid="chains">
Chains: {JSON.stringify(chains, null, 2)}
</div>
{#each accounts as { address, ens, uns, balance }}
<div
Expand Down Expand Up @@ -713,6 +715,7 @@
class="text-input"
placeholder="0x..."
bind:value={toAddress}
data-testid="sendTransaction"
/>
<button on:click={sendTransaction(provider)}>
Send Transaction
Expand All @@ -724,6 +727,7 @@
class="text-input"
placeholder="0x..."
bind:value={toAddress}
data-testid="sendWithPreflight"
/>
<button on:click={sendTransactionWithPreFlight(provider, balance)}>
Send with Preflight Notifications
Expand Down
4 changes: 4 additions & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
/test-results/
/playwright-report/
/playwright/.cache/
9 changes: 9 additions & 0 deletions test/e2e/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path')
const synpressPath = path.join(
process.cwd(),
'/node_modules/@synthetixio/synpress'
)

module.exports = {
extends: `${synpressPath}/.eslintrc.js`
}
1 change: 1 addition & 0 deletions test/e2e/support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@synthetixio/synpress/support/index'
14 changes: 14 additions & 0 deletions test/e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "../../node_modules",
"types": [
"cypress",
"@synthetixio/synpress/support",
"cypress-wait-until",
"@testing-library/cypress"
],
"outDir": "./output"
},
"include": ["**/*.*"]
}
13 changes: 13 additions & 0 deletions test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "-W",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@playwright/test": "^1.31.2",
"@synthetixio/synpress": "^3.5.1",
"dotenv": "^16.0.3"
},
"scripts": {},
"dependencies": {}
}
91 changes: 91 additions & 0 deletions test/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { defineConfig, devices } from '@playwright/test'

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
require('dotenv').config()

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 1 : 0,
/* Opt out of parallel tests on CI. */
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry'
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] }
}

// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] }
// },

// {
// name: 'webkit',
// use: { ...devices['Desktop Safari'] }
// }

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { channel: 'chrome' },
// },
],

/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',

/* Run your local dev server before starting the tests */
webServer: {
command: 'cd .. && yarn && yarn dev',
port: 8080,
reuseExistingServer: true
}
})
17 changes: 17 additions & 0 deletions test/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# @web3-onboard/testing

## A collection of playwright tests run on the web3-onboard demo

To run tests:
1. Create .env file in test/ with the following variables:
TEST_WALLET_PHRASE
TEST_WALLET_ADDRESS
SERIAL_MODE=true
HEADLESS_MODE=true
2. yarn test

There are 4 existing tests for metamask: connect metamask, sign a message, sign a typed message, send a transaction, switche chains, and disconnect.

Please note: your test metamask wallet must have a balance of GoerliETH for all tests to pass.

To view report after running tests: npx playwright show-report
7 changes: 7 additions & 0 deletions test/tests/example.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { test, expect } from '@playwright/test'

test('has title', async ({ page }) => {
await page.goto('http://localhost:8080')
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Svelte app/)
})
49 changes: 49 additions & 0 deletions test/tests/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { test as base, chromium, BrowserContext } from '@playwright/test'
import { prepareMetamask } from '@synthetixio/synpress/helpers'
import { initialSetup } from '@synthetixio/synpress/commands/metamask'

const path = require('path')

export const metamaskTest = base.extend<{
context: BrowserContext
}>({
context: async ({}, use) => {
// required for synpress
global.expect = expect
// download metamask
const metamaskPath = await prepareMetamask(
process.env.METAMASK_VERSION || '10.26.2'
)
// prepare browser args
const browserArgs = [
`--disable-extensions-except=${metamaskPath}`,
`--load-extension=${metamaskPath}`,
'--remote-debugging-port=9222'
]
if (process.env.CI) {
browserArgs.push('--disable-gpu')
}
if (process.env.HEADLESS_MODE) {
browserArgs.push('--headless=new')
}
// launch browser
const context = await chromium.launchPersistentContext('', {
headless: false,
args: browserArgs
})
// wait for metamask
await context.pages()[0].waitForTimeout(3000)
// setup metamask
await initialSetup(chromium, {
secretWordsOrPrivateKey: process.env.TEST_WALLET_PHRASE,
network: 'goerli',
password: 'Tester@1234',
enableAdvancedSettings: true
})
await use(context)
if (!process.env.SERIAL_MODE) {
await context.close()
}
}
})
export const expect = metamaskTest.expect
78 changes: 78 additions & 0 deletions test/tests/metamask.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { metamaskTest, expect } from './fixtures'
import * as metamask from '@synthetixio/synpress/commands/metamask'
import * as playwright from '@synthetixio/synpress/commands/playwright'

let sharedPage
let sharedContext

metamaskTest.describe.configure({ mode: 'serial' })

const connectMetamask = async page => {
await page.getByRole('button', { name: 'Connect Wallet' }).click()
await page.getByRole('checkbox').click()
await page.getByText('Metamask').click()
await metamask.acceptAccess()
}

metamaskTest.beforeAll(async ({ page, context }) => {
sharedPage = page
sharedContext = context
await sharedPage.goto('http://localhost:8080')
await connectMetamask(sharedPage)
})

metamaskTest('metamask connected', async () => {
await expect(sharedPage.getByTestId('MetaMask')).toHaveText('MetaMask')
// Check to make sure connected to goerli
await expect(sharedPage.getByTestId('chains')).toHaveText(
'Chains: [ { "namespace": "evm", "id": "0x5" } ]'
)
})

metamaskTest('metamask sign message', async () => {
const messageText = 'a new message'
const message = sharedPage.getByPlaceholder('Message...')
await message.fill(messageText)
await sharedPage.getByRole('button', { name: 'Sign Message' }).click()
const notificationPage = await playwright.switchToMetamaskNotification()
await expect(notificationPage.getByText(messageText)).toBeDefined()
await notificationPage.getByTestId('page-container-footer-next').click()
})

metamaskTest('metamask sign typed message', async () => {
await sharedPage.getByRole('button', { name: 'Sign Typed Message' }).click()
const notificationPage = await playwright.switchToMetamaskNotification()
await expect(notificationPage.getByText('Hello, Bob!')).toBeDefined()
await notificationPage.getByTestId('signature-request-scroll-button').click()
await notificationPage.getByTestId('page-container-footer-next').click()
})

metamaskTest('send Transaction', async () => {
const address = process.env.TEST_WALLET_ADDRESS
const input = sharedPage.getByTestId('sendTransaction')
await input.fill(address)
await sharedPage.getByRole('button', { name: 'Send Transaction' }).click()
const notificationPage = await playwright.switchToMetamaskNotification()
await notificationPage.getByTestId('page-container-footer-next').click()
await sharedPage.waitForTimeout(3000)
await expect(
sharedPage.getByText('Your account successfully received 0.00001 ETH from')
).toBeDefined()
})

metamaskTest('switch chains', async () => {
await sharedPage.getByRole('button', { name: 'Set Chain to Mainnet' }).click()
const notificationPage = await playwright.switchToMetamaskNotification()
await notificationPage.getByRole('button', { name: 'Switch network' }).click()
await sharedPage.waitForTimeout(3000)
await expect(sharedPage.getByTestId('chains')).toHaveText(
'Chains: [ { "namespace": "evm", "id": "0x1" } ]'
)
})

metamaskTest('disconnect metamask', async () => {
await sharedPage.getByRole('button', { name: 'Disconnect Wallet' }).click()
await sharedPage.waitForTimeout(3000)
await expect(sharedPage.getByTestId('connected-wallet')).toHaveCount(0)
sharedContext.close()
})
Loading

0 comments on commit 3de448a

Please sign in to comment.