Improvement: lint against ambiguous search/aggregate waits in Playwright - #31873
Improvement: lint against ambiguous search/aggregate waits in Playwright#31873harsh-vador wants to merge 2 commits into
Conversation
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
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 |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
✅ Playwright Results — workflow succeededValidated commit ✅ 564 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) 48m 43s ⏱️ Max setup 4m 24s · max shard execution 15m 37s · max shard-job elapsed before upload 18m 41s · reporting 4s 🌐 214.33 requests/attempt · 2.81 app boots/UI scenario · 6.08% 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 |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
2 similar comments
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
A facet dropdown aggregates the same field twice — once when it opens (`value=.*`) and once per typed search. A wait naming only the endpoint or the field matches both, so it can resolve on the open request while the typed search is still in flight; the test then runs ahead of the request it queued. That is how #31859 stayed hidden behind a passing assertion. - playwright/utils/searchAggregation.ts: `waitForAggregation(page, { field, value, deleted })` matches on parsed URL params instead of a glob. `value` is required and takes `null` (or `''`) for the request fired on open, so the intent is stated at the call site. The search text is compared exactly after unwrapping the API's `.*text.*`, so a wait for `service` cannot resolve on an in-flight response for `service-name`; backslashes are normalised away because the API escapes ES reserved characters. - eslint-rules/openmetadata-playwright.mjs: `require-aggregation-wait-helper` flags raw waits on the endpoint — string, template literal or URL predicate — and follows an identifier to its declaration so hoisting the URL to a local const does not silence it. Registered at `warn` while the remaining 27 call sites are migrated, matching the convention used for the other aspirational Playwright rules. - Migrated the sites where the ambiguity is a live latent bug: ExploreDiscovery (4), utils/explore.ts (2), utils/glossary.ts, DataProductCertificationFilter. The explore-tree POST aggregate carries no field/value to discriminate on and is suppressed with a reason. Verified against a local stack: 45/46 of the affected specs pass; the one failure (EntitySummaryPanel display-name modal) contains no aggregation wait and passes in isolation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8b940ed to
c3a2872
Compare
…than strip - resolveMatcherText now walks the scope chain via the same findVariable helper openmetadata-performance.mjs uses, and reads later assignments as well as declarations, so a matcher declared at module scope or assigned to a `let` no longer escapes the rule. Quotes and `+` are dropped before the endpoint check so a path split across concatenated literals still matches. - searchAggregation compares against an unescaped URL value instead of stripping backslashes from both sides, which kept `foo\bar` and `foobar` distinct rather than collapsing them onto each other. - Restores the rule's own doc block, which an earlier comment trim had left sitting above resolveMatcherText. Rule tests cover the module-scope, reassigned-let and concatenated forms: 99 pass. The affected specs still pass against a local stack (27/27). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Code Review ✅ Approved 2 resolved / 2 findingsAdds the ✅ 2 resolved✅ Edge Case: Empty-string value reintroduces the open-request ambiguity
✅ Quality: Lint rule misses concatenated/reassigned aggregate URLs
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 #31859
Follow-up to #31860, which fixed the stale-response race in the Explore filter dropdowns. This one goes after the test-side half of that bug so it cannot be written again.
The mistake worth linting. A facet dropdown fires two aggregations against the same field: one when it opens (
value=.*) and one per typed search (value=.*text.*). A wait likewaitForResponse('…/aggregate?…&field=ownerDisplayName*deleted=true*')matches both. In #31859 it resolved off the dropdown-open request, so the test ran ahead of the search it had queued, and the orphaned response landed in a dropdown opened later — behind a passing assertion.playwright/utils/searchAggregation.ts—waitForAggregation(page, { field, value, deleted }). Matches on parsed URL params rather than a glob, which removes the encoding footguns entirely.valueis required and takesnullfor "the dropdown-open request", so intent is stated at every call site instead of being inferred. Backslashes are stripped from both sides of the comparison becausegetAggregateFieldOptionsruns the search text throughescapeESReservedCharactersbefore putting it invalue— without that, any value containing-or:would never match and would time out.eslint-rules/openmetadata-playwright.mjs— new rulerequire-aggregation-wait-helper, flagging raw waits onsearch/aggregatein string, template-literal and URL-predicate form. The helper module itself is exempt.warn. 36 call sites exist today; this PR migrates 8, leaving 27. That matches the convention already ineslint.config.mjs—errorfor rules with a zero backlog,warnfor ones being worked down. Promote toerroronce the rest are migrated.ExploreDiscovery.spec.ts(4 waits, replacing the value-globs from Fixes 31859: discard an Explore filter search that resolves after its dropdown closed #31860 with the helper),utils/explore.ts(2),utils/glossary.ts,DataProductCertificationFilter.spec.ts. The explore-tree drill-down is a POST aggregate with no field/value pair to discriminate on, so it carries a narrow suppression with the reason inline.Two of the 36 sites are legitimate dropdown-open waits (
utils/advancedSearch.ts,AdvancedSearchSuggestions.spec.ts) — the helper expresses those asvalue: null, which is why the option exists rather than the rule demanding a value.Stacked on
fix/explore-quick-filter-stale-options(#31860) because both touchExploreDiscovery.spec.ts; GitHub will retarget this tomainwhen that merges.Type of change:
High-level design:
N/A — small change.
Tests:
Use cases covered
value: null) and not flagged.Unit tests
eslint-rules/openmetadata-playwright.test.mjs— 4 valid / 3 invalid cases viaRuleTester, plus the plugin-export assertion, in the same style as the existing rule tests.yarn test:eslint-rules→ 93 tests, 93 pass.npx eslint playwright eslint-rules→ 0 errors (299 warnings: 272 pre-existing + the 27 remaining sites this rule now names).npx tsc --noEmit→ 0 errors underplaywright/.Backend integration tests
Ingestion integration tests
Playwright (UI) tests
getAggregateFieldOptions(field,value,deletedon every GET aggregate) and by the backslash normalisation above, but the AUT run is the real check.Manual testing performed
Lint and rule-unit level only, as above.
UI screen recording / screenshots:
Not applicable — test tooling only, no product code.
Checklist:
🤖 Generated with Claude Code
Greptile Summary
This PR introduces a parsed-URL Playwright helper for aggregation waits and a repository lint rule discouraging ambiguous raw waits.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Reviews (7): Last reviewed commit: "Address review: widen the rule's matcher..." | Re-trigger Greptile