From e1e6b33bde3f70c4c8697ccecfe66da118034336 Mon Sep 17 00:00:00 2001 From: Bob Qiu Date: Mon, 28 Sep 2026 10:06:43 +0800 Subject: [PATCH] refactor: enhance clickCreate method to support custom timeout for Git-backed collections --- .../insomnia-test/flows/workspace.flow.ts | 7 ++++++- .../insomnia-test/pages/workspace.page.ts | 21 +++++++++++++++++-- .../workspace/request-pane-tab-order.spec.ts | 5 +++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/insomnia-test/flows/workspace.flow.ts b/packages/insomnia-test/flows/workspace.flow.ts index 1a5da135a9..cb69d1560a 100644 --- a/packages/insomnia-test/flows/workspace.flow.ts +++ b/packages/insomnia-test/flows/workspace.flow.ts @@ -951,7 +951,12 @@ export class WorkspaceFlow extends BaseFlow { if (fileName !== undefined) { await workspace.setCollectionFileName(fileName); } - await workspace.clickCreate(); + // A file name means this collection is backed by its own file in a Git + // Sync project, which writes and stages that file before the dialog + // closes — give it more room than the default UI-only timeout. + await workspace.clickCreate( + fileName !== undefined ? DEFAULT_TIMEOUT * 2 : undefined, + ); } /** diff --git a/packages/insomnia-test/pages/workspace.page.ts b/packages/insomnia-test/pages/workspace.page.ts index 9a76dac67a..bbcbf40f73 100644 --- a/packages/insomnia-test/pages/workspace.page.ts +++ b/packages/insomnia-test/pages/workspace.page.ts @@ -382,8 +382,13 @@ export class WorkspacePage extends BasePage { /** * Clicks the "Create" button and waits for the create/update dialog to * close. + * @param timeoutMs - How long to wait for the dialog to close; defaults + * to `DEFAULT_TIMEOUT`. Callers that create a Git-backed collection + * should pass a longer budget — that path writes the new file into the + * repo and stages it before the dialog closes, which can run past the + * default timeout under CI load. */ - async clickCreate(): Promise { + async clickCreate(timeoutMs: number = DEFAULT_TIMEOUT): Promise { const createButton = this.page.getByRole("button", { name: "Create", exact: true, @@ -391,7 +396,7 @@ export class WorkspacePage extends BasePage { await createButton.click(); await this.page .locator(this.NEW_PROJECT_DIALOG) - .waitFor({ state: "hidden", timeout: DEFAULT_TIMEOUT }); + .waitFor({ state: "hidden", timeout: timeoutMs }); } /** @@ -711,6 +716,12 @@ export class WorkspacePage extends BasePage { // (and its effect) happen before the menu ever opens, so it can't // close a menu that doesn't exist yet. await this.waitForSelectionSettled(node); + // The shortcut listener is rebound on every render of the component + // that owns it (see CommandPalettePage.openViaShortcut()'s doc comment + // for the same race), so draining the renderer's task queue first + // ensures the re-render `waitForSelectionSettled()` just waited out has + // actually finished before the keypress is sent. + await this.waitForRendererIdle(); await this.page.keyboard.press("ControlOrMeta+n"); await expect(this.page.getByRole("menu")).toBeVisible({ timeout: DEFAULT_TIMEOUT, @@ -1260,6 +1271,12 @@ export class WorkspacePage extends BasePage { * @returns The indicator's current state, or undefined if none is rendered */ async getDropIndicator(): Promise { + // dragOver()'s pointer moves are handled asynchronously (react-aria's + // own drag-and-drop machinery resolves the hovered drop target off the + // pointermove event, then re-renders the indicator a tick later), so + // reading it back immediately can catch the DOM before that render has + // happened. Draining the renderer's task queue first ensures it has. + await this.waitForRendererIdle(); const indicator = this.page.locator( '[class*="outline-(--color-surprise)"], [class*="outline-(--color-danger)"]', ); diff --git a/packages/insomnia-test/tests/workspace/request-pane-tab-order.spec.ts b/packages/insomnia-test/tests/workspace/request-pane-tab-order.spec.ts index 14f835cc1c..e686967889 100644 --- a/packages/insomnia-test/tests/workspace/request-pane-tab-order.spec.ts +++ b/packages/insomnia-test/tests/workspace/request-pane-tab-order.spec.ts @@ -39,7 +39,9 @@ test("Verify a freshly created request focuses the URL bar and Tab/arrow-key ord await user.page.keyboard.press("Tab"); const paramsTab = user.page.getByRole("tab", { name: "Params" }); const paramsTabFocusedAfterThirdTab = await httpRequestPage.isFocused(paramsTab); - const paramsTabFocusVisible = paramsTab; + // Must be asserted before ArrowRight moves focus to Body — the + // attribute only holds while Params itself is focused. + await expect(paramsTab).toHaveAttribute("data-focus-visible", "true"); await user.page.keyboard.press("ArrowRight"); const bodyTab = user.page.getByRole("tab", { name: "Body" }); const bodyTabFocusedAfterArrowRight = await httpRequestPage.isFocused(bodyTab); @@ -47,6 +49,5 @@ test("Verify a freshly created request focuses the URL bar and Tab/arrow-key ord expect(urlBarFocusedAfterCreate).toBe(true); expect(sendFocusedAfterFirstTab).toBe(true); expect(paramsTabFocusedAfterThirdTab).toBe(true); - await expect(paramsTabFocusVisible).toHaveAttribute("data-focus-visible", "true"); expect(bodyTabFocusedAfterArrowRight).toBe(true); });