From 9af7103be183b782281277568edc70b289ddaf61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zsef=20Kozma?= Date: Tue, 21 Oct 2025 22:36:17 +0200 Subject: [PATCH 1/2] test: test Deployment and Tx Fee authorizations refs #2006 --- .../authorizations/AllowanceIssuedRow.tsx | 4 +- .../authorizations/AllowanceModal.tsx | 3 +- .../authorizations/Authorizations.tsx | 12 ++- .../authorizations/DeploymentGrantTable.tsx | 6 +- .../authorizations/FeeGrantTable.tsx | 2 +- .../components/authorizations/GrantModal.tsx | 3 +- .../tests/ui/authorize-spending.spec.ts | 77 +++++++++++++++++++ .../tests/ui/change-wallets.spec.ts | 4 +- .../tests/ui/disconnect-wallet.spec.ts | 4 +- .../ui/fixture/context-with-extension.ts | 56 +++++++------- .../tests/ui/fixture/testing-helpers.ts | 19 ++++- .../tests/ui/pages/AuthorizationsPage.tsx | 55 +++++++++++++ apps/deploy-web/tests/ui/pages/LeapExt.tsx | 6 ++ .../tests/ui/uiState/isWalletConnected.ts | 4 +- packages/ui/components/custom/address.tsx | 6 +- 15 files changed, 216 insertions(+), 45 deletions(-) create mode 100644 apps/deploy-web/tests/ui/authorize-spending.spec.ts create mode 100644 apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx diff --git a/apps/deploy-web/src/components/authorizations/AllowanceIssuedRow.tsx b/apps/deploy-web/src/components/authorizations/AllowanceIssuedRow.tsx index b58189a8f..3ce03a178 100644 --- a/apps/deploy-web/src/components/authorizations/AllowanceIssuedRow.tsx +++ b/apps/deploy-web/src/components/authorizations/AllowanceIssuedRow.tsx @@ -53,10 +53,10 @@ export const AllowanceIssuedRow: React.FunctionComponent = ({ allowance, }} /> - - diff --git a/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx b/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx index 0411cb02e..30ac532e9 100644 --- a/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx +++ b/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx @@ -144,6 +144,7 @@ export const AllowanceModal: React.FunctionComponent = ({ editingAllowanc step={0.000001} max={denomData?.max} startIcon={{denomData?.label}} + aria-label="Spending Limit" /> ); }} @@ -155,7 +156,7 @@ export const AllowanceModal: React.FunctionComponent = ({ editingAllowanc control={control} name="granteeAddress" render={({ field }) => { - return ; + return ; }} /> diff --git a/apps/deploy-web/src/components/authorizations/Authorizations.tsx b/apps/deploy-web/src/components/authorizations/Authorizations.tsx index 850655d7d..caf8b59d3 100644 --- a/apps/deploy-web/src/components/authorizations/Authorizations.tsx +++ b/apps/deploy-web/src/components/authorizations/Authorizations.tsx @@ -223,7 +223,7 @@ export const Authorizations: React.FunctionComponent = () => { headerActions={ address && (
- @@ -335,7 +335,15 @@ export const Authorizations: React.FunctionComponent = () => {
Tx Fee Authorizations {address && ( - diff --git a/apps/deploy-web/src/components/authorizations/DeploymentGrantTable.tsx b/apps/deploy-web/src/components/authorizations/DeploymentGrantTable.tsx index e73afbe94..8e0667f92 100644 --- a/apps/deploy-web/src/components/authorizations/DeploymentGrantTable.tsx +++ b/apps/deploy-web/src/components/authorizations/DeploymentGrantTable.tsx @@ -130,10 +130,10 @@ export const DeploymentGrantTable: React.FC = ({ }} />
- -
@@ -164,7 +164,7 @@ export const DeploymentGrantTable: React.FC = ({ return (
- +
{table.getHeaderGroups().map(headerGroup => ( diff --git a/apps/deploy-web/src/components/authorizations/FeeGrantTable.tsx b/apps/deploy-web/src/components/authorizations/FeeGrantTable.tsx index 6fcfca483..229527e8d 100644 --- a/apps/deploy-web/src/components/authorizations/FeeGrantTable.tsx +++ b/apps/deploy-web/src/components/authorizations/FeeGrantTable.tsx @@ -63,7 +63,7 @@ export const FeeGrantTable: React.FC = ({ return (
-
+
Type diff --git a/apps/deploy-web/src/components/authorizations/GrantModal.tsx b/apps/deploy-web/src/components/authorizations/GrantModal.tsx index 780ec2359..3a553fbb5 100644 --- a/apps/deploy-web/src/components/authorizations/GrantModal.tsx +++ b/apps/deploy-web/src/components/authorizations/GrantModal.tsx @@ -189,6 +189,7 @@ export const GrantModal: React.FunctionComponent = ({ editingGrant, addre max={denomData?.max} startIcon={{denomData?.label}} className="ml-4 flex-grow" + aria-label="Spending Limit" /> ); }} @@ -200,7 +201,7 @@ export const GrantModal: React.FunctionComponent = ({ editingGrant, addre control={control} name="granteeAddress" render={({ field }) => { - return ; + return ; }} /> diff --git a/apps/deploy-web/tests/ui/authorize-spending.spec.ts b/apps/deploy-web/tests/ui/authorize-spending.spec.ts new file mode 100644 index 000000000..0fd90605a --- /dev/null +++ b/apps/deploy-web/tests/ui/authorize-spending.spec.ts @@ -0,0 +1,77 @@ +import { shortenAddress } from "@akashnetwork/ui/components"; +import type { BrowserContext, Page } from "@playwright/test"; + +import { expect, test } from "./fixture/context-with-extension"; +import { clickCopyAddressButton } from "./fixture/testing-helpers"; +import { getExtensionPage } from "./fixture/wallet-setup"; +import type { AuthorizationListLabel, AuthorizeButtonLabel } from "./pages/AuthorizationsPage"; +import { AuthorizationsPage } from "./pages/AuthorizationsPage"; +import { LeapExt } from "./pages/LeapExt"; + +type TestProps = { + name: string; + buttonLabel: AuthorizeButtonLabel; + listLabel: AuthorizationListLabel; +}; + +const runAuthorizationTest = ({ name, buttonLabel, listLabel }: TestProps) => { + test.describe(`${name} Authorizations`, () => { + test("can authorize spending", async ({ page, context, extensionId }) => { + test.setTimeout(5 * 60 * 1000); + + const { authorizationsPage, address } = await setup({ page, context, extensionId, buttonLabel }); + + const shortenedAddress = shortenAddress(address); + const grantList = authorizationsPage.page.getByLabel(listLabel); + await expect(grantList.locator("tr", { hasText: shortenedAddress })).toBeVisible(); + }); + + test("can edit spending", async ({ page, context, extensionId }) => { + test.setTimeout(5 * 60 * 1000); + + const { authorizationsPage, address } = await setup({ page, context, extensionId, buttonLabel }); + await authorizationsPage.editSpending(address, listLabel); + + const grantList = authorizationsPage.page.getByLabel(listLabel); + await expect(grantList.locator("tr", { hasText: "10.000000 AKT" })).toBeVisible(); + }); + + test("can revoke spending", async ({ page, context, extensionId }) => { + test.setTimeout(5 * 60 * 1000); + + const { authorizationsPage, address } = await setup({ page, context, extensionId, buttonLabel }); + await authorizationsPage.revokeSpending(address, listLabel); + + const shortenedAddress = shortenAddress(address); + const grantList = authorizationsPage.page.getByLabel(listLabel); + await expect(grantList.locator("tr", { hasText: shortenedAddress })).not.toBeVisible(); + }); + }); +}; + +runAuthorizationTest({ name: "Deployment", buttonLabel: "Authorize Spend", listLabel: "Deployment Authorization List" }); +runAuthorizationTest({ name: "Tx Fee", buttonLabel: "Authorize Fee Spend", listLabel: "Tx Fee Authorization List" }); + +type SetupProps = { + page: Page; + context: BrowserContext; + extensionId: string; + buttonLabel: AuthorizeButtonLabel; +}; + +const setup = async ({ page, context, extensionId, buttonLabel }: SetupProps) => { + const extension = new LeapExt(context, page); + const address = await clickCopyAddressButton(await getExtensionPage(context, extensionId)); + await extension.createWallet(extensionId); + + const authorizationsPage = new AuthorizationsPage(context, page); + await authorizationsPage.goto(); + + await authorizationsPage.authorizeSpending(address, buttonLabel); + + return { + authorizationsPage, + address, + extension + }; +}; diff --git a/apps/deploy-web/tests/ui/change-wallets.spec.ts b/apps/deploy-web/tests/ui/change-wallets.spec.ts index f238a5ca6..0e888f4c4 100644 --- a/apps/deploy-web/tests/ui/change-wallets.spec.ts +++ b/apps/deploy-web/tests/ui/change-wallets.spec.ts @@ -6,9 +6,9 @@ import { LeapExt } from "./pages/LeapExt"; test("switching to another wallet in the extension affects Console", async ({ page, context, extensionId }) => { test.setTimeout(5 * 60 * 1000); - const frontPage = new LeapExt(context, page); + const extension = new LeapExt(context, page); - const newWalletName = await frontPage.createWallet(extensionId); + const newWalletName = await extension.createWallet(extensionId); const container = page.getByLabel("Connected wallet name and balance"); await container.waitFor({ state: "visible", timeout: 20_000 }); diff --git a/apps/deploy-web/tests/ui/disconnect-wallet.spec.ts b/apps/deploy-web/tests/ui/disconnect-wallet.spec.ts index f5e4dc7bf..ff8c7b15d 100644 --- a/apps/deploy-web/tests/ui/disconnect-wallet.spec.ts +++ b/apps/deploy-web/tests/ui/disconnect-wallet.spec.ts @@ -3,8 +3,8 @@ import { LeapExt } from "./pages/LeapExt"; test("wallet stays disconnected after disconnecting and reloading", async ({ page, context }) => { test.setTimeout(5 * 60 * 1000); - const frontPage = new LeapExt(context, page); - await frontPage.disconnectWallet(); + const extension = new LeapExt(context, page); + await extension.disconnectWallet(); await expect(page.getByTestId("connect-wallet-btn")).toBeVisible(); }); diff --git a/apps/deploy-web/tests/ui/fixture/context-with-extension.ts b/apps/deploy-web/tests/ui/fixture/context-with-extension.ts index 106bd41cf..2568ad268 100644 --- a/apps/deploy-web/tests/ui/fixture/context-with-extension.ts +++ b/apps/deploy-web/tests/ui/fixture/context-with-extension.ts @@ -27,7 +27,8 @@ export const test = baseTest.extend<{ const context = await chromium.launchPersistentContext(userDataDir, { channel: "chromium", - args + args, + permissions: ["clipboard-read", "clipboard-write"] }); await use(context); @@ -42,36 +43,39 @@ export const test = baseTest.extend<{ const extensionId = background.url().split("/")[2]; await use(extensionId); }, - page: async ({ context, extensionId }, use) => { - try { - await context.waitForEvent("page", { timeout: 5000 }); - } catch { - // ignore timeout error - } + page: [ + async ({ context, extensionId }, use) => { + try { + await context.waitForEvent("page", { timeout: 5000 }); + } catch { + // ignore timeout error + } - const extPage = await getExtensionPage(context, extensionId); + const extPage = await getExtensionPage(context, extensionId); - await setupWallet(context, extPage); - await extPage.close(); - const page = await context.newPage(); - await injectUIConfig(page); + await setupWallet(context, extPage); + await extPage.close(); + const page = await context.newPage(); + await injectUIConfig(page); - if (testEnvConfig.NETWORK_ID !== "mainnet") { - try { - await page.goto(testEnvConfig.BASE_URL); - await connectWalletViaLeap(context, page); - await selectChainNetwork(page, testEnvConfig.NETWORK_ID); - await connectWalletViaLeap(context, page); - } catch { - // Fallback in case the default network is non-functional. - // E.g., during network upgrade when sandbox is already on a different version from mainnet - await page.goto(`${testEnvConfig.BASE_URL}?network=${testEnvConfig.NETWORK_ID}`); - await awaitWalletAndApprove(context, page); + if (testEnvConfig.NETWORK_ID !== "mainnet") { + try { + await page.goto(testEnvConfig.BASE_URL); + await connectWalletViaLeap(context, page); + await selectChainNetwork(page, testEnvConfig.NETWORK_ID); + await connectWalletViaLeap(context, page); + } catch { + // Fallback in case the default network is non-functional. + // E.g., during network upgrade when sandbox is already on a different version from mainnet + await page.goto(`${testEnvConfig.BASE_URL}?network=${testEnvConfig.NETWORK_ID}`); + await awaitWalletAndApprove(context, page); + } } - } - await use(page); - } + await use(page); + }, + { scope: "test", timeout: 5 * 60 * 1000 } + ] }); export const expect = test.expect; diff --git a/apps/deploy-web/tests/ui/fixture/testing-helpers.ts b/apps/deploy-web/tests/ui/fixture/testing-helpers.ts index 4a08c0280..429da2de8 100644 --- a/apps/deploy-web/tests/ui/fixture/testing-helpers.ts +++ b/apps/deploy-web/tests/ui/fixture/testing-helpers.ts @@ -15,8 +15,7 @@ export const clickCreateNewWalletButton = async (page: Page) => { }; export const fillWalletName = async (page: Page, name: string) => { - const input = await waitForLocator(page.getByPlaceholder("Enter wallet Name")); - return await input.fill(name); + return await page.getByPlaceholder("Enter wallet Name").fill(name); }; export const clickCreateWalletButton = async (page: Page) => { @@ -29,6 +28,22 @@ export const clickConnectWalletButton = async (page: Page) => { return await button.click(); }; +export const getCopyAddressButton = async (page: Page) => { + const buttons = await page.$$("#popup-layout button"); + return buttons.length ? buttons[1] : null; +}; + +export const clickCopyAddressButton = async (page: Page) => { + const button = await getCopyAddressButton(page); + await button?.click(); + + const clipboardContents = await page.evaluate(async () => { + return await navigator.clipboard.readText(); + }); + + return clipboardContents; +}; + export const waitForLocator = async (locator: Locator) => { await locator.waitFor({ state: "visible", timeout: 20_000 }); return locator; diff --git a/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx b/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx new file mode 100644 index 000000000..51527628a --- /dev/null +++ b/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx @@ -0,0 +1,55 @@ +import { shortenAddress } from "@akashnetwork/ui/components"; +import type { BrowserContext as Context, Page } from "@playwright/test"; + +import { testEnvConfig } from "../fixture/test-env.config"; + +export type AuthorizeButtonLabel = "Authorize Spend" | "Authorize Fee Spend"; +export type AuthorizationListLabel = "Deployment Authorization List" | "Tx Fee Authorization List"; + +export class AuthorizationsPage { + constructor( + readonly context: Context, + readonly page: Page + ) {} + + async goto(url = `${testEnvConfig.BASE_URL}/settings/authorizations`) { + await this.page.goto(url); + } + + async clickGrantButton() { + return await this.page.getByRole("button", { name: "Grant" }).click(); + } + + async authorizeSpending(address: string, buttonLabel: AuthorizeButtonLabel) { + await this.page.getByLabel(buttonLabel).click(); + await this.page.getByLabel("Spending Limit").fill("5"); + await this.page.getByLabel("Grantee Address").fill(address); + + this.context.on("page", this.acceptTransaction.bind(this)); + await this.clickGrantButton(); + } + + async editSpending(address: string, listLabel: AuthorizationListLabel) { + const shortenedAddress = shortenAddress(address); + await this.page.getByLabel(listLabel).locator("tr", { hasText: shortenedAddress }).getByLabel("Edit Authorization").click(); + + await this.page.getByLabel("Spending Limit").fill("10"); + + this.context.on("page", this.acceptTransaction.bind(this)); + await this.clickGrantButton(); + } + + async revokeSpending(address: string, listLabel: AuthorizationListLabel) { + const shortenedAddress = shortenAddress(address); + await this.page.getByLabel(listLabel).locator("tr", { hasText: shortenedAddress }).getByLabel("Revoke Authorization").click(); + + this.context.on("page", this.acceptTransaction.bind(this)); + await this.page.getByTestId("confirm-button").click(); + } + + async acceptTransaction() { + await this.page.waitForLoadState("domcontentloaded"); + await this.page.getByTestId("btn-connect-wallet").click(); + this.context.off("page", this.acceptTransaction.bind(this)); + } +} diff --git a/apps/deploy-web/tests/ui/pages/LeapExt.tsx b/apps/deploy-web/tests/ui/pages/LeapExt.tsx index 02fd249eb..8066e1b41 100644 --- a/apps/deploy-web/tests/ui/pages/LeapExt.tsx +++ b/apps/deploy-web/tests/ui/pages/LeapExt.tsx @@ -37,4 +37,10 @@ export class LeapExt { await this.page.reload({ waitUntil: "domcontentloaded" }); } + + async acceptTransaction() { + await this.page.waitForLoadState("domcontentloaded"); + await this.page.getByTestId("btn-connect-wallet").click(); + this.context.off("page", this.acceptTransaction.bind(this)); + } } diff --git a/apps/deploy-web/tests/ui/uiState/isWalletConnected.ts b/apps/deploy-web/tests/ui/uiState/isWalletConnected.ts index 2e0e684e0..f92c50f24 100644 --- a/apps/deploy-web/tests/ui/uiState/isWalletConnected.ts +++ b/apps/deploy-web/tests/ui/uiState/isWalletConnected.ts @@ -4,12 +4,12 @@ export async function isWalletConnected(page: Page) { const result = await Promise.race([ page .getByLabel("Connected wallet name and balance") - .waitFor({ state: "visible", timeout: 10_000 }) + .waitFor({ state: "visible", timeout: 30_000 }) .then(() => true) .catch(() => null), page .getByTestId("connect-wallet-btn") - .waitFor({ state: "visible", timeout: 10_000 }) + .waitFor({ state: "visible", timeout: 30_000 }) .then(() => false) .catch(() => null) ]); diff --git a/packages/ui/components/custom/address.tsx b/packages/ui/components/custom/address.tsx index dac1732e5..afef370c9 100644 --- a/packages/ui/components/custom/address.tsx +++ b/packages/ui/components/custom/address.tsx @@ -8,6 +8,10 @@ import { cn, copyTextToClipboard } from "../../utils"; import { CustomTooltip } from "../tooltip"; import { Snackbar } from "./snackbar"; +export const shortenAddress = (address: string) => { + return [address?.slice(0, 8), "...", address?.slice(address?.length - 5)].join(""); +}; + type Props = { address: string; isCopyable?: boolean; @@ -21,7 +25,7 @@ type Props = { export const Address: React.FunctionComponent = ({ address, isCopyable, disableTruncate, disableTooltip, showIcon, className, ...rest }) => { const [isOver, setIsOver] = useState(false); const { enqueueSnackbar } = useSnackbar(); - const formattedAddress = disableTruncate ? address : [address?.slice(0, 8), "...", address?.slice(address?.length - 5)].join(""); + const formattedAddress = disableTruncate ? address : shortenAddress(address); const onClick = (event: React.MouseEvent) => { if (isCopyable) { From 5691c7d150fee05de91a6e473b49ac7b7f8770ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zsef=20Kozma?= Date: Sun, 26 Oct 2025 19:50:10 +0000 Subject: [PATCH 2/2] fix: follow-up on PR feedback refs #2006 --- .../components/authorizations/AllowanceModal.tsx | 3 +-- .../components/authorizations/Authorizations.tsx | 3 +-- .../src/components/authorizations/GrantModal.tsx | 3 +-- .../tests/ui/authorize-spending.spec.ts | 7 +++++-- .../tests/ui/fixture/context-with-extension.ts | 2 +- .../tests/ui/fixture/testing-helpers.ts | 8 +------- apps/deploy-web/tests/ui/fixture/wallet-setup.ts | 7 +++++-- .../tests/ui/pages/AuthorizationsPage.tsx | 15 +-------------- apps/deploy-web/tests/ui/pages/LeapExt.tsx | 13 ++++++------- packages/ui/components/custom/address.tsx | 2 +- packages/ui/components/input.tsx | 2 +- 11 files changed, 24 insertions(+), 41 deletions(-) diff --git a/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx b/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx index 30ac532e9..0411cb02e 100644 --- a/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx +++ b/apps/deploy-web/src/components/authorizations/AllowanceModal.tsx @@ -144,7 +144,6 @@ export const AllowanceModal: React.FunctionComponent = ({ editingAllowanc step={0.000001} max={denomData?.max} startIcon={{denomData?.label}} - aria-label="Spending Limit" /> ); }} @@ -156,7 +155,7 @@ export const AllowanceModal: React.FunctionComponent = ({ editingAllowanc control={control} name="granteeAddress" render={({ field }) => { - return ; + return ; }} /> diff --git a/apps/deploy-web/src/components/authorizations/Authorizations.tsx b/apps/deploy-web/src/components/authorizations/Authorizations.tsx index caf8b59d3..bbd3471cf 100644 --- a/apps/deploy-web/src/components/authorizations/Authorizations.tsx +++ b/apps/deploy-web/src/components/authorizations/Authorizations.tsx @@ -223,7 +223,7 @@ export const Authorizations: React.FunctionComponent = () => { headerActions={ address && (
- @@ -342,7 +342,6 @@ export const Authorizations: React.FunctionComponent = () => { className="md:ml-4" type="button" size="sm" - aria-label="Authorize Fee Spend" >  Authorize Fee Spend diff --git a/apps/deploy-web/src/components/authorizations/GrantModal.tsx b/apps/deploy-web/src/components/authorizations/GrantModal.tsx index 3a553fbb5..780ec2359 100644 --- a/apps/deploy-web/src/components/authorizations/GrantModal.tsx +++ b/apps/deploy-web/src/components/authorizations/GrantModal.tsx @@ -189,7 +189,6 @@ export const GrantModal: React.FunctionComponent = ({ editingGrant, addre max={denomData?.max} startIcon={{denomData?.label}} className="ml-4 flex-grow" - aria-label="Spending Limit" /> ); }} @@ -201,7 +200,7 @@ export const GrantModal: React.FunctionComponent = ({ editingGrant, addre control={control} name="granteeAddress" render={({ field }) => { - return ; + return ; }} />
diff --git a/apps/deploy-web/tests/ui/authorize-spending.spec.ts b/apps/deploy-web/tests/ui/authorize-spending.spec.ts index 0fd90605a..1610f864c 100644 --- a/apps/deploy-web/tests/ui/authorize-spending.spec.ts +++ b/apps/deploy-web/tests/ui/authorize-spending.spec.ts @@ -29,8 +29,9 @@ const runAuthorizationTest = ({ name, buttonLabel, listLabel }: TestProps) => { test("can edit spending", async ({ page, context, extensionId }) => { test.setTimeout(5 * 60 * 1000); - const { authorizationsPage, address } = await setup({ page, context, extensionId, buttonLabel }); + const { authorizationsPage, address, extension } = await setup({ page, context, extensionId, buttonLabel }); await authorizationsPage.editSpending(address, listLabel); + await extension.acceptTransaction(context); const grantList = authorizationsPage.page.getByLabel(listLabel); await expect(grantList.locator("tr", { hasText: "10.000000 AKT" })).toBeVisible(); @@ -39,8 +40,9 @@ const runAuthorizationTest = ({ name, buttonLabel, listLabel }: TestProps) => { test("can revoke spending", async ({ page, context, extensionId }) => { test.setTimeout(5 * 60 * 1000); - const { authorizationsPage, address } = await setup({ page, context, extensionId, buttonLabel }); + const { authorizationsPage, address, extension } = await setup({ page, context, extensionId, buttonLabel }); await authorizationsPage.revokeSpending(address, listLabel); + await extension.acceptTransaction(context); const shortenedAddress = shortenAddress(address); const grantList = authorizationsPage.page.getByLabel(listLabel); @@ -68,6 +70,7 @@ const setup = async ({ page, context, extensionId, buttonLabel }: SetupProps) => await authorizationsPage.goto(); await authorizationsPage.authorizeSpending(address, buttonLabel); + await extension.acceptTransaction(context); return { authorizationsPage, diff --git a/apps/deploy-web/tests/ui/fixture/context-with-extension.ts b/apps/deploy-web/tests/ui/fixture/context-with-extension.ts index 2568ad268..7a3aca4f0 100644 --- a/apps/deploy-web/tests/ui/fixture/context-with-extension.ts +++ b/apps/deploy-web/tests/ui/fixture/context-with-extension.ts @@ -68,7 +68,7 @@ export const test = baseTest.extend<{ // Fallback in case the default network is non-functional. // E.g., during network upgrade when sandbox is already on a different version from mainnet await page.goto(`${testEnvConfig.BASE_URL}?network=${testEnvConfig.NETWORK_ID}`); - await awaitWalletAndApprove(context, page); + await awaitWalletAndApprove(context, page, extensionId); } } diff --git a/apps/deploy-web/tests/ui/fixture/testing-helpers.ts b/apps/deploy-web/tests/ui/fixture/testing-helpers.ts index 429da2de8..1b00165e5 100644 --- a/apps/deploy-web/tests/ui/fixture/testing-helpers.ts +++ b/apps/deploy-web/tests/ui/fixture/testing-helpers.ts @@ -28,14 +28,8 @@ export const clickConnectWalletButton = async (page: Page) => { return await button.click(); }; -export const getCopyAddressButton = async (page: Page) => { - const buttons = await page.$$("#popup-layout button"); - return buttons.length ? buttons[1] : null; -}; - export const clickCopyAddressButton = async (page: Page) => { - const button = await getCopyAddressButton(page); - await button?.click(); + await page.getByRole("button", { name: /akash\.\.\.[a-z0-9]{5}/ }).click(); const clipboardContents = await page.evaluate(async () => { return await navigator.clipboard.readText(); diff --git a/apps/deploy-web/tests/ui/fixture/wallet-setup.ts b/apps/deploy-web/tests/ui/fixture/wallet-setup.ts index 4ce8664f8..cc022bca5 100644 --- a/apps/deploy-web/tests/ui/fixture/wallet-setup.ts +++ b/apps/deploy-web/tests/ui/fixture/wallet-setup.ts @@ -56,8 +56,11 @@ export async function connectWalletViaLeap(context: BrowserContext, page: Page) } } -export async function awaitWalletAndApprove(context: BrowserContext, page: Page) { - const popupPage = await context.waitForEvent("page", { timeout: 5_000 }); +export async function awaitWalletAndApprove(context: BrowserContext, page: Page, extensionId: string) { + const popupPage = await Promise.race([ + context.waitForEvent("page", { timeout: 5_000 }), + getExtensionPage(context, extensionId), + ]); await approveWalletOperation(popupPage); await isWalletConnected(page); } diff --git a/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx b/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx index 51527628a..b84b2a3b7 100644 --- a/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx +++ b/apps/deploy-web/tests/ui/pages/AuthorizationsPage.tsx @@ -21,35 +21,22 @@ export class AuthorizationsPage { } async authorizeSpending(address: string, buttonLabel: AuthorizeButtonLabel) { - await this.page.getByLabel(buttonLabel).click(); + await this.page.getByRole("button", { name: buttonLabel }).click(); await this.page.getByLabel("Spending Limit").fill("5"); await this.page.getByLabel("Grantee Address").fill(address); - - this.context.on("page", this.acceptTransaction.bind(this)); await this.clickGrantButton(); } async editSpending(address: string, listLabel: AuthorizationListLabel) { const shortenedAddress = shortenAddress(address); await this.page.getByLabel(listLabel).locator("tr", { hasText: shortenedAddress }).getByLabel("Edit Authorization").click(); - await this.page.getByLabel("Spending Limit").fill("10"); - - this.context.on("page", this.acceptTransaction.bind(this)); await this.clickGrantButton(); } async revokeSpending(address: string, listLabel: AuthorizationListLabel) { const shortenedAddress = shortenAddress(address); await this.page.getByLabel(listLabel).locator("tr", { hasText: shortenedAddress }).getByLabel("Revoke Authorization").click(); - - this.context.on("page", this.acceptTransaction.bind(this)); await this.page.getByTestId("confirm-button").click(); } - - async acceptTransaction() { - await this.page.waitForLoadState("domcontentloaded"); - await this.page.getByTestId("btn-connect-wallet").click(); - this.context.off("page", this.acceptTransaction.bind(this)); - } } diff --git a/apps/deploy-web/tests/ui/pages/LeapExt.tsx b/apps/deploy-web/tests/ui/pages/LeapExt.tsx index 8066e1b41..02620f86d 100644 --- a/apps/deploy-web/tests/ui/pages/LeapExt.tsx +++ b/apps/deploy-web/tests/ui/pages/LeapExt.tsx @@ -1,14 +1,14 @@ import { faker } from "@faker-js/faker"; -import type { BrowserContext as Context, Page } from "@playwright/test"; +import type { BrowserContext, Page } from "@playwright/test"; import { wait } from "@src/utils/timer"; import { testEnvConfig } from "../fixture/test-env.config"; import { clickConnectWalletButton } from "../fixture/testing-helpers"; -import { createWallet } from "../fixture/wallet-setup"; +import { approveWalletOperation, createWallet } from "../fixture/wallet-setup"; export class LeapExt { constructor( - readonly context: Context, + readonly context: BrowserContext, readonly page: Page ) {} @@ -38,9 +38,8 @@ export class LeapExt { await this.page.reload({ waitUntil: "domcontentloaded" }); } - async acceptTransaction() { - await this.page.waitForLoadState("domcontentloaded"); - await this.page.getByTestId("btn-connect-wallet").click(); - this.context.off("page", this.acceptTransaction.bind(this)); + async acceptTransaction(context: BrowserContext) { + const popupPage = await context.waitForEvent("page", { timeout: 5_000 }); + await approveWalletOperation(popupPage); } } diff --git a/packages/ui/components/custom/address.tsx b/packages/ui/components/custom/address.tsx index afef370c9..295648624 100644 --- a/packages/ui/components/custom/address.tsx +++ b/packages/ui/components/custom/address.tsx @@ -9,7 +9,7 @@ import { CustomTooltip } from "../tooltip"; import { Snackbar } from "./snackbar"; export const shortenAddress = (address: string) => { - return [address?.slice(0, 8), "...", address?.slice(address?.length - 5)].join(""); + return `${address.slice(0, 8)}...${address.slice(-5)}`; }; type Props = { diff --git a/packages/ui/components/input.tsx b/packages/ui/components/input.tsx index 1da1a9d44..3ce831efe 100644 --- a/packages/ui/components/input.tsx +++ b/packages/ui/components/input.tsx @@ -56,7 +56,7 @@ const Input = React.forwardRef( return (
- {label && (formField.id ? {label} : )} + {label && (formField.id ? {label} : )}
{startIcon &&
{startIcon}
}