diff --git a/ui/src/e2e/approval-page.e2e.test.ts b/ui/src/e2e/approval-page.e2e.test.ts index 2033e323a53b..e845f4e61ed4 100644 --- a/ui/src/e2e/approval-page.e2e.test.ts +++ b/ui/src/e2e/approval-page.e2e.test.ts @@ -6,7 +6,11 @@ import type { AllowedApprovalSnapshot, PendingApprovalSnapshot, } from "../../../packages/gateway-protocol/src/index.js"; -import { installMockGateway, type MockGatewayControls } from "../test-helpers/control-ui-e2e.ts"; +import { + controlUiE2eWaitTimeoutMs, + installMockGateway, + type MockGatewayControls, +} from "../test-helpers/control-ui-e2e.ts"; import { createControlUiE2eSuite } from "./control-ui-e2e-suite.test-support.ts"; const suite = createControlUiE2eSuite({ @@ -109,7 +113,7 @@ async function createSurface(params: { }); openContexts.add(context); const page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); await page.clock.setFixedTime(new Date(APPROVAL_NOW_MS)); const pageErrors: string[] = []; page.on("pageerror", (error) => pageErrors.push(String(error))); diff --git a/ui/src/e2e/chat-file-links.e2e.test.ts b/ui/src/e2e/chat-file-links.e2e.test.ts index 20f5b5ffbd23..594c36dcd862 100644 --- a/ui/src/e2e/chat-file-links.e2e.test.ts +++ b/ui/src/e2e/chat-file-links.e2e.test.ts @@ -5,6 +5,7 @@ import { chromium, type Browser } from "playwright"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, installMockGateway, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, @@ -38,7 +39,7 @@ describeControlUiE2e("Control UI chat file links", () => { viewport: { height: 900, width: 1280 }, }); const page = await context.newPage(); - page.setDefaultTimeout(15_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); try { const gateway = await installMockGateway(page, { historyMessages: [ @@ -192,7 +193,7 @@ describeControlUiE2e("Control UI chat file links", () => { }); try { const page = await context.newPage(); - page.setDefaultTimeout(15_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); const gateway = await installMockGateway(page, { methodResponses: { "sessions.files.get": { diff --git a/ui/src/e2e/chat-large-paste-99213.e2e.test.ts b/ui/src/e2e/chat-large-paste-99213.e2e.test.ts index aa1c04e255dc..b8c3891957c2 100644 --- a/ui/src/e2e/chat-large-paste-99213.e2e.test.ts +++ b/ui/src/e2e/chat-large-paste-99213.e2e.test.ts @@ -7,6 +7,7 @@ import { chromium, type Browser, type BrowserContext, type Page } from "playwrig import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, installMockGateway, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, @@ -132,7 +133,7 @@ async function newRecordedPage(label: string): Promise { viewport, }); page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); return { browser, context, page, rawVideoDir }; } catch (error) { await page?.close().catch(() => {}); diff --git a/ui/src/e2e/chat-quota-pill-93041.e2e.test.ts b/ui/src/e2e/chat-quota-pill-93041.e2e.test.ts index 51500dd6926b..3c1eda3ea856 100644 --- a/ui/src/e2e/chat-quota-pill-93041.e2e.test.ts +++ b/ui/src/e2e/chat-quota-pill-93041.e2e.test.ts @@ -3,7 +3,7 @@ import path from "node:path"; import type { BrowserContext, Page } from "playwright"; import { expect, it } from "vitest"; -import { installMockGateway } from "../test-helpers/control-ui-e2e.ts"; +import { controlUiE2eWaitTimeoutMs, installMockGateway } from "../test-helpers/control-ui-e2e.ts"; import { createControlUiE2eSuite } from "./control-ui-e2e-suite.test-support.ts"; const suite = createControlUiE2eSuite({ @@ -123,7 +123,7 @@ async function openChat( viewport: { height: 900, width: 1280 }, }); page = await context.newPage(); - page.setDefaultTimeout(15_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); const gateway = await installMockGateway(page, { deferredMethods, methodResponses: { "models.authStatus": authStatus, ...extraMethodResponses }, diff --git a/ui/src/e2e/control-ui-auth-transports.e2e.test.ts b/ui/src/e2e/control-ui-auth-transports.e2e.test.ts index 1aad2e912905..54459919dda1 100644 --- a/ui/src/e2e/control-ui-auth-transports.e2e.test.ts +++ b/ui/src/e2e/control-ui-auth-transports.e2e.test.ts @@ -16,6 +16,7 @@ import { } from "../../../src/test-utils/openclaw-test-state.js"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, type ControlUiE2eServer, @@ -470,7 +471,7 @@ async function createBrowserPage( const page = await context.newPage(); const errors: string[] = []; page.on("pageerror", (error) => errors.push(String(error))); - page.setDefaultTimeout(15_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); const evidenceStartIndex = proxy.evidence.length; const response = await page.goto(withGatewayUrl(baseUrl, gatewayUrl), { timeout: controlUiSettleTimeoutMs, diff --git a/ui/src/e2e/control-ui-credentials.e2e.test.ts b/ui/src/e2e/control-ui-credentials.e2e.test.ts index d9f6a7e96f12..48ba9db72bf3 100644 --- a/ui/src/e2e/control-ui-credentials.e2e.test.ts +++ b/ui/src/e2e/control-ui-credentials.e2e.test.ts @@ -7,6 +7,7 @@ import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; import { ConnectErrorDetailCodes } from "../../../packages/gateway-protocol/src/connect-error-details.js"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, installMockGateway, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, @@ -51,7 +52,7 @@ async function createCredentialPage(): Promise<{ }); openContexts.add(context); const page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); const gateway = await installMockGateway(page, { deferredMethods: ["connect"] }); const response = await page.goto(server.baseUrl); expect(response?.status()).toBe(200); diff --git a/ui/src/e2e/control-ui-e2e-suite.test-support.ts b/ui/src/e2e/control-ui-e2e-suite.test-support.ts index 701e9bbf5243..1827c3570ec2 100644 --- a/ui/src/e2e/control-ui-e2e-suite.test-support.ts +++ b/ui/src/e2e/control-ui-e2e-suite.test-support.ts @@ -2,6 +2,7 @@ import { chromium, type Browser, type BrowserContext, type Page } from "playwrig import { afterAll, afterEach, beforeAll, describe } from "vitest"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, type ControlUiE2eServer, @@ -57,6 +58,8 @@ export function createControlUiE2eSuite(options: ControlUiE2eSuiteOptions): Cont throw new Error("Control UI E2E browser accessed before suite setup"); } const context = await browser.newContext(contextOptions); + // Harness owns the wait budget; per-test setDefaultTimeout sprinkles defeat CI scaling. + context.setDefaultTimeout(controlUiE2eWaitTimeoutMs); openBrowserContexts.add(context); return context; }; diff --git a/ui/src/e2e/initial-connect-splash.e2e.test.ts b/ui/src/e2e/initial-connect-splash.e2e.test.ts index 8ae3839ac934..b39daa87fe92 100644 --- a/ui/src/e2e/initial-connect-splash.e2e.test.ts +++ b/ui/src/e2e/initial-connect-splash.e2e.test.ts @@ -7,6 +7,7 @@ import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; import { ConnectErrorDetailCodes } from "../../../packages/gateway-protocol/src/connect-error-details.js"; import { canRunPlaywrightChromium, + controlUiE2eWaitTimeoutMs, installMockGateway, resolvePlaywrightChromiumExecutablePath, startControlUiE2eServer, @@ -34,7 +35,7 @@ async function createPage(): Promise { }); openContexts.add(context); const page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); return page; } diff --git a/ui/src/pages/chat/critical-observer-notice.e2e.test.ts b/ui/src/pages/chat/critical-observer-notice.e2e.test.ts index a1a0d8da0370..57d8188c45ca 100644 --- a/ui/src/pages/chat/critical-observer-notice.e2e.test.ts +++ b/ui/src/pages/chat/critical-observer-notice.e2e.test.ts @@ -236,8 +236,6 @@ suite.define(() => { viewport: { height: 900, width: 1440 }, }, async ({ page }) => { - page.setDefaultTimeout(10_000); - const gateway = await installMockGateway(page, { historyMessages: [ { @@ -407,8 +405,6 @@ suite.define(() => { viewport: { height: 900, width: 1440 }, }, async ({ page }) => { - page.setDefaultTimeout(10_000); - const gateway = await installMockGateway(page, { assistantAgentId: "work", defaultAgentId: "work", diff --git a/ui/src/pages/workboard/workboard-routing.e2e.test.ts b/ui/src/pages/workboard/workboard-routing.e2e.test.ts index 46c98afc3632..7f41cff4f807 100644 --- a/ui/src/pages/workboard/workboard-routing.e2e.test.ts +++ b/ui/src/pages/workboard/workboard-routing.e2e.test.ts @@ -3,7 +3,11 @@ import path from "node:path"; import type { BrowserContext, Page } from "playwright"; import { expect, it } from "vitest"; import { createControlUiE2eSuite } from "../../e2e/control-ui-e2e-suite.test-support.ts"; -import { installMockGateway, waitForControlUiRoute } from "../../test-helpers/control-ui-e2e.ts"; +import { + controlUiE2eWaitTimeoutMs, + installMockGateway, + waitForControlUiRoute, +} from "../../test-helpers/control-ui-e2e.ts"; const suite = createControlUiE2eSuite({ name: "Control UI Workboard routing", @@ -64,7 +68,7 @@ async function newRecordedPage(label: string): Promise<{ viewport: { width: 1600, height: 1000 }, }); const page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); return { context, page, rawVideoDir }; } diff --git a/ui/src/pages/workboard/workboard.e2e.test.ts b/ui/src/pages/workboard/workboard.e2e.test.ts index 240e8cf8315b..edfc5ecd6bd4 100644 --- a/ui/src/pages/workboard/workboard.e2e.test.ts +++ b/ui/src/pages/workboard/workboard.e2e.test.ts @@ -14,6 +14,7 @@ import type { WorkboardStatus, } from "../../lib/workboard/index.ts"; import { + controlUiE2eWaitTimeoutMs, installMockGateway, type MockGatewayControls, type MockGatewayRequest, @@ -302,7 +303,7 @@ async function newRecordedPage(label: string): Promise { viewport, }); page = await context.newPage(); - page.setDefaultTimeout(10_000); + page.setDefaultTimeout(controlUiE2eWaitTimeoutMs); return { context, page, rawVideoDir }; } catch (error) { await page?.close().catch(() => {}); diff --git a/ui/src/test-helpers/control-ui-e2e-readiness.ts b/ui/src/test-helpers/control-ui-e2e-readiness.ts index 2274b40bcb6d..7fd0ee489ed8 100644 --- a/ui/src/test-helpers/control-ui-e2e-readiness.ts +++ b/ui/src/test-helpers/control-ui-e2e-readiness.ts @@ -1,4 +1,5 @@ import type { Page } from "playwright"; +import { controlUiE2eWaitTimeoutMs } from "./control-ui-e2e.ts"; /** A sent connect request is not the delivered Gateway handshake. */ export async function waitForControlUiGatewayReady(page: Page): Promise { @@ -23,11 +24,11 @@ export async function waitForControlUiGatewayReconnecting(page: Page): Promise request.method === targetMethod)); }, method, - { timeout: 10_000 }, + { timeout: controlUiE2eWaitTimeoutMs }, ); const requests = await getRequests(method); const request = requests.at(-1);