Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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