Skip to content

test(teams): stop the add-team click from landing in a toast - #31734

Merged
harsh-vador merged 2 commits into
mainfrom
fix/teams-hierarchy-toast-intercepted-click
Aug 20, 2026
Merged

test(teams): stop the add-team click from landing in a toast#31734
harsh-vador merged 2 commits into
mainfrom
fix/teams-hierarchy-toast-intercepted-click

Conversation

@harsh-vador

@harsh-vador harsh-vador commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Describe your changes

TeamsHierarchy.spec.tsAdd teams in hierarchy flakes: the add-team modal never opens, and the failure surfaces ~15s later as expect(locator('[role="dialog"].ant-modal').last()).toBeVisible() timing out.

Root cause. addTeamHierarchy clicked the add button with { force: true }, which skips Playwright's hit-target check. The backend fans delete/job notifications out to every socket of the logged-in admin, so a parallel worker's success toast (e.g. "archive-test-….txt" deleted successfully!) can sit over add-placeholder-button. With force the click was dispatched into the toast — it reported success in ~148ms, no modal opened, and the next assertion ate the full 15s.

Fix. Drop force: true and click a getByTestId locator normally. Success toasts render no close button (showClose: false for the success variant) and self-dismiss after 3500ms, so the hit-target check simply waits the toast out — well inside the test timeout. This also brings the helper in line with the repo rule that { force: true } is not allowed in Playwright tests.

Considered and rejected:

  • closeFirstPopupAlert(page) — targets alert-icon-close, which the success toast never renders, so it is a no-op here.
  • An explicit wait for alert-bar to detach — a cross-worker toast can arrive after that wait, so it is not sound; the hit-target retry covers both cases without adding a timeout.

Blast radius: the other addTeamHierarchy callers — TeamsDragAndDrop.spec.ts and Teams.spec.ts — get the same de-forced click. None relied on force; the button is a normal enabled placeholder button in every case.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have read the CONTRIBUTING document.
  • My PR title is following the convention.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.

Verified locally: prettier, eslint, and tsc --noEmit clean on playwright/utils/team.ts. The spec itself needs a live server, so it was not executed here.

🤖 Generated with Claude Code

Greptile Summary

The PR centralizes opening the add-team modal in a retrying Playwright helper to prevent transient toast overlays from swallowing clicks.

  • Replaces direct and forced add-team clicks with hit-target-checked clicks.
  • Waits through toast overlays and verifies that the add-team modal becomes visible.
  • Reuses the helper across team creation and hierarchy test flows.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/playwright/utils/team.ts Adds the shared toast-aware modal-opening helper and adopts it in the affected team utilities without an established blocking failure.
openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts Replaces duplicated direct add-team clicks with the shared modal-opening helper.

Reviews (2): Last reviewed commit: "test(teams): retry the add-team open whe..." | Re-trigger Greptile

addTeamHierarchy clicked the add button with `force: true`, which skips the
hit-target check. The backend fans delete/job notifications out to every
socket of the logged-in admin, so a parallel worker's success toast can sit
over that button — and with force the click was dispatched into the toast.
The click "succeeded", the modal never opened, and the failure surfaced 15s
later on the modal assertion.

Success toasts carry no close button and self-dismiss after 3.5s, so
clicking without force is the fix: the hit-target check waits the toast out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

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.

@github-actions github-actions Bot added the UI UI specific issues label Aug 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@harsh-vador harsh-vador self-assigned this Aug 19, 2026
@harsh-vador harsh-vador added the safe to test Add this label to run secure Github workflows on PRs label Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

✅ Playwright Results — workflow succeeded

Validated commit b63c2052aee4ffd0297494a0b1b426bd1e9070e1 in Playwright run 32235657833, attempt 2.

✅ 570 passed · ❌ 0 failed · 🟡 0 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) 1h 7m 2s

⏱️ Max setup 4m 20s · max shard execution 14m 50s · max shard-job elapsed before upload 18m 18s · reporting 5s

🌐 218.43 requests/attempt · 2.85 app boots/UI scenario · 4.38% common-shard skew

Optimization targets still in progress:

  • Browser traffic was 218.43 requests per attempt (convergence target: fewer than 200).
  • Application boot ratio was 2.85 per UI scenario (1690 boots / 592 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
✅ Shard chromium-01 104 0 0 0 0 0
✅ Shard chromium-02 114 0 0 0 0 0
✅ Shard chromium-03 96 0 0 0 0 0
✅ Shard chromium-04 104 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 ingestion-01 1 0 0 0 0 0
✅ Shard reindex-01 2 0 0 0 0 0
✅ Shard search-01 11 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0

📦 Download artifacts

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

@harsh-vador harsh-vador added the To release Will cherry-pick this PR into the release branch label Aug 19, 2026
Dropping `force` was not enough. Playwright checks the hit target and then
dispatches, so a socket-fanned success toast landing in that window still
swallows the click — the trace shows the click "succeeding" in 16ms with a
delete toast on screen and the modal never opening.

Route every add-team trigger through openAddTeamModal: let a pending toast
expire, click, and retry until the modal is up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@harsh-vador

Copy link
Copy Markdown
Contributor Author

Pushed b63c205 — the first fix was not sufficient, it still failed in nightly (run 32129322883, Verify breadcrumb navigation for a team with a dot in its name).

Dropping force narrows the window but does not close it: Playwright runs the hit-target check and then dispatches, so a toast that lands in between still swallows the click. The trace shows exactly that — the add-placeholder-button click "succeeds" in 16ms with "cc-permission-folder-4fd44780" deleted successfully! on screen, then [role="dialog"].ant-modal never appears and the 15s assertion times out. One click, no retry, nothing to recover from.

New openAddTeamModal(page, trigger) in playwright/utils/team.ts waits for any alert-bar to detach (6s, past the 3.5s self-dismiss; a failure there is ignored since it just means we click and retry), clicks, asserts the modal within 10s, and wraps that in toPass (60s) so a swallowed click is retried. Still no force — that dispatches into the toast.

Applied at every add-team trigger so it cannot regress at one call site: addTeamHierarchy (both the add-team and add-placeholder-button paths), executionOnOwnerTeam's placeholder click, and the two direct add-team clicks in Teams.spec.ts.

Verified locally: prettier clean, eslint 0 errors on both files (the 4 remaining warnings are the pre-existing browser.newPage() multi-user fixtures), tsc --project playwright/tsconfig.json reports nothing for either file. The spec itself needs a live server, so CI is the real check here.

@harsh-vador
harsh-vador added this pull request to the merge queue Aug 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚦 Removed from the merge queue — failed_checks (2026-08-19T23:23:15Z)

Blocked the queue: playwright-summary

@harsh-vador
harsh-vador added this pull request to the merge queue Aug 20, 2026
Merged via the queue into main with commit af609a6 Aug 20, 2026
109 of 115 checks passed
@harsh-vador
harsh-vador deleted the fix/teams-hierarchy-toast-intercepted-click branch August 20, 2026 08:29
@github-actions

Copy link
Copy Markdown
Contributor

Failed to cherry-pick changes to the 1.13 branch.
Please cherry-pick the changes manually.
You can find more details here.

@github-actions

Copy link
Copy Markdown
Contributor

Changes have been cherry-picked to the 2.0 branch.

github-actions Bot pushed a commit that referenced this pull request Aug 20, 2026
* test(teams): stop the add-team click from landing in a toast

addTeamHierarchy clicked the add button with `force: true`, which skips the
hit-target check. The backend fans delete/job notifications out to every
socket of the logged-in admin, so a parallel worker's success toast can sit
over that button — and with force the click was dispatched into the toast.
The click "succeeded", the modal never opened, and the failure surfaced 15s
later on the modal assertion.

Success toasts carry no close button and self-dismiss after 3.5s, so
clicking without force is the fix: the hit-target check waits the toast out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(teams): retry the add-team open when a toast eats the click

Dropping `force` was not enough. Playwright checks the hit target and then
dispatches, so a socket-fanned success toast landing in that window still
swallows the click — the trace shows the click "succeeding" in 16ms with a
delete toast on screen and the modal never opening.

Route every add-team trigger through openAddTeamModal: let a pending toast
expire, click, and retry until the modal is up.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit af609a6)
@gitar-bot

gitar-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Removes forced clicks from the team-hierarchy Playwright helper to let tests wait out transient success toasts, eliminating test flakiness. No issues found.

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 👍 / 👎 | Powered by Gitar — free for open source

anuj-kumary pushed a commit that referenced this pull request Aug 24, 2026
* test(teams): backport addTeamHierarchy hardening to 1.13

1.13 never received the addTeamHierarchy waits that main and 2.0 carry, so
the helper returns while the teams table is still refetching: it opens the
modal on a plain click a toast can swallow, resolves on the first
`/api/v1/teams` response regardless of method or status, and never waits
for the modal to close or the row to render.

Backports the team.ts changes from #25894, #30334 and #31734.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(teams): stop the teams landing from eating the test budget

TeamsDragAndDrop's beforeEach spent the whole 60s test timeout before any
test body ran. settingClick already ends in waitForAllLoadersToDisappear
(30s), and the hook then called it a second time. The Teams table's antd
spinner is the shared `data-testid="loader"`, and it stays up until both
the child-teams fetch and the per-team asset-count aggregation settle — on
a long-lived deployment that is tens of seconds, so the two waits together
consumed the budget and the hook timed out on the second one.

Give the suite test.slow(true) so the landing has headroom, and hard-delete
the four teams the suite creates. Without that cleanup every nightly run
left four more teams under Organization, growing the aggregation the
landing waits on and making the next run slower.

Fold the duplicated navigation into visitTeamsPage and reuse it from
TeamsHierarchy, which had the same hook with looser glob waits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(teams): surface a failed cleanup delete

hardDeleteTeamByName issued the DELETE and ignored the result, so a delete
rejected on permissions or failing with a 500 left the team behind with no
signal in the run — quietly reintroducing the accumulation this cleanup
exists to prevent. Assert the response instead, with the status and body in
the message.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(teams): only tolerate a 404 on the cleanup lookup

The lookup guard keyed off `ok()`, which is false for an auth error or a 500
just as it is for a 404. A broken lookup therefore took the same path as a
team that was already gone: return without deleting, and report success.

Tolerate 404 alone — the spec may have deleted the team itself, and a
recursive delete of its parent takes its children — and assert every other
lookup failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(teams): attempt every cleanup delete before asserting

The assertion sat inside hardDeleteTeamByName, so the first team that failed
to delete threw out of the caller's loop and the remaining names were never
attempted — leaving those teams on the deployment, which is the accumulation
the cleanup exists to prevent.

Move the assertion up into hardDeleteTeamsByName: the per-team helper now
reports a failure instead of throwing (network errors included), every name
is attempted, and one assertion at the end names every team that survived
along with the status and body that explain why.

Wrap the call in try/finally in the spec so the API context is disposed even
when cleanup fails.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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 To release Will cherry-pick this PR into the release branch UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants