Fixes 31518: Stabilize Data Quality and Incident Manager tests - #31519
Fixes 31518: Stabilize Data Quality and Incident Manager tests#31519shah-harshit wants to merge 4 commits into
Conversation
✅ Playwright Results — workflow succeededValidated commit ✅ 772 passed · ❌ 0 failed · 🟡 0 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky PerformanceBlocking 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) 51m 28s ⏱️ Max setup 3m 3s · max shard execution 18m 4s · max shard-job elapsed before upload 21m 25s · reporting 6s 🌐 212.77 requests/attempt · 2.64 app boots/UI scenario · 4.34% common-shard skew Optimization targets still in progress:
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
Code Review ✅ ApprovedStabilizes flaky Data Quality and Incident Manager Playwright tests by replacing unreliable click triggers and global assertions with proper hover interactions and search-index polling. No issues found. OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
Describe your changes:
Fixes #31518
This PR stabilizes two independent Playwright flakes in the Data Quality and Incident Manager suites. Both failures came from synchronizing on an event weaker than the product state the test intended to verify:
No product behavior or API contract changes. The patch only makes the existing tests interact with the real UI contract and wait for the exact observable state.
Root cause analysis
1. Data Quality pagination page-size dropdown
Failure signature
The failure happened after the page-size trigger was clicked. The captured DOM showed the page-size button as active, but no visible dropdown menu was mounted during the fixed five-second window.
Product interaction contract
The pagination component wraps the page-size button in Ant Design
Dropdownwithout an explicittrigger: NextPrevious.tsx lines 125-144.preventDefault().The original test clicked the trigger and then waited on the broad
.ant-dropdown-menuselector with a hard five-second timeout: original DataQuality.spec.ts lines 1460-1474.This was flaky for two independent reasons:
.ant-dropdown-menucan match Ant menus that remain mounted but hidden, so it did not uniquely identify the popup associated with this trigger.A controlled repetition reproduced the original failure after four successful iterations. That pass/pass/pass/pass/fail pattern is consistent with an input-event race, not a consistently slow render.
Fix
The corrected flow is at DataQuality.spec.ts lines 1460-1474:
hover(), matching the component contract..ant-dropdown:not(.ant-dropdown-hidden)so only the visible popup is considered.waitFor.menuitemroles within the visible popup.The explanatory comment for the non-obvious hover behavior is at lines 1468-1471.
Increasing the original timeout would only give an incorrect click interaction more time; it would not guarantee that the hover-triggered menu opens.
2. Incident Manager assignee filter
This failure had two original synchronization defects, followed by one authentication defect exposed by the first version of the index-polling fix.
2a. The post-assignment assertion targeted the wrong incident row
The assignment helper identifies the target row by test-case identifier before opening its editor: incidentManager.ts lines 177-185.
The original post-write assertion then discarded that identity and read
page.getByTestId('assignee').first(): original incidentManager.ts lines 254-272.On a multi-row Incident Manager listing, the first assignee is not necessarily the incident just updated. If the first unrelated row is unassigned, the assertion receives
No Assigneeeven when the target assignment succeeded. The previous globalowner-link.first()wait had the same problem: it proved only that some owner link existed somewhere on the page.The helper now preserves target identity and reads the assignee within the exact incident row: incidentManager.ts lines 258-275. The 30-second web-first assertion permits that row to re-render after the acknowledged update without a blind sleep. The reason for row scoping is documented at lines 261-269.
2b. The assignment write completed before the search listing converged
Assignment waits for the task-resolution POST response: task.ts lines 60-65, consumed at incidentManager.ts lines 254-256.
That response acknowledges the write side. The assignee filter reads from
/api/v1/dataQuality/testCases/testCaseIncidentStatus/search/list?assignee=..., so it observes the asynchronously updated search document. A successful task transition does not guarantee that the updated assignee is already searchable.The original filter flow waited for exactly one search response and immediately asserted its rows: original IncidentManager.spec.ts lines 1081-1090. If that first request reached search before indexing completed, it returned a valid but stale result. Waiting longer on an already completed response cannot make its payload current.
Why the existing helper needed to be extended
waitForIncidentToBeIndexedalready existed, but before this PR it called the database-backed incident endpoint: original dataQuality.ts lines 577-611.The two server routes have different consistency boundaries:
GET /testCaseIncidentStatusroute ends inrepository.list(...): TestCaseResolutionStatusResource.java lines 108-219.GET /testCaseIncidentStatus/search/list, whose implementation builds aSearchListFilterand callsrepository.listLatestFromSearch(...)orrepository.listFromSearchWithOffset(...): TestCaseResolutionStatusResource.java lines 639-791.Therefore, the unchanged helper could return as soon as the database row existed while Incident Manager's search document still contained the prior assignee. A generic search-presence check would also be insufficient: document existence does not prove that the assignee transition has been indexed.
The extended helper polls the same search-backed route and verifies the exact FQN, status, and nested assignee: dataQuality.ts lines 569-638.
It now:
/testCaseIncidentStatus/search/list.updatedAtfor assignee transitions because they update an existing incident whose originaltimestampremains unchanged.2c. Follow-up CI failure: the index poll was unauthenticated
The first implementation passed
page.requestto the extended helper. The subsequent ingestion CI failure timed out inwaitForIncidentToBeIndexedwithExpected: true / Received: false.Inspection of the failed job's server diagnostics provided an artifact-level reproduction without rerunning the test: failed ingestion job.
The relevant request sequence was:
The retry repeated the same pattern from
14:31:50through14:32:49. Every poll returned HTTP 401 with a 58-byte response. This rules out an index query mismatch as the cause of this particular timeout: the helper never reached the search read at all.The application stores its JWT in browser local storage. Browser-originated API calls inject that bearer token, but the request made through
page.requestdid not inherit it. The repository's authenticated context explicitly reads the page token and addsAuthorization: Bearer <token>: common.ts lines 58-76, wrapped bygetApiContext(page)at common.ts lines 294-305.The corrected test now:
waitForIncidentToBeIndexedwithAssigned + <username>.finally.This sequence is at IncidentManager.spec.ts lines 1063-1104. The authentication rationale is documented inline at lines 1073-1076.
The original product race is still a search-index propagation issue, so the existing helper remains the right synchronization primitive after extending it to verify the indexed assignee. The follow-up CI failure was in how that helper was called, not evidence that the indexing diagnosis was wrong.
Why these failures were flaky
assignee.first()assertionScope and risk
Type of change:
High-level design:
The tests synchronize on observable business state:
Tests:
Use cases covered
Unit tests
Backend integration tests
Ingestion integration tests
Playwright (UI) tests
Static validation performed
git diff --checkpassed.UI screen recording / screenshots:
Not applicable — no product UI behavior changed.
Checklist:
Bug fix: