diff --git a/docs/api/helpers/ui-helper.md b/docs/api/helpers/ui-helper.md index 15eb6ce..4be1149 100644 --- a/docs/api/helpers/ui-helper.md +++ b/docs/api/helpers/ui-helper.md @@ -33,10 +33,11 @@ Alias for `waitForLoad()`. #### `dismissQuickstartIfVisible()` ```typescript async dismissQuickstartIfVisible(options?: { + waitVisibleMs?: number; waitHiddenMs?: number; }): Promise ``` -If the RHDH quickstart drawer is open, clicks its **Hide** button and waits for the control to disappear. Does nothing when the button is not visible. Use before catalog search or other UI that the drawer can cover. Default `waitHiddenMs` is `5000`. +Waits briefly for the RHDH quickstart **Hide** button (`waitVisibleMs`, default `5000`), clicks it if it appears, then waits for it to disappear (`waitHiddenMs`, default `5000`). Returns quietly if Hide never shows. Call after login before `waitForAppReady` — the open drawer keeps a progressbar visible that would otherwise block app-ready waits. ### Verification Methods diff --git a/docs/changelog.md b/docs/changelog.md index 5bdbb65..d67ee69 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. -## [2.1.4] - Current +## [2.1.5] - Current + +### Fixed + +- **`dismissQuickstartIfVisible()` race after login**: The helper used an immediate `isVisible()` check, so it no-op'd when the Quickstart drawer mounted shortly after login. Later `waitForAppReady` / `waitForLoad` calls then timed out on the drawer's sticky `[role="progressbar"]`. The helper now waits briefly for the **Hide** button (`waitVisibleMs`, default `5000`) before clicking, and still returns quietly if Quickstart never appears. + +## [2.1.4] ### Changed diff --git a/docs/guide/helpers/ui-helper.md b/docs/guide/helpers/ui-helper.md index 0b6aeda..8422397 100644 --- a/docs/guide/helpers/ui-helper.md +++ b/docs/guide/helpers/ui-helper.md @@ -34,14 +34,17 @@ On instances using the new frontend system (BUI), `waitForLoad` waits for both l ### `dismissQuickstartIfVisible(options?)` -When the [quickstart](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/quickstart) plugin opens its drawer (for example after login), it can sit over the catalog, search field, or other controls. This method clicks **Hide** only if that button is visible, then waits for it to go away; otherwise it returns immediately. +When the [quickstart](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/quickstart) plugin opens its drawer (for example after login), it can sit over the catalog, search field, or other controls — and its sticky progressbar blocks `waitForAppReady`. This method waits briefly for **Hide** to appear (`waitVisibleMs`, default `5000`), clicks it, then waits for it to go away (`waitHiddenMs`, default `5000`). If Hide never shows, it returns immediately. ```typescript await uiHelper.dismissQuickstartIfVisible(); -await uiHelper.dismissQuickstartIfVisible({ waitHiddenMs: 10_000 }); +await uiHelper.dismissQuickstartIfVisible({ + waitVisibleMs: 10_000, + waitHiddenMs: 10_000, +}); ``` -Typical use is right after navigation or login, before assertions or interactions that need an unobstructed main view. +Typical use is right after login, before `waitForAppReady` or assertions that need an unobstructed main view. Do not call `waitForAppReady` first — that wait includes the quickstart progressbar. ## Verification Methods diff --git a/docs/overlay/reference/patterns.md b/docs/overlay/reference/patterns.md index c076a60..9f72089 100644 --- a/docs/overlay/reference/patterns.md +++ b/docs/overlay/reference/patterns.md @@ -284,10 +284,11 @@ await uiHelper.selectMuiBox("Category", "Option 1"); ### Dismiss quickstart drawer -When the RHDH quickstart plugin shows its drawer, it can cover catalog search and other controls. Call this after login or navigation if needed (it is a no-op when **Hide** is not visible): +When the RHDH quickstart plugin shows its drawer, it can cover catalog search and other controls — and its progressbar blocks `waitForAppReady`. Call this after login (it waits briefly for **Hide**, then no-ops if the drawer never appears). Call it *before* `waitForAppReady`: ```typescript await uiHelper.dismissQuickstartIfVisible(); +await uiHelper.waitForAppReady(); ``` See [UIhelper](/guide/helpers/ui-helper) and [UIhelper API](/api/helpers/ui-helper). diff --git a/package.json b/package.json index e6b67a1..a65216b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@red-hat-developer-hub/e2e-test-utils", - "version": "2.1.4", + "version": "2.1.5", "description": "Test utilities for RHDH E2E tests", "license": "Apache-2.0", "repository": { diff --git a/src/playwright/helpers/ui-helper.ts b/src/playwright/helpers/ui-helper.ts index 44b871e..9f9e064 100644 --- a/src/playwright/helpers/ui-helper.ts +++ b/src/playwright/helpers/ui-helper.ts @@ -29,19 +29,34 @@ export class UIhelper { } /** - * Closes the quickstart drawer when the "Hide" button is visible (RHDH quickstart plugin), - * so it does not cover catalog or other UI under test. + * Closes the quickstart drawer when the "Hide" button appears (RHDH quickstart plugin), + * so it does not cover catalog or other UI under test / block waitForAppReady via its + * sticky progressbar. Waits briefly for Hide to mount (drawer often appears after login + * settles); returns without error if it never shows. + * + * Do not call waitForAppReady before this — that wait includes `[role="progressbar"]`, + * which the open quickstart drawer keeps visible until dismissed. */ - async dismissQuickstartIfVisible(options?: { waitHiddenMs?: number }) { + async dismissQuickstartIfVisible(options?: { + waitVisibleMs?: number; + waitHiddenMs?: number; + }) { + const waitVisibleMs = options?.waitVisibleMs ?? 5000; const waitHiddenMs = options?.waitHiddenMs ?? 5000; const quickstartHide = this.page.getByRole("button", { name: "Hide" }); - if (await quickstartHide.isVisible()) { - await quickstartHide.click(); + try { await quickstartHide.waitFor({ - state: "hidden", - timeout: waitHiddenMs, + state: "visible", + timeout: waitVisibleMs, }); + } catch { + return; } + await quickstartHide.click(); + await quickstartHide.waitFor({ + state: "hidden", + timeout: waitHiddenMs, + }); } async verifyComponentInCatalog(kind: string, expectedRows: string[]) {