Skip to content

test(e2e): fix 12 chronically flaky Playwright tests - #31063

Open
ShaileshParmar11 wants to merge 14 commits into
mainfrom
fix/ports-lineage-expand-helper-main
Open

test(e2e): fix 12 chronically flaky Playwright tests#31063
ShaileshParmar11 wants to merge 14 commits into
mainfrom
fix/ports-lineage-expand-helper-main

Conversation

@ShaileshParmar11

@ShaileshParmar11 ShaileshParmar11 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Fixes 12 chronically flaky Playwright tests. Every one failed its first attempt and passed on retry, so none of them ever blocked a run — they simply eroded confidence in the suite.

11 files, +273/-48 — all under playwright/, no application code.

Two of these are already confirmed fixed in nightlies: Toggle fullscreen mode and navigation blocker after saving changes each went from flaky in 16 of 16 runs to passing on the first attempt, on both Postgres and MySQL. Both are flaky 9/9 on main, so the same result is expected here.


Tests fixed

Test Flaky before Commit
InputOutputPorts › Toggle fullscreen mode 16/16 1
InputOutputPorts › Remove last port shows empty state 16/16 1, 6
NavigationBlocker › should not show navigation blocker after saving changes 16/16 2
PlatformLineage › Verify domain platform view 15/16 3
PlatformLineage › Verify platform view switching 13/16 3
BulkImport › Range selection 11/16 4
Entity › Domain Propagation 8/16 5
LargeGlossaryPerformance › should search and filter glossary terms 6/16 7
CustomProperties › … in right panel (4 tests × 18 entity types) 6/16 8
PersonaFlow › Set default persona for team 6/16 10
ObservabilityAlerts › Table alert (+3 siblings) 5/16 11
ContextCenterDocument › scrolling the bulk "Move" dropdown 4/16 9

Commits

  1. expandLineageSection waits on state instead of proxies — the accordion header is a toggle, but the helper clicked it unconditionally; calling it on an expanded section collapsed it, and since no /portsView follows a collapse the subsequent waitForResponse hung to the timeout. Also disambiguates the response matcher (the count probe and the lineage fetch share an endpoint) and waits for a terminal render state rather than a loader count that can pass vacuously.
  2. Match the docStore update — tests here share one persona and run sequentially, so an earlier test creates the layout and this save is an update. The wait used a bare '/api/v1/docStore', an exact URL match, which never matches PUT /api/v1/docStore/{id}. Note * does not cross a / in Playwright globs.
  3. Navigate before driving the global search box — the page fixture hands out browser.newPage(), which sits on about:blank; TableClass.visitEntityPage only navigates on its direct-navigation branch, so the fallback drove a search box on a page that had none. Probes for the box rather than checking page.url(), since a URL test cannot tell an app page from any other http page.
  4. Re-press arrow keys RDG drops while settling — react-data-grid discards the keypress outright while re-rendering; focus never moves, so waiting longer cannot help. Re-presses until focus lands, checking the destination first so a registered press is never doubled.
  5. Stop a slow search response aborting waitForSearchResult's poll — each iteration registered a waitForResponse with its own hard 15s timeout inside an expect.poll with a 45s budget. expect.poll does not swallow exceptions, so one slow search aborted the whole poll.
  6. Reload when a port row is missing — the ports endpoint sources rows and total from separate queries and drops unresolvable records without adjusting the total, so it can answer with no rows beside a non-zero total; the list only fetches on mount, so waiting can never recover it but a reload can.
  7. Poll the glossary row count instead of sampling oncewaitForResponse proves the bytes arrived, not that the rows rendered; a single .count() has no retry budget and read the stale search results.
  8. Wait for virtualised filter options — the entity filter is a virtualised list holding ~11 rows, and the helper probed with non-retrying isVisible() then threw inside an expect.poll, aborting a 90s budget after 224ms. Every flaking entity sits at index ≥ 11; none inside the initial window ever flaked.
  9. Scope the moved-document assertion to its folder — the reload refetches page 1 of an updatedAt DESC list; parallel uploads evict the moved row, and the test never scrolls.
  10. Assert the team-persona invariant, not global default state — the backend resolves an unset user default to the system default persona, which a sibling describe sets and clears concurrently.
  11. Settle the alerts table before deciding to paginateisHidden() does not wait while isEnabled() does, so the helper sampled an unpainted table, walked past the alert, and (being forward-only) could never return.

Notes for review

  • No application code. Every change is under playwright/. A component-level fix was drafted for the ports list and deliberately dropped in favour of the test-side reload in commit 6.
  • Shared helpers touched: utils/domain.ts, utils/entity.ts, utils/common.ts, utils/entityPanel.ts, utils/alert.ts. Blast radius is wide by design — several of these fix a whole class rather than one test.
  • Verification limits stated honestly per commit. Most of these tests pass locally before the fix, because the trigger only appears under CI load; local green therefore shows no regression rather than proving the flake is gone. Only nightlies confirm that.
  • Commit 10 could not be verified locally at all — the spec fails earlier on a missing local search index, upstream of the change.

Related work not included

Three product bugs surfaced during this investigation and are worth separate issues: getPaginatedPorts reporting a count its payload cannot support; SIZE.X_LARGE — a pixel-dimension enum — used as an Elasticsearch bucket size, silently truncating the browse tree past 166 services; and CsvJobsTray auto-opening for jobs the user never started.

🤖 Generated with Claude Code

@ShaileshParmar11
ShaileshParmar11 requested a review from a team as a code owner August 5, 2026 17:58
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@ShaileshParmar11
ShaileshParmar11 marked this pull request as draft August 5, 2026 17:58
@ShaileshParmar11

Copy link
Copy Markdown
Contributor Author

Holding this PR until the same fix is validated on 2.0 (#31062).

The fix is opened here so the change isn't lost, but it should not be merged until the next few 2.0 nightlies confirm that Toggle fullscreen mode and Remove last port shows empty state come back clean. Both tests currently pass locally even without the fix, so CI is the only signal that matters.

Marked as draft until then.

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Aug 5, 2026
@ShaileshParmar11 ShaileshParmar11 changed the title test(e2e): make expandLineageSection wait on state instead of proxies test(e2e): flaky Playwright fixes for main (rolling) Aug 5, 2026
ShaileshParmar11 and others added 2 commits August 6, 2026 09:35
`Input Output Ports > Section 7 > Toggle fullscreen mode` and
`Section 4 > Remove last port shows empty state` were flaky in 9 of 9 Main
V2 nightly runs (16/16 on 2.0), failing the first attempt on a 60s timeout
and passing on retry.

expandLineageSection had three defects:

1. Unconditional toggle. The accordion header is a toggle, but the helper
   clicked it on every call despite its doc saying "only expands if
   currently collapsed". Calling it on an already-expanded section
   collapsed it, and since no /portsView request follows a collapse the
   subsequent waitForResponse hung until the test timeout.

2. Ambiguous response matcher. `url.includes('/portsView')` cannot
   distinguish the lineage fetch from the port-count probe — both hit the
   same endpoint — so the wait could resolve on the counts response while
   the lineage request was still in flight. The count probe always carries
   pagination params, so excluding `inputLimit=` targets the lineage call.

3. Vacuous loader wait. `toHaveCount(0)` on [data-testid="loader"] passes
   when React has not yet mounted the loader, letting callers act on a
   panel that is still loading. Now also waits for a terminal state:
   ports-lineage-view, or .ports-lineage-view-empty.

Validated on 2.0 (#31062): both tests passed on the first attempt in the
AUT nightlies 31060529978 (Postgres) and 31060526260 (MySQL).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Navigation Blocker Tests > should not show navigation blocker after
saving changes` was flaky in 9 of 9 Main V2 nightly runs (16/16 on 2.0,
20/34 on 1.13).

The tests in this file share one persona and run sequentially
(describe.configure mode: 'default'). An earlier test already saves a
layout for that persona, so by the time this test saves, the request is an
UPDATE (PUT /api/v1/docStore/{id}) rather than a create.

The wait was `waitForResponse('/api/v1/docStore')`. A bare string is an
exact URL match, so it never matches the update and the await hangs until
the test timeout. This was the only exact docStore matcher left in the
suite. Note '*' does not cross a '/', so the sibling's 'api/v1/docStore*'
works only because its own save is a create — matching the update needs
'**'.

On retry Playwright starts a fresh worker, beforeAll creates a new persona,
and the save becomes a create again — which is why the test always passed
on the second attempt and never on the first.

Also relaxes the toast assertion to accept "created" or "updated": this
test covers navigation-blocker behaviour, not create-vs-update semantics.

Validated on 2.0 (#31064): passed on the first attempt in the AUT nightlies
31060529978 (Postgres) and 31060526260 (MySQL).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ShaileshParmar11
ShaileshParmar11 force-pushed the fix/ports-lineage-expand-helper-main branch from 6668a08 to 621978b Compare August 6, 2026 04:06
ShaileshParmar11 and others added 4 commits August 6, 2026 15:05
`PlatformLineage > Verify domain platform view` and `> Verify platform view
switching` are flaky in both AUT 2.0 nightlies (15/16 and 13/16), failing in
beforeEach with a 30s waitForResponse timeout and a fill still waiting for
getByTestId('searchBox').

The page fixture hands tests a browser.newPage(), which sits on about:blank.
PlatformLineage's beforeEach relies on TableClass.visitEntityPage to
navigate, but that only navigates on its direct-navigation branch; when the
table FQN is empty it falls through to visitEntityPage(), which drives the
global search box on a page that has none.

visitEntityPage now probes for the search box and navigates to /my-data when
it is absent. Probing rather than checking page.url(): a URL test only says
whether this is a web page, not whether it renders the global header, so an
http(s) URL without the header would hang identically. No-op for callers
already on an app page.

Reproduced deterministically for both preconditions — about:blank, and a
real http URL with no header — each failing with the CI signature before the
fix and recovering after. PlatformLineage.spec.ts: 4/4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Bulk Import Export > Range selection` is flaky in both AUT 2.0 nightlies
(11/16), failing with expect(locator).toBeFocused() — Received: inactive.

The failed attempt's snapshot shows focus never moved at all: the column
header is not active while the origin gridcell still is. react-data-grid
drops the key press outright while settling after a click or re-render, so
its keydown handler never runs. Waiting longer cannot help because no
further press is ever sent.

move() now re-presses until focus lands, checking the destination first so a
press that did register is never doubled. Both helpers are declared inside
the test body, so the change is scoped to this test.

Reproduced at 3 failures in 5 runs before the fix; 5/5 passing after.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… poll

`Entity.spec.ts > ... > Domain Propagation` is flaky in both AUT 2.0
nightlies (8/16), failing with a 15s waitForResponse timeout raised from
inside utils/common.ts:862.

waitForSearchResult wraps its work in expect.poll with a 45s budget, but each
iteration registers a waitForResponse with its own hard 15s timeout.
expect.poll does not swallow exceptions from the callback, so a single slow
search rejects and aborts the whole poll rather than counting as 'not ready
yet' — the 45s budget can fail after one 15s iteration. The failure stack
shows exactly that.

The response wait only exists to let the search settle; the poll decides
success. Attaching .catch(() => null) makes a slow response a non-event.

Entity.spec.ts 'Domain Propagation': 19/19 passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Input Output Ports > Section 4 > Remove last port shows empty state` is
flaky in 16 of the last 16 AUT 2.0 nightlies, on both engines, failing with a
60s timeout waiting for getByTestId('port-actions-<id>').

The failed attempt's snapshot shows the contradiction directly: the heading
reads 'Input Ports (1)' while the list group is empty.
DataProductRepository.getPaginatedPorts reads rows via findToWithOffset +
Entity.getEntities(..., NON_DELETED) but the total via a separate
countFindTo, and drops records whose entity cannot be resolved without
adjusting the total — so it can answer with no rows next to a non-zero total.

PortsListView fetches only on mount, so that empty result is held until the
component remounts. Waiting longer can never recover it, which is why the
click burned the full budget; a reload can, which is why the retry passes.

waitForPortRow polls for the row and reloads when absent, restoring the ports
tab if the reload lands elsewhere. It is a no-op when the row is already
present, so the normal path is unchanged.

Reproduced deterministically with page.route: rewriting only the first
/inputPorts response to data:[] with total:1 leaves the list permanently
empty; waitForPortRow then reloads and finds the row in 7.8s.

InputOutputPorts.spec.ts: 43/43 (workers=2).

The backend inconsistency is deliberately left alone — reporting a count the
payload cannot support is worth fixing on its own, but it is a separate
change and would not by itself make the row appear.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ShaileshParmar11 and others added 6 commits August 6, 2026 15:56
`Large Glossary Performance Tests > should search and filter glossary terms`
is flaky in 6 of the last 16 AUT 2.0 nightlies, failing with:

    expect(received).toBeGreaterThanOrEqual(expected)
    Expected: >= 50
    Received: 17

After clearing the search box the test awaited the listing response and then
read locator.count() exactly once, with no retry budget. waitForResponse only
proves the bytes arrived; GlossaryTermTab still has to apply the store update
and re-render the rows, which happens in a later microtask. The single sample
therefore returns the stale search results.

17 is not a partial render — it is precisely what 'Term_5' matches (Term_5,
Term_50..59, and six child terms), and the same 17 appears in two independent
failing runs. The failure-time page snapshot shows all 50 rows present and the
search box already cleared: the state the assertion wanted had arrived, just
after it looked.

The search branch of this same test already waits for loaders (line 198) and
does not flake; the clear branch omitted it. In one failing run that loader
wait took 906ms — the clear branch granted the same work 2ms.

Polls the rendered row count rather than asserting an exact one: the tab
auto-fetches another page when rows do not fill the viewport, so toHaveCount
would trade this flake for a different one.

LargeGlossaryPerformance 'should search and filter glossary terms': 3/3 local.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The four '... in right panel' tests in CustomProperties.spec.ts are flaky
across the AUT 2.0 nightlies, failing in Before Hooks with:

    Unable to find global search filter option "API Endpoint" for endpoint
    "apiEndpoints" after 5 scroll attempts
       at playwright/utils/entityPanel.ts:50

The global-search entity filter is a virtualised antd Select: rc-virtual-list
keeps only the ~11 rows around the current offset in the DOM, so every option
below Container — Stored Procedure, Data Product, API Endpoint, API Collection,
Metric — does not exist until scrolled into range.

findOptionByScrolling scrolled and then immediately called isVisible(), the one
Playwright API that does not auto-wait, so all five attempts completed in about
200ms while racing React's commit of the new window. On losing that race it
threw, and because the caller runs it inside an expect.poll, the throw aborted a
90s budget after 224ms rather than retrying.

The correlation is decisive: every flaking right-panel test across sixteen runs
is for an entity whose filter sits at index 11 or beyond, and there are no
flakes at all for the entities inside the initial window, despite those tests
running identically.

Now waits for the option with a retrying waitFor, advances a whole viewport per
step, detects the end of the list from a clamped scrollTop rather than a fixed
count, and returns false instead of throwing so the enclosing poll can retry.
Two specs already solve this interaction the same way (ExploreQuickFilters,
MetricSearch) and neither flakes.

CustomProperties '... in right panel': 72/72 local.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Context Center - Documents Page > scrolling the bulk "Move" dropdown loads
the next page` is flaky in 4 of the last 16 AUT 2.0 nightlies:

    expect(locator).toHaveText(expected) failed
    Locator: ... filter({ hasText: 'folder-pagination-bulk-move-<uuid>.txt' })
             .getByTestId('document-folder-name')
    Error: element(s) not found

The scroll under test worked and the move itself succeeded (200,
numberOfRowsPassed 1, ids matched). What failed was the lookup after the
reload.

That reload refetches page 1 of the root document list, which the backend
serves ORDER BY updatedAt DESC LIMIT 15. Workers share this backend, so
uploads landing in the window between the move and the reload occupy all 15
slots with newer rows and evict the moved file — and since the test never
scrolls, it is then on no page the test loads.

The failure snapshot shows exactly 15 rows against 44 total files, every one
of them under a second old, with the target absent; the sidebar shows two
copies of the spec's fixture folder, i.e. a second worker running the same
beforeAll. 2x(1+20)+2 = 44 exactly.

The per-file Move test in this same file makes the same assertion and does not
flake — it asserts in place without re-navigating. Rather than drop the reload
(it is what proves the move persisted), scope the list to the target folder,
where the row is the only hit and pagination cannot displace it.

ContextCenterDocument.spec.ts: full file green locally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Team persona setting flow > Set default persona for team should work
properly` is flaky in 6 of the last 16 AUT 2.0 nightlies:

    expect(locator).toContainText(expected) failed
    Expected substring: "No default persona"
    Received string:    "PW Persona 469e8e9f"

The chip renders user.defaultPersona, and the backend resolves an unset user
default to the SYSTEM default persona (UserRepository.getDefaultPersona). That
is global state this test does not own: the sibling describe in this same file
sets and clears a system default, and under fullyParallel the two run
concurrently.

Across seven failing runs every received value is a system-default persona,
and each failure overlaps the sibling in time while the passing retry always
starts after the sibling finishes. The received names match the sibling's own
fixtures (PW Persona <hex>, persona <hex>).

The environment also ships a pre-seeded "Onboarding System Default
Experience" persona, which appears as the received value in three of those
runs — so the "No default persona" placeholder only ever showed because the
sibling incidentally cleared it. The assertion was depending on another test's
side effect.

Asserts what this test actually owns: the team's persona is not auto-applied.
Adds a visibility check first so the negative assertion cannot pass against a
chip that never rendered.

Not verified locally: this spec fails earlier on this machine at line 560
(search response 404, a missing local index) before reaching the changed step.
The change is downstream of that failure, so it is unaffected by it, but only a
nightly can confirm the flake is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`Table alert` (and its siblings) are flaky in 5 of the last 16 AUT 2.0
nightlies, exhausting the 180s budget:

    Test timeout of 180000ms exceeded.
    Error: locator.click: Target page, context or browser has been closed
      waiting for locator('[id="<uuid>"], [data-row-key="<uuid>"]')...

findPageWithAlert sampled two probes with different waiting semantics against
the same unsettled table: isHidden() returns immediately without waiting, while
isEnabled() waits for attachment. The alerts page renders no
[data-testid="loader"], so the preceding waitForAllLoadersToDisappear passes
vacuously, and the table body renders zero rows while a fetch is in flight.

So isHidden() reported a false "row not on this page" against an unpainted
table, isEnabled() resolved later once Next had rendered and was enabled, and
the helper paginated past the alert. The walk is forward-only and returns
silently on failure, so the caller then waited out the entire budget for a row
that was on an earlier page.

The failure snapshot confirms the overshoot directly: Page 2 of 2, Next
disabled, target absent, and the seven rendered rows are the fixture alerts in
ascending name order — while the target's generated name sorts ahead of all of
them, i.e. it was row 1 of page 1.

Waits for the body to paint before sampling either probe, checks the row
before the button, and throws with the alert name instead of returning
silently. This also removes the same latent hang from deleteAlert and
visitEditAlertPage, which share the helper.

Step arithmetic confirms this was never slowness: 180000 - 12712 = 167288ms,
matching the hanging step almost exactly.

ObservabilityAlerts.spec.ts: 8/8 local.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ShaileshParmar11 ShaileshParmar11 changed the title test(e2e): flaky Playwright fixes for main (rolling) test(e2e): Playwright flaky-test fixes for main (batches 1-3) Aug 6, 2026
@ShaileshParmar11
ShaileshParmar11 marked this pull request as ready for review August 6, 2026 11:30
@ShaileshParmar11 ShaileshParmar11 changed the title test(e2e): Playwright flaky-test fixes for main (batches 1-3) test(e2e): fix 12 chronically flaky Playwright tests Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

✅ Playwright Results — workflow succeeded

Validated commit bc4cdef7704d02d1201cef890a8d73cc87fe873e in Playwright run 31108707232, attempt 1.

✅ 648 passed · ❌ 0 failed · 🟡 2 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky

Performance

Blocking targets: ✅ met · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 58m 0s

⏱️ Max setup 2m 59s · max shard execution 19m 2s · max shard-job elapsed before upload 25m 17s · reporting 4s

🌐 200.01 requests/attempt · 2.71 app boots/UI scenario · 14.22% common-shard skew

Optimization targets still in progress:

  • Browser traffic was 200.01 requests per attempt (convergence target: fewer than 200).
  • Application boot ratio was 2.71 per UI scenario (1827 boots / 675 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
✅ Shard chromium-01 124 0 0 0 0 0
🟡 Shard chromium-02 132 0 2 0 0 0
✅ Shard chromium-03 132 0 0 0 0 0
✅ Shard chromium-04 103 0 0 0 0 0
✅ Shard data-asset-rules-01 61 0 0 0 0 0
✅ Shard domain-isolation-01 14 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 6 0 0 0 0 0
✅ Shard ingestion-01 1 0 0 0 0 0
✅ Shard reindex-01 2 0 0 0 0 0
✅ Shard search-01 10 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0
🟡 2 flaky test(s) (passed on retry)
  • Pages/InputOutputPorts.spec.tsRemove last port shows empty state (shard chromium-02, 1 retry)
  • Pages/InputOutputPorts.spec.tsOutput ports section collapse/expand (shard chromium-02, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

@ShaileshParmar11
ShaileshParmar11 added this pull request to the merge queue Aug 6, 2026
@ShaileshParmar11
ShaileshParmar11 removed this pull request from the merge queue due to a manual request Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

🚦 Removed from the merge queue — manual (2026-08-06T14:00:40Z)

No failing check on merge-queue commit 79dafa7 — invalidated by an entry ahead in the queue, or a required check timed out.

@gitar-bot

gitar-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Adds flaky Playwright test fixes and refactors helper logic across multiple E2E specs. Consider addressing the pre-existing toBeVisible assertion that defeats waitForPortRow recovery in the first step.

✅ 1 resolved
Edge Case: Preceding toBeVisible() defeats waitForPortRow recovery in first step

📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/InputOutputPorts.spec.ts:869-871
In the 'Verify action dropdown is visible' step, the pre-existing await expect(page.getByTestId(port-actions-${portId})).toBeVisible() on line 869 runs immediately before the new waitForPortRow(page, portId). If the port row is genuinely dropped by the ports endpoint (exactly the transient the new helper is meant to recover from via reload), this assertion throws on its default 5s timeout before waitForPortRow ever gets a chance to reload, so this step stays flaky. The other four call sites correctly place waitForPortRow first. Remove the redundant toBeVisible() here (or move waitForPortRow above it) so the reload-recovery path can actually run.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source

@ShaileshParmar11
ShaileshParmar11 added this pull request to the merge queue Aug 6, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants