refactor: enhance clickCreate method to support custom timeout for Git-backed collections

This commit is contained in:
Bob Qiu committed 2026-09-28 10:06:43 +08:00
1 parent 40141bde48
commit e1e6b33bde
3 files changed
+28 -5

No files matched your search

@@ -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,
);
}
/**
+19 -2
View File
@@ -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<void> {
async clickCreate(timeoutMs: number = DEFAULT_TIMEOUT): Promise<void> {
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<DropIndicator | undefined> {
// 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)"]',
);
@@ -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);
});