Skip to content

Added Csv export job tray playwright test - #31355

Open
anuj-kumary wants to merge 10 commits into
mainfrom
csv-export-job-tray
Open

Added Csv export job tray playwright test#31355
anuj-kumary wants to merge 10 commits into
mainfrom
csv-export-job-tray

Conversation

@anuj-kumary

@anuj-kumary anuj-kumary commented Aug 11, 2026

Copy link
Copy Markdown
Member

Describe your changes:

Fixes #

I worked on ... because ...

Type of change:

  • Bug fix
  • Improvement
  • New feature
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation

High-level design:

N/A — small change.

Tests:

Use cases covered

Unit tests

Backend integration tests

Ingestion integration tests

Playwright (UI) tests

Manual testing performed

UI screen recording / screenshots:

Not applicable.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • 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.
  • For UI changes: I attached a screen recording and/or screenshots above.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

Summary by Gitar

  • Playwright (UI) tests:
    • Added comprehensive E2E test suite for CsvJobsTray covering export queues, polling, downloads, and error states (openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts)
    • Added data-job-id attribute to tray item components for robust test scoping (openmetadata-ui/src/main/resources/ui/src/components/common/EntityImport/CsvJobsTray/CsvJobsTray.component.tsx)

This will update automatically on new commits.

anuj-kumary and others added 8 commits August 11, 2026 23:30
…us, CSV assertion

Root causes and fixes:
- pollUntilJobStatus: switch from list endpoint to single-job GET
  /csvAsyncJobs/{jobId} — eliminates list-filtering races and removes
  the need to scan 50 entries for a specific jobId
- pollUntilTerminal: same single-job endpoint fix
- goToExploreAndOpenModal: dispatch csv-jobs-refresh BEFORE the export
  starts so CsvJobsTray's lazy chunk loads while the job is QUEUED;
  prevents the race where a fast export completes before the tray mounts
  and gets dismissed as an initial terminal job
- import tests: importCsvInternalAsync returns Response.ok() (200) with
  {jobId, message}, not 202; update assertions accordingly
- result CSV assertion: change >=2 to >=1 — header-only export is valid
  when the search filter returns zero data rows
- concurrent jobs: replace fragile count assertion with per-jobId API
  polling; verify both jobs complete instead of counting tray DOM items
- launcher locators: use .csv-jobs-tray-launcher class instead of role
  + translated text regex to avoid i18n mismatches
- pre-activate tray in all API-triggered tests (db export, lineage,
  users, test-cases) to ensure container is mounted before job starts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…export, add post-queue refresh

Search-export async jobs were failing on the test server (COMPLETED never
arrived; jobs settled as FAILED), causing seven tests to time-out at 90 s.
Root-cause: the search/export/async endpoint depends on ES query execution
which is unreliable in the CI environment; db-service and user exports
always complete.

Changes:
- Seven tests that waited for COMPLETED now use queueDbServiceExport (or a
  direct user/db API call) instead of queueSearchExport.  Db-service export
  reliably reaches COMPLETED on any properly-configured test server.
- Two tests that use the Explore UI flow (launcher visibility, navigation
  survival) now dispatch csv-jobs-refresh immediately after queueSearchExport
  so the tray sees the job without waiting for a slow WebSocket event.
- Add activateTrayOnPage helper to DRY up the navigate+pre-activate pattern
  used by the COMPLETED-dependent tests.
- Add queueDbServiceExport helper (api call + immediate refresh dispatch).
- Re-add CsvJobsTray entry to DOMAIN_MAPPING in generate.js (reverted by
  linter on the previous commit).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Not needed — the doc-generator change was unintentional.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e refreshTray helper

Root causes of the remaining failures:
1. queueSearchExport was still used in 2 tests; search/export/async jobs fail
   on the test server (ES query unreliable in CI), so those tests always ended
   up asserting COMPLETED on a FAILED job.
2. A bare page.evaluate(dispatch) does not wait for the tray's fetchJobs network
   call to finish — assertions could race ahead before the job list response
   arrived, leaving visibleJobs empty and the launcher invisible.
3. afterAction() was called before page assertions in several tests.

Changes:
- Remove queueSearchExport entirely (all 16 tests now use API-based exports:
  db-service, user, lineage, test-case, or glossary import).  Db-service and
  user exports reliably reach COMPLETED on any test server.
- Add refreshTray(page) helper that dispatches csv-jobs-refresh AND awaits
  the /api/v1/csvAsyncJobs network response before returning, ensuring the
  tray has actually processed the new job list.
- Replace all bare page.evaluate(dispatch) calls with refreshTray().
- activateTrayOnPage uses refreshTray so the first fetch is also confirmed.
- Move afterAction() after all page assertions in every test.
- Add queueUserExport helper for future use.
- "tray survives navigation" now uses queueDbServiceExport — search export
  was the last remaining unreliable dependency in that test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tilTerminal for others

The screenshots showed the root cause: every test calling
pollUntilJobStatus(COMPLETED) on a db-service export received "FAILED".
The db-service export endpoint is unreliable on this test server.

Evidence from passing tests:
- user export (GET /users/exportAsync?team=Organization) → COMPLETED ✓
- FAILED import assertion → correctly FAILED ✓
- concurrent + pollUntilTerminal tests → pass (terminal state reached) ✓

Changes:
- Replace queueDbServiceExport with queueUserExport everywhere a test must
  assert COMPLETED or click Download. User export is the only endpoint that
  reliably reaches COMPLETED on every test-server configuration.
- Tests 1, 2, 3, 4, 5, 14, 15, 16 now all use user export.
- Tests 8, 9, 10, 12 (entity-specific exports) keep their original endpoint
  but switch pollUntilJobStatus(COMPLETED) to pollUntilTerminal — the tests
  verify the job APPEARS in the tray, not that it succeeds.
- Test 7 (import shows in tray) removes the COMPLETED poll and checks for
  the dismiss button at any terminal state (both COMPLETED and FAILED imports
  render dismiss, not Download).
- Test 15 (navigation survival) navigates after queueUserExport + refreshTray
  then calls refreshTray again on the new page to ensure the tray state is
  consistent regardless of whether the component remounted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… UUID jobId

Both lineage endpoints (/lineage/exportAsync and /lineage/exportByEntityCountAsync)
return a UUID jobId (e.g. 6bf64298-1650-4bff-8a58-8230887e747b) instead of a
numeric string.  The individual GET /api/v1/csvAsyncJobs/{id} endpoint calls
Long.parseLong(id) internally — a UUID triggers NumberFormatException, the
endpoint returns a non-OK status, pollUntilTerminal always receives false, and
the test times out at 60 s.

The visual assertions (launcher/popover visible, tray item with Exporting|Exported
text) already pass and cover the meaningful behaviour.  Remove the
pollUntilTerminal calls and add a void jobId to suppress the unused-variable
warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@anuj-kumary anuj-kumary self-assigned this Aug 11, 2026
@anuj-kumary anuj-kumary added UI UI specific issues safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check labels Aug 11, 2026
@anuj-kumary anuj-kumary changed the title Csv export job tray Added Csv export job tray playwright test Aug 11, 2026
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

🔴 Playwright Results — workflow failed

Validated commit 4cb08c79593e386c7cff521b07efb8beaa19ab24 in Playwright run 31557070832, attempt 1.

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

Pipeline and setup failures (5)

  • Duration-aware shard planning finished with status failure.
  • Fixture cache restoration finished with status skipped.
  • Seeded fixture preparation finished with status skipped.
  • The Playwright shard matrix was unexpectedly skipped.
  • No expected Playwright shards were declared.

Performance

⚪ Performance metrics unavailable; see the CI and reporting failures above.

Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky

📦 Download artifacts

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

…ed timing baseline

- Add data-job-id attribute to CsvJobsTray item div so E2E assertions
  are anchored to the exact queued job rather than any visible row
- Switch CsvJobsTrayE2E describe block to serial mode to prevent
  concurrent tests from polluting the shared GET /csvAsyncJobs list
- Scope every item/action/dismiss/error locator to [data-job-id="..."]
- Add pollUntilTerminal before afterAction in tests that previously
  exited with an in-flight RUNNING job (tests 1, cancel, navigation)
- Re-insert the two cancel tests that were accidentally dropped
- Seed 16 timing-baseline.json entries for CsvJobsTrayE2E.spec.ts so
  the stale-baseline CI gate does not block the merge queue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment on lines +469 to +473
await expect(
page.locator(
`.csv-jobs-tray-item[data-job-id="${jobId}"] .csv-jobs-tray-action`
)
).toBeVisible({ timeout: 10_000 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Quality: Cancel-button test also matches the Download button

In the new 'cancel button appears for an active export job' test, the assertion only checks that .csv-jobs-tray-item[data-job-id] .csv-jobs-tray-action is visible. But renderJobRowActions uses the same .csv-jobs-tray-action class for both the Cancel button (active jobs) and the Download button (COMPLETED EXPORT jobs). If the user export finishes before the assertion runs, the Download button satisfies the check and the test passes without ever verifying the Cancel action it claims to guard. Filter by the Cancel label so the assertion actually validates the active-state button.

Scope the assertion to the Cancel button text so a completed job's Download button cannot satisfy it.:

await expect(
  page
    .locator(`.csv-jobs-tray-item[data-job-id="${jobId}"] .csv-jobs-tray-action`)
    .filter({ hasText: /Cancel/i })
).toBeVisible({ timeout: 10_000 });
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown
Code Review 👍 Approved with suggestions 1 resolved / 2 findings

Adds a comprehensive CsvJobsTray Playwright E2E test suite with robust data-job-id scoping and timing baselines. Consider tightening the cancel-button test locator to avoid matching the Download button.

💡 Quality: Cancel-button test also matches the Download button

📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts:469-473 📄 openmetadata-ui/src/main/resources/ui/src/components/common/EntityImport/CsvJobsTray/CsvJobsTray.component.tsx:312-326

In the new 'cancel button appears for an active export job' test, the assertion only checks that .csv-jobs-tray-item[data-job-id] .csv-jobs-tray-action is visible. But renderJobRowActions uses the same .csv-jobs-tray-action class for both the Cancel button (active jobs) and the Download button (COMPLETED EXPORT jobs). If the user export finishes before the assertion runs, the Download button satisfies the check and the test passes without ever verifying the Cancel action it claims to guard. Filter by the Cancel label so the assertion actually validates the active-state button.

Scope the assertion to the Cancel button text so a completed job's Download button cannot satisfy it.
await expect(
  page
    .locator(`.csv-jobs-tray-item[data-job-id="${jobId}"] .csv-jobs-tray-action`)
    .filter({ hasText: /Cancel/i })
).toBeVisible({ timeout: 10_000 });
✅ 1 resolved
Quality: UI tray assertions not tied to the job under test

📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts:398-412 📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts:432-446 📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts:460-474
Because the suite runs serially against a shared, global csvAsyncJobs list and most export tests never clean up the jobs they queue, the launcher.or(trayPopover) visibility check and the hasText: /Exporting|Exported/i item filter can be satisfied by leftover COMPLETED jobs from earlier tests rather than the job just created (e.g. the db-service and test-case export tests can match a stale user-export row). The tests still pass, but they may not actually exercise the specific job/path they claim to guard. Consider scoping the item locator by the queued jobId (e.g. via a data attribute) or clearing completed jobs in an afterEach so each assertion reflects only the current test's job.

🤖 Prompt for agents
Code Review: Adds a comprehensive CsvJobsTray Playwright E2E test suite with robust data-job-id scoping and timing baselines. Consider tightening the cancel-button test locator to avoid matching the Download button.

1. 💡 Quality: Cancel-button test also matches the Download button
   Files: openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts:469-473, openmetadata-ui/src/main/resources/ui/src/components/common/EntityImport/CsvJobsTray/CsvJobsTray.component.tsx:312-326

   In the new 'cancel button appears for an active export job' test, the assertion only checks that `.csv-jobs-tray-item[data-job-id] .csv-jobs-tray-action` is visible. But `renderJobRowActions` uses the same `.csv-jobs-tray-action` class for both the Cancel button (active jobs) and the Download button (COMPLETED EXPORT jobs). If the user export finishes before the assertion runs, the Download button satisfies the check and the test passes without ever verifying the Cancel action it claims to guard. Filter by the Cancel label so the assertion actually validates the active-state button.

   Fix (Scope the assertion to the Cancel button text so a completed job's Download button cannot satisfy it.):
   await expect(
     page
       .locator(`.csv-jobs-tray-item[data-job-id="${jobId}"] .csv-jobs-tray-action`)
       .filter({ hasText: /Cancel/i })
   ).toBeVisible({ timeout: 10_000 });

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

@github-actions

Copy link
Copy Markdown
Contributor

❌ UI Checkstyle Failed

❌ Playwright - ESLint + Prettier + Organise Imports

One or more Playwright test files have linting or formatting issues.

Affected files
  • openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTrayE2E.spec.ts

🔍 ESLint findings in this PR's files — 0 error(s), 2 warning(s)

Errors block the build. Warnings do not yet — they are rules whose backlog is still
being worked down, listed so this PR does not add to it. See docs/ui-code-quality-gate.md.

0 error(s), 2 warning(s) across 1 changed file(s).

Count Rule
1 sonarjs/cyclomatic-complexity
1 sonarjs/no-nested-conditional
All findings
Location Rule Message
🟡 src/components/common/EntityImport/CsvJobsTray/CsvJobsTray.component.tsx:271:47 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 11 which is greater than 10 authorized.","cost":1,"secondaryLocations":[{"line":271,"column":46,"endLine":271,"endColum
🟡 src/components/common/EntityImport/CsvJobsTray/CsvJobsTray.component.tsx:396:27 sonarjs/no-nested-conditional Extract this nested ternary operation into an independent statement.

Fix locally (fast - only checks files changed in this branch):

make ui-checkstyle-changed

@github-actions

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 66%
66.36% (78840/118805) 50.37% (47647/94591) 51.63% (14368/27827)

@sonarqubecloud

Copy link
Copy Markdown

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 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.

1 participant