Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: revoke handling #111

Merged
merged 15 commits into from
Aug 24, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,16 @@ 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 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 "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
15 changes: 14 additions & 1 deletion tests/e2e/src/helpers/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -88,6 +88,19 @@ export class Helper {
return result;
}

async checkSelectorHidden(selector: string, waitTime = 10000): Promise<boolean> {
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<boolean> {
result = true;
try {
Expand Down
19 changes: 14 additions & 5 deletions tests/e2e/src/pages/main.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ export class MainPage extends BasePage {
return "//button[text()='Confirm']";
}

async commonButtonByItsName(value: string) {
return `//button[contains(., '${value}')]`;
}

async buttonOfModalCard(buttonText: string) {
return `${this.modalCard}//button[text()='${buttonText}']`;
}

async selectTransaction(transactionType: string) {
try {
let route: string;
Expand Down Expand Up @@ -125,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);

await metamaskPage.operateTransaction(result);
const selector = await this.getTransactionSelector(transactionType);
await metamaskPage.callTransactionInterface();
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) {
Expand Down
76 changes: 65 additions & 11 deletions tests/e2e/src/pages/metamask.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 { config, wallet } from "../support/config";

import type { ICustomWorld } from "../support/custom-world";
Expand All @@ -13,6 +13,8 @@ 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;

Expand Down Expand Up @@ -49,6 +51,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";
}
Expand All @@ -58,7 +68,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() {
Expand Down Expand Up @@ -109,6 +119,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]";
Expand Down Expand Up @@ -154,6 +168,17 @@ 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 helper.getClipboardValue();
await page.goto(currentURL);
}

async authorizeInMetamaskExtension(secretPhrase: Array<string>, password: string) {
const helper = await new Helper(this.world);
const wallet_password = await helper.decrypt(wallet.password);
Expand All @@ -174,20 +199,49 @@ export class MetamaskPage extends BasePage {
}
}
logoutTrigger = false;
if (transactionsTag) {
await this.extractCurrentWalletAddress();
}
}

async operateTransaction(triggeredElement: string) {
//change network
try {
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 helper.checkElementVisible(selector);
if (networkChangeRequest) {
await this.switchNetwork();
} finally {
await setTimeout(config.minimalTimeout.timeout);
await this.click(this.continueBtn);
}
await setTimeout(config.defaultTimeout.timeout);
selector = await mainPage.commonButtonByItsName("Continue");
const continueBtn = await helper.checkElementVisible(selector);
const modalCard = await helper.checkElementVisible(mainPage.modalCard);
if (continueBtn && !modalCard) {
await this.click(selector);
}
}

const popUpContext = await this.catchPopUpByClick(`//span[contains(text(),'${triggeredElement}')]`);
await setTimeout(config.minimalTimeout.timeout);
await popUpContext?.setViewportSize(config.popUpWindowSize);
async approveAllovance(selector: string) {
const mainPage = await new MainPage(this.world);
selector = `${mainPage.modalCard}${selector}`;
if (selector.includes("Approve allowance")) {
selector = `${mainPage.modalCard}//*[contains(text(), 'Allowance approved')]`;
await this.world.page?.waitForSelector(selector, config.extraTimeout);
await this.click(await mainPage.buttonOfModalCard("Continue"));
}
}

async operateTransaction(selector: string, argument: string) {
const popUpContext = await this.catchPopUpByClick(selector);
await setTimeout(config.minimalTimeout.timeout);
await popUpContext?.setViewportSize(config.popUpWindowSize);
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);
}
}

Expand Down
103 changes: 103 additions & 0 deletions tests/e2e/src/pages/revoke.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
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";

let metamaskPage: any;
let result: any;
let selector: string;
let argument: string;

export class RevokePage extends BasePage {
constructor(world: ICustomWorld) {
super(world);
}

// selectors for revoke
get networkSelectorsListForRevoke() {
return "//*[@id='react-select-address-chain-select-live-region']";
}

get menuWalletButton() {
return "//button/div[contains(text(), '0x')]";
}

get metamaskButton() {
return `//button[contains(text(),'MetaMask')]`;
}

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;
selector = this.metamaskButton;
argument = "next and confirm";
await basePage.goTo(revokeUrl);
await basePage.clickByText("Connect Wallet");
await metamaskPage.operateTransaction(selector, argument);
}

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 helper.checkElementVisible(selector);
return result;
}

async clickByMenuWalletButton() {
selector = this.menuWalletButton;
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;
argument = "networkSwitch";
const networkForRevokeIsSelected = await this.checkNetworkForRevoke("Goerli");
if (!networkForRevokeIsSelected) {
await this.goTo(revokeGoerliUrl);
}
await setTimeout(config.defaultTimeout.timeout);
selector = await this.revokeButton("Switch Network");
const switchNetworkIsVisible = await helper.checkElementVisible(selector);
if (switchNetworkIsVisible) {
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) {
await metamaskPage.operateTransaction(selector, argument);
await this.revokeAllowance();
}

selector = await this.revokeButton("Revoking");
const revokingButtonIsVisible = await helper.checkElementVisible(selector);
if (revokingButtonIsVisible) {
await helper.checkSelectorHidden(selector, config.increasedTimeout.timeout);
}
}
}
16 changes: 15 additions & 1 deletion tests/e2e/src/steps/portal.steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import { ContactsPage } from "../pages/contacts.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";

let basePage: BasePage;
let mainPage: MainPage;
let loginPage: LoginPage;
let revokePage: RevokePage;
let metamaskPage: MetamaskPage;
let contactsPage: ContactsPage;
let helper: Helper;
Expand Down Expand Up @@ -94,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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -362,3 +369,10 @@ Then(
await expect(element).toBeVisible();
}
);

Given("I reset allowance", config.stepExtraTimeout, async function (this: ICustomWorld) {
revokePage = new RevokePage(this);
await revokePage.login();
await revokePage.revokeAllowance();
await revokePage.logout();
});
2 changes: 2 additions & 0 deletions tests/e2e/src/support/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ 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,
feeBoundaryLevel: 0.2, // in ETH
networkL1: "goerli",
Expand Down
Loading