Skip to content

Commit

Permalink
📦️ chore: Add example project (#1028)
Browse files Browse the repository at this point in the history
  • Loading branch information
duckception authored Dec 3, 2023
1 parent bff9f57 commit 2bd7e99
Show file tree
Hide file tree
Showing 15 changed files with 431 additions and 18 deletions.
2 changes: 2 additions & 0 deletions examples/new-dawn/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SEED_PHRASE="test test test test test test test test test test test junk"
WALLET_PASSWORD="SynpressIsAwesomeNow!!!"
63 changes: 63 additions & 0 deletions examples/new-dawn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<h1 align="center">
Synpress: New Dawn
<br>
<small>⭐ Example Project ⭐</small>
</h1>

# 📖 Intro

The New Dawn version of Synpress differs in one major way from all previous versions and all other similar Web3 tools:
- We set up the browser only once, and we cache it. Thanks to this, tests not only run faster, but it also allows to use **ALL FEATURES** of [Playwright](https://playwright.dev/), such as parallel testing 🚀

You can define how a browser should be set up yourself. You can find setup file examples [here](./test/wallet-setup). All setup files must have the following naming structure: `*.setup.{js,ts}`.

Once you define a setup file, you can build a cache with our CLI. By default, the cache is built in a headed mode and utilizes the setup files from `test/wallet-setup` directory.
Try running it with the `--help` flag to see all available configuration options.

Here's how to use it:
```bash
# Build cache in a headed mode:
synpress

# Build cache in a headless mode:
synpress --headless
```

# 🧑‍💻 Usage

1. Install dependencies:
```bash
pnpm install
```

2. Build cache with our CLI by using a script:
```bash
# You can either build cache in a headed mode:
pnpm run build:cache

# Or in a headless mode:
pnpm run build:cache:headless
```

3. Run Playwright tests as you would normally do:
```bash
# Use one of our scripts:
pnpm run test:e2e:headful
pnpm run test:e2e:headless
pnpm run test:e2e:headless:ui

# Or use Playwright directly:
playwright test
HEADLESS=true playwright test
HEADLESS=true playwright test --ui
```

### ⚠️ Important note ⚠️

Currently, tests are triggered in a headed mode by default. Add `HEADLESS=true` to run them in a headless mode.

This behavior will change soon! 🫡

# 🤔 Still want more?

If you need more than this example project, check out our tests for MetaMask [here](../../wallets/metamask/test/e2e).
10 changes: 10 additions & 0 deletions examples/new-dawn/environment.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
declare global {
namespace NodeJS {
interface ProcessEnv {
SEED_PHRASE: string
WALLET_PASSWORD: string
}
}
}

export {}
25 changes: 25 additions & 0 deletions examples/new-dawn/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "example-new-dawn",
"private": true,
"type": "module",
"scripts": {
"build:cache": "synpress",
"build:cache:force": "synpress --force",
"build:cache:headless": "synpress --headless",
"serve:test-dapp": "serve node_modules/@metamask/test-dapp/dist -p 12345",
"test:e2e:headful": "playwright test",
"test:e2e:headless": "HEADLESS=true playwright test",
"test:e2e:headless:ui": "HEADLESS=true playwright test --ui"
},
"dependencies": {
"@playwright/test": "1.40.0",
"@synthetixio/synpress": "workspace:*",
"dotenv": "16.3.1"
},
"devDependencies": {
"@metamask/test-dapp": "8.0.0",
"@types/node": "20.10.2",
"serve": "14.2.1",
"typescript": "5.3.2"
}
}
35 changes: 35 additions & 0 deletions examples/new-dawn/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineConfig, devices } from '@playwright/test'

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
// Look for test files in the "test/e2e" directory, relative to this configuration file.
testDir: './test/e2e',

// Run all tests in parallel.
fullyParallel: true,

// Use half of the number of logical CPU cores for running tests in parallel.
workers: undefined,

use: {
// We are using locally deployed MetaMask Test Dapp.
baseURL: 'http://localhost:12345'
},

// Synpress currently only supports Chromium, however, this will change in the future.
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] }
}
],

// Serve MetaMask Test Dapp locally before starting the tests.
webServer: {
command: 'pnpm run serve:test-dapp',
url: 'http://localhost:12345',
reuseExistingServer: true
}
})
39 changes: 39 additions & 0 deletions examples/new-dawn/test/advancedFixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { test as base } from './simpleFixture'

/**
* This fixture is further built upon the `simpleFixture`.
* It will serve as a foundation for the tests in the `03_advanced.spec.ts` file.
*
* You can read more about Playwright fixtures here: https://playwright.dev/docs/test-fixtures
*/
export const test = base.extend<{
deployToken: () => Promise<void>
deployPiggyBank: () => Promise<void>
}>({
deployToken: async ({ page, metamask }, use) => {
await use(async () => {
// We want to make sure we are connected to the local Anvil node.
await expect(page.locator('#network')).toHaveText('0x53a')

await expect(page.locator('#tokenAddresses')).toBeEmpty()
await page.locator('#createToken').click()

await metamask.confirmTransaction()
})
},
deployPiggyBank: async ({ page, metamask }, use) => {
await use(async () => {
// We want to make sure we are connected to the local Anvil node.
await expect(page.locator('#network')).toHaveText('0x53a')

await expect(page.locator('#contractStatus')).toHaveText('Not clicked')

await page.locator('#deployButton').click()
await metamask.confirmTransaction()

await expect(page.locator('#contractStatus')).toHaveText('Deployed')
})
}
})

export const { expect, describe } = test
19 changes: 19 additions & 0 deletions examples/new-dawn/test/e2e/01_basic.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MetaMask, testWithSynpress, unlockForFixture } from '@synthetixio/synpress'
import BasicSetup from '../wallet-setup/basic.setup'

const test = testWithSynpress(BasicSetup, unlockForFixture)

const { expect } = test

test('should connect wallet to the MetaMask Test Dapp', async ({ context, page, extensionId }) => {
const metamask = new MetaMask(context, page, BasicSetup.walletPassword, extensionId)

await page.goto('/')

await page.locator('#connectButton').click()
await metamask.connectToDapp()
await expect(page.locator('#accounts')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266')

await page.locator('#getAccounts').click()
await expect(page.locator('#getAccountsResult')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266')
})
42 changes: 42 additions & 0 deletions examples/new-dawn/test/e2e/02_simple.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { expect, test } from '../simpleFixture'

test('should confirm contract deployment', async ({ page, metamask, connectToAnvil }) => {
await connectToAnvil()

await expect(page.locator('#tokenAddresses')).toBeEmpty()
await page.locator('#createToken').click()

await metamask.confirmTransaction()

await expect(page.locator('#tokenAddresses')).toHaveText('0x5FbDB2315678afecb367f032d93F642f64180aa3')
})

test('should confirm legacy transaction', async ({ page, metamask, connectToAnvil }) => {
await connectToAnvil()

await page.locator('#sendButton').click()

await metamask.confirmTransaction()
})

test('should confirm EIP-1559 transaction', async ({ page, metamask, connectToAnvil }) => {
await connectToAnvil()

await page.locator('#sendEIP1559Button').click()

await metamask.confirmTransaction()
})

test('should sign and verify EIP-712 message', async ({ page, metamask }) => {
await page.locator('#signTypedDataV4').click()

await metamask.confirmSignature()

await expect(page.locator('#signTypedDataV4Result')).toHaveText(
'0x1cf422c4a319c19ecb89c960e7c296810278fa2bef256c7e9419b285c8216c547b3371fa1ec3987ce08561d3ed779845393d8d3e4311376d0bc0846f37d1b2821c'
)

await page.locator('#signTypedDataV4Verify').click()

await expect(page.locator('#signTypedDataV4VerifyResult')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266')
})
41 changes: 41 additions & 0 deletions examples/new-dawn/test/e2e/03_advanced.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, test } from '../advancedFixture'

describe('Token', () => {
test('should confirm tokens transfer', async ({ page, metamask, connectToAnvil, deployToken }) => {
await connectToAnvil()
await deployToken()

await page.locator('#transferTokens').click()
await metamask.confirmTransaction()
})

test('should approve tokens', async ({ page, metamask, connectToAnvil, deployToken }) => {
await connectToAnvil()
await deployToken()

await page.locator('#approveTokens').click()
await metamask.approvePermission()
})
})

describe('Piggy Bank', () => {
test('should deposit and then withdraw ETH from the contract', async ({
page,
metamask,
connectToAnvil,
deployPiggyBank
}) => {
await connectToAnvil()
await deployPiggyBank()

await page.locator('#depositButton').click()
await metamask.confirmTransaction()

await expect(page.locator('#contractStatus')).toHaveText('Deposit completed')

await page.locator('#withdrawButton').click()
await metamask.confirmTransaction()

await expect(page.locator('#contractStatus')).toHaveText('Withdrawn')
})
})
44 changes: 44 additions & 0 deletions examples/new-dawn/test/simpleFixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { MetaMask, testWithSynpress, unlockForFixture } from '@synthetixio/synpress'
import ConnectedSetup from './wallet-setup/connected.setup'

/**
* We're creating a fixture that will serve as a foundation for tests in the `02_simple.spec.ts` file.
*
* You can read more about Playwright fixtures here: https://playwright.dev/docs/test-fixtures
*/
export const test = testWithSynpress(ConnectedSetup, unlockForFixture).extend<{
metamask: MetaMask
connectToAnvil: () => Promise<void>
}>({
metamask: async ({ context, metamaskPage, extensionId }, use) => {
const metamask = new MetaMask(context, metamaskPage, ConnectedSetup.walletPassword, extensionId)

await use(metamask)
},
page: async ({ page }, use) => {
/**
* Refers to the home page of the locally hosted MetaMask Test Dapp.
*
* See: https://playwright.dev/docs/api/class-testoptions#test-options-base-url
*/
await page.goto('/')

await use(page)
},
connectToAnvil: async ({ metamask, createAnvilNode }, use) => {
await use(async () => {
const { rpcUrl, chainId } = await createAnvilNode({
chainId: 1338
})

await metamask.addNetwork({
name: 'Local Anvil Network',
rpcUrl,
chainId,
symbol: 'ETH'
})
})
}
})

export const { expect } = test
10 changes: 10 additions & 0 deletions examples/new-dawn/test/wallet-setup/basic.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { MetaMask, defineWalletSetup } from '@synthetixio/synpress'

const SEED_PHRASE = 'test test test test test test test test test test test junk'
const PASSWORD = 'SynpressIsAwesomeNow!!!'

export default defineWalletSetup(PASSWORD, async (context, walletPage) => {
const metamask = new MetaMask(context, walletPage, PASSWORD)

await metamask.importWallet(SEED_PHRASE)
})
24 changes: 24 additions & 0 deletions examples/new-dawn/test/wallet-setup/connected.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { MetaMask, defineWalletSetup, getExtensionId } from '@synthetixio/synpress'
import 'dotenv/config'

const SEED_PHRASE = process.env.SEED_PHRASE
const PASSWORD = process.env.WALLET_PASSWORD

export default defineWalletSetup(PASSWORD, async (context, walletPage) => {
// This is a workaround for the fact that the MetaMask extension ID changes.
// This workaround won't be needed in the near future! 😁
const extensionId = await getExtensionId(context, 'MetaMask')

const metamask = new MetaMask(context, walletPage, PASSWORD, extensionId)

await metamask.importWallet(SEED_PHRASE)

const page = await context.newPage()

// Go to a locally hosted MetaMask Test Dapp.
await page.goto('http://localhost:12345')

await page.locator('#connectButton').click()

await metamask.connectToDapp()
})
14 changes: 14 additions & 0 deletions examples/new-dawn/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"rootDir": "test",
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["test"],
"files": ["environment.d.ts"]
}
Loading

0 comments on commit 2bd7e99

Please sign in to comment.