From 8eb2f3b2f5c00ec04633cf92f1742cf3f8b038ca Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 17 Aug 2023 13:15:25 +0200 Subject: [PATCH 01/15] test: revoke handling --- .../deposit/deposit-with-blockchain.feature | 15 ++++ tests/e2e/src/pages/external.page.ts | 88 +++++++++++++++++++ tests/e2e/src/pages/metamask.page.ts | 74 +++++++++++++--- tests/e2e/src/steps/portal.steps.ts | 35 ++++++++ tests/e2e/src/support/config.ts | 1 + 5 files changed, 202 insertions(+), 11 deletions(-) create mode 100644 tests/e2e/src/pages/external.page.ts diff --git a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature index e4618d9a..6fedd4de 100644 --- a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature +++ b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature @@ -16,3 +16,18 @@ Feature: Deposit When I choose "ETH" as token and insert "0.0000000001" as amount When I "confirm" transaction after clicking "Add funds to zkSync Era Testnet" button Then Message "Transaction submitted" should be visible + + # It takes ~2m40.775s + @id1295 @resetAllowance + Scenario: Make a deposit with approving an allowance + Given I reset allowance + Given I go to the main page + Given I am on the Main page + Given I go to "Deposit" transaction section + When I click by "text" with "Your account" value + Then Element with "testId" "fee-amount" should be "visible" + When I choose "DAI" as token and insert "0.0000000001" as amount + Then I call the transaction interface + Then I "handle" transaction after clicking "Approve allowance" button + When I "confirm" transaction after clicking "Add funds to zkSync Era Testnet" button + Then Message "Transaction submitted" should be visible diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts new file mode 100644 index 00000000..bffef65f --- /dev/null +++ b/tests/e2e/src/pages/external.page.ts @@ -0,0 +1,88 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { setTimeout } from "timers/promises"; + +import { BasePage } from "./base.page"; +import { currentWalletAddress, MetamaskPage } from "./metamask.page"; +import { MainPage } from "../pages/main.page"; +import { config } from "../support/config"; + +import type { ICustomWorld } from "../support/custom-world"; + +let metamaskPage: any; +let result: any; +let selector: string; + +export class ExternalPage extends BasePage { + constructor(world: ICustomWorld) { + super(world); + } + + // selectors for revoke + get networkSelectorsListForRevoke() { + return "//*[@id='react-select-address-chain-select-live-region']"; + } + + async revokeButton(value: string) { + return `//button[contains(text(), '${value}')]`; + } + + async commonButtonByItsName(value: string) { + return `//button[contains(., '${value}')]`; + } + + async checkNetworkForRevoke(network: string) { + const selector = `${this.networkSelectorsListForRevoke}/..//img[@alt='${network}']`; + result = await this.world.page?.locator(selector).first().isVisible(); + return result; + } + + async buttonOfModalCard(buttonText: string) { + const mainPage = new MainPage(this.world); + return `${mainPage.modalCard}//button[contains(., '${buttonText}')]`; + } + + async clickByMenuWalletButton() { + selector = "//button/div[contains(text(), '0x')]"; + await this.world.page?.waitForSelector(selector); + await this.world.page?.locator(selector).first().click(config.defaultTimeout); + } + + async revokeAllowance() { + metamaskPage = await new MetamaskPage(this.world); + const networkChainId = "?chainId=5"; // Goerli + const revokeGoerliUrl = "https://revoke.cash/address/" + currentWalletAddress + networkChainId; + const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); + if (!networkForRevokeIsSelected) { + await this.goTo(revokeGoerliUrl); + console.log(revokeGoerliUrl); + } + + await setTimeout(config.defaultTimeout.timeout); + selector = await this.revokeButton("Switch Network"); + const switchNetworkIsVisible = await this.world.page?.locator(selector).isVisible(); + if (switchNetworkIsVisible) { + const popUpContext = await metamaskPage.catchPopUpByClick(selector); + await popUpContext?.setViewportSize(config.popUpWindowSize); + await popUpContext?.click(metamaskPage.switchNetworkButton); + } + + await setTimeout(config.defaultTimeout.timeout); + selector = await this.revokeButton("Revoke"); + const revokeButtonIsVisible = await this.world.page?.locator(selector).isVisible(); + if (revokeButtonIsVisible) { + const popUpContext = await metamaskPage.catchPopUpByClick(selector); + await popUpContext?.setViewportSize(config.popUpWindowSize); + await popUpContext?.click(metamaskPage.confirmTransaction); + await this.revokeAllowance(); + } + + selector = await this.revokeButton("Revoking"); + let revokingButtonIsVisible = await this.world.page?.locator(selector).isVisible(); + if (revokingButtonIsVisible) { + do { + await setTimeout(3 * 1000); + revokingButtonIsVisible = await this.world.page?.locator(selector).isVisible(); + } while (revokingButtonIsVisible); + } + } +} diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 941cc795..68492535 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -5,6 +5,7 @@ import { BasePage } from "./base.page"; import { MainPage } from "./main.page"; import { Extension } from "../data/data"; import { depositTag, Helper } from "../helpers/helper"; +import { ExternalPage } from "../pages/external.page"; import { config, wallet } from "../support/config"; import type { ICustomWorld } from "../support/custom-world"; @@ -13,6 +14,8 @@ let page: any; let element: any; let metamaskHomeUrl: string; let metamaskWelcomeUrl: string; +export let currentWalletAddress: string; +let selector: string; let testId: any; let logoutTrigger: any = undefined; @@ -49,6 +52,14 @@ export class MetamaskPage extends BasePage { return "//*[@data-testid='advanced-setting-reset-account']//button[1]"; // //button[contains(text(),'Reset')]| } + get nextButton() { + return "//button[contains(text(), 'Next')]"; + } + + get switchNetworkButton() { + return "//button[contains(text(), 'Switch network')]"; + } + get extensionDetailsBtn() { return "id=detailsButton"; } @@ -58,7 +69,7 @@ export class MetamaskPage extends BasePage { } get confirmTransaction() { - return "//*[@data-testid='page-container-footer-next']"; + return `//*[@data-testid='page-container-footer-next'] | //button[contains(text(), 'Confirm')]`; } get declineBtn() { @@ -109,6 +120,10 @@ export class MetamaskPage extends BasePage { return `@value='${value}'`; } + get copyWalletAddress() { + return "//button[@class='selected-account__clickable']"; + } + //metamask home page get headerIcon() { return "(//*[contains(@class,'app-header')]//div[contains(@class,'identicon')])[1]"; @@ -154,6 +169,17 @@ export class MetamaskPage extends BasePage { } } + async getCurrentWalletAddress() { + await this.getMetamaskExtensionUrl(); + await page.goto(metamaskWelcomeUrl); + await page.reload(); + //await page.bringToFront(); + await page.locator("//button[@data-testid='popover-close']").click(); + await page.locator(this.copyWalletAddress).click(); + const address = await page.evaluate("navigator.clipboard.readText()"); + return address.toString(); + } + async authorizeInMetamaskExtension(secretPhrase: Array, password: string) { const helper = await new Helper(this.world); const wallet_password = await helper.decrypt(wallet.password); @@ -174,20 +200,46 @@ export class MetamaskPage extends BasePage { } } logoutTrigger = false; + currentWalletAddress = await this.getCurrentWalletAddress(); + console.log(currentWalletAddress); } - async operateTransaction(triggeredElement: string) { - //change network - try { + async callTransactionInterface() { + const externalPage = await new ExternalPage(this.world); + selector = await externalPage.commonButtonByItsName("Change wallet network"); + const networkChangeRequest = await this.world.page?.locator(selector).isVisible(); + if (networkChangeRequest) { await this.switchNetwork(); - } finally { - await setTimeout(config.minimalTimeout.timeout); - await this.click(this.continueBtn); + } + await setTimeout(config.defaultTimeout.timeout); + selector = await externalPage.commonButtonByItsName("Continue"); + const continueBtn = await this.world.page?.locator(selector).isVisible(); + if (continueBtn) { + await this.click(selector); + } + } - const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`); - await setTimeout(config.minimalTimeout.timeout); - await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(this.confirmTransaction); + async operateTransaction(triggeredElement: string) { + const externalPage = await new ExternalPage(this.world); + const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`); + await setTimeout(2.5 * 1000); + await popUpContext?.setViewportSize(config.popUpWindowSize); + // will be required for metamask > v10.14.1 + // if (triggeredElement === "Approve allowance") { + // await popUpContext?.click(this.metamaskUseDefaultButton); + // } + await popUpContext?.click(this.confirmTransaction); + + if (triggeredElement === "Approve allowance") { + selector = "//div[@class='modal-card']//*[contains(text(), 'Allowance approved')]"; + let allowanceFinalized = await this.world.page?.locator(selector).isVisible(); + if (!allowanceFinalized) { + do { + await setTimeout(5 * 1000); + allowanceFinalized = await this.world.page?.locator(selector).isVisible(); + } while (!allowanceFinalized); + } + await this.click(await externalPage.buttonOfModalCard("Continue")); } } diff --git a/tests/e2e/src/steps/portal.steps.ts b/tests/e2e/src/steps/portal.steps.ts index 3e2f39ec..c09e87e7 100644 --- a/tests/e2e/src/steps/portal.steps.ts +++ b/tests/e2e/src/steps/portal.steps.ts @@ -6,6 +6,7 @@ import { NetworkSwitcher } from "../data/data"; import { Helper } from "../helpers/helper"; import { BasePage } from "../pages/base.page"; import { ContactsPage } from "../pages/contacts.page"; +import { ExternalPage } from "../pages/external.page"; import { LoginPage } from "../pages/login.page"; import { MainPage } from "../pages/main.page"; import { MetamaskPage } from "../pages/metamask.page"; @@ -16,6 +17,7 @@ import type { ICustomWorld } from "../support/custom-world"; let basePage: BasePage; let mainPage: MainPage; let loginPage: LoginPage; +let externalPage: ExternalPage; let metamaskPage: MetamaskPage; let contactsPage: ContactsPage; let helper: Helper; @@ -212,6 +214,11 @@ Given("I click on the {string} contact button", async function (this: ICustomWor await contactsPage.pressRemoveBtnModal(removeButtonName); }); +Given("I go to the main page", config.stepTimeout, async function (this: ICustomWorld) { + await this.page?.waitForLoadState("load", config.defaultTimeout); + await this.page?.goto(config.BASE_URL + config.DAPP_NETWORK); +}); + Given("I am on the Main page", async function (this: ICustomWorld) { const basePage = new BasePage(this); element = await basePage.returnElementByType("text", "Assets"); @@ -362,3 +369,31 @@ Then( await expect(element).toBeVisible(); } ); + +Given("I reset allowance", config.stepExtraTimeout, async function (this: ICustomWorld) { + externalPage = new ExternalPage(this); + basePage = new BasePage(this); + metamaskPage = new MetamaskPage(this); + + const revokeUrl = "https://revoke.cash/"; + + await basePage.goTo(revokeUrl); + // login + await basePage.clickByText("Connect Wallet"); + const popUpContext = await metamaskPage.catchPopUpByClick(`//button[contains(text(),'MetaMask')]`); + await popUpContext?.setViewportSize(config.popUpWindowSize); + await popUpContext?.click(metamaskPage.nextButton); + await popUpContext?.click(metamaskPage.confirmTransaction); + + // operate + await externalPage.revokeAllowance(); + + // logout + await externalPage.clickByMenuWalletButton(); + await basePage.clickByText("Disconnect"); +}); + +When("I call the transaction interface", config.stepTimeout, async function (this: ICustomWorld) { + metamaskPage = new MetamaskPage(this); + await metamaskPage.callTransactionInterface(); +}); diff --git a/tests/e2e/src/support/config.ts b/tests/e2e/src/support/config.ts index 19c126b7..d8a1f403 100644 --- a/tests/e2e/src/support/config.ts +++ b/tests/e2e/src/support/config.ts @@ -41,6 +41,7 @@ export const config = { minimalTimeout: { timeout: 1 * 1000 }, increasedTimeout: { timeout: 15 * 1000 }, stepTimeout: { timeout: 60 * 1000 }, + stepExtraTimeout: { timeout: 120 * 1000 }, feeLimitations: true, feeBoundaryLevel: 0.2, // in ETH networkL1: "goerli", From 781aa6af2133a333a766a3baf1fd5f951cd1a14b Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 17 Aug 2023 16:32:32 +0200 Subject: [PATCH 02/15] test: revoke handling fix context --- tests/e2e/src/pages/external.page.ts | 4 ++-- tests/e2e/src/pages/metamask.page.ts | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index bffef65f..9def3c23 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -2,7 +2,7 @@ import { setTimeout } from "timers/promises"; import { BasePage } from "./base.page"; -import { currentWalletAddress, MetamaskPage } from "./metamask.page"; +import { MetamaskPage } from "./metamask.page"; import { MainPage } from "../pages/main.page"; import { config } from "../support/config"; @@ -49,12 +49,12 @@ export class ExternalPage extends BasePage { async revokeAllowance() { metamaskPage = await new MetamaskPage(this.world); + const currentWalletAddress = (await metamaskPage.getCurrentWalletAddress()).toString; const networkChainId = "?chainId=5"; // Goerli const revokeGoerliUrl = "https://revoke.cash/address/" + currentWalletAddress + networkChainId; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); if (!networkForRevokeIsSelected) { await this.goTo(revokeGoerliUrl); - console.log(revokeGoerliUrl); } await setTimeout(config.defaultTimeout.timeout); diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 68492535..c2fdc0a4 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -14,7 +14,6 @@ let page: any; let element: any; let metamaskHomeUrl: string; let metamaskWelcomeUrl: string; -export let currentWalletAddress: string; let selector: string; let testId: any; let logoutTrigger: any = undefined; @@ -170,14 +169,16 @@ export class MetamaskPage extends BasePage { } async getCurrentWalletAddress() { + const newPage = await this.world.context?.newPage(); await this.getMetamaskExtensionUrl(); - await page.goto(metamaskWelcomeUrl); - await page.reload(); - //await page.bringToFront(); - await page.locator("//button[@data-testid='popover-close']").click(); - await page.locator(this.copyWalletAddress).click(); - const address = await page.evaluate("navigator.clipboard.readText()"); - return address.toString(); + await newPage?.goto(metamaskWelcomeUrl); + await newPage?.reload(); + await newPage?.locator("//button[@data-testid='popover-close']").click(); + await newPage?.locator(this.copyWalletAddress).click(); + const address = await newPage?.evaluate("navigator.clipboard.readText()"); + await newPage?.close(); + await page.bringToFront(); + return address; } async authorizeInMetamaskExtension(secretPhrase: Array, password: string) { @@ -200,8 +201,6 @@ export class MetamaskPage extends BasePage { } } logoutTrigger = false; - currentWalletAddress = await this.getCurrentWalletAddress(); - console.log(currentWalletAddress); } async callTransactionInterface() { From 2be67bdc445dddcd2ae7b46c5fb4c9a772cfe90f Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 17 Aug 2023 17:14:58 +0200 Subject: [PATCH 03/15] test: update a transaction interface --- tests/e2e/src/pages/external.page.ts | 4 ---- tests/e2e/src/pages/main.page.ts | 6 +++++- tests/e2e/src/pages/metamask.page.ts | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index 9def3c23..70c621bb 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -26,10 +26,6 @@ export class ExternalPage extends BasePage { return `//button[contains(text(), '${value}')]`; } - async commonButtonByItsName(value: string) { - return `//button[contains(., '${value}')]`; - } - async checkNetworkForRevoke(network: string) { const selector = `${this.networkSelectorsListForRevoke}/..//img[@alt='${network}']`; result = await this.world.page?.locator(selector).first().isVisible(); diff --git a/tests/e2e/src/pages/main.page.ts b/tests/e2e/src/pages/main.page.ts index c161068b..99a46f3d 100644 --- a/tests/e2e/src/pages/main.page.ts +++ b/tests/e2e/src/pages/main.page.ts @@ -93,6 +93,10 @@ export class MainPage extends BasePage { return "//button[text()='Confirm']"; } + async commonButtonByItsName(value: string) { + return `//button[contains(., '${value}')]`; + } + async selectTransaction(transactionType: string) { try { let route: string; @@ -126,7 +130,7 @@ export class MainPage extends BasePage { async makeTransaction(actionType: string, transactionType: string) { metamaskPage = await new MetamaskPage(this.world); result = await this.getTransactionSelector(transactionType); - + await metamaskPage.callTransactionInterface(); await metamaskPage.operateTransaction(result); } diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index c2fdc0a4..f80b67d0 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -204,14 +204,14 @@ export class MetamaskPage extends BasePage { } async callTransactionInterface() { - const externalPage = await new ExternalPage(this.world); - selector = await externalPage.commonButtonByItsName("Change wallet network"); + const mainPage = await new MainPage(this.world); + selector = await mainPage.commonButtonByItsName("Change wallet network"); const networkChangeRequest = await this.world.page?.locator(selector).isVisible(); if (networkChangeRequest) { await this.switchNetwork(); } await setTimeout(config.defaultTimeout.timeout); - selector = await externalPage.commonButtonByItsName("Continue"); + selector = await mainPage.commonButtonByItsName("Continue"); const continueBtn = await this.world.page?.locator(selector).isVisible(); if (continueBtn) { await this.click(selector); From a2cf3ba4ae8037982ad9a9d35d1f35de9dd8d348 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 17 Aug 2023 23:04:20 +0200 Subject: [PATCH 04/15] test: update modal-card call --- .../transactions/deposit/deposit-with-blockchain.feature | 1 - tests/e2e/src/pages/external.page.ts | 2 +- tests/e2e/src/pages/metamask.page.ts | 3 ++- tests/e2e/src/steps/portal.steps.ts | 7 +------ 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature index 6fedd4de..069707b6 100644 --- a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature +++ b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature @@ -27,7 +27,6 @@ Feature: Deposit When I click by "text" with "Your account" value Then Element with "testId" "fee-amount" should be "visible" When I choose "DAI" as token and insert "0.0000000001" as amount - Then I call the transaction interface Then I "handle" transaction after clicking "Approve allowance" button When I "confirm" transaction after clicking "Add funds to zkSync Era Testnet" button Then Message "Transaction submitted" should be visible diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index 70c621bb..2c6d792d 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -45,7 +45,7 @@ export class ExternalPage extends BasePage { async revokeAllowance() { metamaskPage = await new MetamaskPage(this.world); - const currentWalletAddress = (await metamaskPage.getCurrentWalletAddress()).toString; + const currentWalletAddress = await metamaskPage.getCurrentWalletAddress(); const networkChainId = "?chainId=5"; // Goerli const revokeGoerliUrl = "https://revoke.cash/address/" + currentWalletAddress + networkChainId; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index f80b67d0..f292ba47 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -213,7 +213,8 @@ export class MetamaskPage extends BasePage { await setTimeout(config.defaultTimeout.timeout); selector = await mainPage.commonButtonByItsName("Continue"); const continueBtn = await this.world.page?.locator(selector).isVisible(); - if (continueBtn) { + const modalCard = await this.world.page?.locator(mainPage.modalCard).isVisible(); + if (continueBtn && !modalCard) { await this.click(selector); } } diff --git a/tests/e2e/src/steps/portal.steps.ts b/tests/e2e/src/steps/portal.steps.ts index c09e87e7..0dd94bc3 100644 --- a/tests/e2e/src/steps/portal.steps.ts +++ b/tests/e2e/src/steps/portal.steps.ts @@ -96,7 +96,7 @@ When("Circle timer for fee updating should be visible", config.stepTimeout, asyn When( "I {string} transaction after clicking {string} button", - config.stepTimeout, + config.stepExtraTimeout, async function (this: ICustomWorld, actionType: string, transactionBtn: string) { mainPage = new MainPage(this); await mainPage.makeTransaction(actionType, transactionBtn); @@ -392,8 +392,3 @@ Given("I reset allowance", config.stepExtraTimeout, async function (this: ICusto await externalPage.clickByMenuWalletButton(); await basePage.clickByText("Disconnect"); }); - -When("I call the transaction interface", config.stepTimeout, async function (this: ICustomWorld) { - metamaskPage = new MetamaskPage(this); - await metamaskPage.callTransactionInterface(); -}); From a2571ce0591f7283d066b67cce1227767ccb22c4 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 17 Aug 2023 23:34:53 +0200 Subject: [PATCH 05/15] test: debug on CI --- .github/workflows/e2e.yml | 28 ++++++++++++++-------------- tests/e2e/cucumber.mjs | 2 +- tests/e2e/src/pages/metamask.page.ts | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 1347430d..d6d0078d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -53,21 +53,21 @@ jobs: matrix: command: ["xvfb-run --auto-servernum --server-args '-screen 0 1920x1080x24' npx cucumber-js --tags "] tags: [ - "@artifacts and @bridge", - "@artifacts and @contactsPage", - "@artifacts and @depositPage", - "@artifacts and @transferPage", - "@artifacts and @header", - "@artifacts and @menuItems", - "@artifacts and @upperNavigationMenu", - "@artifacts and @contactsPage", - "@artifacts and @withdraw", - "@navigation and not @emptyWallet", - "@artifacts and @various", - "@artifacts and @transactionsItems", + # "@artifacts and @bridge", + # "@artifacts and @contactsPage", + # "@artifacts and @depositPage", + # "@artifacts and @transferPage", + # "@artifacts and @header", + # "@artifacts and @menuItems", + # "@artifacts and @upperNavigationMenu", + # "@artifacts and @contactsPage", + # "@artifacts and @withdraw", + # "@navigation and not @emptyWallet", + # "@artifacts and @various", + # "@artifacts and @transactionsItems", "@transactions and @deposit and @blockchain", - "@transactions and @withdraw", - "@various and @emptyWallet", + # "@transactions and @withdraw", + # "@various and @emptyWallet", "@actions and @contacts" ] diff --git a/tests/e2e/cucumber.mjs b/tests/e2e/cucumber.mjs index 209ce014..261a25b4 100644 --- a/tests/e2e/cucumber.mjs +++ b/tests/e2e/cucumber.mjs @@ -16,7 +16,7 @@ export default { "summary", "progress-bar", "@cucumber/pretty-formatter", - "./src/support/reporters/allure-reporter.js", + // "./src/support/reporters/allure-reporter.js", ], formatOptions: { snippetInterface: "async-await" }, worldParameters: getWorldParams(), diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index f292ba47..b7b545fe 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -176,7 +176,7 @@ export class MetamaskPage extends BasePage { await newPage?.locator("//button[@data-testid='popover-close']").click(); await newPage?.locator(this.copyWalletAddress).click(); const address = await newPage?.evaluate("navigator.clipboard.readText()"); - await newPage?.close(); + //await newPage?.close(); await page.bringToFront(); return address; } From 30a0e26fd29c21f1fd7efd65297896e9faa160bb Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 11:57:56 +0200 Subject: [PATCH 06/15] test: debug part 1 --- tests/e2e/src/pages/external.page.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index 2c6d792d..cc6d96dc 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -45,14 +45,17 @@ export class ExternalPage extends BasePage { async revokeAllowance() { metamaskPage = await new MetamaskPage(this.world); + console.log("going to take wallet address"); const currentWalletAddress = await metamaskPage.getCurrentWalletAddress(); + console.log("Wallet address is " + currentWalletAddress); const networkChainId = "?chainId=5"; // Goerli const revokeGoerliUrl = "https://revoke.cash/address/" + currentWalletAddress + networkChainId; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); if (!networkForRevokeIsSelected) { + console.log("going to take insert revoke adress"); await this.goTo(revokeGoerliUrl); } - + console.log("Im on the revoke page"); await setTimeout(config.defaultTimeout.timeout); selector = await this.revokeButton("Switch Network"); const switchNetworkIsVisible = await this.world.page?.locator(selector).isVisible(); From d48c524e66cdf3253daf865b3f64928a7e70aca5 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 12:12:41 +0200 Subject: [PATCH 07/15] test: debug part 2 --- tests/e2e/src/pages/metamask.page.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index b7b545fe..121e1d89 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -169,14 +169,20 @@ export class MetamaskPage extends BasePage { } async getCurrentWalletAddress() { + console.log("create new page"); const newPage = await this.world.context?.newPage(); + console.log("getting mm url"); await this.getMetamaskExtensionUrl(); + console.log("going to go to mm url"); await newPage?.goto(metamaskWelcomeUrl); + console.log("reload a page"); await newPage?.reload(); await newPage?.locator("//button[@data-testid='popover-close']").click(); await newPage?.locator(this.copyWalletAddress).click(); + console.log("going to copy address"); const address = await newPage?.evaluate("navigator.clipboard.readText()"); //await newPage?.close(); + console.log("going to bring a previous page to front"); await page.bringToFront(); return address; } From 007b6f1387cbfdbcaf4cb883e2c2cc97524ea01a Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 14:32:49 +0200 Subject: [PATCH 08/15] test: fix for address --- tests/e2e/src/helpers/helper.ts | 2 +- tests/e2e/src/pages/external.page.ts | 9 ++------ tests/e2e/src/pages/metamask.page.ts | 31 ++++++++++++---------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/tests/e2e/src/helpers/helper.ts b/tests/e2e/src/helpers/helper.ts index 66ee8fc9..98f7d03d 100644 --- a/tests/e2e/src/helpers/helper.ts +++ b/tests/e2e/src/helpers/helper.ts @@ -24,7 +24,7 @@ let authorizedTag: boolean; let unauthorizedTag: boolean; let emptyWalletTag: boolean; let incognitoTag: boolean; -let transactionsTag: boolean; +export let transactionsTag: boolean; let noBlockChain: boolean; let wallet_1: string[]; let wallet_2: string[]; diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index cc6d96dc..7bb038c8 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -2,7 +2,7 @@ import { setTimeout } from "timers/promises"; import { BasePage } from "./base.page"; -import { MetamaskPage } from "./metamask.page"; +import { address, MetamaskPage } from "./metamask.page"; import { MainPage } from "../pages/main.page"; import { config } from "../support/config"; @@ -45,17 +45,12 @@ export class ExternalPage extends BasePage { async revokeAllowance() { metamaskPage = await new MetamaskPage(this.world); - console.log("going to take wallet address"); - const currentWalletAddress = await metamaskPage.getCurrentWalletAddress(); - console.log("Wallet address is " + currentWalletAddress); const networkChainId = "?chainId=5"; // Goerli - const revokeGoerliUrl = "https://revoke.cash/address/" + currentWalletAddress + networkChainId; + const revokeGoerliUrl = "https://revoke.cash/address/" + address + networkChainId; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); if (!networkForRevokeIsSelected) { - console.log("going to take insert revoke adress"); await this.goTo(revokeGoerliUrl); } - console.log("Im on the revoke page"); await setTimeout(config.defaultTimeout.timeout); selector = await this.revokeButton("Switch Network"); const switchNetworkIsVisible = await this.world.page?.locator(selector).isVisible(); diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 121e1d89..57a7e642 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -4,7 +4,7 @@ import { setTimeout } from "timers/promises"; import { BasePage } from "./base.page"; import { MainPage } from "./main.page"; import { Extension } from "../data/data"; -import { depositTag, Helper } from "../helpers/helper"; +import { depositTag, Helper, transactionsTag } from "../helpers/helper"; import { ExternalPage } from "../pages/external.page"; import { config, wallet } from "../support/config"; @@ -14,6 +14,7 @@ let page: any; let element: any; let metamaskHomeUrl: string; let metamaskWelcomeUrl: string; +export let address: string; let selector: string; let testId: any; let logoutTrigger: any = undefined; @@ -168,23 +169,14 @@ export class MetamaskPage extends BasePage { } } - async getCurrentWalletAddress() { - console.log("create new page"); - const newPage = await this.world.context?.newPage(); - console.log("getting mm url"); - await this.getMetamaskExtensionUrl(); - console.log("going to go to mm url"); - await newPage?.goto(metamaskWelcomeUrl); - console.log("reload a page"); - await newPage?.reload(); - await newPage?.locator("//button[@data-testid='popover-close']").click(); - await newPage?.locator(this.copyWalletAddress).click(); - console.log("going to copy address"); - const address = await newPage?.evaluate("navigator.clipboard.readText()"); - //await newPage?.close(); - console.log("going to bring a previous page to front"); - await page.bringToFront(); - return address; + async extractCurrentWalletAddress() { + const currentURL = page.url(); + await page.goto(metamaskWelcomeUrl); + await page.reload(); + await page.locator("//button[@data-testid='popover-close']").click(); + await page.locator(this.copyWalletAddress).click(); + address = await page.evaluate("navigator.clipboard.readText()"); + await page.goto(currentURL); } async authorizeInMetamaskExtension(secretPhrase: Array, password: string) { @@ -207,6 +199,9 @@ export class MetamaskPage extends BasePage { } } logoutTrigger = false; + if (transactionsTag) { + await this.extractCurrentWalletAddress(); + } } async callTransactionInterface() { From 46c87879f5f689a93547c35e76ca3add6d504b42 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 14:34:19 +0200 Subject: [PATCH 09/15] test: refactoring --- .github/workflows/e2e.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d6d0078d..1347430d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -53,21 +53,21 @@ jobs: matrix: command: ["xvfb-run --auto-servernum --server-args '-screen 0 1920x1080x24' npx cucumber-js --tags "] tags: [ - # "@artifacts and @bridge", - # "@artifacts and @contactsPage", - # "@artifacts and @depositPage", - # "@artifacts and @transferPage", - # "@artifacts and @header", - # "@artifacts and @menuItems", - # "@artifacts and @upperNavigationMenu", - # "@artifacts and @contactsPage", - # "@artifacts and @withdraw", - # "@navigation and not @emptyWallet", - # "@artifacts and @various", - # "@artifacts and @transactionsItems", + "@artifacts and @bridge", + "@artifacts and @contactsPage", + "@artifacts and @depositPage", + "@artifacts and @transferPage", + "@artifacts and @header", + "@artifacts and @menuItems", + "@artifacts and @upperNavigationMenu", + "@artifacts and @contactsPage", + "@artifacts and @withdraw", + "@navigation and not @emptyWallet", + "@artifacts and @various", + "@artifacts and @transactionsItems", "@transactions and @deposit and @blockchain", - # "@transactions and @withdraw", - # "@various and @emptyWallet", + "@transactions and @withdraw", + "@various and @emptyWallet", "@actions and @contacts" ] From f24e04bb0d1f91d3314d4497175a30d0991e38b5 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 16:29:03 +0200 Subject: [PATCH 10/15] test: refactoring --- tests/e2e/cucumber.mjs | 2 +- tests/e2e/src/pages/external.page.ts | 12 +++++------- tests/e2e/src/pages/main.page.ts | 4 ++++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/e2e/cucumber.mjs b/tests/e2e/cucumber.mjs index 261a25b4..209ce014 100644 --- a/tests/e2e/cucumber.mjs +++ b/tests/e2e/cucumber.mjs @@ -16,7 +16,7 @@ export default { "summary", "progress-bar", "@cucumber/pretty-formatter", - // "./src/support/reporters/allure-reporter.js", + "./src/support/reporters/allure-reporter.js", ], formatOptions: { snippetInterface: "async-await" }, worldParameters: getWorldParams(), diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/external.page.ts index 7bb038c8..2a52e08b 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/external.page.ts @@ -3,7 +3,6 @@ import { setTimeout } from "timers/promises"; import { BasePage } from "./base.page"; import { address, MetamaskPage } from "./metamask.page"; -import { MainPage } from "../pages/main.page"; import { config } from "../support/config"; import type { ICustomWorld } from "../support/custom-world"; @@ -22,6 +21,10 @@ export class ExternalPage extends BasePage { return "//*[@id='react-select-address-chain-select-live-region']"; } + get menuWalletButton() { + return "//button/div[contains(text(), '0x')]"; + } + async revokeButton(value: string) { return `//button[contains(text(), '${value}')]`; } @@ -32,13 +35,8 @@ export class ExternalPage extends BasePage { return result; } - async buttonOfModalCard(buttonText: string) { - const mainPage = new MainPage(this.world); - return `${mainPage.modalCard}//button[contains(., '${buttonText}')]`; - } - async clickByMenuWalletButton() { - selector = "//button/div[contains(text(), '0x')]"; + selector = this.menuWalletButton; await this.world.page?.waitForSelector(selector); await this.world.page?.locator(selector).first().click(config.defaultTimeout); } diff --git a/tests/e2e/src/pages/main.page.ts b/tests/e2e/src/pages/main.page.ts index 99a46f3d..53e7c700 100644 --- a/tests/e2e/src/pages/main.page.ts +++ b/tests/e2e/src/pages/main.page.ts @@ -97,6 +97,10 @@ export class MainPage extends BasePage { return `//button[contains(., '${value}')]`; } + async buttonOfModalCard(buttonText: string) { + return `${this.modalCard}//button[contains(., '${buttonText}')]`; + } + async selectTransaction(transactionType: string) { try { let route: string; From 1d19df95d6821b112b900705d0e6d62d6b014880 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Fri, 18 Aug 2023 16:40:37 +0200 Subject: [PATCH 11/15] test: refactoring --- tests/e2e/src/pages/metamask.page.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 57a7e642..6a208a0a 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -5,7 +5,6 @@ import { BasePage } from "./base.page"; import { MainPage } from "./main.page"; import { Extension } from "../data/data"; import { depositTag, Helper, transactionsTag } from "../helpers/helper"; -import { ExternalPage } from "../pages/external.page"; import { config, wallet } from "../support/config"; import type { ICustomWorld } from "../support/custom-world"; @@ -221,7 +220,7 @@ export class MetamaskPage extends BasePage { } async operateTransaction(triggeredElement: string) { - const externalPage = await new ExternalPage(this.world); + const mainPage = await new MainPage(this.world); const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`); await setTimeout(2.5 * 1000); await popUpContext?.setViewportSize(config.popUpWindowSize); @@ -240,7 +239,7 @@ export class MetamaskPage extends BasePage { allowanceFinalized = await this.world.page?.locator(selector).isVisible(); } while (!allowanceFinalized); } - await this.click(await externalPage.buttonOfModalCard("Continue")); + await this.click(await mainPage.buttonOfModalCard("Continue")); } } From c171e7fd515d84653e1666894cd2c4d8bd62a91f Mon Sep 17 00:00:00 2001 From: pcheremu Date: Tue, 22 Aug 2023 10:05:25 +0200 Subject: [PATCH 12/15] test: optimization of the code --- .../deposit/deposit-with-blockchain.feature | 1 - tests/e2e/src/helpers/helper.ts | 13 ++++++ tests/e2e/src/pages/metamask.page.ts | 39 ++++++++-------- .../{external.page.ts => revoke.page.ts} | 45 +++++++++++++------ tests/e2e/src/steps/portal.steps.ts | 28 +++--------- 5 files changed, 69 insertions(+), 57 deletions(-) rename tests/e2e/src/pages/{external.page.ts => revoke.page.ts} (62%) diff --git a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature index 069707b6..0714593a 100644 --- a/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature +++ b/tests/e2e/features/transactions/deposit/deposit-with-blockchain.feature @@ -22,7 +22,6 @@ Feature: Deposit Scenario: Make a deposit with approving an allowance Given I reset allowance Given I go to the main page - Given I am on the Main page Given I go to "Deposit" transaction section When I click by "text" with "Your account" value Then Element with "testId" "fee-amount" should be "visible" diff --git a/tests/e2e/src/helpers/helper.ts b/tests/e2e/src/helpers/helper.ts index 98f7d03d..a961e96a 100644 --- a/tests/e2e/src/helpers/helper.ts +++ b/tests/e2e/src/helpers/helper.ts @@ -88,6 +88,19 @@ export class Helper { return result; } + async checkElementHidden(element: string, waitTime = 10000): Promise { + result = true; + try { + await this.world.page?.locator(element).waitFor({ + state: "hidden", + timeout: waitTime, + }); + } catch { + result = false; + } + return result; + } + async checkElementClickable(element: any, waitTime = 10000): Promise { result = true; try { diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 6a208a0a..923f6d10 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -169,12 +169,13 @@ export class MetamaskPage extends BasePage { } async extractCurrentWalletAddress() { + const helper = await new Helper(this.world); const currentURL = page.url(); await page.goto(metamaskWelcomeUrl); await page.reload(); await page.locator("//button[@data-testid='popover-close']").click(); await page.locator(this.copyWalletAddress).click(); - address = await page.evaluate("navigator.clipboard.readText()"); + address = await helper.getClipboardValue(); await page.goto(currentURL); } @@ -204,43 +205,39 @@ export class MetamaskPage extends BasePage { } async callTransactionInterface() { + const helper = await new Helper(this.world); const mainPage = await new MainPage(this.world); selector = await mainPage.commonButtonByItsName("Change wallet network"); - const networkChangeRequest = await this.world.page?.locator(selector).isVisible(); + const networkChangeRequest = await helper.checkElementVisible(selector); if (networkChangeRequest) { await this.switchNetwork(); } await setTimeout(config.defaultTimeout.timeout); selector = await mainPage.commonButtonByItsName("Continue"); - const continueBtn = await this.world.page?.locator(selector).isVisible(); - const modalCard = await this.world.page?.locator(mainPage.modalCard).isVisible(); + const continueBtn = await helper.checkElementVisible(selector); + const modalCard = await helper.checkElementVisible(mainPage.modalCard); if (continueBtn && !modalCard) { await this.click(selector); } } - async operateTransaction(triggeredElement: string) { + async approveAllovance(triggeredElement: string) { + const helper = await new Helper(this.world); const mainPage = await new MainPage(this.world); + selector = `${mainPage.modalCard}//*[contains(text(), 'Allowance approved')]`; + if (triggeredElement === "Approve allowance") { + await helper.checkElementVisible(selector); + await helper.checkElementHidden(selector); + await this.click(await mainPage.buttonOfModalCard("Continue")); + } + } + + async operateTransaction(triggeredElement: string) { const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`); await setTimeout(2.5 * 1000); await popUpContext?.setViewportSize(config.popUpWindowSize); - // will be required for metamask > v10.14.1 - // if (triggeredElement === "Approve allowance") { - // await popUpContext?.click(this.metamaskUseDefaultButton); - // } await popUpContext?.click(this.confirmTransaction); - - if (triggeredElement === "Approve allowance") { - selector = "//div[@class='modal-card']//*[contains(text(), 'Allowance approved')]"; - let allowanceFinalized = await this.world.page?.locator(selector).isVisible(); - if (!allowanceFinalized) { - do { - await setTimeout(5 * 1000); - allowanceFinalized = await this.world.page?.locator(selector).isVisible(); - } while (!allowanceFinalized); - } - await this.click(await mainPage.buttonOfModalCard("Continue")); - } + await this.approveAllovance(triggeredElement); } async catchPopUpByClick(element: string) { diff --git a/tests/e2e/src/pages/external.page.ts b/tests/e2e/src/pages/revoke.page.ts similarity index 62% rename from tests/e2e/src/pages/external.page.ts rename to tests/e2e/src/pages/revoke.page.ts index 2a52e08b..c8754118 100644 --- a/tests/e2e/src/pages/external.page.ts +++ b/tests/e2e/src/pages/revoke.page.ts @@ -3,6 +3,7 @@ import { setTimeout } from "timers/promises"; import { BasePage } from "./base.page"; import { address, MetamaskPage } from "./metamask.page"; +import { Helper } from "../helpers/helper"; import { config } from "../support/config"; import type { ICustomWorld } from "../support/custom-world"; @@ -11,7 +12,7 @@ let metamaskPage: any; let result: any; let selector: string; -export class ExternalPage extends BasePage { +export class RevokePage extends BasePage { constructor(world: ICustomWorld) { super(world); } @@ -25,24 +26,47 @@ export class ExternalPage extends BasePage { return "//button/div[contains(text(), '0x')]"; } + get revokeURL() { + return "https://revoke.cash/"; + } + async revokeButton(value: string) { return `//button[contains(text(), '${value}')]`; } + async login() { + const basePage = new BasePage(this.world); + metamaskPage = new MetamaskPage(this.world); + const revokeUrl = this.revokeURL; + await basePage.goTo(revokeUrl); + await basePage.clickByText("Connect Wallet"); + const popUpContext = await metamaskPage.catchPopUpByClick(`//button[contains(text(),'MetaMask')]`); + await popUpContext?.setViewportSize(config.popUpWindowSize); + await popUpContext?.click(metamaskPage.nextButton); + await popUpContext?.click(metamaskPage.confirmTransaction); + } + + async logout() { + const basePage = new BasePage(this.world); + await this.clickByMenuWalletButton(); + await basePage.clickByText("Disconnect"); + } + async checkNetworkForRevoke(network: string) { + const helper = await new Helper(this.world); const selector = `${this.networkSelectorsListForRevoke}/..//img[@alt='${network}']`; - result = await this.world.page?.locator(selector).first().isVisible(); + result = await helper.checkElementVisible(selector); return result; } async clickByMenuWalletButton() { selector = this.menuWalletButton; - await this.world.page?.waitForSelector(selector); - await this.world.page?.locator(selector).first().click(config.defaultTimeout); + await this.click(selector); } async revokeAllowance() { metamaskPage = await new MetamaskPage(this.world); + const helper = await new Helper(this.world); const networkChainId = "?chainId=5"; // Goerli const revokeGoerliUrl = "https://revoke.cash/address/" + address + networkChainId; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); @@ -51,7 +75,7 @@ export class ExternalPage extends BasePage { } await setTimeout(config.defaultTimeout.timeout); selector = await this.revokeButton("Switch Network"); - const switchNetworkIsVisible = await this.world.page?.locator(selector).isVisible(); + const switchNetworkIsVisible = await helper.checkElementVisible(selector); if (switchNetworkIsVisible) { const popUpContext = await metamaskPage.catchPopUpByClick(selector); await popUpContext?.setViewportSize(config.popUpWindowSize); @@ -60,7 +84,7 @@ export class ExternalPage extends BasePage { await setTimeout(config.defaultTimeout.timeout); selector = await this.revokeButton("Revoke"); - const revokeButtonIsVisible = await this.world.page?.locator(selector).isVisible(); + const revokeButtonIsVisible = await helper.checkElementVisible(selector); if (revokeButtonIsVisible) { const popUpContext = await metamaskPage.catchPopUpByClick(selector); await popUpContext?.setViewportSize(config.popUpWindowSize); @@ -69,12 +93,7 @@ export class ExternalPage extends BasePage { } selector = await this.revokeButton("Revoking"); - let revokingButtonIsVisible = await this.world.page?.locator(selector).isVisible(); - if (revokingButtonIsVisible) { - do { - await setTimeout(3 * 1000); - revokingButtonIsVisible = await this.world.page?.locator(selector).isVisible(); - } while (revokingButtonIsVisible); - } + await helper.checkElementVisible(selector); // should appear + await helper.checkElementHidden(selector); // should disappear } } diff --git a/tests/e2e/src/steps/portal.steps.ts b/tests/e2e/src/steps/portal.steps.ts index 0dd94bc3..098446a2 100644 --- a/tests/e2e/src/steps/portal.steps.ts +++ b/tests/e2e/src/steps/portal.steps.ts @@ -6,10 +6,10 @@ import { NetworkSwitcher } from "../data/data"; import { Helper } from "../helpers/helper"; import { BasePage } from "../pages/base.page"; import { ContactsPage } from "../pages/contacts.page"; -import { ExternalPage } from "../pages/external.page"; import { LoginPage } from "../pages/login.page"; import { MainPage } from "../pages/main.page"; import { MetamaskPage } from "../pages/metamask.page"; +import { RevokePage } from "../pages/revoke.page"; import { config } from "../support/config"; import type { ICustomWorld } from "../support/custom-world"; @@ -17,7 +17,7 @@ import type { ICustomWorld } from "../support/custom-world"; let basePage: BasePage; let mainPage: MainPage; let loginPage: LoginPage; -let externalPage: ExternalPage; +let revokePage: RevokePage; let metamaskPage: MetamaskPage; let contactsPage: ContactsPage; let helper: Helper; @@ -371,24 +371,8 @@ Then( ); Given("I reset allowance", config.stepExtraTimeout, async function (this: ICustomWorld) { - externalPage = new ExternalPage(this); - basePage = new BasePage(this); - metamaskPage = new MetamaskPage(this); - - const revokeUrl = "https://revoke.cash/"; - - await basePage.goTo(revokeUrl); - // login - await basePage.clickByText("Connect Wallet"); - const popUpContext = await metamaskPage.catchPopUpByClick(`//button[contains(text(),'MetaMask')]`); - await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(metamaskPage.nextButton); - await popUpContext?.click(metamaskPage.confirmTransaction); - - // operate - await externalPage.revokeAllowance(); - - // logout - await externalPage.clickByMenuWalletButton(); - await basePage.clickByText("Disconnect"); + revokePage = new RevokePage(this); + await revokePage.login(); + await revokePage.revokeAllowance(); + await revokePage.logout(); }); From bb9cc1412840fe18deed1386a272edfdc0d3d8d8 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 24 Aug 2023 13:14:52 +0200 Subject: [PATCH 13/15] test: improving popups method and refactoring --- tests/e2e/src/pages/main.page.ts | 9 +++++---- tests/e2e/src/pages/metamask.page.ts | 22 ++++++++++++++-------- tests/e2e/src/pages/revoke.page.ts | 22 ++++++++++++---------- tests/e2e/src/support/config.ts | 2 +- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/tests/e2e/src/pages/main.page.ts b/tests/e2e/src/pages/main.page.ts index 53e7c700..0ca50718 100644 --- a/tests/e2e/src/pages/main.page.ts +++ b/tests/e2e/src/pages/main.page.ts @@ -133,14 +133,15 @@ export class MainPage extends BasePage { async makeTransaction(actionType: string, transactionType: string) { metamaskPage = await new MetamaskPage(this.world); - result = await this.getTransactionSelector(transactionType); + const selector = await this.getTransactionSelector(transactionType); await metamaskPage.callTransactionInterface(); - await metamaskPage.operateTransaction(result); + await metamaskPage.operateTransaction(selector, "confirm"); + await metamaskPage.approveAllovance(selector); } async getTransactionSelector(transactionType: string) { - result = transactionType; - return result; + const selector = `//*[contains(text(),'${transactionType}')]`; + return selector; } async monitorBalance(walletAddress: string, layer: string) { diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 923f6d10..22109d30 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -221,23 +221,29 @@ export class MetamaskPage extends BasePage { } } - async approveAllovance(triggeredElement: string) { + async approveAllovance(selector: string) { const helper = await new Helper(this.world); const mainPage = await new MainPage(this.world); - selector = `${mainPage.modalCard}//*[contains(text(), 'Allowance approved')]`; - if (triggeredElement === "Approve allowance") { + selector = `${mainPage.modalCard}${selector}`; + if (selector.includes("Approve allowance")) { await helper.checkElementVisible(selector); await helper.checkElementHidden(selector); await this.click(await mainPage.buttonOfModalCard("Continue")); } } - async operateTransaction(triggeredElement: string) { - const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`); - await setTimeout(2.5 * 1000); + async operateTransaction(selector: string, argument: string) { + const popUpContext = await this.catchPopUpByClick(selector); + await setTimeout(config.minimalTimeout.timeout); await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(this.confirmTransaction); - await this.approveAllovance(triggeredElement); + if (argument == "confirm") { + await popUpContext?.click(this.confirmTransaction); + } else if (argument == "next and confirm") { + await popUpContext?.click(this.nextButton); + await popUpContext?.click(this.confirmTransaction); + } else if (argument == "networkSwitch") { + await popUpContext?.click(this.switchNetworkButton); + } } async catchPopUpByClick(element: string) { diff --git a/tests/e2e/src/pages/revoke.page.ts b/tests/e2e/src/pages/revoke.page.ts index c8754118..53b98f6d 100644 --- a/tests/e2e/src/pages/revoke.page.ts +++ b/tests/e2e/src/pages/revoke.page.ts @@ -11,6 +11,7 @@ import type { ICustomWorld } from "../support/custom-world"; let metamaskPage: any; let result: any; let selector: string; +let argument: string; export class RevokePage extends BasePage { constructor(world: ICustomWorld) { @@ -26,6 +27,10 @@ export class RevokePage extends BasePage { return "//button/div[contains(text(), '0x')]"; } + get metamaskButton() { + return `//button[contains(text(),'MetaMask')]`; + } + get revokeURL() { return "https://revoke.cash/"; } @@ -38,12 +43,11 @@ export class RevokePage extends BasePage { const basePage = new BasePage(this.world); metamaskPage = new MetamaskPage(this.world); const revokeUrl = this.revokeURL; + selector = this.metamaskButton; + argument = "next and confirm"; await basePage.goTo(revokeUrl); await basePage.clickByText("Connect Wallet"); - const popUpContext = await metamaskPage.catchPopUpByClick(`//button[contains(text(),'MetaMask')]`); - await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(metamaskPage.nextButton); - await popUpContext?.click(metamaskPage.confirmTransaction); + await metamaskPage.operateTransaction(selector, argument); } async logout() { @@ -69,6 +73,7 @@ export class RevokePage extends BasePage { const helper = await new Helper(this.world); const networkChainId = "?chainId=5"; // Goerli const revokeGoerliUrl = "https://revoke.cash/address/" + address + networkChainId; + argument = "networkSwitch"; const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli"); if (!networkForRevokeIsSelected) { await this.goTo(revokeGoerliUrl); @@ -77,18 +82,15 @@ export class RevokePage extends BasePage { selector = await this.revokeButton("Switch Network"); const switchNetworkIsVisible = await helper.checkElementVisible(selector); if (switchNetworkIsVisible) { - const popUpContext = await metamaskPage.catchPopUpByClick(selector); - await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(metamaskPage.switchNetworkButton); + await metamaskPage.operateTransaction(selector, argument); } await setTimeout(config.defaultTimeout.timeout); + argument = "confirm"; selector = await this.revokeButton("Revoke"); const revokeButtonIsVisible = await helper.checkElementVisible(selector); if (revokeButtonIsVisible) { - const popUpContext = await metamaskPage.catchPopUpByClick(selector); - await popUpContext?.setViewportSize(config.popUpWindowSize); - await popUpContext?.click(metamaskPage.confirmTransaction); + await metamaskPage.operateTransaction(selector, argument); await this.revokeAllowance(); } diff --git a/tests/e2e/src/support/config.ts b/tests/e2e/src/support/config.ts index d8a1f403..dbd42cd7 100644 --- a/tests/e2e/src/support/config.ts +++ b/tests/e2e/src/support/config.ts @@ -41,7 +41,7 @@ export const config = { minimalTimeout: { timeout: 1 * 1000 }, increasedTimeout: { timeout: 15 * 1000 }, stepTimeout: { timeout: 60 * 1000 }, - stepExtraTimeout: { timeout: 120 * 1000 }, + stepExtraTimeout: { timeout: 180 * 1000 }, feeLimitations: true, feeBoundaryLevel: 0.2, // in ETH networkL1: "goerli", From d6c400f338e40a79b0e1526c33520baec77e8823 Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 24 Aug 2023 15:17:23 +0200 Subject: [PATCH 14/15] test: fix for hidden selectors --- tests/e2e/src/helpers/helper.ts | 13 ------------- tests/e2e/src/pages/main.page.ts | 2 +- tests/e2e/src/pages/metamask.page.ts | 5 ++--- tests/e2e/src/pages/revoke.page.ts | 6 ++++-- tests/e2e/src/support/config.ts | 1 + 5 files changed, 8 insertions(+), 19 deletions(-) diff --git a/tests/e2e/src/helpers/helper.ts b/tests/e2e/src/helpers/helper.ts index a961e96a..98f7d03d 100644 --- a/tests/e2e/src/helpers/helper.ts +++ b/tests/e2e/src/helpers/helper.ts @@ -88,19 +88,6 @@ export class Helper { return result; } - async checkElementHidden(element: string, waitTime = 10000): Promise { - result = true; - try { - await this.world.page?.locator(element).waitFor({ - state: "hidden", - timeout: waitTime, - }); - } catch { - result = false; - } - return result; - } - async checkElementClickable(element: any, waitTime = 10000): Promise { result = true; try { diff --git a/tests/e2e/src/pages/main.page.ts b/tests/e2e/src/pages/main.page.ts index 0ca50718..ab972855 100644 --- a/tests/e2e/src/pages/main.page.ts +++ b/tests/e2e/src/pages/main.page.ts @@ -98,7 +98,7 @@ export class MainPage extends BasePage { } async buttonOfModalCard(buttonText: string) { - return `${this.modalCard}//button[contains(., '${buttonText}')]`; + return `${this.modalCard}//button[text()='${buttonText}']`; } async selectTransaction(transactionType: string) { diff --git a/tests/e2e/src/pages/metamask.page.ts b/tests/e2e/src/pages/metamask.page.ts index 22109d30..aac094f8 100644 --- a/tests/e2e/src/pages/metamask.page.ts +++ b/tests/e2e/src/pages/metamask.page.ts @@ -222,12 +222,11 @@ export class MetamaskPage extends BasePage { } async approveAllovance(selector: string) { - const helper = await new Helper(this.world); const mainPage = await new MainPage(this.world); selector = `${mainPage.modalCard}${selector}`; if (selector.includes("Approve allowance")) { - await helper.checkElementVisible(selector); - await helper.checkElementHidden(selector); + selector = `${mainPage.modalCard}//*[contains(text(), 'Allowance approved')]`; + await this.world.page?.waitForSelector(selector, config.extraTimeout); await this.click(await mainPage.buttonOfModalCard("Continue")); } } diff --git a/tests/e2e/src/pages/revoke.page.ts b/tests/e2e/src/pages/revoke.page.ts index 53b98f6d..549001be 100644 --- a/tests/e2e/src/pages/revoke.page.ts +++ b/tests/e2e/src/pages/revoke.page.ts @@ -95,7 +95,9 @@ export class RevokePage extends BasePage { } selector = await this.revokeButton("Revoking"); - await helper.checkElementVisible(selector); // should appear - await helper.checkElementHidden(selector); // should disappear + const revokingButtonIsVisible = await helper.checkElementVisible(selector); + if (revokingButtonIsVisible) { + await this.world.page?.waitForSelector(selector, { state: "hidden", timeout: config.increasedTimeout.timeout }); + } } } diff --git a/tests/e2e/src/support/config.ts b/tests/e2e/src/support/config.ts index dbd42cd7..0589c694 100644 --- a/tests/e2e/src/support/config.ts +++ b/tests/e2e/src/support/config.ts @@ -40,6 +40,7 @@ export const config = { defaultTimeout: { timeout: 6 * 1000 }, minimalTimeout: { timeout: 1 * 1000 }, increasedTimeout: { timeout: 15 * 1000 }, + extraTimeout: { timeout: 30 * 1000 }, stepTimeout: { timeout: 60 * 1000 }, stepExtraTimeout: { timeout: 180 * 1000 }, feeLimitations: true, From 8580a46dbb2d567620da509a4079d05aed382e7d Mon Sep 17 00:00:00 2001 From: pcheremu Date: Thu, 24 Aug 2023 15:34:18 +0200 Subject: [PATCH 15/15] test: refactoring --- tests/e2e/src/helpers/helper.ts | 13 +++++++++++++ tests/e2e/src/pages/revoke.page.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/e2e/src/helpers/helper.ts b/tests/e2e/src/helpers/helper.ts index 98f7d03d..d7c3246b 100644 --- a/tests/e2e/src/helpers/helper.ts +++ b/tests/e2e/src/helpers/helper.ts @@ -88,6 +88,19 @@ export class Helper { return result; } + async checkSelectorHidden(selector: string, waitTime = 10000): Promise { + result = true; + try { + await this.world.page?.waitForSelector(selector, { + state: "hidden", + timeout: waitTime, + }); + } catch { + result = false; + } + return result; + } + async checkElementClickable(element: any, waitTime = 10000): Promise { result = true; try { diff --git a/tests/e2e/src/pages/revoke.page.ts b/tests/e2e/src/pages/revoke.page.ts index 549001be..013f0ff6 100644 --- a/tests/e2e/src/pages/revoke.page.ts +++ b/tests/e2e/src/pages/revoke.page.ts @@ -97,7 +97,7 @@ export class RevokePage extends BasePage { selector = await this.revokeButton("Revoking"); const revokingButtonIsVisible = await helper.checkElementVisible(selector); if (revokingButtonIsVisible) { - await this.world.page?.waitForSelector(selector, { state: "hidden", timeout: config.increasedTimeout.timeout }); + await helper.checkSelectorHidden(selector, config.increasedTimeout.timeout); } } }