-
Couldn't load subscription status.
- Fork 77
test: test Deployment and Tx Fee authorizations #2109
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| 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, 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(); | ||
| }); | ||
|
|
||
| test("can revoke spending", async ({ page, context, extensionId }) => { | ||
| test.setTimeout(5 * 60 * 1000); | ||
|
|
||
| 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); | ||
| 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); | ||
| await extension.acceptTransaction(context); | ||
|
|
||
| return { | ||
| authorizationsPage, | ||
| address, | ||
| extension | ||
| }; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| 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.getByRole("button", { name: buttonLabel }).click(); | ||
| await this.page.getByLabel("Spending Limit").fill("5"); | ||
| await this.page.getByLabel("Grantee Address").fill(address); | ||
| 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"); | ||
| 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(); | ||
| await this.page.getByTestId("confirm-button").click(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,7 +56,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>( | |
|
|
||
| return ( | ||
| <div className={cn("space-y-1", className)}> | ||
| {label && (formField.id ? <FormLabel>{label}</FormLabel> : <Label htmlFor={`${finalId}-input`}>{label}</Label>)} | ||
| {label && (formField.id ? <FormLabel htmlFor={`${finalId}-input`}>{label}</FormLabel> : <Label htmlFor={`${finalId}-input`}>{label}</Label>)} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainGood accessibility improvement; verify consistency with Textarea. The addition of However, the Textarea component at line 107 uses FormLabel without the 🏁 Script executed: #!/bin/bash
# Verify if FormLabel in other similar components should also have htmlFor attribute
rg -n -C3 -P '<FormLabel[^>]*>.*?</FormLabel>' --type=tsx --type=tsLength of output: 27 Length of output: 177 🏁 Script executed: #!/bin/bash
# Search for FormLabel patterns using file glob instead of type
rg -n -C3 '<FormLabel' packages/ui/ Length of output: 1199 🏁 Script executed: #!/bin/bash
# Look for all tsx files in the ui components directory
fd -e tsx packages/ui/components/Length of output: 397 Length of output: 4778 Add htmlFor attribute to Textarea's FormLabel for consistency with Input component. The accessibility improvement at line 59 (adding Update line 107: 🤖 Prompt for AI Agents |
||
| <div className="relative flex items-center"> | ||
| {startIcon && <div className={cn("absolute inset-y-0 left-0 flex items-center", startIconClassName)}>{startIcon}</div>} | ||
| <input | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify the 5-minute timeout is necessary.
The page fixture now has explicit scope and timeout configuration. The test scope is appropriate for isolation, but the 5-minute timeout seems quite long for fixture setup.
Is the 5-minute timeout necessary for your test environment? Consider whether a shorter timeout (e.g., 2-3 minutes) would be sufficient, as excessively long timeouts can mask real issues with slow setup operations.
🌐 Web query:
💡 Result:
{ timeout: 60000 }on the fixture. [1][2]References:
[1] Playwright Test — Timeouts (defaults and fixture behavior).
[2] Playwright docs/examples showing fixture timeout usage (example uses 60000 ms).
Reduce fixture timeout from 5 minutes to align with best practices.
The 5-minute timeout (300,000 ms) is significantly excessive. Playwright's default per-test timeout is 30 seconds, and even for slower or heavy fixtures, common practice is to use a separate fixture timeout of around 60 seconds.
Set the timeout to 60,000 ms (1 minute) or 90,000 ms if the wallet setup consistently requires that duration. Overly long timeouts mask real issues with slow operations.
🤖 Prompt for AI Agents