From def186fa5abaa882470a02cacf3d3dedc68bd47a Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 11:27:42 +0300 Subject: [PATCH 01/15] feat: created minimal packet of ctrl methods; deleted xdefi --- .../ctrl.constants.ts} | 10 +- packages/wallets/src/ctrl/ctrl.page.ts | 145 ++++++++++++++++++ packages/wallets/src/ctrl/helper.ts | 8 + packages/wallets/src/ctrl/index.ts | 3 + packages/wallets/src/ctrl/pages/index.ts | 3 + packages/wallets/src/ctrl/pages/login.page.ts | 28 ++++ .../wallets/src/ctrl/pages/onboarding.page.ts | 97 ++++++++++++ .../src/ctrl/pages/walletOperations.page.ts | 11 ++ packages/wallets/src/index.ts | 2 +- packages/wallets/src/okx/okx.page.ts | 2 +- packages/wallets/src/xdefi/index.ts | 2 - packages/wallets/src/xdefi/xdefi.page.ts | 122 --------------- wallets-testing/browser/browser.constants.ts | 4 +- wallets-testing/package.json | 2 +- wallets-testing/playwright.config.ts | 4 +- wallets-testing/test/widgets/ethereum.spec.ts | 7 +- 16 files changed, 311 insertions(+), 139 deletions(-) rename packages/wallets/src/{xdefi/xdefi.constants.ts => ctrl/ctrl.constants.ts} (52%) create mode 100644 packages/wallets/src/ctrl/ctrl.page.ts create mode 100644 packages/wallets/src/ctrl/helper.ts create mode 100644 packages/wallets/src/ctrl/index.ts create mode 100644 packages/wallets/src/ctrl/pages/index.ts create mode 100644 packages/wallets/src/ctrl/pages/login.page.ts create mode 100644 packages/wallets/src/ctrl/pages/onboarding.page.ts create mode 100644 packages/wallets/src/ctrl/pages/walletOperations.page.ts delete mode 100644 packages/wallets/src/xdefi/index.ts delete mode 100644 packages/wallets/src/xdefi/xdefi.page.ts diff --git a/packages/wallets/src/xdefi/xdefi.constants.ts b/packages/wallets/src/ctrl/ctrl.constants.ts similarity index 52% rename from packages/wallets/src/xdefi/xdefi.constants.ts rename to packages/wallets/src/ctrl/ctrl.constants.ts index 0ad4d4e0..0307b40b 100644 --- a/packages/wallets/src/xdefi/xdefi.constants.ts +++ b/packages/wallets/src/ctrl/ctrl.constants.ts @@ -1,11 +1,11 @@ import { CommonWalletConfig } from '../wallets.constants'; -export const XDEFI_COMMON_CONFIG: CommonWalletConfig = { - WALLET_NAME: 'xdefi', - CONNECTED_WALLET_NAME: 'XDEFI', +export const CTRL_COMMON_CONFIG: CommonWalletConfig = { + WALLET_NAME: 'ctrl', + CONNECTED_WALLET_NAME: 'Ctrl', RPC_URL_PATTERN: 'https://mainnet.infura.io/v3/**', STORE_EXTENSION_ID: 'hmeobnfnfcmdkdcmlblgagmfpfboieaf', - CONNECT_BUTTON_NAME: 'XDEFI', + CONNECT_BUTTON_NAME: 'Ctrl', SIMPLE_CONNECT: false, - EXTENSION_START_PATH: '/app.html', + EXTENSION_START_PATH: '/popup.html', }; diff --git a/packages/wallets/src/ctrl/ctrl.page.ts b/packages/wallets/src/ctrl/ctrl.page.ts new file mode 100644 index 00000000..ee0ec64b --- /dev/null +++ b/packages/wallets/src/ctrl/ctrl.page.ts @@ -0,0 +1,145 @@ +import { WalletPage } from '../wallet.page'; +import { test, BrowserContext, Page } from '@playwright/test'; +import { WalletConfig } from '../wallets.constants'; +import { LoginPage, OnboardingPage, WalletOperations } from './pages'; +import { closeUnnecessaryPages } from './helper'; + +export class CtrlPage implements WalletPage { + page: Page | undefined; + onboardingPage: OnboardingPage; + loginPage: LoginPage; + + constructor( + private browserContext: BrowserContext, + private extensionUrl: string, + public config: WalletConfig, + ) {} + + /** Init all page objects Classes included to wallet */ + async initLocators() { + this.page = await this.browserContext.newPage(); + this.onboardingPage = new OnboardingPage( + this.page, + this.browserContext, + this.extensionUrl, + this.config, + ); + this.loginPage = new LoginPage(this.page, this.config); + } + + /** Open the home page of the wallet extension */ + async goto() { + await this.page.goto( + this.extensionUrl + this.config.COMMON.EXTENSION_START_PATH, + ); + } + + /** Navigate to home page of OXK Wallet extension: + * - open the wallet extension + * - unlock extension (if needed) + * - cancel awaited transactions (if needed) + */ + async navigate() { + await test.step('Navigate to Ctrl', async () => { + await this.initLocators(); + await this.goto(); + await this.loginPage.unlock(); + // await this.walletOperations.cancelAllTxInQueue(); + }); + } + + async setup() { + await test.step('Setup', async () => { + await this.initLocators(); + if (await this.onboardingPage.isNeedToGoThroughOnboarding()) { + await this.onboardingPage.firstTimeSetup(); + await this.goto(); + await this.onboardingPage.closeWalletTour(); + await this.onboardingPage.createWalletPassword(); + } + await closeUnnecessaryPages(this.browserContext); + }); + } + + /** Click `Connect` button */ + async connectWallet(page: Page) { + await test.step('Connect OKX wallet', async () => { + const operationPage = new WalletOperations(page); + await operationPage.connectBtn.waitFor({ + state: 'visible', + timeout: 10000, + }); + await operationPage.connectBtn.click(); + // need wait the page to be closed after the extension is connected + await new Promise((resolve) => { + operationPage.page.on('close', () => { + resolve(); + }); + }); + }); + } + + importKey(): Promise { + throw new Error('Method not implemented.'); + } + + assertTxAmount(): Promise { + throw new Error('Method not implemented.'); + } + + confirmTx(): Promise { + throw new Error('Method not implemented.'); + } + + cancelTx(): Promise { + throw new Error('Method not implemented.'); + } + + approveTokenTx(): Promise { + throw new Error('Method not implemented.'); + } + + openLastTxInEthplorer(): Promise { + throw new Error('Method not implemented.'); + } + + getTokenBalance(): Promise { + throw new Error('Method not implemented.'); + } + + confirmAddTokenToWallet(): Promise { + throw new Error('Method not implemented.'); + } + + assertReceiptAddress(): Promise { + throw new Error('Method not implemented.'); + } + + getWalletAddress(): Promise { + throw new Error('Method not implemented.'); + } + + setupNetwork(): Promise { + throw new Error('Method not implemented.'); + } + + addNetwork(): Promise { + throw new Error('Method not implemented.'); + } + + changeNetwork(): Promise { + throw new Error('Method not implemented.'); + } + + changeWalletAccountByName(): Promise { + throw new Error('Method not implemented.'); + } + + changeWalletAccountByAddress(): Promise { + throw new Error('Method not implemented.'); + } + + isWalletAddressExist(): Promise { + throw new Error('Method not implemented.'); + } +} diff --git a/packages/wallets/src/ctrl/helper.ts b/packages/wallets/src/ctrl/helper.ts new file mode 100644 index 00000000..6ad88a2d --- /dev/null +++ b/packages/wallets/src/ctrl/helper.ts @@ -0,0 +1,8 @@ +import { BrowserContext } from '@playwright/test'; + +export async function closeUnnecessaryPages(browserContext: BrowserContext) { + const pages = browserContext.pages().slice(1); + for (const page of pages) { + await page.close(); + } +} diff --git a/packages/wallets/src/ctrl/index.ts b/packages/wallets/src/ctrl/index.ts new file mode 100644 index 00000000..cf36ea65 --- /dev/null +++ b/packages/wallets/src/ctrl/index.ts @@ -0,0 +1,3 @@ +export * from './ctrl.page'; +export * from './ctrl.constants'; +export * from './helper'; diff --git a/packages/wallets/src/ctrl/pages/index.ts b/packages/wallets/src/ctrl/pages/index.ts new file mode 100644 index 00000000..1d6628c9 --- /dev/null +++ b/packages/wallets/src/ctrl/pages/index.ts @@ -0,0 +1,3 @@ +export * from './onboarding.page'; +export * from './login.page'; +export * from './walletOperations.page'; diff --git a/packages/wallets/src/ctrl/pages/login.page.ts b/packages/wallets/src/ctrl/pages/login.page.ts new file mode 100644 index 00000000..46296c75 --- /dev/null +++ b/packages/wallets/src/ctrl/pages/login.page.ts @@ -0,0 +1,28 @@ +import { Locator, Page, test } from '@playwright/test'; +import { WalletConfig } from '../../wallets.constants'; + +export class LoginPage { + page: Page; + unlockBtn: Locator; + passwordInput: Locator; + homeBtn: Locator; + + constructor(page: Page, public config: WalletConfig) { + this.page = page; + this.unlockBtn = this.page.getByTestId('unlock-btn'); + this.passwordInput = this.page.locator('input[type="password"]'); + } + + async unlock() { + await test.step('Unlock wallet', async () => { + try { + await this.unlockBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.passwordInput.fill(this.config.PASSWORD); + await this.unlockBtn.click(); + await this.homeBtn.waitFor({ state: 'visible' }); + } catch { + console.log('The Wallet unlocking is not needed'); + } + }); + } +} diff --git a/packages/wallets/src/ctrl/pages/onboarding.page.ts b/packages/wallets/src/ctrl/pages/onboarding.page.ts new file mode 100644 index 00000000..0759f47b --- /dev/null +++ b/packages/wallets/src/ctrl/pages/onboarding.page.ts @@ -0,0 +1,97 @@ +import { BrowserContext, Locator, Page, test } from '@playwright/test'; +import { WalletConfig } from '../../wallets.constants'; + +export class OnboardingPage { + page: Page; + alreadyHaveWalletBtn: Locator; + importRecoveryPhraseBtn: Locator; + passwordInput: Locator; + nextBtn: Locator; + importBtn: Locator; + closeTourBtn: Locator; + notNowBtn: Locator; + createPasswordBtn: Locator; + confirmPasswordBtn: Locator; + + constructor( + page: Page, + private browserContext: BrowserContext, + private extensionUrl: string, + public config: WalletConfig, + ) { + this.page = page; + this.alreadyHaveWalletBtn = this.page.getByTestId( + 'i-already-have-a-wallet-btn', + ); + this.importRecoveryPhraseBtn = this.page.getByText( + 'Import with Recovery Phrase', + ); + this.passwordInput = this.page.locator('input[type="password"]'); + this.nextBtn = this.page.getByTestId('next-btn'); + this.importBtn = this.page.getByTestId('import-btn'); + this.closeTourBtn = this.page.locator( + '[testID="home-page-tour-close-icon"]', + ); + this.notNowBtn = this.page.getByText('Not now'); + this.createPasswordBtn = this.page.getByText('create a password'); + this.confirmPasswordBtn = this.page.getByTestId('button'); + } + + async isNeedToGoThroughOnboarding() { + return await test.step('Open the onboarding page', async () => { + // Need to open onboarding page cause the extension does not redirect from home url automatically + await this.page.goto( + this.extensionUrl + '/tabs/onboarding.html#onboarding', + ); + + const btn = this.page.getByTestId('i-already-have-a-wallet-btn'); + try { + await btn.waitFor({ + state: 'visible', + timeout: 5000, + }); + } catch { + console.log('Onboarding process is not needed'); + } + return btn.isVisible(); + }); + } + + async firstTimeSetup() { + await test.step('First time set up', async () => { + // Need to wait some time for button enabling + await this.page.waitForTimeout(1000); + await this.alreadyHaveWalletBtn.click({ force: true }); + + await test.step('Import wallet with recovery phrase', async () => { + await this.importRecoveryPhraseBtn.click(); + const seedWords = this.config.SECRET_PHRASE.split(' '); + for (let i = 0; i < seedWords.length; i++) { + await this.passwordInput.nth(i).fill(seedWords[i]); + } + await this.nextBtn.click(); + await this.importBtn.waitFor({ state: 'visible', timeout: 60000 }); + await this.importBtn.click(); + await this.nextBtn.click(); + }); + }); + } + + async closeWalletTour() { + await test.step('Close wallet tour', async () => { + await this.closeTourBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.closeTourBtn.click(); + await this.notNowBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.notNowBtn.click({ force: true }); + }); + } + + async createWalletPassword() { + await test.step('Create wallet password', async () => { + await this.createPasswordBtn.click(); + await this.passwordInput.nth(0).fill(this.config.PASSWORD); + await this.passwordInput.nth(1).fill(this.config.PASSWORD); + await this.confirmPasswordBtn.click(); + }); + } +} diff --git a/packages/wallets/src/ctrl/pages/walletOperations.page.ts b/packages/wallets/src/ctrl/pages/walletOperations.page.ts new file mode 100644 index 00000000..e4f69193 --- /dev/null +++ b/packages/wallets/src/ctrl/pages/walletOperations.page.ts @@ -0,0 +1,11 @@ +import { Locator, Page } from '@playwright/test'; + +export class WalletOperations { + page: Page; + connectBtn: Locator; + + constructor(page: Page) { + this.page = page; + this.connectBtn = this.page.getByTestId('connect-dapp-button'); + } +} diff --git a/packages/wallets/src/index.ts b/packages/wallets/src/index.ts index d01a0d41..f041a47a 100644 --- a/packages/wallets/src/index.ts +++ b/packages/wallets/src/index.ts @@ -5,6 +5,6 @@ export * from './metamask'; export * from './trustwallet'; export * from './coinbase'; export * from './exodus'; -export * from './xdefi'; export * from './okx'; export * from './bitget'; +export * from './ctrl'; diff --git a/packages/wallets/src/okx/okx.page.ts b/packages/wallets/src/okx/okx.page.ts index ab042a20..8af865f9 100644 --- a/packages/wallets/src/okx/okx.page.ts +++ b/packages/wallets/src/okx/okx.page.ts @@ -65,7 +65,7 @@ export class OkxPage implements WalletPage { }); } - /** Checks the wallet is set correctly and starts ot wallet setup as the first time (if needed) */ + /** Checks the wallet is set correctly and starts the wallet setup as the first time (if needed) */ async setup() { await test.step('Setup', async () => { await this.navigate(); diff --git a/packages/wallets/src/xdefi/index.ts b/packages/wallets/src/xdefi/index.ts deleted file mode 100644 index b50948ca..00000000 --- a/packages/wallets/src/xdefi/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './xdefi.page'; -export * from './xdefi.constants'; diff --git a/packages/wallets/src/xdefi/xdefi.page.ts b/packages/wallets/src/xdefi/xdefi.page.ts deleted file mode 100644 index caa2cf95..00000000 --- a/packages/wallets/src/xdefi/xdefi.page.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { WalletConfig } from '../wallets.constants'; -import { WalletPage } from '../wallet.page'; -import expect from 'expect'; -import { test, BrowserContext, Page } from '@playwright/test'; - -export class XdefiPage implements WalletPage { - page: Page | undefined; - - constructor( - private browserContext: BrowserContext, - private extensionUrl: string, - public config: WalletConfig, - ) {} - - async navigate() { - await test.step('Navigate to xdefi', async () => { - this.page = await this.browserContext.newPage(); - await this.page.goto( - this.extensionUrl + this.config.COMMON.EXTENSION_START_PATH, - ); - await this.page.reload(); - await this.page.waitForTimeout(1000); - }); - } - - async setup() { - await test.step('Setup', async () => { - // added explicit route to /onboarding due to unexpected first time route from /home.html to /onboarding - page is close - this.page = await this.browserContext.newPage(); - await this.page.goto(this.extensionUrl + '/onboarding.html'); - if (!this.page) throw "Page isn't ready"; - const firstTime = await this.page.waitForSelector( - "text=Let's get started", - ); - if (firstTime) await this.firstTimeSetup(); - }); - } - - async importTokens(token: string) { - await test.step('Import token', async () => { - await this.navigate(); - if (!this.page) throw "Page isn't ready"; - await this.page.click('button[data-testid="addAssetsBtn"]'); - await this.page.click('li[data-testid="customTab"]'); - await this.page.type('input[name="address"]', token); - await this.page.click('button[data-testid="nextBtn"]'); - }); - } - - async firstTimeSetup() { - await test.step('First time setup', async () => { - if (!this.page) throw "Page isn't ready"; - await this.page.click('text=Restore XDEFI Wallet'); - await this.page.click('text=Restore with secret phrase'); - const inputs = this.page.locator('input[data-testid=input]'); - const seedWords = this.config.SECRET_PHRASE.split(' '); - for (let i = 0; i < seedWords.length; i++) { - await inputs.nth(i).fill(seedWords[i]); - } - await this.page.click('text=Next'); - await this.page.fill('input[name="password"]', this.config.PASSWORD); - await this.page.fill('input[name="cpassword"]', this.config.PASSWORD); - await this.page.click('div[data-testid=termsAndConditionsCheckbox]'); - await this.page.click('button[type="submit"]'); - await this.page.fill( - 'input[name="walletName"]', - this.config.COMMON.WALLET_NAME, - ); - await this.page.click('button[type="submit"]'); - await this.page.click('div[data-testid=prioritiesXdefiToggle]'); - await this.page.click('button[data-testid=nextBtn]'); - }); - } - - async importKey(key: string) { - await test.step('Import key', async () => { - if (!this.page) throw "Page isn't ready"; - await this.navigate(); - await this.page.click('button[data-testid="menuBtn"]'); - await this.page.click('li[data-testid="walletManagementBtn"]'); - await this.page.click('div[data-testid="importWalletBtn"]'); - await this.page.click('text=Seed Phrase'); - await this.page.fill('textarea[name="[phrase"]', key); - await this.page.click('svg:below(input)'); - await this.page.click('button[data-testid="importBtn"]'); - }); - } - - async connectWallet(page: Page) { - await test.step('Connect wallet', async () => { - await page.click('button[data-testid="nextBtn"]'); - await page - .locator('svg[data-testid="checkbox-unchecked"]') - .first() - .locator('..') - .click(); - await page.click('button[data-testid="connectBtn"]'); - await page.close(); - }); - } - - async assertTxAmount(page: Page, expectedAmount: string) { - await test.step('Assert TX Amount', async () => { - expect(await page.locator(`text=${expectedAmount} ETH`).count()).toBe(1); - }); - } - - async confirmTx(page: Page) { - await test.step('Confirm TX', async () => { - await page.click('button[data-testid="confirmBtn"]'); - }); - } - - // eslint-disable-next-line - async signTx(page: Page) {} - - // eslint-disable-next-line - async assertReceiptAddress(page: Page, expectedAddress: string) {} - - // eslint-disable-next-line - async addNetwork(networkName: string, networkUrl: string, chainId: number, tokenSymbol: string) {} -} diff --git a/wallets-testing/browser/browser.constants.ts b/wallets-testing/browser/browser.constants.ts index d0ea2bae..c253cd43 100644 --- a/wallets-testing/browser/browser.constants.ts +++ b/wallets-testing/browser/browser.constants.ts @@ -4,9 +4,9 @@ import { TrustWalletPage, ExodusPage, CoinbasePage, - XdefiPage, OkxPage, BitgetPage, + CtrlPage, } from '@lidofinance/wallets-testing-wallets'; import { EthereumPage } from '@lidofinance/wallets-testing-widgets'; @@ -16,9 +16,9 @@ export const WALLET_PAGES = { trust: TrustWalletPage, exodus: ExodusPage, coinbase: CoinbasePage, - xdefi: XdefiPage, okx: OkxPage, bitget: BitgetPage, + ctrl: CtrlPage, }; export const WIDGET_PAGES = { diff --git a/wallets-testing/package.json b/wallets-testing/package.json index 1a50b71b..0452ffb0 100644 --- a/wallets-testing/package.json +++ b/wallets-testing/package.json @@ -15,7 +15,7 @@ "start:prod": "node dist/main", "test": "playwright test -c ./dist", "test:smoke": "playwright test -c ./dist smoke", - "test:widgets": "playwright test -c ./dist widgets" + "test:widgets": "playwright test -c ./dist widgets --retries=10" }, "dependencies": { "@lidofinance/wallets-testing-extensions": "*", diff --git a/wallets-testing/playwright.config.ts b/wallets-testing/playwright.config.ts index f22f8e7a..90828bd9 100644 --- a/wallets-testing/playwright.config.ts +++ b/wallets-testing/playwright.config.ts @@ -23,7 +23,7 @@ const config: PlaywrightTestConfig = { /* 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, + forbidOnly: true, //todo revert /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ @@ -46,7 +46,7 @@ const config: PlaywrightTestConfig = { // baseURL: 'http://localhost:3000', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', + trace: 'retain-on-failure', }, /* Folder for test artifacts such as screenshots, videos, traces, etc. */ diff --git a/wallets-testing/test/widgets/ethereum.spec.ts b/wallets-testing/test/widgets/ethereum.spec.ts index df801a45..d8c5f0f2 100644 --- a/wallets-testing/test/widgets/ethereum.spec.ts +++ b/wallets-testing/test/widgets/ethereum.spec.ts @@ -7,9 +7,9 @@ import { TRUST_WALLET_COMMON_CONFIG, COINBASE_COMMON_CONFIG, EXODUS_COMMON_CONFIG, - XDEFI_COMMON_CONFIG, OKX_COMMON_CONFIG, BITGET_COMMON_CONFIG, + CTRL_COMMON_CONFIG, } from '@lidofinance/wallets-testing-wallets'; import { ETHEREUM_WIDGET_CONFIG } from '@lidofinance/wallets-testing-widgets'; import { BrowserModule } from '../../browser/browser.module'; @@ -63,8 +63,9 @@ test.describe('Ethereum', () => { await browserService.connectWallet(); }); - test.skip(`Xdefi wallet connect`, async () => { - await browserService.setup(XDEFI_COMMON_CONFIG, ETHEREUM_WIDGET_CONFIG); + // todo remove .only + test.only(`Ctrl connect`, async () => { + await browserService.setup(CTRL_COMMON_CONFIG, ETHEREUM_WIDGET_CONFIG); await browserService.connectWallet(); }); From d6dc9bf6abdafe58d45efa101bec8c8bb72bd9d1 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 11:47:21 +0300 Subject: [PATCH 02/15] test: set forbidOnly=false --- wallets-testing/playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallets-testing/playwright.config.ts b/wallets-testing/playwright.config.ts index 90828bd9..daa890f7 100644 --- a/wallets-testing/playwright.config.ts +++ b/wallets-testing/playwright.config.ts @@ -23,7 +23,7 @@ const config: PlaywrightTestConfig = { /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: true, //todo revert + forbidOnly: false, //todo revert /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ From 36bc03778eeeae3befaed6c6a946bacbeb5567f7 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 11:55:07 +0300 Subject: [PATCH 03/15] test: set test run attempts = 10 times --- wallets-testing/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallets-testing/package.json b/wallets-testing/package.json index 0452ffb0..2c43de0e 100644 --- a/wallets-testing/package.json +++ b/wallets-testing/package.json @@ -15,7 +15,7 @@ "start:prod": "node dist/main", "test": "playwright test -c ./dist", "test:smoke": "playwright test -c ./dist smoke", - "test:widgets": "playwright test -c ./dist widgets --retries=10" + "test:widgets": "playwright test --repeat-each=10 -c ./dist widgets" }, "dependencies": { "@lidofinance/wallets-testing-extensions": "*", From 30b3fa76bb648ad4b6bfb6dff05e063519321985 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 12:34:19 +0300 Subject: [PATCH 04/15] feat: workflow - updated upload-artifact version, decreased retention-days to 7 --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 279e7856..30848832 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,12 +42,12 @@ jobs: WALLET_PASSWORD: ${{ secrets.WALLET_PASSWORD }} NODE_OPTIONS: --max-old-space-size=4096 - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: ${{ always() }} with: name: playwright-report path: wallets-testing/playwright-report/ - retention-days: 30 + retention-days: 7 - name: Set embeds if: ${{ always() }} From 77459848ff40cfa71ae9c055fb5624d1726ef08d Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 13:21:56 +0300 Subject: [PATCH 05/15] fix: some fixes for test stability --- packages/wallets/src/ctrl/pages/onboarding.page.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/wallets/src/ctrl/pages/onboarding.page.ts b/packages/wallets/src/ctrl/pages/onboarding.page.ts index 0759f47b..34201640 100644 --- a/packages/wallets/src/ctrl/pages/onboarding.page.ts +++ b/packages/wallets/src/ctrl/pages/onboarding.page.ts @@ -59,8 +59,7 @@ export class OnboardingPage { async firstTimeSetup() { await test.step('First time set up', async () => { - // Need to wait some time for button enabling - await this.page.waitForTimeout(1000); + await this.page.waitForTimeout(1000); // Need to wait some time for button enabling await this.alreadyHaveWalletBtn.click({ force: true }); await test.step('Import wallet with recovery phrase', async () => { @@ -71,6 +70,7 @@ export class OnboardingPage { } await this.nextBtn.click(); await this.importBtn.waitFor({ state: 'visible', timeout: 60000 }); + await this.page.waitForTimeout(1000); // Need to wait some time for button enabling await this.importBtn.click(); await this.nextBtn.click(); }); @@ -82,6 +82,7 @@ export class OnboardingPage { await this.closeTourBtn.waitFor({ state: 'visible', timeout: 2000 }); await this.closeTourBtn.click(); await this.notNowBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.page.waitForTimeout(1000); // Need to wait some time for button enabling await this.notNowBtn.click({ force: true }); }); } From 935eeda7ab623f02fceaa96066ae7f84c372150c Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 13:49:51 +0300 Subject: [PATCH 06/15] fix: fixed workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 30848832..3207a0b6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: run: yarn build - name: Install Playwright Browsers - run: npx playwright install --with-deps + run: yarn playwright install chromium --with-deps - name: Run wallets tests run: xvfb-run --auto-servernum -- yarn test:widgets From a4b0aa9ac062a252640e9f4de7522133f83537b8 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 14:17:07 +0300 Subject: [PATCH 07/15] test: revert test fixes --- packages/wallets/src/ctrl/ctrl.page.ts | 2 -- wallets-testing/package.json | 2 +- wallets-testing/playwright.config.ts | 2 +- wallets-testing/test/widgets/ethereum.spec.ts | 3 +-- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/wallets/src/ctrl/ctrl.page.ts b/packages/wallets/src/ctrl/ctrl.page.ts index ee0ec64b..cbe781dd 100644 --- a/packages/wallets/src/ctrl/ctrl.page.ts +++ b/packages/wallets/src/ctrl/ctrl.page.ts @@ -37,14 +37,12 @@ export class CtrlPage implements WalletPage { /** Navigate to home page of OXK Wallet extension: * - open the wallet extension * - unlock extension (if needed) - * - cancel awaited transactions (if needed) */ async navigate() { await test.step('Navigate to Ctrl', async () => { await this.initLocators(); await this.goto(); await this.loginPage.unlock(); - // await this.walletOperations.cancelAllTxInQueue(); }); } diff --git a/wallets-testing/package.json b/wallets-testing/package.json index 2c43de0e..1a50b71b 100644 --- a/wallets-testing/package.json +++ b/wallets-testing/package.json @@ -15,7 +15,7 @@ "start:prod": "node dist/main", "test": "playwright test -c ./dist", "test:smoke": "playwright test -c ./dist smoke", - "test:widgets": "playwright test --repeat-each=10 -c ./dist widgets" + "test:widgets": "playwright test -c ./dist widgets" }, "dependencies": { "@lidofinance/wallets-testing-extensions": "*", diff --git a/wallets-testing/playwright.config.ts b/wallets-testing/playwright.config.ts index daa890f7..d1cdc80f 100644 --- a/wallets-testing/playwright.config.ts +++ b/wallets-testing/playwright.config.ts @@ -23,7 +23,7 @@ const config: PlaywrightTestConfig = { /* Run tests in files in parallel */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: false, //todo revert + forbidOnly: !!process.env.CI, /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ diff --git a/wallets-testing/test/widgets/ethereum.spec.ts b/wallets-testing/test/widgets/ethereum.spec.ts index d8c5f0f2..9561b068 100644 --- a/wallets-testing/test/widgets/ethereum.spec.ts +++ b/wallets-testing/test/widgets/ethereum.spec.ts @@ -63,8 +63,7 @@ test.describe('Ethereum', () => { await browserService.connectWallet(); }); - // todo remove .only - test.only(`Ctrl connect`, async () => { + test(`Ctrl connect`, async () => { await browserService.setup(CTRL_COMMON_CONFIG, ETHEREUM_WIDGET_CONFIG); await browserService.connectWallet(); }); From 27b70c9f87503feb219ec39b1e2ef6f42872e493 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 17:44:24 +0300 Subject: [PATCH 08/15] test: revert test fixes --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3207a0b6..a481515e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: run: yarn build - name: Install Playwright Browsers - run: yarn playwright install chromium --with-deps + run: npx playwright install chromium --with-deps - name: Run wallets tests run: xvfb-run --auto-servernum -- yarn test:widgets From 5456719ef802d856dc49741bbf9b7281bc12aae9 Mon Sep 17 00:00:00 2001 From: jake Date: Tue, 14 Jan 2025 18:38:10 +0300 Subject: [PATCH 09/15] test: revert test fixes --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a481515e..30848832 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: run: yarn build - name: Install Playwright Browsers - run: npx playwright install chromium --with-deps + run: npx playwright install --with-deps - name: Run wallets tests run: xvfb-run --auto-servernum -- yarn test:widgets From ebfd579edb19fbc971d6bc26db09dc929a2c22e2 Mon Sep 17 00:00:00 2001 From: jake Date: Wed, 15 Jan 2025 23:30:23 +0300 Subject: [PATCH 10/15] test: add dbclick for wallet connection --- packages/widgets/src/ethereum/ethereum.page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/src/ethereum/ethereum.page.ts b/packages/widgets/src/ethereum/ethereum.page.ts index bfd7a96a..9f99dfcf 100644 --- a/packages/widgets/src/ethereum/ethereum.page.ts +++ b/packages/widgets/src/ethereum/ethereum.page.ts @@ -50,7 +50,7 @@ export class EthereumPage implements WidgetPage { if (!(await this.page.isChecked('input[type=checkbox]'))) await this.page.click('input[type=checkbox]', { force: true }); if (walletPage.config.COMMON.SIMPLE_CONNECT) { - await this.page.click( + await this.page.dblclick( `button[type=button] :text('${walletPage.config.COMMON.CONNECT_BUTTON_NAME}')`, ); } else { From cf228c0d4e24fb0107da70b0158042fec9d36e0b Mon Sep 17 00:00:00 2001 From: jake Date: Wed, 15 Jan 2025 23:43:20 +0300 Subject: [PATCH 11/15] test: add dbclick for wallet connection x2 --- packages/widgets/src/ethereum/ethereum.page.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/widgets/src/ethereum/ethereum.page.ts b/packages/widgets/src/ethereum/ethereum.page.ts index 9f99dfcf..4364ea86 100644 --- a/packages/widgets/src/ethereum/ethereum.page.ts +++ b/packages/widgets/src/ethereum/ethereum.page.ts @@ -50,13 +50,13 @@ export class EthereumPage implements WidgetPage { if (!(await this.page.isChecked('input[type=checkbox]'))) await this.page.click('input[type=checkbox]', { force: true }); if (walletPage.config.COMMON.SIMPLE_CONNECT) { - await this.page.dblclick( + await this.page.click( `button[type=button] :text('${walletPage.config.COMMON.CONNECT_BUTTON_NAME}')`, ); } else { const [connectWalletPage] = await Promise.all([ this.page.context().waitForEvent('page', { timeout: 5000 }), - this.page.click( + this.page.dblclick( `button[type=button] :text('${walletPage.config.COMMON.CONNECT_BUTTON_NAME}')`, ), ]); From be8fd83eae9dc32b325991bdda8543a14f73f20e Mon Sep 17 00:00:00 2001 From: jake Date: Thu, 16 Jan 2025 00:02:24 +0300 Subject: [PATCH 12/15] test: update widget connectWallet function --- .../widgets/src/ethereum/ethereum.page.ts | 83 ++++++++++--------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/packages/widgets/src/ethereum/ethereum.page.ts b/packages/widgets/src/ethereum/ethereum.page.ts index 4364ea86..1651d6ec 100644 --- a/packages/widgets/src/ethereum/ethereum.page.ts +++ b/packages/widgets/src/ethereum/ethereum.page.ts @@ -9,9 +9,15 @@ import { test, Page, Locator } from '@playwright/test'; export class EthereumPage implements WidgetPage { private readonly logger = new Logger(EthereumPage.name); page: Page; + connectBtn: Locator; + stakeSubmitBtn: Locator; + termsCheckbox: Locator; constructor(page: Page, private stakeConfig: StakeConfig) { this.page = page; + this.connectBtn = this.page.getByTestId('connectBtn'); + this.stakeSubmitBtn = this.page.getByTestId('stakeSubmitBtn'); + this.termsCheckbox = this.page.locator('input[type=checkbox]'); } async navigate() { @@ -37,43 +43,46 @@ export class EthereumPage implements WidgetPage { } async connectWallet(walletPage: WalletPage) { - await test.step( - 'Connect wallet ' + walletPage.config.COMMON.WALLET_NAME, - async () => { - await this.page.waitForTimeout(2000); - const isConnected = - (await this.page.getByTestId('connectBtn').count()) === 0; - if (!isConnected) { - await this.page.getByTestId('connectBtn').first().click(); - await this.page.waitForTimeout(2000); - if ((await this.page.getByTestId('stakeSubmitBtn').count()) === 0) { - if (!(await this.page.isChecked('input[type=checkbox]'))) - await this.page.click('input[type=checkbox]', { force: true }); - if (walletPage.config.COMMON.SIMPLE_CONNECT) { - await this.page.click( - `button[type=button] :text('${walletPage.config.COMMON.CONNECT_BUTTON_NAME}')`, - ); - } else { - const [connectWalletPage] = await Promise.all([ - this.page.context().waitForEvent('page', { timeout: 5000 }), - this.page.dblclick( - `button[type=button] :text('${walletPage.config.COMMON.CONNECT_BUTTON_NAME}')`, - ), - ]); - await walletPage.connectWallet(connectWalletPage); - } - expect( - await this.page.waitForSelector('data-testid=stakeSubmitBtn'), - ).not.toBeNaN(); - await this.page.locator('data-testid=accountSectionHeader').click(); - expect( - await this.page.textContent('div[data-testid="providerName"]'), - ).toContain(walletPage.config.COMMON.CONNECTED_WALLET_NAME); - await this.page.locator('div[role="dialog"] button').nth(0).click(); - } - } - }, - ); + await test.step(`Connect wallet ${walletPage.config.COMMON.WALLET_NAME}`, async () => { + await this.page.waitForTimeout(2000); + // If wallet connected -> return + if ((await this.connectBtn.count()) === 0) return; + await this.connectBtn.first().click(); + await this.page.waitForTimeout(2000); + // If Stake submit button is displayed -> return + if ((await this.stakeSubmitBtn.count()) > 0) return; + + if (!(await this.termsCheckbox.isChecked())) + await this.termsCheckbox.click({ force: true }); + + const walletButton = this.page + .getByRole('button') + .getByText(walletPage.config.COMMON.CONNECT_BUTTON_NAME, { + exact: true, + }); + + if ( + (await walletButton.isEnabled({ timeout: 1000 })) && + walletPage.config.COMMON.SIMPLE_CONNECT + ) { + await walletButton.click(); + } else { + const [connectWalletPage] = await Promise.all([ + this.page.context().waitForEvent('page', { timeout: 5000 }), + walletButton.dblclick(), + ]); + await walletPage.connectWallet(connectWalletPage); + } + + expect( + await this.page.waitForSelector('data-testid=stakeSubmitBtn'), + ).not.toBeNaN(); + await this.page.locator('data-testid=accountSectionHeader').click(); + expect( + await this.page.textContent('div[data-testid="providerName"]'), + ).toContain(walletPage.config.COMMON.CONNECTED_WALLET_NAME); + await this.page.locator('div[role="dialog"] button').nth(0).click(); + }); } async doStaking(walletPage: WalletPage) { From 3ac0b1e9767bb8fb182470c3e5b8e0c213e3dc21 Mon Sep 17 00:00:00 2001 From: jake Date: Thu, 16 Jan 2025 00:20:34 +0300 Subject: [PATCH 13/15] test: update widget connectWallet function x2 --- packages/widgets/src/ethereum/ethereum.page.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/widgets/src/ethereum/ethereum.page.ts b/packages/widgets/src/ethereum/ethereum.page.ts index 1651d6ec..d01078c5 100644 --- a/packages/widgets/src/ethereum/ethereum.page.ts +++ b/packages/widgets/src/ethereum/ethereum.page.ts @@ -54,6 +54,7 @@ export class EthereumPage implements WidgetPage { if (!(await this.termsCheckbox.isChecked())) await this.termsCheckbox.click({ force: true }); + await this.page.waitForTimeout(1000); const walletButton = this.page .getByRole('button') @@ -61,15 +62,12 @@ export class EthereumPage implements WidgetPage { exact: true, }); - if ( - (await walletButton.isEnabled({ timeout: 1000 })) && - walletPage.config.COMMON.SIMPLE_CONNECT - ) { + if (walletPage.config.COMMON.SIMPLE_CONNECT) { await walletButton.click(); } else { const [connectWalletPage] = await Promise.all([ this.page.context().waitForEvent('page', { timeout: 5000 }), - walletButton.dblclick(), + walletButton.click(), ]); await walletPage.connectWallet(connectWalletPage); } From 7f597e560406c4372c121630f69e7d7e595e5b83 Mon Sep 17 00:00:00 2001 From: jake Date: Thu, 16 Jan 2025 12:52:04 +0300 Subject: [PATCH 14/15] fix: fixes after review --- packages/wallets/src/ctrl/ctrl.page.ts | 12 +-- packages/wallets/src/ctrl/helper.ts | 8 -- packages/wallets/src/ctrl/index.ts | 1 - .../wallets/src/ctrl/pages/onboarding.page.ts | 80 ++++++++++--------- .../widgets/src/ethereum/ethereum.page.ts | 1 - wallets-testing/playwright.config.ts | 2 +- 6 files changed, 44 insertions(+), 60 deletions(-) delete mode 100644 packages/wallets/src/ctrl/helper.ts diff --git a/packages/wallets/src/ctrl/ctrl.page.ts b/packages/wallets/src/ctrl/ctrl.page.ts index cbe781dd..81cec221 100644 --- a/packages/wallets/src/ctrl/ctrl.page.ts +++ b/packages/wallets/src/ctrl/ctrl.page.ts @@ -2,7 +2,6 @@ import { WalletPage } from '../wallet.page'; import { test, BrowserContext, Page } from '@playwright/test'; import { WalletConfig } from '../wallets.constants'; import { LoginPage, OnboardingPage, WalletOperations } from './pages'; -import { closeUnnecessaryPages } from './helper'; export class CtrlPage implements WalletPage { page: Page | undefined; @@ -20,7 +19,6 @@ export class CtrlPage implements WalletPage { this.page = await this.browserContext.newPage(); this.onboardingPage = new OnboardingPage( this.page, - this.browserContext, this.extensionUrl, this.config, ); @@ -49,19 +47,13 @@ export class CtrlPage implements WalletPage { async setup() { await test.step('Setup', async () => { await this.initLocators(); - if (await this.onboardingPage.isNeedToGoThroughOnboarding()) { - await this.onboardingPage.firstTimeSetup(); - await this.goto(); - await this.onboardingPage.closeWalletTour(); - await this.onboardingPage.createWalletPassword(); - } - await closeUnnecessaryPages(this.browserContext); + await this.onboardingPage.firstTimeSetup(); }); } /** Click `Connect` button */ async connectWallet(page: Page) { - await test.step('Connect OKX wallet', async () => { + await test.step('Connect Ctrl wallet', async () => { const operationPage = new WalletOperations(page); await operationPage.connectBtn.waitFor({ state: 'visible', diff --git a/packages/wallets/src/ctrl/helper.ts b/packages/wallets/src/ctrl/helper.ts deleted file mode 100644 index 6ad88a2d..00000000 --- a/packages/wallets/src/ctrl/helper.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { BrowserContext } from '@playwright/test'; - -export async function closeUnnecessaryPages(browserContext: BrowserContext) { - const pages = browserContext.pages().slice(1); - for (const page of pages) { - await page.close(); - } -} diff --git a/packages/wallets/src/ctrl/index.ts b/packages/wallets/src/ctrl/index.ts index cf36ea65..2115c3dd 100644 --- a/packages/wallets/src/ctrl/index.ts +++ b/packages/wallets/src/ctrl/index.ts @@ -1,3 +1,2 @@ export * from './ctrl.page'; export * from './ctrl.constants'; -export * from './helper'; diff --git a/packages/wallets/src/ctrl/pages/onboarding.page.ts b/packages/wallets/src/ctrl/pages/onboarding.page.ts index 34201640..15a33cca 100644 --- a/packages/wallets/src/ctrl/pages/onboarding.page.ts +++ b/packages/wallets/src/ctrl/pages/onboarding.page.ts @@ -1,4 +1,4 @@ -import { BrowserContext, Locator, Page, test } from '@playwright/test'; +import { Locator, Page, test, expect } from '@playwright/test'; import { WalletConfig } from '../../wallets.constants'; export class OnboardingPage { @@ -15,7 +15,6 @@ export class OnboardingPage { constructor( page: Page, - private browserContext: BrowserContext, private extensionUrl: string, public config: WalletConfig, ) { @@ -37,29 +36,12 @@ export class OnboardingPage { this.confirmPasswordBtn = this.page.getByTestId('button'); } - async isNeedToGoThroughOnboarding() { - return await test.step('Open the onboarding page', async () => { - // Need to open onboarding page cause the extension does not redirect from home url automatically - await this.page.goto( - this.extensionUrl + '/tabs/onboarding.html#onboarding', - ); - - const btn = this.page.getByTestId('i-already-have-a-wallet-btn'); - try { - await btn.waitFor({ - state: 'visible', - timeout: 5000, - }); - } catch { - console.log('Onboarding process is not needed'); - } - return btn.isVisible(); - }); - } - async firstTimeSetup() { + if (await this.isWalletSetup()) return; + await test.step('First time set up', async () => { - await this.page.waitForTimeout(1000); // Need to wait some time for button enabling + // Without additional awaiting the extension breaks the next step and redirects a user back + await this.page.waitForTimeout(2000); await this.alreadyHaveWalletBtn.click({ force: true }); await test.step('Import wallet with recovery phrase', async () => { @@ -70,29 +52,49 @@ export class OnboardingPage { } await this.nextBtn.click(); await this.importBtn.waitFor({ state: 'visible', timeout: 60000 }); - await this.page.waitForTimeout(1000); // Need to wait some time for button enabling + await expect(this.importBtn).toBeEnabled({ timeout: 2000 }); await this.importBtn.click(); await this.nextBtn.click(); }); - }); - } - async closeWalletTour() { - await test.step('Close wallet tour', async () => { - await this.closeTourBtn.waitFor({ state: 'visible', timeout: 2000 }); - await this.closeTourBtn.click(); - await this.notNowBtn.waitFor({ state: 'visible', timeout: 2000 }); - await this.page.waitForTimeout(1000); // Need to wait some time for button enabling - await this.notNowBtn.click({ force: true }); + await this.page.goto( + this.extensionUrl + this.config.COMMON.EXTENSION_START_PATH, + ); + + await test.step('Close wallet tour', async () => { + await this.closeTourBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.closeTourBtn.click(); + await this.notNowBtn.waitFor({ state: 'visible', timeout: 2000 }); + await this.page.waitForTimeout(1000); // Need to wait some time for button enabling + await this.notNowBtn.click({ force: true }); + }); + + await test.step('Create wallet password', async () => { + await this.createPasswordBtn.click(); + await this.passwordInput.nth(0).fill(this.config.PASSWORD); + await this.passwordInput.nth(1).fill(this.config.PASSWORD); + await this.confirmPasswordBtn.click(); + }); }); } - async createWalletPassword() { - await test.step('Create wallet password', async () => { - await this.createPasswordBtn.click(); - await this.passwordInput.nth(0).fill(this.config.PASSWORD); - await this.passwordInput.nth(1).fill(this.config.PASSWORD); - await this.confirmPasswordBtn.click(); + async isWalletSetup() { + await test.step('Open the onboarding page', async () => { + // Need to open onboarding page cause the extension does not redirect from home url automatically + await this.page.goto( + this.extensionUrl + '/tabs/onboarding.html#onboarding', + ); + }); + return await test.step('Check the wallet is set up', async () => { + try { + await this.alreadyHaveWalletBtn.waitFor({ + state: 'visible', + timeout: 5000, + }); + } catch { + console.log('Ctrl wallet: Onboarding process is not needed'); + } + return !(await this.alreadyHaveWalletBtn.isVisible()); }); } } diff --git a/packages/widgets/src/ethereum/ethereum.page.ts b/packages/widgets/src/ethereum/ethereum.page.ts index d01078c5..c03291d2 100644 --- a/packages/widgets/src/ethereum/ethereum.page.ts +++ b/packages/widgets/src/ethereum/ethereum.page.ts @@ -54,7 +54,6 @@ export class EthereumPage implements WidgetPage { if (!(await this.termsCheckbox.isChecked())) await this.termsCheckbox.click({ force: true }); - await this.page.waitForTimeout(1000); const walletButton = this.page .getByRole('button') diff --git a/wallets-testing/playwright.config.ts b/wallets-testing/playwright.config.ts index d1cdc80f..f22f8e7a 100644 --- a/wallets-testing/playwright.config.ts +++ b/wallets-testing/playwright.config.ts @@ -46,7 +46,7 @@ const config: PlaywrightTestConfig = { // baseURL: 'http://localhost:3000', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'retain-on-failure', + trace: 'on-first-retry', }, /* Folder for test artifacts such as screenshots, videos, traces, etc. */ From c44f78326946050e7bf4cff5cd660eff3f649c5a Mon Sep 17 00:00:00 2001 From: jake Date: Thu, 16 Jan 2025 13:00:06 +0300 Subject: [PATCH 15/15] fix: fix workflow install browser command --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 30848832..3207a0b6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: run: yarn build - name: Install Playwright Browsers - run: npx playwright install --with-deps + run: yarn playwright install chromium --with-deps - name: Run wallets tests run: xvfb-run --auto-servernum -- yarn test:widgets