Skip to content

Fix test suite tab loading race#29561

Merged
shah-harshit merged 4 commits into
mainfrom
codex/test-suite-loader-race
Jun 30, 2026
Merged

Fix test suite tab loading race#29561
shah-harshit merged 4 commits into
mainfrom
codex/test-suite-loader-race

Conversation

@shah-harshit

@shah-harshit shah-harshit commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Description

  • Show a loader while the test suite list request is in flight.
  • Ignore stale test suite list responses when switching between table suites and bundle suites.
  • Add unit coverage and an existing-spec E2E regression for the tab switching race.

Tests

  • ./node_modules/.bin/jest src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.test.tsx --runInBand
  • UI checkstyle sequence on changed UI and Playwright files
  • Targeted Playwright TypeScript check for Pages/TestSuite.spec.ts
  • git diff --check

Fixes open-metadata/openmetadata-collate#4741

Screen.Recording.2026-06-29.at.7.32.31.PM.mov

Greptile Summary

This PR fixes a race condition in the TestSuites component where switching between table suites and bundle suites could cause a stale API response to overwrite the newly loaded data. The fix uses an incrementing request-ID ref (latestRequestId) to discard out-of-order responses, and adds an inline Loader to the table body while data is in flight.

  • Race fix: fetchTestSuites now stamps each call with a monotonically incrementing ID and short-circuits state updates in try/catch/finally if the request is no longer current, so a delayed table-suite response can never replace bundle-suite data.
  • UX improvement: isLoading is set to true at the start of every fetch, forcing Table.Body to render the empty-state slot with a Loader spinner rather than stale rows.
  • Test coverage: A new Jest unit test validates both the loader-visible and stale-response-ignored cases; a new Playwright E2E test intercepts the table-suite network request, holds it open while the user switches tabs, then releases it to confirm no regression.

Confidence Score: 5/5

Safe to merge — the change is a targeted, well-tested fix for a UI race condition with no effect on data persistence or API contracts.

The monotonic request-ID pattern is correct and idiomatic: each fetch captures its own ID before any await, the ref is updated synchronously, and all three outcome branches guard against stale updates. Both unit tests and the E2E test reproduce the exact race sequence from the bug report. No regressions are introduced in unrelated code paths.

No files require special attention.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx Core race-condition fix: replaces a plain async function with a useCallback that stamps each fetch with a monotonic ID, discards stale responses, and renders a Loader while in-flight. Logic is sound and deps arrays are correctly updated.
openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.test.tsx Adds two focused unit tests: loader visibility while the API promise is pending, and stale-response suppression after switching tabs. Mock structure updated to render renderEmptyState inside a table cell so the loader renders correctly in JSDOM.
openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts New E2E test intercepts the table-suite request with a deferred promise, holds the response while the user switches to bundle suites, then verifies the bundle data survives the late table-suite response. BundleTestSuiteClass is added and properly cleaned up in afterAll.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant U as User
    participant C as TestSuites Component
    participant API as API (getListTestSuitesBySearch)

    Note over C: latestRequestId.current = 0

    U->>C: Navigate to Table Suites tab
    C->>C: "requestId=1, latestRequestId=1, setIsLoading(true)"
    C->>API: "fetch(testSuiteType=basic)"

    Note over API: Response delayed…

    U->>C: Switch to Bundle Suites tab
    C->>C: "requestId=2, latestRequestId=2, setIsLoading(true)"
    C->>API: "fetch(testSuiteType=logical)"

    API-->>C: "Bundle suites response (requestId=2)"
    C->>C: "2 === latestRequestId(2) ✓ setTestSuites(bundleData), setIsLoading(false)"

    API-->>C: "Stale table suites response (requestId=1)"
    C->>C: 1 ≠ latestRequestId(2) → DISCARD (no state update)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant U as User
    participant C as TestSuites Component
    participant API as API (getListTestSuitesBySearch)

    Note over C: latestRequestId.current = 0

    U->>C: Navigate to Table Suites tab
    C->>C: "requestId=1, latestRequestId=1, setIsLoading(true)"
    C->>API: "fetch(testSuiteType=basic)"

    Note over API: Response delayed…

    U->>C: Switch to Bundle Suites tab
    C->>C: "requestId=2, latestRequestId=2, setIsLoading(true)"
    C->>API: "fetch(testSuiteType=logical)"

    API-->>C: "Bundle suites response (requestId=2)"
    C->>C: "2 === latestRequestId(2) ✓ setTestSuites(bundleData), setIsLoading(false)"

    API-->>C: "Stale table suites response (requestId=1)"
    C->>C: 1 ≠ latestRequestId(2) → DISCARD (no state update)
Loading

Reviews (4): Last reviewed commit: "Merge branch 'main' into codex/test-suit..." | Re-trigger Greptile

@shah-harshit shah-harshit requested a review from a team as a code owner June 29, 2026 09:05
@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.

@shah-harshit shah-harshit self-assigned this Jun 29, 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!

@shah-harshit shah-harshit added UI UI specific issues data quality e2e This will trigger e2e test workflows observ safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check and removed e2e This will trigger e2e test workflows observ labels Jun 29, 2026
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 62%
63.05% (70475/111765) 45.9% (40654/88559) 47.34% (12577/26567)

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (47 flaky)

✅ 4430 passed · ❌ 0 failed · 🟡 47 flaky · ⏭️ 38 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 322 0 3 4
🟡 Shard 2 819 0 10 9
🟡 Shard 3 825 0 9 7
🟡 Shard 4 822 0 4 10
🟡 Shard 5 862 0 12 0
🟡 Shard 6 780 0 9 8
🟡 47 flaky test(s) (passed on retry)
  • Features/DataAssetRulesDisabled.spec.ts › Verify the Directory entity item action after rules disabled (shard 1, 1 retry)
  • Features/CustomizeDetailPage.spec.ts › Topic - customization should work (shard 1, 1 retry)
  • Flow/SearchRBAC.spec.ts › a fully denied user sees neither asset type when browsing (shard 1, 2 retries)
  • Features/BulkEditEntity.spec.ts › Glossary (shard 2, 1 retry)
  • Features/BulkImport.spec.ts › Database service (shard 2, 1 retry)
  • Features/BulkImport.spec.ts › Database Schema (shard 2, 1 retry)
  • Features/BulkImport.spec.ts › Table (shard 2, 2 retries)
  • Features/BulkImportWithDotInName.spec.ts › Import at schema level with dot in service name (shard 2, 2 retries)
  • Features/Container.spec.ts › expand / collapse should not appear after updating nested fields for container (shard 2, 1 retry)
  • Features/Container.spec.ts › Copy column link button should copy the column URL to clipboard (shard 2, 1 retry)
  • Features/EntitySummaryPanel.spec.ts › should cancel edit display name modal (shard 2, 1 retry)
  • Features/GlobalSearchSuggestions.spec.ts › Navigate to column from column suggestion (shard 2, 2 retries)
  • Features/Glossary/GlossaryPagination.spec.ts › should check for nested glossary term search (shard 2, 2 retries)
  • Features/KnowledgeCenter.spec.ts › Article mentions in description should working for Knowledge Center (shard 3, 1 retry)
  • Features/KnowledgeCenterTextEditor.spec.ts › Rich Text Editor - Text Formatting (shard 3, 1 retry)
  • Features/NestedColumnsExpandCollapse.spec.ts › should not duplicate rows when expanding and collapsing nested columns with same names (shard 3, 1 retry)
  • Features/Permissions/EntityPermissions.spec.ts › Topic deny entity-specific permission operations (shard 3, 1 retry)
  • Features/Permissions/EntityPermissions.spec.ts › SearchIndex deny common operations permissions (shard 3, 1 retry)
  • Features/RecentlyViewed.spec.ts › Check Store Procedure in recently viewed (shard 3, 1 retry)
  • Features/RecentlyViewed.spec.ts › Check Dashboard in recently viewed (shard 3, 2 retries)
  • Features/Topic.spec.ts › Copy nested field link should include full hierarchical path (shard 3, 1 retry)
  • Flow/ApiCollection.spec.ts › Verify Owner Propagation: owner should be propagated to the API Collection's API Endpoint (shard 3, 1 retry)
  • Flow/CustomizeWidgets.spec.ts › Data Products Widget (shard 4, 1 retry)
  • Flow/PersonaFlow.spec.ts › Set default persona for team should work properly (shard 4, 1 retry)
  • Flow/PlatformLineage.spec.ts › Verify Platform Lineage View (shard 4, 2 retries)
  • Pages/CustomProperties.spec.ts › Table (shard 4, 1 retry)
  • Pages/Entity.spec.ts › DisplayName Add, Update and Remove for child entities (shard 5, 1 retry)
  • Pages/Entity.spec.ts › Tier Add, Update and Remove (shard 5, 1 retry)
  • Pages/Entity.spec.ts › Tag Add, Update and Remove (shard 5, 1 retry)
  • Pages/Entity.spec.ts › Update description (shard 5, 1 retry)
  • ... and 17 more

📦 Download artifacts

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

@sonarqubecloud

Copy link
Copy Markdown

@shah-harshit shah-harshit enabled auto-merge (squash) June 30, 2026 08:08
@shah-harshit shah-harshit merged commit f3ddf60 into main Jun 30, 2026
60 of 62 checks passed
@shah-harshit shah-harshit deleted the codex/test-suite-loader-race branch June 30, 2026 11:19
@gitar-bot

gitar-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Implements a loading state and stale response ignore logic to resolve test suite tab race conditions. Includes unit and E2E regression coverage to ensure reliable data fetching.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data quality safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants