diff --git a/docs/index.md b/docs/index.md index 6c0aa0956431..d4857a4883c8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -63,6 +63,7 @@ verdict cites an artifact that was checked to still exist): | `docs/golden-principles.md` | 8 candidate repo-wide invariants (DRAFT for ratification), each with a measured adherence number + reproducing command | Cite/enforce an invariant (acyclic modules, ServiceSpec contract, generated-as-sink, no bare `except:`, …) | 2026-07-24 | CURRENT | | `docs/tech-debt.md` | Prioritized (impact÷size, 3 tiers) ledger of 21 audit findings, each with location, size, and agent-fixability | Pick up a bounded cleanup, or understand a known structural debt before working near it | 2026-07-24 | CURRENT | | `docs/quality.md` | One evidence-cited quality grade (A–C / Not assessed) per Maven module | Gauge a module's structural health / known debt before a large change | 2026-07-24 | CURRENT | +| [Playwright component migration audit](testing/playwright-migration/README.md) | Complete source/queue classification, queue analysis, and migration follow-up | Moving UI assertions from full-stack browser tests into component integration tests | 2026-09-10 | Historical snapshot at `44823acd`; implementation status recorded separately | ## Assets (`docs/assets/`) diff --git a/docs/testing/playwright-migration/MIGRATION.md b/docs/testing/playwright-migration/MIGRATION.md new file mode 100644 index 000000000000..a9bd62bb482d --- /dev/null +++ b/docs/testing/playwright-migration/MIGRATION.md @@ -0,0 +1,109 @@ +# Column-grid migration and remaining candidates + +This implements the first family from the [September 10 audit](README.md). It does **not** remove all 211 candidates. The complete audit remains a historical snapshot at `44823acd`; implementation started from `e006fd96`. The six candidate spec files did not change between those commits. + +| Disposition | Original queue cases | Meaning | +|---|---:|---| +| Migrated in this PR | 22 | Column-grid UI assertions now run in Jest with the real components and controlled HTTP responses | +| Retained column-grid browser contracts | 3 | Authenticated page, browser editor input, and real background update | +| Retained for follow-up | 186 | Permission, general pagination, and nested-entity matrices need their own real component/page replacements | +| **Reviewed first-migration set** | **211** | Every expanded case has a disposition in the ledger | + +The [211-row migration ledger](migration-cases.csv) records the original queue case ID, source definition, title, disposition, replacement test name and follow-up rationale. One replacement may consolidate several overlapping browser cases. **The 19 new Jest cases are not 19 additional end-to-end journeys.** + +## What changed + +[ColumnGrid.integration.test.tsx](../../../openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx) renders the actual `ColumnGrid`, table rows, design-system controls, filters, edit drawer, rich-text editor, hooks, router and query provider. It uses the existing Jest/jsdom/Testing Library stack. No new runner or package dependency is introduced. + +[HttpTestServer.utils.ts](../../../openmetadata-ui/src/main/resources/ui/src/test/unit/HttpTestServer.utils.ts) replaces the Axios transport adapter. The actual REST functions, query encoding and Axios interceptors still run. It rejects unexpected endpoints and reports them after the test even if application error handling catches the rejection. Request recording is bounded. Deferred responses and the existing fake clock control loading and request ordering without wall-clock sleeps. + +The suite undoes the global `ToastUtils` mock and renders the real toast provider for validation and failure feedback. The repository's existing translation/DOM setup remains in use; these tests do not establish translation correctness, layout, hit-testing or native browser editor behavior. The grid, its children, state hooks, request builders and design-system controls are not replaced with mocks. + +The migrated behavior includes: + +- Exact statistics, real rows, empty search results and request/URL query encoding. +- Applying, restoring and clearing metadata/service/entity-type filters. +- Keeping totals while a request is pending and rejecting stale search responses. +- Selection, cancellation, aggregate occurrence counts, multiple independent selections, drawer fields and unsaved-edit discard. +- Exact outgoing update bodies for both occurrences; pending state; failure recovery; rejecting an unchanged submission without scheduling a job. +- Expanding a supplied STRUCT child and opening the correct child's edit form. +- Cursor navigation, rendering a different page, preserving overall totals, going back and resetting the cursor for a new search. + +The retained [Playwright spec](../../../openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts) covers: + +1. The authenticated column page against its real endpoint and application routing. +2. Typing spaces into the real browser editor and closing its drawer. +3. Submitting a real bulk update, receiving its notification and observing both occurrences updated in the server index. + +The page helper opens the feature route directly. Local validation showed the shared sidebar helper still expected the previous sidebar structure; repeatedly exercising that helper is not needed for the column-grid contract. Sidebar navigation deserves its own current component/browser coverage. + +The ESLint suppression baseline drops five positional-locator allowances removed with the retired cases; the two remaining allowances belong to the retained browser spec. + +## Assertion improvements + +The old pagination case guarded its assertions with `if (isNextEnabled)`. The replacement supplies two deterministic pages and requires navigation to change the displayed column, transmit the cursor, preserve totals and reset on search. + +The old nested-child case could skip all child assertions when the child checkbox was absent. The replacement requires the child row and checks the identity in its edit form. + +The old progress case queried `pending-changes-progress-spinner`. `ColumnGrid` passes that attribute to `Loader`, but `Loader` does not forward it and renders `data-testid="loader"`. The replacement checks the actual loader inside the pending-changes card. + +The old multi-occurrence update case accepted any request containing at least two matching-looking names. The replacement checks exactly one update for each of two distinct FQNs, including entity type, display name and absence of unintended fields. A real server-index assertion remains in Playwright. + +## Why the other 186 cases remain + +| Suite | Cases | Required replacement before retirement | +|---|---:|---| +| Entity permissions | 46 | Actual headers, descriptions, tags, management menus and entity-specific tabs with real permission providers; preserve backend enforcement tests | +| Service permissions | 44 | Actual service controls, AutoPilot affordances and child-list guards across service types | +| Data-quality permissions | 25 | Actual test-case/library/bundle/profiler controls and route guards under allowed and denied responses | +| General pagination | 35 | Actual listing consumers, search resets, page-size changes, cursor requests, URL restoration and version views | +| Nested entity updates | 36 | Actual mutation handlers and immediate nested-row updates across eight entity types, including distinct serializers/endpoints | + +A permission utility test does not establish that a page uses its result. A `usePaging` test does not establish that all 35 consumers request and render the correct page. A nested-array utility test does not establish that every entity applies the mutation response. Those gaps are why this PR implements one complete family rather than deleting the whole candidate set. + +## Follow-up discovered during implementation + +An exploratory component test delivered a successful bulk-job notification and supplied a refetched row with the **same ID** but updated values. The refetch ran and pending state cleared, yet the rendered data-type cell retained the previous value in jsdom. This is an investigation lead, not a confirmed browser defect or a regression introduced here. + +Reproduce by rendering `customer_id` with `VARCHAR`, submitting its edit, delivering the active job's completion through `WebSocketContext`, and returning the same column ID with an updated display name and data type from the next grid GET. Assert the refreshed cell and reopened form separately. Inspect the interaction between `ColumnGridTableRow` and the core `Table.Row` collection: the column definitions are stable while the cell renderer closes over changing row data. + +The real job/notification contract remains in Playwright. Establish browser behavior and add an isolated row-refresh regression before migrating that contract or changing collection invalidation. The exploratory same-ID assertion is not included among the 19 passing migration cases and is not used to justify any of the 22 removals. + +## Cost and rollout + +The 22 removed cases consumed **399,283 ms (6.65 cumulative worker-minutes)** in the audited queue run. This is **0.49% of the 4,488 planned product cases**. It is historical test-worker duration, including attempts, not measured queue wall-clock savings. Retained setup, shard tails and replacement execution still cost time. + +Run the pilot through the existing required frontend and browser lanes. Compare actual queue verdict latency, worker time and retry counts before widening the migration. No workflow, branch-rule, retry-budget or shard-allocation changes are included. + +## Validation + +The final targeted Jest run passed **33 tests across four suites** (19 new integration cases plus the existing row, pagination control and paging-hook suites). The **three retained Playwright cases passed in the repository's Chromium project against the workspace Vite UI and the local backend**, including the new assertion that both occurrences reached the server index; their local run took 52.7 seconds with one worker and no retries. Admin authentication was prepared separately without changing server security configuration. The full CI provisioning/sharding workflow was not rerun. + +Three temporary source faults were checked: disabling the stale-response guard, omitting the search query from the HTTP request, and omitting the second occurrence from the update payload. Each made its corresponding integration test fail. All modified production files were restored byte-for-byte before the passing final run. + +Changed-file ESLint/Prettier, license/pre-commit checks, all 114 lint-rule tests and i18n validation pass. Application-doc generation produces no diff, and the generated Playwright rule table is current. The suppression baseline and its exact-count guard both decrease by five. + +Whole-repository TypeScript checks remain red. A compiler-API comparison against the same checkout with the original spec and without the two new test-support files produced **identical diagnostics**: 599 for the UI project and 165 for Playwright, with no additions or removals. This is a baseline limitation, not a claim that type checking passes. The CLI checks were also attempted; their incremental diagnostic counts differed, so the like-for-like compiler comparison is the attribution evidence. + +Validation results and reproduction commands are recorded in the PR description. The new suite's initial coverage run passed **19 cases**. It measured **69.51% line coverage of `ColumnGrid`**, **62.67% of its listing hook**, **83.01% of its filter hook**, **94% of `ColumnGridTableRow`** and **100% of `ColumnGridRow`**. These are the pilot's coverage numbers, not whole-application coverage or proof that all grid behavior migrated. No production implementation changes are included, so a changed-production-class coverage target does not apply. + +Before expanding the migration, preserve the case-level mapping, demonstrate failure for an intended regression, run the retained browser contracts, and measure the resulting gate rather than extrapolating queue speed from test counts. + +Run the frontend tests from `openmetadata-ui/src/main/resources/ui`: + +```sh +yarn test --runInBand --runTestsByPath \ + src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx \ + src/pages/ColumnBulkOperations/ColumnGrid/components/ColumnGridTableRow.test.tsx \ + src/components/common/NextPrevious/NextPrevious.test.tsx \ + src/hooks/paging/usePaging.integration.test.tsx +``` + +For the isolated browser run, use a prepared local stack and `playwright/.auth/admin.json` containing authentication state, including IndexedDB, for the same UI origin. The spec creates and deletes its own edit fixtures. This command skips shared authentication/entity setup: + +```sh +PLAYWRIGHT_TEST_BASE_URL=http://localhost:3001 PW_PRESEEDED_STATE=true \ + PLAYWRIGHT_IS_OSS=true yarn playwright:run \ + playwright/e2e/Features/ColumnBulkOperations.spec.ts \ + --project=chromium --workers=1 --no-deps +``` diff --git a/docs/testing/playwright-migration/QUEUE-ANALYSIS.md b/docs/testing/playwright-migration/QUEUE-ANALYSIS.md new file mode 100644 index 000000000000..ed4cd5dd864e --- /dev/null +++ b/docs/testing/playwright-migration/QUEUE-ANALYSIS.md @@ -0,0 +1,509 @@ +# OpenMetadata Playwright and merge queue audit + +Audited on **9 September 2026**, at repository commit **`44823acde1c85ccc20d9f62c588169567fc28c90`**. This is an assessment with reproducible evidence and proposed changes. Application code, tests, workflows, branch rules, and external issues were not changed. + +## 1. Decision + +**Keep Playwright for browser integration tests. Change the test portfolio and the merge gate.** The evidence does not justify a migration to another browser framework. It does justify reducing repeated full-application work, repairing unreliable tests, making setup reuse effective, and separating trustworthy test verdicts from report production. + +The current suite protects substantial real behavior: discovery, metadata editing, lineage interactions, governance, role-dependent UI, ingestion administration, and data quality. It also runs many entity/role/validation combinations through the complete application. Those combinations are candidates for API and component tests, with representative browser journeys retained. A large browser suite is not inherently wrong; its cost and residual failure rate are incompatible with the present queue arrangement. + +The strongest findings are: + +1. **Queue damage is measurable.** The repository's daily report showed a median total queue wait of **18.6 hours**, a **41% first-pass rate**, and `playwright-summary` associated with **18 dequeued commits**. A separate history query found **598 failed Playwright workflows among 1,331 completed merge-group runs**, or **44.9%**, in the observed September 2–9 window. That is a workflow failure rate, not a test flake rate or a count of unique blocked PRs. +2. **Recent fixes have helped, but current test failures remain.** In the latest 30 completed runs sampled, 25 gates passed and 5 failed. Each failure had a reported test failure; none was an infrastructure-only gate failure. Every run also had at least one test that failed an attempt and passed on retry: **210 retry-rescued cases in total**. +3. **Provisioning is a large, repeated serial cost.** All 30 runs executed seeded-environment preparation. That job took a median **17.05 minutes**, before the shard matrix could run. Median queue-run creation to required Playwright verdict was **61.14 minutes**. +4. **There are reproducible process defects.** Boolean workflow inputs cannot be set to false; the budget-alert expression interprets false as true; its issue lookup also has invalid CLI arguments. A documentation-only change selects the full suite, while a shared lineage helper change omits an actual consumer. The committed generated impact map is stale. +5. **A green run has fidelity limits.** Shared setup disables the application's ETag conditional reads. The default CI bundle also differs from the ordinary build. These are deliberate optimizations/workarounds that need a small test lane exercising normal application behavior. + +The first intervention should be targeted reliability and orchestration work. Broadly disabling retries, extending every timeout, adding workers, or moving everything to nightly would leave important problems unresolved. + +## 2. What was validated + +This audit combines four kinds of evidence: + +| Evidence | Scope | What it establishes | +|---|---|---| +| Repository inspection | Main configuration, fixtures, selectors, planner, reporters, workflows, representative specs, lower-level test configuration | Intended execution paths and concrete implementation behavior | +| Live GitHub configuration | Effective rules for `main`, including merge queue and required checks | What actually gates merging, independently of comments and documentation | +| Hosted execution evidence | 1,336 queue workflow records; detailed jobs and artifacts for 30 recent completed runs; three historical incident runs | Observed latency, results, retries, provisioning, and execution accounting | +| Local behavioral checks | 154 Python CI-tooling tests; selector probes; impact-map regeneration; shell-expression reproductions | Several current defects reproduced without changing application code | + +The 30-run sample is the latest completed sample at collection time, with start times **2026-09-09 11:04:49–13:08:41 UTC**. It is a short, overlapping operational sample, not 30 independent randomly selected commits. The wider history covers run start times **2026-09-02 00:35:56 through 2026-09-09 14:09:16 UTC**. Five runs were still in progress at that snapshot. Recent workflow changes mean the whole-window rate must not be presented as the unchanged current rate. + +The full browser suite was **not rerun locally**. UI dependencies and the full service stack were not installed for this audit. Actual hosted results were inspected instead. A static inventory of all specs is not a line-by-line proof that every assertion is correct, and this report does not claim that. + +Evidence is preserved in analysis.json (original local evidence: `analysis.json`), the complete queue history (original local evidence: `queue-runs-complete.json`), [recent run measurements](evidence/recent-queue-runs.csv), [per-spec cost measurements](evidence/representative-spec-costs.csv), and the `runs/` directory. Source links below refer to the audited commit where possible. + +## 3. How Playwright is currently used + +### 3.1 The principal test system + +The application pins `@playwright/test` **1.57.0**. The main configuration uses desktop Chromium, enables parallel execution, normally gives CI three workers per common shard, and retries a failed test once. Defaults are a 60-second test timeout and a 15-second assertion timeout. Dedicated projects reduce concurrency or isolate tests that mutate global settings or perform expensive stateful operations. Traces are normally captured on the first retry and screenshots on failure. The nearby comment promises more than the default configuration actually records; video is not enabled there. [Configuration][config] + +This is substantial integration testing: the browser talks to a real OpenMetadata server, backed by PostgreSQL and OpenSearch in the principal queue lane. CI builds the application, prepares a seeded environment, restores/clones that environment into multiple runner jobs, and executes the selected projects. API helpers create much of the prerequisite data. Separate server instances isolate shards, while tests within a shard still need their own entity and user state. [Reusable workflow][reusable] + +There are **394 `.spec.ts` files** in the inventoried Playwright tree: 251 under Features, 87 Pages, 34 Flow, 7 Auth, 6 VersionPages, 3 VisualRegression, 3 nightly, 2 Search, and 1 Http2. These are source file counts. They are neither the count of executed tests nor a measure of business coverage. + +A representative current green run, [34355232120][representative], reported **4,490 results**: 4,485 passed, 4 passed after retry, and 1 was skipped. Its coverage verifier accounted for **4,488 distinct planned product test IDs**. Some cases are API-only tests run by the Playwright runner. The run used **37 shard jobs**. The timing history breaks the distinct product cases down as follows: + +| Project | Cases in this run | Main responsibility | +|---|---:|---| +| chromium | 3,579 | Most feature, page, entity, role, and workflow tests | +| Basic | 345 | Basic-project specs; this is larger than the six-spec PR smoke selection | +| ImportExport | 150 | Import/export behavior, with constrained concurrency | +| AdvancedSearch | 130 | Search query construction and application behavior | +| Ingestion | 86 | UI administration and ingestion-related workflows | +| DataAssetRulesDisabled | 34 | Behavior with global data asset rules disabled | +| DataAssetRulesEnabled | 31 | Behavior with rules enabled | +| SearchRBAC | 29 | Search visibility under access controls | +| Reindex | 28 | Reindex-related behavior | +| IntakeForm | 20 | Intake-form behavior | +| DomainIsolation | 16 | Domain-scoped isolation | +| Data Insight | 14 | Data insight behavior | +| search-nightly | 12 | Search tests that are also included in this full run | +| GlobalSettings | 11 | Global-setting behavior | +| SystemCertificationTags | 3 | System certification settings and tags | + +There is a small accounting inconsistency: two invocations of the `data-insight-application` setup test appear in the reporter's product totals. The coverage verifier correctly excludes that lifecycle project, leaving 4,488 planned IDs and 4,488 accounted IDs. Eight other lifecycle entries are reported separately. These counts should remain explicitly named rather than conflated into a single “coverage” number; the product/lifecycle classification should also be made consistent across reporters. + +### 3.2 PR selection and queue selection + +On pull requests, the selector combines six Basic smoke specs, directly changed specs, a manually maintained impact map, and a generated impact map. Shared infrastructure changes add canaries. Unmapped paths under recognized code roots fall back to the full suite. Merge-group events select the full suite. [Selector][selector], [manual impact map][impact-map] + +The six smoke specs cover Login, Navbar, Dashboards, LineageControls, DataMarketplace, and Policies. They are files containing multiple cases, not six individual tests. The shared-infrastructure canary is also substantial: it includes the 353-case Entity spec and dedicated project coverage. + +The dispatcher handles both regular PR and fork-PR event paths, along with label-based eligibility. Some workflow records are intentionally skipped/no-op successes. Mixing all event types into one pass-rate calculation would therefore produce a misleading result. This audit's history analysis filters to `merge_group`. [Dispatcher][dispatcher] + +### 3.3 Other coverage exists, but “full Playwright” does not mean all of it + +| Test system | Observed execution arrangement | Required by the current main rules? | +|---|---|---| +| Main PostgreSQL Playwright suite | PR selection; full merge-group matrix | **Yes**, through `playwright-summary` | +| App Jest tests | 1,419 app `.test` files in the inventory; `ui-coverage` workflow | **Yes**, job-result check; separate Sonar verdict is not required | +| Core component tests | 10 test/spec files; Vitest configuration and Storybook tooling | No separate required core-test check found | +| Java API/integration tests | 347 `*IT.java` files, including 34 `*UIIT.java` files | Main database/search integration checks are required | +| Java Playwright UIITs | PR/merge-group workflow with internal path selection; workflow filename still says nightly | `java-ui-it` is **not** currently required | +| RDF / knowledge graph Playwright | Separate workflow and summary | `playwright-rdf-summary` is **not** required | +| Visual regression | Three spec files; pinned Playwright container for rendering parity; UI-path PR trigger | No required visual check | +| External-provider SSO | Scheduled SSO login workflow | No required SSO check | +| Mock OIDC Playwright config | Separate Chromium/WebKit config exists | No in-repository workflow reference to that config found | +| MySQL/PostgreSQL “nightly” E2E workflows | `workflow_dispatch` in the inspected files | Not evidence of a functioning daily schedule | +| Search “nightly” workflow | Manual trigger, with its project also present in the full main suite | Covered in part by the main suite | + +The main suite is not a browser compatibility matrix. There is no broad Firefox, WebKit, or mobile matrix in this gate. Existing isolated WebKit/SSO configuration should not be mistaken for general Safari coverage. I did not find an integrated axe-based accessibility pass in the inspected main Playwright setup. Some locale-specific regressions exist; locale coverage is not completely absent. + +The visual workflow's PR paths include `openmetadata-ui/**` but omit `openmetadata-ui-core-components/**`. A component-library-only edit can therefore miss this visual trigger. Its pinned rendering container is a good practice to retain. [Visual workflow][visual] + +`ui-coverage` passes on successful or legitimately skipped test jobs. The separate Sonar gate reports its own result. The current rules require the former, not `ui-sonar-gate`; there is no local Jest `coverageThreshold`. Thus a documented 90% new-code target should not be described as an enforced merge requirement without correcting that configuration. A percentage would still not establish that the right behaviors are asserted. [Coverage workflow][yarn-coverage], effective rules (original local evidence: `effective-main-rules.json`) + +## 4. What is happening to the merge queue + +### 4.1 The actual queue contract + +The active [main ruleset][ruleset] allows **five concurrent merge-group builds**, merges between **one and three entries**, requires `ALLGREEN`, and waits up to **240 minutes** for checks. The configured 30-minute minimum-batch wait is not a compulsory extra 30 minutes for every PR: the minimum batch size is one. + +Required checks are `java-checkstyle`, `py-checkstyle`, `integration-tests-mysql-elasticsearch`, `integration-tests-postgres-opensearch`, `py-tests-status`, `playwright-summary`, `ui-checkstyle`, and `ui-coverage`. + +GitHub builds temporary commits incorporating queued changes. A failed required check can remove an entry and force affected downstream groups to be rebuilt. Merge limits and build concurrency are different controls; increasing the merge batch limit does not simply combine all those test builds into one. [GitHub merge queue documentation](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) + +At the observed 33–38 Playwright shards per full run, five simultaneous queue groups can offer **165–190 shard jobs**, before PR runs and other workflows. This is potential demand, not measured runner saturation. Runner limits, CPU utilization, and billed cost were not available in this audit. + +### 4.2 Measured queue health + +The repository's [September 9 daily report][daily-run], emitted at 07:31 UTC for the preceding 24 hours, reported: + +| Metric | Reported value | +|---|---:| +| Queue depth | 45 | +| Projected drain time at recent throughput | 37 hours | +| Throughput | 1.21 merges/hour | +| Median total wait | 18.6 hours | +| Reported “first-pass” median latency | 7.5 hours | +| First-pass rate | 41% | +| Merged via queue / inferred bypasses | 29 / 7 | +| Wasted passes | 32 | +| Non-merge removals | 24: 18 failed checks, 4 manual, 2 conflicts | +| `playwright-summary` occurrences among failed checks on dequeued commits | 18 | + +This establishes that Playwright was a major associated blocker. It does not establish that every one of those removals was caused solely by a flaky browser test. Checks can fail together. + +The wider merge-group workflow query produced: + +| Run start date, UTC | Success | Failure | Cancelled | In progress at snapshot | +|---|---:|---:|---:|---:| +| September 2 | 88 | 83 | 0 | 0 | +| September 3 | 82 | 140 | 1 | 0 | +| September 4 | 114 | 114 | 0 | 0 | +| September 5 | 82 | 74 | 0 | 0 | +| September 6 | 10 | 6 | 0 | 0 | +| September 7 | 126 | 49 | 1 | 0 | +| September 8 | 109 | 98 | 0 | 0 | +| September 9, partial | 120 | 34 | 0 | 5 | +| **Total** | **731** | **598** | **2** | **5** | + +Among 1,331 completed workflows, **44.9% failed**. Workflow creation-to-update duration had a median of 56.92 minutes and p95 of 71.90 minutes. That duration can include post-verdict timing-baseline work; the recent sample below uses the required summary job's completion time instead. + +Only three records had `run_attempt=2`. That does not imply little retrying: a newly synthesized queue commit creates a different workflow run, and Playwright's internal test retry does not increment GitHub's workflow attempt counter. + +### 4.3 The recent sample separates current problems from old incidents + +| Measure | Recent 30 completed runs | +|---|---:| +| Required Playwright verdicts | 25 success, 5 failure | +| Infrastructure-only failed verdicts | 0 | +| Runs with at least one retry-rescued test | 30 / 30 | +| Retry-rescued test cases | 210; median 7/run | +| Required gate latency | Median 61.14 min; p95 71.60 min | +| Seed preparation executed | 30 / 30 | +| Preparation job | Median 17.05 min; p95 21.86 min | +| Build job | Median 6.26 min | +| Summary job | Median 2.44 min | +| Shard count | Median 36; range 33–38 | +| Sum of job execution time | Median 699.97 runner-min/run, about 11.7 runner-hours | +| Total job execution time across sample | About 349.7 runner-hours | + +Runner time is the sum of job start-to-completion durations. It is not wall time, dollar cost, or automatically wasted compute. Parallel Playwright worker durations are another measure again and should not be added to runner hours. + +The representative run's critical path makes the serial costs visible: + +```mermaid +flowchart LR + A["Queue run created
13:08:41"] --> B["Build
13:11:21–13:18:12"] + B --> C["Plan and restore lookup
13:18:15–13:20:32"] + C --> D["Prepare seeded environment
13:20:35–13:40:59"] + D --> E["37 shard jobs
last finishes 14:06:27"] + E --> F["Required summary
14:06:30–14:08:55"] + F --> G["Timing refresh finishes
14:09:16"] +``` + +The measured HTML/report-upload phase was 17 seconds in that run, but the entire summary job took 2.42 minutes. Similarly, the shard environment metric excludes the separate 20.4-minute preparation job. Current budget names and phase metrics can look healthy while the complete gate still takes an hour. + +### 4.4 Confirmed historical incidents, with current status + +**Report infrastructure made a fully executed green matrix red.** In [run 34312746335][report-incident], all 37 shard jobs passed, and timing coverage accounted for all 4,483 planned tests. The summary could not download native JSON results; it reported zero test failures and 75 infrastructure issues, and failed the required gate. The audited HEAD already includes the relaxation from PR #33010 / commit `dfa612d9dd`: merge-group verdicts now require a successful shard matrix and no reported failed tests, while allowing reporting infrastructure problems. This should not be presented as an unfixed current bug. + +**Earlier shard terminations lost real execution coverage.** In September 4 runs [33862281607][timeout-incident-1] and [33869395948][timeout-incident-2], 584 of 4,464 planned IDs were missing from reported execution, about 13.1%. Three common shards failed. The current workflow has a 60-minute hang wrapper and 75-minute job timeout, with performance budgets advisory. Those timeout changes mitigate the earlier cutoff, but do not repair test or setup cost. Missing IDs must not be described as successful tests. + +**One recent green run correctly tolerated a report dependency failure.** Run [34350084849][report-advisory] recorded a summary dependency-installation issue but passed with a green matrix. That is the intended effect of the reporting-policy change. + +## 5. Current failures and why retries are not a strategy + +The five failed runs in the recent sample reduce to three test variants: + +| Variant | Observed final failures | Evidence and next investigation | +|---|---:|---| +| TestSuitePipelineRedeploy: redeploy all test-suite pipelines | 1 | [Run 34354609470][redeploy-failure] expected deployment statuses `[200, 200]`, received `[400, 200]`. Investigate the specific pipeline and response body. The test creates two pipelines but selects the first two rows in a global listing, not those pipeline IDs. | +| GlobalPageSize: page size persists across pages | 2 | [Run 34350081016][page-size-failure] and [34343844656][page-size-failure-2] exhausted the 60-second test limit. Inspected first-attempt evidence also contains a predicate-wait timeout. Separate slow navigation, state readiness, and incorrect expectations before adjusting a budget. | +| DomainDataProductsWidgets: domain asset count after removal | 2 | [Run 34349824126][widget-failure] and [34349258398][widget-failure-2] exhausted the test limit. Inspected first-attempt evidence includes an expected containment value being null. Review indexing/readiness, server state, and the serial suite's prior mutations. | + +These are failed test assertions or timeouts after retries, not proven product defects and not automatically proven flakes. The redeploy 400 may represent a real application/environment failure. The global-row selection is independently visible test fragility regardless of that response's root cause. [Redeploy test][redeploy-spec] + +The most repetitive unstable variant was **“Create and resolve description task for Pipeline via UI”**: it failed an attempt and passed on retry in **21 of 30 runs**, or 70% of this sample. A sampled attempt timed out at roughly 60 seconds and the retry passed in roughly 31 seconds. The shared task helper opens the first task card, creating another reason to bind selection to the task created by the test. That is an investigation lead, not proof of this timeout's cause. [Task flow][tasks-spec], [failure frequency data](evidence/repeated-test-failures.csv) + +The domain widget suite also has serial dependencies, repeated home-page initialization, and some loader waits whose errors are discarded. A serial journey should either be one coherent test or establish each test's own prerequisites. Broadly swallowing readiness failures delays a useful error until a later timeout. [Widget test][widget-spec] + +Playwright starts a fresh worker after a failure; `beforeAll` can run again, and serial groups have group-level retry behavior. Fresh browser state does not undo application database changes. Unique entities, specific selectors, and cleanup remain necessary. [Playwright retry documentation](https://playwright.dev/docs/test-retries) + +Recommended handling: + +- Keep the current retry allowance during stabilization. Under the observed first-attempt outcomes, every run in this sample would have encountered a failure without retry recovery. This does not predict the exact behavior of a differently scheduled zero-retry run. +- Preserve first-attempt error, response, and trace evidence for identified unstable variants. The default first-retry trace can show a passing retry while missing the original failure. +- Assign a repair owner to each stable test ID and distinguish product regression, test state collision, selector/readiness failure, service failure, and reporting failure. +- Quarantine narrowly, with a linked issue, owner, expiry, replacement protection for critical behavior, and a regularly executed recovery lane. +- Record both final gate success and first-attempt stability. A retry-rescued test remains useful, but its green final result is not evidence of reliability. + +The repository already supports `@quarantine` and a `PLAYWRIGHT_RUN_QUARANTINED` opt-in. I found no workflow setting that variable to run the recovery lane. A quarantine facility without an exercised return path can silently reduce coverage. [Quarantine configuration][config] + +The current 0.5% flaky-case budget can permit about 22 retry-rescued cases in a 4,490-case run. All recent runs can stay below that threshold while the queue is still unreliable. Gate reliability needs its own target. As an illustrative independent-failure model, `P(all pass) = (1 - q)^4490`; achieving 99% suite success would require residual per-case failure probability near 2.24 parts per million. Real service failures are correlated, so this is an explanation of aggregation sensitivity, not an estimate of actual failure probability. + +## 6. Test portfolio: retain the behavior, change where combinations run + +Playwright is a strong fit for actual browser behavior: DOM interaction, browser navigation, downloads, canvas operations, focus, and application-to-server integration. Its own guidance emphasizes observable behavior, isolated state, and retrying assertions. Switching browser frameworks would not remove OpenMetadata's setup time, shared backend state, or the number of combinations currently placed in browser tests. [Playwright best practices](https://playwright.dev/docs/best-practices) + +The goal should be **a small set of explicit browser contracts, backed by broad cheaper coverage**, with full regression retained during migration. Browser and API assertions complement each other: UI visibility does not prove server authorization; an HTTP 200 does not prove that the user saw the correct result. + +| Behavior | Browser coverage to retain | Broader combinations to test elsewhere | +|---|---|---| +| Login, logout, route protection | Normal login, protected navigation, expiry/refresh, representative SSO callback, role switching | Token validation and authorization policy in backend tests; callback parsing and error states in component tests | +| Entity metadata editing | Search/open entity, edit description/owner/tag, save, reload and verify persistence | Entity type × field × permission combinations through API integration tests and component tests | +| Steward/consumer/admin behavior | Representative visible controls and an attempted prohibited action | Complete permission enforcement matrix through API tests; role-dependent component affordances with real components | +| Lineage | Drag/connect, pan/zoom, expand/collapse, modal interactions, persistence across reload | Graph transformation/layout helpers and edge validation with focused tests; server lineage traversal and authorization through API ITs | +| Advanced search | Compose representative filters, submit, navigate result, confirm visible semantics | Operator/type/null/escaping truth tables in parser, component, and search-engine integration tests | +| Custom properties | Each materially different editor interaction, save/error/reload behavior | Property type/entity/validation combinations in component and schema/API tests | +| Data contracts and semantic rules | Create/edit contract through the form, execute, show pass/fail/error state | Semantic rule truth tables, missing fields, bounds, and type errors below the browser layer | +| Widgets and page size | Placement, user preference persistence, cross-page integration, useful empty/error states | Widget state combinations and rendering using Jest/Vitest/Testing Library; counts and propagation through backend integration tests | +| Import/export | Browser upload/download, progress and error feedback, a successful round trip | File parsing, encoding, malformed rows, limits, and large datasets through direct API/processing tests | +| Ingestion and connectors | Configure one representative service, deploy, display status, inspect logs | Connector pagination/schema/types/error handling in Python tests; source-specific integration tests; deployment API checks | +| Reindex and search availability | Start operation and show completion/error feedback | Long-running lifecycle, consistency and engine-specific guarantees through Java integration tests | +| Visual quality and accessibility | Stable visual snapshots, keyboard/focus journeys, accessibility checks on representative screens | Component stories and state variations, with explicit supported-browser coverage | + +This does not require converting all API checks to Java. Playwright's `APIRequestContext` supports direct API testing without launching a browser, and is useful for setup and postconditions. An API-only project can be separated from browser provisioning. [Playwright API testing](https://playwright.dev/docs/api-testing) + +The repository already has a substantial Jest suite and an emerging Vitest/core-component suite. Extend those tools and existing component stories. Tests should exercise rendered behavior using real core components, with external boundaries mocked where appropriate; replacing the entire component tree with mocks only proves wiring. [Testing Library principles](https://testing-library.com/docs/guiding-principles/) + +### 6.1 Where to start, using measured cost + +The eight most expensive files in the representative run account for **520.3 test-worker minutes**, **38.4%** of the reporter's product-worker time, and **1,411 logical cases**: + +| Spec | Cases | Worker minutes, including observed test lifecycle work | +|---|---:|---:| +| Pages/Entity.spec.ts | 353 | 131.7 | +| Pages/Lineage/DataAssetLineage.spec.ts | 85 | 98.8 | +| Pages/ExplorePageRightPanel.spec.ts | 234 | 53.3 | +| Pages/CustomProperties.spec.ts | 173 | 50.1 | +| Pages/EntityDataSteward.spec.ts | 158 | 49.3 | +| Pages/EntityDataConsumer.spec.ts | 143 | 46.6 | +| Features/AdvancedSearch.spec.ts | 130 | 45.5 | +| Pages/ServiceEntity.spec.ts | 135 | 45.2 | + +This is a prioritization list, not a claim that 38.4% of work can be deleted. In particular, lineage interactions can justify real browser cost. Review each file's matrix dimensions: retain every distinct browser interaction and move repetitive backend or validation combinations only after equivalent lower-layer assertions exist. + +Additional useful candidates are DataContractsSemanticRules, with 41 cases and 21.0 worker-minutes, and BulkImport, with only 6 cases but 24.9 worker-minutes. Test count alone is a poor optimization target. Conversely, an API-only Tasks case took 61 milliseconds in the timing data: merely finding API calls inside a Playwright file does not establish that it is a major cost problem. + +Static pattern counts provide review leads, not a quality score. The inventory found `test.slow()` in 171 files, custom test timeouts in 50, serial declarations in 58, literal hard waits in 10, and request routing in 38. Hard sleeps are therefore not a sufficient explanation for the observed queue problem. Some timeout extensions, serialization, and route fixtures are legitimate. Review their purpose and observed cost. Static inventory (original local evidence: `static-inventory.json`) + +## 7. Coverage fidelity and blind spots + +### 7.1 Shared setup disables a normal application cache path + +`disableEtagConditionalReads()` writes `OM_DISABLE_ETAG_CONDITIONAL_READS=true`. Role-page fixtures, home navigation, and persisted authentication setup install the opt-out. The production interceptor explicitly explains that entity version/updatedAt does not cover every relationship/child mutation. [Shared helper][common], [role fixtures][pages-fixture], [production ETag interceptor][etag] + +This creates an important limit: the main suite predominantly verifies fresh unconditional reads, while normal users exercise conditional reads. The production client already invalidates its local cache on non-GET responses, so this finding is **not** proof that every ordinary edit is broken. Cross-session changes, background updates, and relationship-dependent representations still need an integration contract under normal caching. + +Add a small production-behavior lane that explicitly leaves the opt-out unset. For example: session A reads an entity; session B changes a relationship or child state; session A refetches the relevant fields and must display the new state. Add a backend assertion that the ETag/representation contract is correct for that change. Keep this protection until the underlying semantics permit removing the workaround. + +### 7.2 Other optimizations need explicit boundaries + +The shared server-load helper caches selected bootstrap responses in a bounded, identity-aware worker cache and stubs analytics by default. It deliberately excludes important dynamic endpoints such as permissions and the logged-in user. That is thoughtful existing work, and should be retained where it does not mask the contract under test. Tests specifically about analytics can opt in to collection. [Server-load helper][server-load] + +CI also defaults to an alternate coarse bundle, and raises the server's active-session limit to 10,000. These choices help the workload run but do not test ordinary bundle behavior or normal session-limit enforcement. Include a small default-build/auth/cache lane rather than multiplying the entire 4,490-case suite across every configuration. + +Browser contexts remain useful isolation. Sharing all contexts or one mutable server entity across tests to save startup time would trade away reproducibility. Reduce unnecessary app boots within a scenario, use browser-free API setup where possible, and give server-side mutable resources explicit ownership. + +### 7.3 Execution accounting is not requirement coverage + +`verify_playwright_coverage.py` reconciles planned IDs with timing/results and detects missing or duplicate execution. That is valuable infrastructure protection. It does not determine whether the selector chose the right tests, whether quarantined requirements remain protected, or whether a passing assertion checks the right result. [Coverage verifier][coverage-verifier] + +A useful coverage ledger should track: requirement/risk, owner, browser contract, API/component/connector coverage, entity/role/engine dimensions, excluded variants, and the evidence required to retire or relocate a test. For high-risk behavior, validate a representative deliberate defect: the wrong permission result, stale count, omitted persistence, or incorrect search operator should cause the intended test to fail. Use focused mutation or negative-case checks, not another test that mirrors internal method calls. + +## 8. Reproduced process defects + +### 8.1 Budget alerts silently treat a breach as success + +The workflow computes: + +```sh +met=$(jq -r '.budgetTargetsMet // true' "$performance") +``` + +In jq, `//` substitutes its right side for both null and false. The local reproduction `jq -n '{budgetTargetsMet:false} | .budgetTargetsMet // true'` prints `true`. Consequently this step exits with “All Playwright budget targets met” when the boolean is explicitly false. One of the recent sampled runs has a false shard-duration budget, so the false state is not merely hypothetical input. [Budget signal, line 366][budget-signal] + +Use an explicit missing/null check that preserves false, and test true, false, absent, and malformed payloads. Keep performance reporting advisory to merge correctness, but make alert delivery observable and tested. + +There is a second defect on the alert path: `gh issue list ... --jq --arg t ...` treats jq's `--arg` as arguments to `gh`. The equivalent read-only command fails argument parsing. Pipe JSON to a separate `jq --arg ...` invocation or use a valid `gh --jq` expression. Otherwise fixing the boolean alone still leaves issue publication broken. No issue was created or commented on during this audit. + +### 8.2 Manual experiment switches cannot be turned off + +The dispatcher passes both `full_suite` and `coarse_bundle` using the pattern: + +```yaml +full_suite: ${{ github.event_name == 'workflow_dispatch' && inputs.full_suite || true }} +``` + +An explicitly false input reaches `|| true`, producing true. The same bug affects `coarse_bundle`. This makes the declared A/B controls misleading and prevents an actual false dispatch from reaching the reusable workflow. Use boolean logic that preserves an explicit false while applying the intended default only for other event types. Cover all event/input combinations. [Dispatcher, line 108][dispatch-flags], [GitHub expression semantics](https://docs.github.com/en/actions/reference/workflows-and-actions/expressions) + +### 8.3 Selection has both over-selection and missed dependencies + +The selector was executed locally on real individual paths: + +| Changed path | Actual selection | Assessment | +|---|---|---| +| `playwright/utils/lineage.ts` | 22 targeted spec files | Omits `Pages/Lineage/DataAssetLineage.spec.ts`, an actual helper consumer | +| `playwright/utils/common.ts` | Same 22-file canary selection | Shared-helper change does not select all consumers | +| `playwright/PLAYWRIGHT_DEVELOPER_HANDBOOK.md` | Full | Documentation is treated as unmapped code because path classification is too broad | +| `src/rest/etagInterceptor.ts` | Full | Sensible conservative behavior for a shared production path | +| `src/components/common/Table/Table.tsx` | Full | Conservative fallback for broad UI impact | +| Snowflake ingestion `metadata.py` | 23 targeted browser specs | Exercises some UI/ingestion administration; does not establish source-specific extraction correctness | + +These are selector outputs, not estimates. Probe results (original local evidence: `selection-probes/summary.json`) + +The generated map uses bounded import/test-ID heuristics, not a sound graph of all production and helper dependencies. Unmapped-code fallback is valuable, but it cannot detect incomplete mappings for a path that already has at least one edge. + +Locally, **153 CI-tooling tests passed and one failed**: `test_committed_generated_impact_map_matches_the_generator_output`. The generator reports the committed map is out of date by four added lines. Regeneration to an ignored output file confirmed drift without modifying the committed file. Test output (original local evidence: `pytest-results.log`), regenerated map (original local evidence: `impact-map.regenerated.json`) + +Improve selection in this order: + +1. Add reliable reverse dependencies for test helpers and fixtures; a changed helper must select its consumers or fall back conservatively. +2. Distinguish documentation from executable/configuration changes using explicit rules, while retaining broad fallback for unknown production code. +3. Generate and validate the impact data deterministically. Consider computing it for the current tree at runtime instead of requiring bot commits to keep a derived file synchronized. +4. Shadow-test selection against full runs on the same commits across UI, backend, schema, helper, rename, deletion, and documentation changes. Measure missed failures before relying on a smaller queue gate. + +The automatic drift workflow does not replace that validation: it has restricted event/path behavior and cannot prove that a partially populated map is correct. I did not find an in-repository workflow invoking this Python CI-planning test collection as a test suite; occurrences in path filters do not execute tests. + +### 8.4 Budget and documentation names have drifted from behavior + +Current code uses a 19-minute common planning budget, at most 28 common shards, a 60-minute hang wrapper, and a 75-minute job limit. The Playwright README still describes 21 minutes, 24 common shards, a 25-minute wrapper, and a 35-minute job clock. It also describes coarse bundling as opt-in despite the current default. [Planner][planner], [reusable workflow][reusable], [README][ci-readme] + +The metric named `environmentAtMostFiveMinutes` currently allows 480 seconds during a documented transition. Actual end-to-end setup additionally includes the separate seed-preparation job. Names should expose what is measured and the real threshold. Otherwise optimization discussions compare different clocks. [Performance evaluation][performance] + +## 9. Provisioning, packing, reporting, and queue mechanics + +### 9.1 Make compatible asset reuse effective + +The golden-fixture mechanism and duration-aware planner are worthwhile foundations. The fixture fingerprint currently spans about 2,880 tracked inputs, including schemas, server code, migrations, ingestion code, and transitive UI seed dependencies. Broad invalidation can be correct, but its hit rate must be measured by asset and by compatibility reason. [Fingerprint implementation][fingerprint] + +All 30 sampled runs executed seeded-environment preparation. This proves complete reuse was unavailable; preparation can be triggered by either the database fixture or the ingestion image being absent. The inspected representative restore log explicitly missed both assets. It would be incorrect to infer 30 database-cache misses solely from the preparation-job count. Restore log (original local evidence: `fixture-restore.log`) + +The warmer runs on main pushes and a six-hour schedule. In a separate recent 15-run snapshot, eight warmer workflows were cancelled, six succeeded, and one was still running. This is consistent with cancellation pressure, but does not prove that every useful cache asset was lost. A main-only warmer also cannot prewarm a novel compatibility key introduced by an unmerged queue candidate. [Warmer workflow][warmer], warmer history (original local evidence: `cache-warmer-runs.json`) + +Recommended changes: + +- Record hit/miss separately for DB seed, ingestion image, UI bundle, and dependencies, including the input category that invalidated each key. +- Reuse immutable assets only when their compatibility fingerprints match. Preserve isolation and validate cold versus warm behavior, including migrations and data reset. +- Coalesce production of the same asset by fingerprint. Avoid cancelling useful work simply because another main push arrived; equally avoid building the same missing asset independently for every queue group. +- Give queue jobs safe read access to compatible completed assets across intended workflow scopes. Do not assume a PR artifact is compatible with a synthesized merge commit without verifying inputs. +- Let non-ingestion test lanes start without waiting for an ingestion image when their declared dependencies permit it. +- Review whether build, test discovery/planning, and reusable asset preparation can overlap. The current plan waits for the build before restore/preparation can progress. + +Expected savings should be measured in a warm/cold comparison; the 17-minute median preparation job is an opportunity bound, not a promised 17-minute reduction for every change. + +### 9.2 Optimize total work and tail latency together + +The planner uses recent successful full-run timing history and isolated lanes for stateful suites. This is preferable to blind equal-file sharding. Keep the duration and execution accounting, but investigate large atomic suites and imbalanced lanes. [Planner][planner] + +In the representative run, the reporter observed **981,104 requests**, including **324,756 API requests**, and **10,919 app boots** for 4,733 recorded UI scenarios, or **2.31 boots per scenario**. Reported static response bytes total roughly 65.6 GB; that is a reporter measure, not billed transfer. These counts support reducing repeated app initialization and unnecessary navigation within scenarios. + +Three browser workers share a runner with server/search processes. CPU, memory, search indexing, and connection pressure are plausible contributors to timeouts, but this audit did not measure resource saturation. Compare one/two/three workers with the same test set, runner class, bundle, and seed state. Optimize p95 completion and stable verdicts, not the greatest worker count. + +Experiment with queue build concurrency only after instrumenting demand. Five concurrent groups may reduce throughput if they contend with each other and active PR jobs; reducing it may also reduce useful parallelism. Compare two/three/five with reserved capacity, and measure merges/hour, p95 wait, obsolete work, and runner-hours per successful merge. Cancel demonstrably obsolete group builds, while preserving other valid queue groups. + +### 9.3 Keep a small trusted verdict separate from rich reports + +The current merge-group policy fails if the shard matrix is not successful or reported tests failed, while ignoring aggregate reporting infrastructure issues. PRs retain a stricter policy. This solves a real class of false red gates, but aggregate result/coverage downloads can now fail without blocking an otherwise green matrix. [Summary decision, line 870][summary-decision] + +The stronger design is a small per-shard receipt, produced and verified inside the shard before it reports success: source SHA, project/shard identity, planned IDs, executed IDs, unexpected outcomes, and explicit skips. The final required check reconciles those small receipts against the expected matrix. Rich HTML, traces, request metrics, historical timing exports, and comments can run separately and report operational failures without making passed tests fail. + +Do not solve artifact unreliability by allowing an unsuccessful test matrix to become green. Conversely, an HTML merge failure should not invalidate a trustworthy completed test verdict. Reuse the existing coverage verifier's logic in the trustworthy path where possible. + +### 9.4 Timing history should not need direct pushes to main + +The successful full-run workflow attempts to commit a materially changed timing baseline directly to main. In the inspected run, GitHub rejected the push with `GH013`; the job emitted a warning and passed. Automatic baseline refresh therefore did not succeed in that run. Refresh log (original local evidence: `baseline-refresh.log`), [refresh job][refresh-job] + +Granting a bypass is not the preferred repair. Timing observations are operational data, and additional main commits can invalidate speculative queue work even when tagged to skip ordinary CI. The planner already consumes recent successful timing artifacts. Use immutable artifact/object storage as the normal source, retain a bootstrap fallback, and update that fallback infrequently through a controlled process. + +## 10. The merge gate to aim for + +Use explicit risk contracts rather than treating the current project name `Basic` as a sufficient definition of smoke coverage. + +| Stage | Proposed responsibility | Failure consequence | +|---|---|---| +| Local / fast PR checks | Changed component/unit/API tests, formatting, CI-planning tests | Author fixes before queue entry | +| PR browser checks | Critical browser contracts plus validated impacted coverage; full coverage for high-risk or uncertain changes | Required before entering queue where that coverage is part of the change contract | +| Exact merge-group candidate | Critical browser contracts and necessary integration/compatibility tests for the actual combined commit | Blocks merge for real failures or incomplete execution | +| Full regression on main and release candidates | Broad entity/role matrices during migration; engine, SSO, connector, visual and browser compatibility coverage | Owned response; release blocking for relevant failures; prompt revert/fix for regressions | +| Recovery and operational checks | Quarantine soak, performance, reporting, cache and selection audits | Tracked ownership and repair deadlines; separate from product verdict | + +A smaller exact-candidate queue gate is an architectural destination, not an immediate recommendation to drop today's full gate. First preserve the migrated cases below the browser layer, validate selection in shadow, and establish a reliable full-regression response. A green PR run alone does not validate the combined merge candidate. + +A possible starting operating target is **p95 required-gate latency of 15–20 minutes**, setup around **five minutes**, and **at least 99% noise-free full-gate success on unchanged known-good candidates**. These are proposed pilot goals, not measured capabilities or industry guarantees. Distinguish real defect detection from noise when measuring that success target. The exact budget should follow a measured pilot and the team's risk requirements. + +## 11. Prioritized work packages and acceptance criteria + +| Priority | Work package | Why first | Acceptance evidence | +|---|---|---|---| +| P0 | Diagnose/repair the three currently failing variants and the repeatedly retrying Pipeline task flow | These account for all sampled final failures and the most persistent retry | Specific owned entities; captured failing response/state; repeated isolated and concurrent runs; no dropped assertions | +| P0 | Fix budget false handling, CLI argument parsing, and manual boolean inputs | Reproducible defects break visibility and experiments | Fast tests for false/true/missing inputs and event combinations; dry-run alert payload, without requiring issue writes in tests | +| P0 | Run CI-planning checks and repair generated-map drift | An existing useful test already detects a current defect | Current 154-test collection green; drift/selection checks executed on relevant changes | +| P0 | Add trusted completion receipts while retaining report-only failure tolerance | Prevents both false red and incomplete green results | Deliberately missing execution fails; deliberate HTML failure leaves a complete passing matrix green | +| P1 | Measure and repair cache/seed reuse and preparation dependencies | Repeated median 17-minute serial work | Per-asset hit rates, fingerprint reasons, cold/warm correctness, reduced setup and gate p95 | +| P1 | Fix helper dependencies and documentation classification | Avoids both missed consumers and unnecessary full PR runs | Probe regressions covered; helper/rename/deletion cases verified; same-SHA selection shadow results | +| P1 | Move expensive repetitive matrices to appropriate lower layers | Eight specs account for 38.4% of measured worker time | Requirement ledger shows every relocated case; representative browser interactions retained; measured cost reduction | +| P1 | Add default-cache/default-bundle behavior and an owned quarantine recovery lane | Current green results omit important normal paths and excluded variants | Cross-session ETag regression test; dispatch false controls exercised; quarantines have owner/expiry and repeated recovery evidence | +| P1 | Pilot a bounded critical queue suite and runner/concurrency settings | Targets queue throughput without blindly reducing assurance | Compare equivalent commits and workload; report first-pass stability, p95 verdict, total wait, regressions, and runner-hours/merge | +| P2 | Align actual branch checks, schedules, visual paths, and documentation | Removes mistaken assumptions about protection | Machine-readable check contract agrees with effective rules and trigger tests | +| P2 | Store timing history outside source commits; improve queue accounting | Avoids needless main changes and misleading measurements | No operational-data pushes to main; complete attribution and stable dashboards | + +Use small, separately reviewable changes for control-plane fixes, individual unstable tests, provisioning, and portfolio migration. A single large “Playwright optimization” rewrite makes it difficult to tell which change improved reliability or reduced coverage. + +## 12. Improve the measurements before declaring the queue fixed + +The existing daily queue report is valuable and exposed the problem. A few definitions need correction or clearer labels. [Queue metrics implementation][queue-metrics] + +- “Total wait” measures first enqueue to merge. “First-pass latency” actually measures **last enqueue to merge for every merged PR**, not browser execution time and not only PRs that succeeded on their first enqueue. +- “Wasted passes” derives from enqueue counts and misses automatic group rebuilds that do not produce a new enqueue event. +- “Bypassed” is inferred from the absence of enqueue events; a PR previously queued and then bypassed can be misclassified. +- Failure attribution requests the first 100 check runs without pagination or filtering to required checks. It examines available check state, not necessarily an immutable snapshot from the moment of removal. +- Reported requeue penalty subtracts medians rather than taking the median of each PR's actual added delay. + +Track a stable test-ID ledger and a queue-group ledger. For each group, record source/base SHAs, included PRs, start/end of each stage, asset reuse, expected/executed tests, first-attempt outcomes, final failures, runner delay, and why the group became obsolete. Join failed checks to the actual required-check configuration and paginate all results. + +Publish separate measures for: real regressions caught, noise failures, retry-rescued tests, incomplete execution, setup latency, runner wait, total gate latency, reporting health, and total runner-hours per merged PR. Keep an absolute healthy operating target alongside a rolling baseline; being 26% better than a degraded previous week is not evidence of acceptable service. + +## 13. Reproduction and audit limits + +This is the original audit snapshot, preserved for follow-up. Selected public summary CSVs are included under `evidence/`. References labeled “original local evidence” identify collection files that are not published here; raw logs and result payloads may contain session details. All source/run links and conclusions refer to the audited commit and collection window, not a fresh verification of this PR. + +The local check was run in an activated Python 3.11 virtual environment: + +```sh +source env/bin/activate +python -m pytest -q \ + .github/scripts/tests/test_playwright_ci_planning.py \ + .github/scripts/tests/test_playwright_performance_gate.py \ + .github/scripts/tests/test_playwright_pr_comment.py \ + .github/scripts/tests/test_playwright_custom_properties_selection.py \ + .github/scripts/tests/test_playwright_cache_assets.py \ + .github/scripts/test_classify_playwright_outcome.py +``` + +Result: **153 passed, 1 failed in 11.53 seconds**. The failure is the committed generated impact-map drift guard. It was not repaired because the requested deliverable is an audit. This is not a claim that the CI tooling is fully green. + +Additional evidence files: + +- Effective branch rules (original local evidence: `effective-main-rules.json`) and ruleset snapshot (original local evidence: `main-ruleset.json`). +- Daily queue report log (original local evidence: `daily-report-2026-09-09.log`) and [daily workflow counts](evidence/queue-daily-outcomes.csv). +- Detailed calculations (original local evidence: `analyze-evidence.cjs`), table exporter (original local evidence: `export-tables.cjs`), and collection helper (original local evidence: `collect-evidence.cjs`). +- Selection probes (original local evidence: `selection-probes/summary.json`), with individual input/output files alongside them. +- [Repeated failing variants](evidence/repeated-test-failures.csv), with original hosted timing/result artifacts under `runs/`. +- Redacted first-attempt failure extracts under `raw-results/`; raw local result payloads are not intended for publication. + +Run counts are not independent PR counts. Retry-rescued cases are not established product bugs. Completed workflow failures are not all flakes. Timing accounting does not establish business coverage. Resource contention, the exact cause of the deployment 400, and the counterfactual throughput of a smaller gate need controlled follow-up experiments. + +[config]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright.config.ts#L206 +[reusable]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-e2e-reusable.yml +[dispatcher]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-postgresql-e2e.yml +[selector]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/select_playwright_tests.py +[impact-map]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/playwright/impact-map.json +[representative]: https://github.com/open-metadata/OpenMetadata/actions/runs/34355232120 +[visual]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-visual.yml#L27 +[yarn-coverage]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/yarn-coverage.yml#L205 +[ruleset]: https://github.com/open-metadata/OpenMetadata/rules/6520078 +[daily-run]: https://github.com/open-metadata/OpenMetadata/actions/runs/34324239537 +[report-incident]: https://github.com/open-metadata/OpenMetadata/actions/runs/34312746335 +[timeout-incident-1]: https://github.com/open-metadata/OpenMetadata/actions/runs/33862281607 +[timeout-incident-2]: https://github.com/open-metadata/OpenMetadata/actions/runs/33869395948 +[report-advisory]: https://github.com/open-metadata/OpenMetadata/actions/runs/34350084849 +[redeploy-failure]: https://github.com/open-metadata/OpenMetadata/actions/runs/34354609470 +[page-size-failure]: https://github.com/open-metadata/OpenMetadata/actions/runs/34350081016 +[page-size-failure-2]: https://github.com/open-metadata/OpenMetadata/actions/runs/34343844656 +[widget-failure]: https://github.com/open-metadata/OpenMetadata/actions/runs/34349824126 +[widget-failure-2]: https://github.com/open-metadata/OpenMetadata/actions/runs/34349258398 +[redeploy-spec]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TestSuitePipelineRedeploy.spec.ts#L65 +[tasks-spec]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TasksUIFlow.spec.ts#L132 +[widget-spec]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts#L203 +[common]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts#L169 +[pages-fixture]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/fixtures/pages.ts#L35 +[etag]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/src/rest/etagInterceptor.ts#L46 +[server-load]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/support/fixtures/serverLoad.ts +[coverage-verifier]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/verify_playwright_coverage.py +[budget-signal]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-postgresql-e2e.yml#L366 +[dispatch-flags]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-postgresql-e2e.yml#L108 +[planner]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/build_playwright_shards.py +[ci-readme]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/playwright/README.md#L12 +[performance]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/evaluate_playwright_performance.py#L139 +[fingerprint]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/playwright_cache_fingerprint.py +[warmer]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/populate-playwright-caches.yml +[summary-decision]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/render_playwright_summary.cjs#L870 +[refresh-job]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/workflows/playwright-postgresql-e2e.yml#L569 +[queue-metrics]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/.github/scripts/merge_queue_metrics.py#L307 diff --git a/docs/testing/playwright-migration/README.md b/docs/testing/playwright-migration/README.md new file mode 100644 index 000000000000..20f6685eb146 --- /dev/null +++ b/docs/testing/playwright-migration/README.md @@ -0,0 +1,220 @@ +# Should OpenMetadata move Playwright coverage into frontend tests? + +Audited 10 September 2026 at commit `44823acde1c85ccc20d9f62c588169567fc28c90`. This follow-up classifies every frontend Playwright product-test definition in this checkout and maps the classification to an actual full merge-queue run at the same commit. It supplements the [overall Playwright and merge-queue audit](QUEUE-ANALYSIS.md). + +## Decision + +**Yes. This is a worthwhile route: 1,589 of 4,488 queue cases, or 35.4%, are strong candidates for frontend component/page integration tests.** Another **1,778 cases, or 39.6%, combine extractable UI checks with real backend behavior**. Those need splitting while preserving integration coverage. Together they form a **75.0% candidate pool for some frontend extraction; 75.0% is not the percentage of whole tests that can safely be deleted.** + +Counting unique source definitions instead of expanded queue cases, **1,239 of 2,884, or 43.0%, are strong candidates**. The difference matters: several expensive mixed suites repeat the same code across many entities and roles. + +The preferred destination is usually **a real React component or page integration test**, exercising real children, form logic, providers, routing and request construction against controlled HTTP responses. A large collection of shallow tests that mock the component's own behavior would lose coverage. + +The strong candidates account for **23.2% of recorded test-worker duration** in the measured run. The opportunity is substantial, but removing 35.4% of queue cases would not make the queue 35.4% faster. Backend setup, shard scheduling, retained long journeys and replacement-test cost all matter. + +## Complete inventory and how the review was performed + +| Inventory | Count | Meaning | +|---|---:|---| +| Frontend Playwright `.spec.ts` files | 394 | All product spec files in the inventoried Playwright tree | +| Additional files defining product tests | 2 | Shared search-separation factory and production-bundle smoke | +| Unique source test definitions reviewed | 2,884 | Each inline test definition counted once, before entity/role loops expand | +| Definitions instantiated by the 394 spec files | 2,903 | Includes 22 factory instances in 11 specs; excludes standalone bundle smoke | +| Distinct planned product cases in the measured queue run | 4,488 | Parameterized and project-expanded cases, each counted once | +| Queue cases mapped to a reviewed definition | 4,488 / 4,488 | Exact source-location match using native Playwright JSON results | +| Owning spec files represented in that run | 365 | Some SSO, visual and other specialized suites use separate lanes | +| Unique definitions represented in that run | 2,747 | The source review also covers the remaining 137 definitions | + +The source denominator needs care. There are 2,881 inline definitions inside the specs. Eleven specs instantiate two shared factory definitions each, producing 2,903 spec-instantiated definitions. Counting each factory definition once and adding the standalone bundle smoke instead produces 2,884 unique definitions. The strong numerator is 1,239 under either approach: **42.7% of spec-instantiated definitions**, or **43.0% of unique definitions**. + +The runtime evidence is [queue run 34355232120][run], at the audited source commit. Its native results were collected across 37 shards. The 4,488 product cases comprise 4,483 expected outcomes, four cases rescued by retry and one skipped case. Two Data Insight lifecycle invocations in the reporter's 4,490 total are excluded. Retries contribute duration but do not add cases to the denominator. + +I parsed every inventoried source file using the TypeScript AST, extracted each definition's title, enclosing suites/loops, actions, helper calls and assertions, and reviewed every definition at that level. Ambiguous cases were followed into full bodies, hooks, helpers and relevant application code. Examples include pagination, permissions, entity CRUD, right-panel validators, graph instrumentation, chart clicks, token helpers and contract import parsing. All 396 files parsed without diagnostics. All 2,884 definitions have a recorded classification; none remain unclassified. + +This is an assertion-and-behavior audit, not a filename heuristic or a sampled percentage. It is also not a claim to have manually read every line of every transitive helper, proved every assertion correct, or implemented equivalent replacements. Classification remains engineering judgment about the appropriate testing boundary. Java Playwright UIITs, runner/reporting unit tests and authentication/setup lifecycle files are outside this frontend product-test denominator. + +The full suite was **not rerun locally**. The percentages use reviewed source and existing hosted execution evidence, not a migration benchmark. + +## Classification results + +| Category | Unique definitions | Queue cases | Queue share | Recorded worker-time share | +|---|---:|---:|---:|---:| +| **U — Strong frontend component/page integration candidate** | **1,239** | **1,589** | **35.4%** | **23.2%** | +| **M — Mixed: extract UI checks, preserve backend integration** | **839** | **1,778** | **39.6%** | **41.9%** | +| B — Retain browser; potentially isolate from backend | 138 | 145 | 3.2% | 2.4% | +| A — Backend/API contract, outside UI component migration | 231 | 254 | 5.7% | 2.4% | +| E — Retain integrated journey during initial migration | 437 | 722 | 16.1% | 30.1% | +| **Total** | **2,884** | **4,488** | **100.0%** | **100.0%** | + +Percentages are rounded. Category A includes API-only tests already using the Playwright runner and browser-driven tests whose primary assertions concern server contracts. It is not an exact count of tests that currently launch no browser. Category E is a conservative decision for the first frontend migration, not proof that every variant must remain an end-to-end test forever. + +**What earns U:** the important assertion can still fail for a frontend regression when API responses are supplied at the HTTP boundary. Examples are required-field validation, permission-derived controls, URL construction, stale-request handling, tab/selection state, and rendering a supplied response. Creating entities through real APIs merely to prepare those states does not itself make the assertion end to end. + +**What earns M:** replacing the server would remove a meaningful assertion about persistence, actual search results, permission propagation or another backend result. Move the UI matrix, but keep that contract under real integration coverage. CRUD helpers often fall here. + +**What stays in B/E:** real browser geometry, pointer interactions, clipboard, screenshots, editor behavior, built-bundle loading, authentication/session renewal, ingestion/background processing, cross-user workflows, cascades and file round-trips. Some browser-specific tests could run against isolated fixtures without the full OpenMetadata stack. + +## Where the strongest opportunities are + +These are current cases classified U. Counts for a partially eligible file refer only to its U cases; they are not recommendations to remove the entire file. Durations are cumulative test-worker minutes in the representative run. + +| Area | Strong queue candidates | Recorded worker minutes | Recommended replacement | +|---|---:|---:|---| +| Entity, service and data-quality permission suites, combined | 115 | 28.7 | Render real screens with allowed/denied permission responses; assert actions and route guards | +| `Pages/CustomProperties.spec.ts` | 88 | 17.0 | Real form validation, local property search, field and link rendering | +| `Pages/ExplorePageRightPanel.spec.ts` | 88 | 14.5 | Real panel, tabs, schema search, selection and permission state | +| U cases inside `Pages/Entity.spec.ts` | 48 | 14.0 | Shared entity UI affordances, labels, local schema state and navigation | +| `Flow/NestedChildrenUpdates.spec.ts` | 36 | 7.9 | Apply mutation responses to the real nested table and assert immediate updates | +| `Features/ColumnBulkOperations.spec.ts` | 25 | 7.7 | Grid rendering, selection, bulk-edit state and validation | +| `Features/Pagination.spec.ts` | 35 | 7.2 | Page-size/cursor requests, URL state, loading, navigation and search reset | + +The per-file totals and every contributing case are available in [all-files.csv](evidence/all-files.csv) and the [complete definition inventory](evidence/all-definitions.csv.gz). + +### 1. Custom properties: clear validation and rendering candidates + +The suite contains **15 separate name-validation definitions**, covering invalid initial characters, punctuation, valid names and length. These are straightforward candidates for parameterized tests of the real form, with a small utility test matrix if validation is factored into a reusable function. Most do not need a real database, search index, login or browser. [Name validation][custom-validation] + +Four further definitions repeat display, search, clear-search and property-name checks across 17 entity contexts: **68 queue cases**. Preserve the shared panel and real custom-property rendering; provide representative entity payloads and assert the visible result. Keep distinct serializers and genuinely different entity behavior represented rather than replacing the whole matrix with one generic fixture. [Property panel tests][custom-panel] + +There is already evidence of the intended direction in this repository: `CustomPropertiesApiContract.spec.ts` explicitly covers **272 removed browser-matrix combinations**, across 16 entity types plus table columns and 16 value variants. It runs 17 API compatibility cases plus one matrix-shape assertion. That coverage is already outside the UI-candidate count; it must not be claimed again as future savings. [Existing API compatibility contract][custom-contract] + +The remaining custom-property suite still has 81 mixed queue cases and four browser-dependent cases. Its real persistence, search and browser-specific behavior should remain covered while the UI-only parts move. + +### 2. Permission matrices: separate presentation from enforcement + +The entity/service permission helpers largely assert whether controls are visible or disabled. The data-quality suite includes analogous create/delete/edit affordances and page access. These can exercise the actual permission-to-UI logic with controlled permission responses. [Entity permission matrix][entity-permissions], [service permission matrix][service-permissions], [data-quality permission matrix][dq-permissions], [shared assertions][permission-helper] + +A hidden button does not prove server authorization. Preserve real API tests that attempt forbidden operations and assert denial, plus representative browser journeys confirming that the signed-in identity receives and applies the correct permissions. The large presentation matrix and the backend enforcement matrix protect different failures. + +### 3. Pagination, local state and asynchronous UI races + +The shared pagination helpers exercise page/URL state, outgoing limits/cursors and resulting table display. The complete-flow helper's search checks do not establish that every returned item actually matches the search. This makes a real table/page integration with controlled HTTP pages a good destination; a service-level cursor and search contract should remain separate. [Pagination suite][pagination], [pagination helper][pagination-helper] + +`SearchSettings.spec.ts` has a particularly strong example: **“Latest preview config wins when a superseded request resolves late.”** The Playwright test already intercepts and delays responses. The essential regression is frontend response ordering. A component/page test can deliver the old response after the new one and assert the current preview stays visible, using the real state and rendering logic. [Stale preview regression][search-race] + +Nested-child update tests similarly protect an important UI regression: a successful edit should update the displayed nested row immediately without requiring refresh. These should remain strong behavior tests after migration; checking only that an API mock was called would miss the regression. [Nested updates][nested-updates] + +### 4. Right panels: repeated UI, with some meaningful integration contracts + +There are **126 strong queue candidates across seven files whose names contain `RightPanel`**, accounting for 20.4 worker-minutes. They cover tabs, entity links, empty states, schema filtering and role affordances in multiple page contexts. The shared components are a natural component/page integration boundary. + +Keep representative host-page wiring checks: opening the correct entity from Explore, Glossary, Tag and Team contexts can expose different routing or selection bugs. Actual edits, deleted users disappearing from selectors, and search-index propagation remain mixed or integrated cases. In the main Explore panel file alone, 116 cases are mixed and 30 retain integrated coverage. [Explore panel tests][explore-panel] + +One quality defect reinforces why this should improve assertions as well as placement: `validateRightPanelForAsset` checks an expected tab only **if it is already present**. An absent expected tab can therefore pass that helper. A replacement should assert that every expected tab exists before checking its contents. [Conditional tab validator][panel-helper] + +### 5. Lineage: a browser page is not automatically a browser-dependent assertion + +Layer toggles, selected/traced/dimmed attributes, panel state, breadcrumbs and graph-data transformations are frontend behavior. The shared `clickEdgeBetweenNodes` helper uses a synthetic `dispatchEvent('click')`; those cases do not establish that a user can hit the rendered edge at the correct screen position. Several ontology helpers likewise read serialized graph data from DOM datasets, rather than inspecting canvas pixels. [Synthetic edge click][edge-helper], [graph data reader][graph-helper] + +Move appropriate state/transformation cases into frontend integration, and keep genuine canvas/layout, drag, zoom, hit-testing and screenshot checks in a browser. Graph libraries may make a backend-free browser fixture more practical than jsdom for some candidates; that still removes the full-stack dependency, but it is not the same as a Jest unit test. + +The broad `DataAssetLineage` journeys remain outside U: **79 cases account for 97.6 worker-minutes** in the measured run. They combine real graph creation, column relationships and export behavior. Removing small control tests alone will not remove this cost. [Integrated lineage suite][lineage] + +### 6. Import/export: distinguish the modal from the format contract + +Local YAML/JSON parsing errors, preview content, mode selection and disabled import buttons can be frontend tests. Server schema validation, ODCS/OpenMetadata conversion, merge/replace semantics, persistence and actual export round-trips need real API or integrated coverage. The implementation performs local parsing and also calls server parsing/validation endpoints; these are separate boundaries. [Import implementation][odcs-implementation], [import/export cases][odcs-tests] + +Existing `ODCSImportModal.test.tsx` already covers many modal behaviors, so this is partly consolidation and strengthening. However, it replaces core components including the upload control, and implements extension filtering inside the mock. A passing test of that mock is not evidence that the real upload control behaves the same way. [Existing modal tests][odcs-unit] + +## Mixed tests are the larger, harder opportunity + +The 1,778 mixed cases account for **41.9% of recorded worker time**. In `Entity`, `EntityDataConsumer`, `EntityDataSteward` and `ServiceEntity` alone, **605 mixed cases consume 3.37 worker-hours**. Much of this repeats owner, tag, glossary, tier, description and announcement operations across entities and roles. [Shared entity helper][entity-helper] + +The useful decomposition is: + +1. **Frontend integration:** interaction, form state, correct endpoint/body, response handling and visible update, with the real UI. +2. **Backend/API integration:** the operation actually stores the intended data, search returns it, permissions are enforced and entity-specific contracts hold. +3. **Representative browser journey:** the assembled application connects those contracts correctly for meaningful entity/role differences. + +Do not replace a real search-result assertion with a fabricated matching result and call that equivalent coverage. For example, the advanced-search helpers verify real search hits as well as query/chip state. The UI builder/serialization matrix can move, but the actual AND/OR/filter semantics belong under real search integration. **124 of the 130 AdvancedSearch queue cases are mixed**, not whole-test U candidates. [Advanced search helper][advanced-helper] + +Similarly, workflow authorization and approval, inherited ownership, deletion propagation and ingestion execution should not be erased merely because their final assertion appears in the DOM. + +## Existing Jest coverage needs strengthening before browser tests are retired + +The application already has Jest, jsdom, React Testing Library and user-event. This migration does not require a new test runner. [Package scripts and dependencies][package], [Jest configuration][jest] + +Targeted inspection found important limitations: + +- **AddCustomProperty:** the unit test mocks `generateFormFields` into plain inputs, leaving out the real validation rules. Its three tests check child placeholders, field presence and Back navigation. It cannot replace the browser name-validation matrix in its current form. [Current test][custom-unit] +- **QueryBuilderWidgetV1:** the test replaces `Builder` and `Query`, makes several tree utilities identities and returns constant JSON logic. It can test surrounding wiring, but cannot establish correct user-driven query construction or real serialization. [Current test][query-unit] +- **ODCSImportModal:** substantial behavior coverage exists, but several real design-system controls are replaced, including a mock that implements file filtering. Preserve component behavior through the real controls where that behavior is the target. [Current test][odcs-unit] + +These are examples from targeted inspection, not a claim that all existing frontend unit tests are poor. The required change is **less mocking of the behavior under test**, not simply a larger unit-test count. Testing Library's guidance supports testing components through user-visible behavior; Playwright likewise recommends observable behavior and test isolation. [Testing Library principles](https://testing-library.com/docs/guiding-principles/), [Playwright best practices](https://playwright.dev/docs/best-practices) + +## Assertion quality affects the migration estimate + +The ledger carries **77 source-definition notes** about weak assertions, conditional coverage or limits on what a title proves. These are review notes, not 77 independently confirmed production defects. Examples include a password-reset title that only checks navigation, zoom titles that do not assert a changed zoom, and a comment-viewing title that only checks the task card. + +Of the 1,589 strong candidate queue cases, **71 have an assertion note**. Excluding all of them still leaves **1,518 cases, or 33.8% of the queue**, as strong candidates. This sensitivity check shows the opportunity is not driven by obviously weak tests. It is not a statistical confidence interval. + +Migration should preserve or improve the intended outcome assertions. Some cases deserve repair or consolidation instead of a one-for-one translation. For example, a replacement for a zoom test should either verify the real transform in a browser or clearly limit its claim to control state. + +## What this would do for the merge queue + +The representative run records **22.58 cumulative test-worker hours**, including attempts. U accounts for **5.23 hours**; U plus M accounts for **14.69 hours**. These figures describe where current work is spent. They exclude separately accounted lifecycle work and are neither billed runner-hours nor predicted savings. + +The earlier operational audit found a median **17.05-minute seed preparation** and a **61.14-minute required Playwright gate** in its 30-run snapshot. Frontend extraction can reduce repeated application work and allow fast feedback without that setup. It does not automatically shorten preparation or the longest retained shard. Files that still contain M/E cases may still incur their shared setup. [Operational measurements](QUEUE-ANALYSIS.md#43-the-recent-sample-separates-current-problems-from-old-incidents) + +There is also no basis to promise a proportional flake reduction. In this particular representative run, the four retry-rescued cases are in **M, A and E**, with none in U. Moving U cases therefore targets test placement, feedback speed and compute first; it would not have eliminated that run's observed retries. Reliability and queue orchestration work from the original audit remain necessary. + +## Recommended first migration + +Start with a bounded set of **211 strong queue candidates across six files**, representing **51.4 current worker-minutes**: + +- `Features/Permissions/EntityPermissions.spec.ts`: 46 cases. +- `Features/Permissions/ServiceEntityPermissions.spec.ts`: 44 cases. +- `Features/DataQuality/DataQualityPermissions.spec.ts`: 25 cases. +- `Features/Pagination.spec.ts`: 35 cases. +- `Flow/NestedChildrenUpdates.spec.ts`: 36 cases. +- `Features/ColumnBulkOperations.spec.ts`: 25 cases. + +Begin implementation with one small family, such as required-field validation or pagination, to establish the real-provider/HTTP-boundary harness. The six-file set is the next bounded target, not a demand to rewrite all six at once. Retain representative assembled-app journeys and the real backend contracts they currently touch. Custom-property validation and right-panel rendering are strong subsequent targets. + +For each migrated behavior: + +1. Identify the actual defect the test must detect, including negative outcomes. Record which UI, API and browser checks will cover it after migration. +2. Implement the replacement with real components and controlled network/time boundaries. Use user interactions; assert visible outcomes and meaningful request contracts. Avoid mocking the validator, query serializer, state hook or control being tested. +3. Demonstrate that the replacement fails for the intended regression: invalid names accepted, wrong permission combinations, stale response replacing current data, or a nested row failing to update. A temporary targeted fault or existing regression fixture is stronger evidence than coverage percentage alone. +4. Compare current and replacement runtime and repeatability, and verify retained backend/browser checks. Retire the redundant browser variants only once replacement coverage is demonstrated. +5. Rebalance shards and measure the actual queue verdict latency, setup time, test-worker time and retries separately. + +Require the fast frontend suite for changed behavior, retain representative critical journeys in the merge gate, and keep API/security/format semantics under real integration coverage. Choose the eventual broader browser schedule and gate size from measured residual cost and failure detection, rather than using an arbitrary target percentage. This audit makes no workflow or branch-rule changes. + +## Preserved evidence and follow-up + +- [All 2,884 unique definitions](evidence/all-definitions.csv.gz): source links, category, rationale, assertion notes and queue contribution. +- [All 4,488 expanded queue cases](evidence/all-queue-cases.csv.gz): owning spec, source definition, category, measured duration, attempts and result. +- [All 394 specs plus supporting files](evidence/all-files.csv): complete inventory and per-category totals. +- [All 2,903 spec-instantiated definitions](evidence/all-spec-instances.csv.gz): explicit accounting for shared factory definitions. +- [Machine-readable summary](evidence/summary.json). CSV exports are gzip-compressed; use `gzip -dc ` to inspect them. +- [Migration status and validation](MIGRATION.md): distinguishes the 211-case candidate set from coverage actually replaced in this PR. + +These are immutable audit exports at the source commit above, not generated descriptions of the current branch. The original TypeScript AST extraction, hand-reviewed decisions and downloaded shard results produced the reconciled exports. Repeating the classification requires checking out that commit and collecting the linked run's native results; hosted artifact retention may limit future retrieval. This repository preserves the reviewed decisions and measurements, rather than depending on an ignored local workspace directory or a live artifact URL. + +[run]: https://github.com/open-metadata/OpenMetadata/actions/runs/34355232120 +[custom-validation]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts#L3803 +[custom-panel]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts#L3668 +[custom-contract]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomPropertiesApiContract.spec.ts#L900 +[entity-permissions]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/EntityPermissions.spec.ts#L217 +[service-permissions]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/ServiceEntityPermissions.spec.ts#L93 +[dq-permissions]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQualityPermissions.spec.ts#L320 +[permission-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/entityPermissionUtils.ts#L197 +[pagination]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Pagination.spec.ts#L66 +[pagination-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/common.ts#L1335 +[search-race]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SearchSettings.spec.ts#L612 +[nested-updates]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/NestedChildrenUpdates.spec.ts#L62 +[explore-panel]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExplorePageRightPanel.spec.ts#L204 +[panel-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/PageObject/Explore/RightPanelPageObject.ts#L838 +[edge-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/lineage.ts#L141 +[graph-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/ontologyStudio.ts#L170 +[lineage]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/DataAssetLineage.spec.ts +[odcs-implementation]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ODCSImportModal/ODCSImportModal.component.tsx#L335 +[odcs-tests]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ODCSImportExport.spec.ts +[odcs-unit]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/src/components/DataContract/ODCSImportModal/ODCSImportModal.test.tsx#L41 +[entity-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/support/entity/EntityClass.ts#L145 +[advanced-helper]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts#L371 +[package]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/package.json +[jest]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/jest.config.js#L121 +[custom-unit]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/src/components/Settings/CustomProperty/AddCustomProperty/AddCustomProperty.test.tsx#L198 +[query-unit]: https://github.com/open-metadata/OpenMetadata/blob/44823acde1c85ccc20d9f62c588169567fc28c90/openmetadata-ui/src/main/resources/ui/src/components/common/QueryBuilderWidgetV1/QueryBuilderWidgetV1.test.tsx#L97 diff --git a/docs/testing/playwright-migration/evidence/all-definitions.csv.gz b/docs/testing/playwright-migration/evidence/all-definitions.csv.gz new file mode 100644 index 000000000000..7269fc349bd6 Binary files /dev/null and b/docs/testing/playwright-migration/evidence/all-definitions.csv.gz differ diff --git a/docs/testing/playwright-migration/evidence/all-files.csv b/docs/testing/playwright-migration/evidence/all-files.csv new file mode 100644 index 000000000000..6973eff63e24 --- /dev/null +++ b/docs/testing/playwright-migration/evidence/all-files.csv @@ -0,0 +1,397 @@ +"file","path","kind","reviewed","parseErrors","uniqueDefinitions","specInstantiatedDefinitions","queueCases","queueDurationMs","U_sourceDefinitions","U_queueCases","U_durationMs","M_sourceDefinitions","M_queueCases","M_durationMs","B_sourceDefinitions","B_queueCases","B_durationMs","A_sourceDefinitions","A_queueCases","A_durationMs","E_sourceDefinitions","E_queueCases","E_durationMs" +"Auth/OktaSelfSignupClaims.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/OktaSelfSignupClaims.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Auth/OktaSessionRenewalPublic.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/OktaSessionRenewalPublic.spec.ts","spec","true","0","2","2","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2","0","0" +"Auth/SSOAuthentication.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/SSOAuthentication.spec.ts","spec","true","0","25","25","0","0","0","0","0","0","0","0","0","0","0","5","0","0","20","0","0" +"Auth/SSOLogin.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/SSOLogin.spec.ts","spec","true","0","6","6","0","0","1","0","0","0","0","0","0","0","0","0","0","0","5","0","0" +"Auth/SSORenewal.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/SSORenewal.spec.ts","spec","true","0","3","3","0","0","0","0","0","0","0","0","0","0","0","0","0","0","3","0","0" +"Auth/SSOSelfSignup.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/SSOSelfSignup.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Auth/SSOSessionLimit.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Auth/SSOSessionLimit.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Features/ActivityAPI.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ActivityAPI.spec.ts","spec","true","0","10","10","10","156931","7","7","100990","3","3","55941","0","0","0","0","0","0","0","0","0" +"Features/ActivityFeed.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ActivityFeed.spec.ts","spec","true","0","17","17","17","344411","14","14","245977","1","1","15079","1","1","27670","0","0","0","1","1","55685" +"Features/ActivityFeedTabBadge.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ActivityFeedTabBadge.spec.ts","spec","true","0","4","4","4","100378","2","2","41958","2","2","58420","0","0","0","0","0","0","0","0","0" +"Features/ActivityStream.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ActivityStream.spec.ts","spec","true","0","6","6","5","98440","4","3","47696","0","0","0","0","0","0","0","0","0","2","2","50744" +"Features/AdvancedSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts","spec","true","0","28","28","130","2727165","6","6","84753","22","124","2642412","0","0","0","0","0","0","0","0","0" +"Features/AdvancedSearchSuggestions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearchSuggestions.spec.ts","spec","true","0","1","1","9","82047","0","0","0","1","9","82047","0","0","0","0","0","0","0","0","0" +"Features/AgentLogStreamHandover.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AgentLogStreamHandover.spec.ts","spec","true","0","3","3","3","21120","1","1","4981","0","0","0","2","2","16139","0","0","0","0","0","0" +"Features/Announcements/AnnouncementEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Announcements/AnnouncementEntity.spec.ts","spec","true","0","3","3","3","70856","0","0","0","3","3","70856","0","0","0","0","0","0","0","0","0" +"Features/Announcements/EntityHeaderAnnouncements.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Announcements/EntityHeaderAnnouncements.spec.ts","spec","true","0","3","3","3","65026","3","3","65026","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/AppMode/AppModeAiPersonaLandsAtRoot.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeAiPersonaLandsAtRoot.spec.ts","spec","true","0","1","1","1","18625","0","0","0","0","0","0","0","0","0","0","0","0","1","1","18625" +"Features/AppMode/AppModeAuthGating.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeAuthGating.spec.ts","spec","true","0","8","8","8","3105","0","0","0","0","0","0","0","0","0","8","8","3105","0","0","0" +"Features/AppMode/AppModeCrossDevice.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeCrossDevice.spec.ts","spec","true","0","1","1","1","28019","0","0","0","0","0","0","0","0","0","0","0","0","1","1","28019" +"Features/AppMode/AppModePrecedence.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModePrecedence.spec.ts","spec","true","0","5","5","5","65556","0","0","0","4","4","47818","0","0","0","0","0","0","1","1","17738" +"Features/AppMode/AppModePreferenceRoundTrip.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModePreferenceRoundTrip.spec.ts","spec","true","0","2","2","2","26695","2","2","26695","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/AppMode/AppModeResolver.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeResolver.spec.ts","spec","true","0","6","6","6","81854","2","2","22074","0","0","0","0","0","0","0","0","0","4","4","59780" +"Features/AppMode/AppModeRouteIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeRouteIsolation.spec.ts","spec","true","0","2","2","2","33128","2","2","33128","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/AppMode/AppModeSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AppMode/AppModeSettings.spec.ts","spec","true","0","6","6","6","74455","5","5","63768","1","1","10687","0","0","0","0","0","0","0","0","0" +"Features/ArticleReviewerWorkflow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ArticleReviewerWorkflow.spec.ts","spec","true","0","1","1","1","112211","0","0","0","0","0","0","0","0","0","0","0","0","1","1","112211" +"Features/AutoPilot.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AutoPilot.spec.ts","spec","true","0","2","2","12","707031","0","0","0","0","0","0","0","0","0","0","0","0","2","12","707031" +"Features/BlockEditorEmbedLink.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BlockEditorEmbedLink.spec.ts","spec","true","0","1","1","1","15789","0","0","0","0","0","0","1","1","15789","0","0","0","0","0","0" +"Features/BlockEditorMathEquations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BlockEditorMathEquations.spec.ts","spec","true","0","1","1","1","24946","0","0","0","0","0","0","0","0","0","0","0","0","1","1","24946" +"Features/BulkEditEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkEditEntity.spec.ts","spec","true","0","6","6","6","352971","0","0","0","0","0","0","0","0","0","0","0","0","6","6","352971" +"Features/BulkEditImportPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkEditImportPermissions.spec.ts","spec","true","0","4","4","4","137387","4","4","137387","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/BulkEditOperationBadges.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkEditOperationBadges.spec.ts","spec","true","0","6","6","6","120992","6","6","120992","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/BulkImport.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImport.spec.ts","spec","true","0","6","6","6","1494003","0","0","0","0","0","0","1","1","25957","0","0","0","5","5","1468046" +"Features/BulkImportWithDotInName.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkImportWithDotInName.spec.ts","spec","true","0","8","8","8","271198","0","0","0","1","1","27719","0","0","0","0","0","0","7","7","243479" +"Features/CertificationDropdown.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CertificationDropdown.spec.ts","spec","true","0","4","4","4","76194","1","1","12238","3","3","63956","0","0","0","0","0","0","0","0","0" +"Features/ChangeSummaryBadge.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ChangeSummaryBadge.spec.ts","spec","true","0","5","5","5","108760","5","5","108760","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ClassificationImportExport.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ClassificationImportExport.spec.ts","spec","true","0","4","4","4","35082","3","3","22086","1","1","12996","0","0","0","0","0","0","0","0","0" +"Features/ColumnBulkOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts","spec","true","0","25","25","25","461822","25","25","461822","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ColumnBulkOperationsTagsGlossary.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperationsTagsGlossary.spec.ts","spec","true","0","2","2","2","64474","2","2","64474","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ColumnSorting.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnSorting.spec.ts","spec","true","0","7","7","7","50484","7","7","50484","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Container.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Container.spec.ts","spec","true","0","12","12","12","108971","2","2","21141","8","8","71115","2","2","16715","0","0","0","0","0","0" +"Features/ContextCenterArchive.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterArchive.spec.ts","spec","true","0","3","3","3","64461","0","0","0","0","0","0","1","1","6439","0","0","0","2","2","58022" +"Features/ContextCenterArticles.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterArticles.spec.ts","spec","true","0","41","41","41","977537","4","4","55681","9","9","254974","17","17","280314","0","0","0","11","11","386568" +"Features/ContextCenterDashboard.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterDashboard.spec.ts","spec","true","0","9","9","9","126479","5","5","69151","2","2","28218","0","0","0","0","0","0","2","2","29110" +"Features/ContextCenterDocument.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterDocument.spec.ts","spec","true","0","30","30","30","369624","12","12","125464","6","6","72767","4","4","50212","0","0","0","8","8","121181" +"Features/ContextCenterMemories.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterMemories.spec.ts","spec","true","0","55","55","55","603702","31","31","314665","23","23","279319","1","1","9718","0","0","0","0","0","0" +"Features/ContextCenterPermission.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterPermission.spec.ts","spec","true","0","34","34","34","479944","17","17","194157","14","14","226352","0","0","0","0","0","0","3","3","59435" +"Features/CronValidations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CronValidations.spec.ts","spec","true","0","1","1","1","8737","1","1","8737","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/CsvJobsTray.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CsvJobsTray.spec.ts","spec","true","0","11","11","11","112540","11","11","112540","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/CuratedAssets.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CuratedAssets.spec.ts","spec","true","0","6","6","23","811934","1","1","18294","5","22","793640","0","0","0","0","0","0","0","0","0" +"Features/CustomMetric.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CustomMetric.spec.ts","spec","true","0","2","2","2","50418","0","0","0","2","2","50418","0","0","0","0","0","0","0","0","0" +"Features/CustomizeDetailPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CustomizeDetailPage.spec.ts","spec","true","0","10","10","25","623212","4","4","44160","4","19","517171","0","0","0","0","0","0","2","2","61881" +"Features/CustomizeNavigationNewItems.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CustomizeNavigationNewItems.spec.ts","spec","true","0","2","2","2","37294","1","1","13049","1","1","24245","0","0","0","0","0","0","0","0","0" +"Features/Dashboards.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Dashboards.spec.ts","spec","true","0","4","4","4","66571","1","1","10877","2","2","32642","0","0","0","0","0","0","1","1","23052" +"Features/DataAssetRulesDisabled.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataAssetRulesDisabled.spec.ts","spec","true","0","7","7","34","739574","0","0","0","4","31","560498","0","0","0","0","0","0","3","3","179076" +"Features/DataAssetRulesEnabled.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataAssetRulesEnabled.spec.ts","spec","true","0","4","4","31","448396","0","0","0","4","31","448396","0","0","0","0","0","0","0","0","0" +"Features/DataProductDomainMigration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductDomainMigration.spec.ts","spec","true","0","3","3","3","74466","0","0","0","0","0","0","0","0","0","0","0","0","3","3","74466" +"Features/DataProductPersonaCustomization.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductPersonaCustomization.spec.ts","spec","true","0","2","2","2","43442","0","0","0","2","2","43442","0","0","0","0","0","0","0","0","0" +"Features/DataProductRename.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductRename.spec.ts","spec","true","0","4","4","4","98645","0","0","0","2","2","34702","0","0","0","0","0","0","2","2","63943" +"Features/DataProductRenameConsolidation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductRenameConsolidation.spec.ts","spec","true","0","4","4","4","103356","0","0","0","0","0","0","0","0","0","0","0","0","4","4","103356" +"Features/DataQuality/AddTestCaseNewFlow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/AddTestCaseNewFlow.spec.ts","spec","true","0","4","4","4","62566","1","1","14358","0","0","0","0","0","0","0","0","0","3","3","48208" +"Features/DataQuality/BundleSuiteBulkOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/BundleSuiteBulkOperations.spec.ts","spec","true","0","3","3","3","34647","1","1","10719","2","2","23928","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/CertificationFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/CertificationFilter.spec.ts","spec","true","0","4","4","4","33608","3","3","21610","1","1","11998","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/ColumnLevelTests.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/ColumnLevelTests.spec.ts","spec","true","0","16","16","16","284710","0","0","0","16","16","284710","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/DataObservabilityGovernanceTab.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataObservabilityGovernanceTab.spec.ts","spec","true","0","14","14","14","97103","13","13","84373","1","1","12730","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/DataQuality.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQuality.spec.ts","spec","true","0","9","9","9","138361","3","3","29306","5","5","103211","1","1","5844","0","0","0","0","0","0" +"Features/DataQuality/DataQualityDashboard.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQualityDashboard.spec.ts","spec","true","0","11","11","11","194837","9","9","145302","1","1","38247","0","0","0","0","0","0","1","1","11288" +"Features/DataQuality/DataQualityPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQualityPermissions.spec.ts","spec","true","0","25","25","25","436135","25","25","436135","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/Dimensionality.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/Dimensionality.spec.ts","spec","true","0","1","1","1","10831","0","0","0","1","1","10831","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/IncidentManagerAfterOwnerChange.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/IncidentManagerAfterOwnerChange.spec.ts","spec","true","0","1","1","1","23883","0","0","0","0","0","0","0","0","0","1","1","23883","0","0","0" +"Features/DataQuality/IncidentManagerAfterSoftDelete.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/IncidentManagerAfterSoftDelete.spec.ts","spec","true","0","1","1","1","17259","0","0","0","0","0","0","0","0","0","1","1","17259","0","0","0" +"Features/DataQuality/IncidentManagerDateFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/IncidentManagerDateFilter.spec.ts","spec","true","0","11","11","11","142844","11","11","142844","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/IncidentManagerLocaleLayout.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/IncidentManagerLocaleLayout.spec.ts","spec","true","0","5","5","7","38079","0","0","0","0","0","0","5","7","38079","0","0","0","0","0","0" +"Features/DataQuality/Profiler.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/Profiler.spec.ts","spec","true","0","4","4","4","49908","0","0","0","4","4","49908","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/ProfilerIngestionForm.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/ProfilerIngestionForm.spec.ts","spec","true","0","7","7","7","47736","7","7","47736","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TableLevelTests.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TableLevelTests.spec.ts","spec","true","0","9","9","8","204638","0","0","0","9","8","204638","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TableTestCasePagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TableTestCasePagination.spec.ts","spec","true","0","1","1","1","13983","1","1","13983","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TestCaseImportExportBasic.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseImportExportBasic.spec.ts","spec","true","0","24","24","24","206511","16","16","112893","0","0","0","0","0","0","0","0","0","8","8","93618" +"Features/DataQuality/TestCaseImportExportE2eFlow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseImportExportE2eFlow.spec.ts","spec","true","0","2","2","2","518236","0","0","0","0","0","0","0","0","0","0","0","0","2","2","518236" +"Features/DataQuality/TestCaseIncidentPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseIncidentPermissions.spec.ts","spec","true","0","8","8","8","85221","5","5","53145","3","3","32076","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TestCaseResultPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseResultPermissions.spec.ts","spec","true","0","11","11","11","235476","7","7","133227","4","4","102249","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TestCaseSoftDeleteRestore.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseSoftDeleteRestore.spec.ts","spec","true","0","3","3","3","45353","1","1","13605","0","0","0","0","0","0","0","0","0","2","2","31748" +"Features/DataQuality/TestCaseStatusAfterReindex.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestCaseStatusAfterReindex.spec.ts","spec","true","0","1","1","1","1978","0","0","0","0","0","0","0","0","0","1","1","1978","0","0","0" +"Features/DataQuality/TestDefinitionFilters.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestDefinitionFilters.spec.ts","spec","true","0","7","7","7","89896","6","6","79573","1","1","10323","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TestDefinitionPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestDefinitionPermissions.spec.ts","spec","true","0","7","7","7","100160","3","3","40033","1","1","10837","0","0","0","3","3","49290","0","0","0" +"Features/DataQuality/TestLibrary.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestLibrary.spec.ts","spec","true","0","15","15","15","189675","9","9","87555","6","6","102120","0","0","0","0","0","0","0","0","0" +"Features/DataQuality/TestSuiteListAfterReindex.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestSuiteListAfterReindex.spec.ts","spec","true","0","1","1","1","950","0","0","0","0","0","0","0","0","0","1","1","950","0","0","0" +"Features/DataQuality/TestSuiteSummaryAfterReindex.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/TestSuiteSummaryAfterReindex.spec.ts","spec","true","0","1","1","1","859","0","0","0","0","0","0","0","0","0","1","1","859","0","0","0" +"Features/DescriptionSuggestion.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DescriptionSuggestion.spec.ts","spec","true","0","7","7","7","161702","0","0","0","0","0","0","0","0","0","0","0","0","7","7","161702" +"Features/DomainFilterQueryFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainFilterQueryFilter.spec.ts","spec","true","0","13","13","13","480556","0","0","0","11","11","393205","0","0","0","1","1","53678","1","1","33673" +"Features/DomainIsolation/DomainDropdownIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainDropdownIsolation.spec.ts","spec","true","0","2","2","2","13300","0","0","0","0","0","0","0","0","0","0","0","0","2","2","13300" +"Features/DomainIsolation/DomainIncidentIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainIncidentIsolation.spec.ts","spec","true","0","2","2","2","14719","0","0","0","0","0","0","0","0","0","0","0","0","2","2","14719" +"Features/DomainIsolation/DomainLineageIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainLineageIsolation.spec.ts","spec","true","0","3","3","3","24981","0","0","0","0","0","0","0","0","0","0","0","0","3","3","24981" +"Features/DomainIsolation/DomainListingIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainListingIsolation.spec.ts","spec","true","0","3","3","3","20347","0","0","0","0","0","0","0","0","0","0","0","0","3","3","20347" +"Features/DomainIsolation/DomainSearchIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainSearchIsolation.spec.ts","spec","true","0","3","3","3","12041","0","0","0","0","0","0","0","0","0","3","3","12041","0","0","0" +"Features/DomainIsolation/DomainTaskIsolation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainIsolation/DomainTaskIsolation.spec.ts","spec","true","0","3","3","3","10097","0","0","0","0","0","0","0","0","0","3","3","10097","0","0","0" +"Features/DomainTierCertificationVoting.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainTierCertificationVoting.spec.ts","spec","true","0","8","8","8","98455","2","2","18970","6","6","79485","0","0","0","0","0","0","0","0","0" +"Features/EntityRenameConsolidation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/EntityRenameConsolidation.spec.ts","spec","true","0","9","9","9","154063","0","0","0","0","0","0","0","0","0","0","0","0","9","9","154063" +"Features/EntityRightCollapsablePanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/EntityRightCollapsablePanel.spec.ts","spec","true","0","1","1","1","18506","1","1","18506","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/EntitySummaryPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/EntitySummaryPanel.spec.ts","spec","true","0","9","9","19","212679","8","18","195096","1","1","17583","0","0","0","0","0","0","0","0","0" +"Features/ExploreFilterComposition.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreFilterComposition.spec.ts","spec","true","0","7","7","7","190682","0","0","0","7","7","190682","0","0","0","0","0","0","0","0","0" +"Features/ExploreQueryBar.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQueryBar.spec.ts","spec","true","0","3","3","3","31399","3","3","31399","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ExploreQuickFilters.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreQuickFilters.spec.ts","spec","true","0","17","17","17","218601","10","10","104363","7","7","114238","0","0","0","0","0","0","0","0","0" +"Features/ExploreSortOrderFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreSortOrderFilter.spec.ts","spec","true","0","1","1","17","287515","0","0","0","1","17","287515","0","0","0","0","0","0","0","0","0" +"Features/ExploreUrlState.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreUrlState.spec.ts","spec","true","0","7","7","7","164810","4","4","81489","3","3","83321","0","0","0","0","0","0","0","0","0" +"Features/FailedTestCaseSampleData.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/FailedTestCaseSampleData.spec.ts","spec","true","0","2","2","2","15508","1","1","6006","1","1","9502","0","0","0","0","0","0","0","0","0" +"Features/GlobalPageSize.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/GlobalPageSize.spec.ts","spec","true","0","1","1","1","32060","0","0","0","0","0","0","0","0","0","0","0","0","1","1","32060" +"Features/GlobalSearchSuggestions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/GlobalSearchSuggestions.spec.ts","spec","true","0","1","1","1","13964","1","1","13964","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryAdvancedOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryAdvancedOperations.spec.ts","spec","true","0","28","28","28","436340","4","4","51562","24","24","384778","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryApprovalAfterMove.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryApprovalAfterMove.spec.ts","spec","true","0","2","2","2","63776","0","0","0","0","0","0","0","0","0","0","0","0","2","2","63776" +"Features/Glossary/GlossaryAssets.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryAssets.spec.ts","spec","true","0","10","10","10","173404","4","4","60429","6","6","112975","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryBulkOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryBulkOperations.spec.ts","spec","true","0","4","4","4","57778","4","4","57778","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryCRUDOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryCRUDOperations.spec.ts","spec","true","0","13","13","13","116849","7","7","59033","6","6","57816","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryExpandAllWithStatusFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryExpandAllWithStatusFilter.spec.ts","spec","true","0","4","4","4","43259","4","4","43259","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryHierarchy.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryHierarchy.spec.ts","spec","true","0","7","7","6","129475","2","2","37496","0","0","0","1","1","12022","0","0","0","4","3","79957" +"Features/Glossary/GlossaryInheritedReviewerApproval.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryInheritedReviewerApproval.spec.ts","spec","true","0","2","2","2","21880","0","0","0","0","0","0","0","0","0","0","0","0","2","2","21880" +"Features/Glossary/GlossaryMiscOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryMiscOperations.spec.ts","spec","true","0","5","5","5","148736","0","0","0","0","0","0","1","1","11525","0","0","0","4","4","137211" +"Features/Glossary/GlossaryMutualExclusivity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryMutualExclusivity.spec.ts","spec","true","0","11","11","11","239187","8","8","171504","3","3","67683","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryMutualExclusivityDataProductTree.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryMutualExclusivityDataProductTree.spec.ts","spec","true","0","7","7","7","126891","6","6","109780","1","1","17111","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryNavigation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryNavigation.spec.ts","spec","true","0","9","9","9","122880","9","9","122880","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryP2Tests.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryP2Tests.spec.ts","spec","true","0","5","5","5","91675","3","3","56472","2","2","35203","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryP3Tests.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryP3Tests.spec.ts","spec","true","0","20","20","20","129551","11","11","80642","1","1","6356","1","1","7561","6","6","23960","1","1","11032" +"Features/Glossary/GlossaryPagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryPagination.spec.ts","spec","true","0","6","6","6","43676","3","3","17121","3","3","26555","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryPersonaCustomization.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryPersonaCustomization.spec.ts","spec","true","0","3","3","3","31643","2","2","11385","1","1","20258","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryRelationsGraph.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryRelationsGraph.spec.ts","spec","true","0","17","17","17","231633","4","4","54955","4","4","52957","9","9","123721","0","0","0","0","0","0" +"Features/Glossary/GlossaryRelationsGraphPerf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryRelationsGraphPerf.spec.ts","spec","true","0","1","1","1","14065","1","1","14065","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryRemoveOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryRemoveOperations.spec.ts","spec","true","0","6","6","6","119495","0","0","0","6","6","119495","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryStatusFilterLargeDataset.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryStatusFilterLargeDataset.spec.ts","spec","true","0","19","19","19","188279","3","3","28703","14","14","141831","1","1","8461","0","0","0","1","1","9284" +"Features/Glossary/GlossaryStatusFilterNestedTerms.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryStatusFilterNestedTerms.spec.ts","spec","true","0","15","15","15","147289","1","1","8817","14","14","138472","0","0","0","0","0","0","0","0","0" +"Features/Glossary/GlossaryTermDetails.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryTermDetails.spec.ts","spec","true","0","7","7","7","103734","0","0","0","5","5","73076","0","0","0","0","0","0","2","2","30658" +"Features/Glossary/GlossaryTermInverseRelation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryTermInverseRelation.spec.ts","spec","true","0","4","4","4","56780","0","0","0","2","2","21432","0","0","0","0","0","0","2","2","35348" +"Features/Glossary/GlossaryTermRelatedTerms.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryTermRelatedTerms.spec.ts","spec","true","0","6","6","6","95239","1","1","16161","3","3","40685","0","0","0","0","0","0","2","2","38393" +"Features/Glossary/GlossaryTermRelationsGraph.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryTermRelationsGraph.spec.ts","spec","true","0","12","12","12","196624","2","2","34968","2","2","32081","8","8","129575","0","0","0","0","0","0" +"Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts","spec","true","0","4","4","4","46604","0","0","0","2","2","21993","2","2","24611","0","0","0","0","0","0" +"Features/Glossary/GlossaryVoting.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryVoting.spec.ts","spec","true","0","3","3","3","56530","0","0","0","2","2","35954","0","0","0","0","0","0","1","1","20576" +"Features/Glossary/GlossaryWorkflow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryWorkflow.spec.ts","spec","true","0","10","10","10","226974","4","4","106298","1","1","22543","0","0","0","0","0","0","5","5","98133" +"Features/Glossary/LargeGlossaryPerformance.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/LargeGlossaryPerformance.spec.ts","spec","true","0","9","9","9","111117","6","6","76789","1","1","13458","1","1","6343","0","0","0","1","1","14527" +"Features/ImpactAnalysis.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ImpactAnalysis.spec.ts","spec","true","0","23","23","23","386906","7","7","103346","16","16","283560","0","0","0","0","0","0","0","0","0" +"Features/IncidentManager.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/IncidentManager.spec.ts","spec","true","0","5","5","5","98619","0","0","0","2","2","18282","0","0","0","0","0","0","3","3","80337" +"Features/IncidentManagerPagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/IncidentManagerPagination.spec.ts","spec","true","0","2","2","2","20759","2","2","20759","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/IngestionListNameSorting.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/IngestionListNameSorting.spec.ts","spec","true","0","2","2","2","14842","0","0","0","2","2","14842","0","0","0","0","0","0","0","0","0" +"Features/KnowledgeGraph.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/KnowledgeGraph.spec.ts","spec","true","0","6","6","0","0","5","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Features/LandingPageWidgets/DataAssetsWidget.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DataAssetsWidget.spec.ts","spec","true","0","1","1","7","63638","0","0","0","1","7","63638","0","0","0","0","0","0","0","0","0" +"Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts","spec","true","0","6","6","6","278951","1","1","20037","1","1","40813","0","0","0","0","0","0","4","4","218101" +"Features/LandingPageWidgets/DomainWidgetFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/DomainWidgetFilter.spec.ts","spec","true","0","2","2","2","46826","0","0","0","2","2","46826","0","0","0","0","0","0","0","0","0" +"Features/LandingPageWidgets/FollowingWidget.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LandingPageWidgets/FollowingWidget.spec.ts","spec","true","0","1","1","11","236129","0","0","0","0","0","0","0","0","0","0","0","0","1","11","236129" +"Features/LanguageOverride.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LanguageOverride.spec.ts","spec","true","0","1","1","1","13158","1","1","13158","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/LineageExportPNGSnapshot.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LineageExportPNGSnapshot.spec.ts","spec","true","0","1","1","1","13038","0","0","0","0","0","0","1","1","13038","0","0","0","0","0","0" +"Features/LineagePipelineAnnotator.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/LineagePipelineAnnotator.spec.ts","spec","true","0","4","4","4","22786","0","0","0","0","0","0","0","0","0","4","4","22786","0","0","0" +"Features/Markdown.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Markdown.spec.ts","spec","true","0","1","1","1","8814","1","1","8814","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/MetricBulkImportExportEdit.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/MetricBulkImportExportEdit.spec.ts","spec","true","0","24","24","24","226458","18","18","128045","3","3","40833","0","0","0","0","0","0","3","3","57580" +"Features/MetricCustomUnitFlow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/MetricCustomUnitFlow.spec.ts","spec","true","0","1","1","1","14362","0","0","0","1","1","14362","0","0","0","0","0","0","0","0","0" +"Features/MultipleRename.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/MultipleRename.spec.ts","spec","true","0","4","4","4","90856","0","0","0","0","0","0","0","0","0","0","0","0","4","4","90856" +"Features/MutuallyExclusiveColumnTags.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/MutuallyExclusiveColumnTags.spec.ts","spec","true","0","1","1","1","11982","0","0","0","1","1","11982","0","0","0","0","0","0","0","0","0" +"Features/NavigationBlocker.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/NavigationBlocker.spec.ts","spec","true","0","5","5","5","69089","4","4","53549","1","1","15540","0","0","0","0","0","0","0","0","0" +"Features/NestedColumnsExpandCollapse.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/NestedColumnsExpandCollapse.spec.ts","spec","true","0","4","4","11","121633","4","11","121633","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/OnlineUsers.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OnlineUsers.spec.ts","spec","true","0","7","7","7","65715","5","5","42354","1","1","5045","0","0","0","0","0","0","1","1","18316" +"Features/OntologyAiFlagRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyAiFlagRdf.spec.ts","spec","true","0","2","2","0","0","2","0","0","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/OntologyAuthoringRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyAuthoringRdf.spec.ts","spec","true","0","3","3","0","0","0","0","0","0","0","0","1","0","0","0","0","0","2","0","0" +"Features/OntologyConceptAttributesRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyConceptAttributesRdf.spec.ts","spec","true","0","9","9","0","0","2","0","0","0","0","0","0","0","0","6","0","0","1","0","0" +"Features/OntologyConceptRealizationRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyConceptRealizationRdf.spec.ts","spec","true","0","9","9","0","0","2","0","0","0","0","0","0","0","0","7","0","0","0","0","0" +"Features/OntologyDataExploreRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyDataExploreRdf.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Features/OntologyGovernanceRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyGovernanceRdf.spec.ts","spec","true","0","4","4","0","0","0","0","0","1","0","0","0","0","0","2","0","0","1","0","0" +"Features/OntologyImportFidelityRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyImportFidelityRdf.spec.ts","spec","true","0","6","6","0","0","0","0","0","0","0","0","0","0","0","6","0","0","0","0","0" +"Features/OntologyImportRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyImportRdf.spec.ts","spec","true","0","3","3","0","0","1","0","0","1","0","0","0","0","0","0","0","0","1","0","0" +"Features/OntologyImportRoundTripRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyImportRoundTripRdf.spec.ts","spec","true","0","3","3","0","0","0","0","0","0","0","0","0","0","0","3","0","0","0","0","0" +"Features/OntologyLibraryRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyLibraryRdf.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Features/OntologyQueryRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyQueryRdf.spec.ts","spec","true","0","5","5","0","0","0","0","0","2","0","0","0","0","0","2","0","0","1","0","0" +"Features/OntologyRbacRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyRbacRdf.spec.ts","spec","true","0","6","6","0","0","2","0","0","1","0","0","0","0","0","2","0","0","1","0","0" +"Features/OntologyStudio.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudio.spec.ts","spec","true","0","7","7","7","61840","4","4","34578","3","3","27262","0","0","0","0","0","0","0","0","0" +"Features/OntologyStudioCardinality.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioCardinality.spec.ts","spec","true","0","10","10","10","78575","9","9","71374","1","1","7201","0","0","0","0","0","0","0","0","0" +"Features/OntologyStudioE2E.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioE2E.spec.ts","spec","true","0","15","15","15","118841","11","11","87566","1","1","7148","3","3","24127","0","0","0","0","0","0" +"Features/OntologyStudioIntegration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioIntegration.spec.ts","spec","true","0","7","7","7","55233","3","3","20838","3","3","25138","1","1","9257","0","0","0","0","0","0" +"Features/OntologyStudioInteractions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioInteractions.spec.ts","spec","true","0","9","9","9","85148","4","4","37686","2","2","17510","3","3","29952","0","0","0","0","0","0" +"Features/OntologyStudioIsolatedToggle.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioIsolatedToggle.spec.ts","spec","true","0","1","1","1","7948","0","0","0","1","1","7948","0","0","0","0","0","0","0","0","0" +"Features/OntologyStudioRdf.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/OntologyStudioRdf.spec.ts","spec","true","0","7","7","0","0","5","0","0","0","0","0","2","0","0","0","0","0","0","0","0" +"Features/Pagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Pagination.spec.ts","spec","true","0","35","35","35","430318","35","35","430318","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Permission.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permission.spec.ts","spec","true","0","1","1","1","106157","0","0","0","1","1","106157","0","0","0","0","0","0","0","0","0" +"Features/Permissions/DataProductPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/DataProductPermissions.spec.ts","spec","true","0","3","3","3","74953","3","3","74953","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Permissions/DomainPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/DomainPermissions.spec.ts","spec","true","0","2","2","2","55848","2","2","55848","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Permissions/EntityPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/EntityPermissions.spec.ts","spec","true","0","6","6","46","723999","6","46","723999","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Permissions/GlossaryPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/GlossaryPermissions.spec.ts","spec","true","0","9","9","9","284597","8","8","259404","0","0","0","0","0","0","0","0","0","1","1","25193" +"Features/Permissions/ServiceEntityPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/ServiceEntityPermissions.spec.ts","spec","true","0","7","7","44","559111","7","44","559111","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/PersonaAIContext.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaAIContext.spec.ts","spec","true","0","29","29","29","273458","25","25","234867","0","0","0","2","2","28550","1","1","605","1","1","9436" +"Features/PersonaAIContextPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaAIContextPermissions.spec.ts","spec","true","0","2","2","2","19005","2","2","19005","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/PersonaAIContextRuleCardAndStates.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaAIContextRuleCardAndStates.spec.ts","spec","true","0","6","6","6","50524","6","6","50524","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/PersonaAIContextRules.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaAIContextRules.spec.ts","spec","true","0","8","8","7","119663","4","3","46409","4","4","73254","0","0","0","0","0","0","0","0","0" +"Features/PersonaSessionPersistence.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaSessionPersistence.spec.ts","spec","true","0","2","2","2","27774","0","0","0","0","0","0","0","0","0","0","0","0","2","2","27774" +"Features/QueryEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/QueryEntity.spec.ts","spec","true","0","3","3","3","66265","2","2","32199","1","1","34066","0","0","0","0","0","0","0","0","0" +"Features/RTL.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/RTL.spec.ts","spec","true","0","2","2","2","29741","1","1","11403","0","0","0","0","0","0","0","0","0","1","1","18338" +"Features/RecentlyViewed.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/RecentlyViewed.spec.ts","spec","true","0","1","1","11","169370","0","0","0","0","0","0","0","0","0","0","0","0","1","11","169370" +"Features/RestoreEntityInheritedFields.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/RestoreEntityInheritedFields.spec.ts","spec","true","0","1","1","11","469818","0","0","0","0","0","0","0","0","0","0","0","0","1","11","469818" +"Features/SSOConfiguration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SSOConfiguration.spec.ts","spec","true","0","42","42","42","213725","42","42","213725","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/SSOTestLogin.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SSOTestLogin.spec.ts","spec","true","0","6","6","8","55514","6","8","55514","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/SampleDataDomainDataProduct.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SampleDataDomainDataProduct.spec.ts","spec","true","0","3","3","3","28503","0","0","0","0","0","0","0","0","0","0","0","0","3","3","28503" +"Features/SampleDataTableOperations.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SampleDataTableOperations.spec.ts","spec","true","0","11","11","11","151810","9","9","124446","1","1","13555","0","0","0","0","0","0","1","1","13809" +"Features/SchemaDefinition.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SchemaDefinition.spec.ts","spec","true","0","1","1","1","8503","1","1","8503","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/SchemaSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SchemaSearch.spec.ts","spec","true","0","1","1","1","5933","1","1","5933","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/SearchExport.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchExport.spec.ts","spec","true","0","7","7","7","97263","3","3","26461","0","0","0","0","0","0","0","0","0","4","4","70802" +"Features/SearchIndexNestedColumns.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchIndexNestedColumns.spec.ts","spec","true","0","1","1","1","7573","0","0","0","0","0","0","0","0","0","0","0","0","1","1","7573" +"Features/SearchSeparation/ApiEndpoint.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/ApiEndpoint.spec.ts","spec","true","0","0","2","2","54911","0","0","0","0","0","0","0","0","0","0","0","0","0","2","54911" +"Features/SearchSeparation/Container.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Container.spec.ts","spec","true","0","0","2","2","56718","0","0","0","0","0","0","0","0","0","0","0","0","0","2","56718" +"Features/SearchSeparation/Dashboard.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Dashboard.spec.ts","spec","true","0","0","2","2","49291","0","0","0","0","0","0","0","0","0","0","0","0","0","2","49291" +"Features/SearchSeparation/Database.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Database.spec.ts","spec","true","0","0","2","2","55718","0","0","0","0","0","0","0","0","0","0","0","0","0","2","55718" +"Features/SearchSeparation/DatabaseSchema.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/DatabaseSchema.spec.ts","spec","true","0","0","2","2","55542","0","0","0","0","0","0","0","0","0","0","0","0","0","2","55542" +"Features/SearchSeparation/DomainRenamePrefixCascade.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/DomainRenamePrefixCascade.spec.ts","spec","true","0","1","1","1","813","0","0","0","0","0","0","0","0","0","1","1","813","0","0","0" +"Features/SearchSeparation/ExploreFilterSeparation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/ExploreFilterSeparation.spec.ts","spec","true","0","0","2","2","59516","0","0","0","0","0","0","0","0","0","0","0","0","0","2","59516" +"Features/SearchSeparation/GlossaryRenameCascade.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/GlossaryRenameCascade.spec.ts","spec","true","0","1","1","1","1642","0","0","0","0","0","0","0","0","0","1","1","1642","0","0","0" +"Features/SearchSeparation/GlossaryRenamePrefixCascade.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/GlossaryRenamePrefixCascade.spec.ts","spec","true","0","1","1","1","989","0","0","0","0","0","0","0","0","0","1","1","989","0","0","0" +"Features/SearchSeparation/Metric.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Metric.spec.ts","spec","true","0","0","2","2","38900","0","0","0","0","0","0","0","0","0","0","0","0","0","2","38900" +"Features/SearchSeparation/MlModel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/MlModel.spec.ts","spec","true","0","0","2","2","52013","0","0","0","0","0","0","0","0","0","0","0","0","0","2","52013" +"Features/SearchSeparation/Pipeline.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Pipeline.spec.ts","spec","true","0","0","2","2","52159","0","0","0","0","0","0","0","0","0","0","0","0","0","2","52159" +"Features/SearchSeparation/StoredProcedure.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/StoredProcedure.spec.ts","spec","true","0","0","2","2","51712","0","0","0","0","0","0","0","0","0","0","0","0","0","2","51712" +"Features/SearchSeparation/Topic.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/Topic.spec.ts","spec","true","0","0","2","2","48683","0","0","0","0","0","0","0","0","0","0","0","0","0","2","48683" +"Features/ServiceAgentsDeploymentSummary.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ServiceAgentsDeploymentSummary.spec.ts","spec","true","0","5","5","5","25345","5","5","25345","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ServiceAgentsLiveProgress.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ServiceAgentsLiveProgress.spec.ts","spec","true","0","3","3","3","16863","0","0","0","0","0","0","0","0","0","0","0","0","3","3","16863" +"Features/ServiceAgentsPauseResume.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ServiceAgentsPauseResume.spec.ts","spec","true","0","1","1","1","5364","1","1","5364","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ServiceAgentsRefresh.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ServiceAgentsRefresh.spec.ts","spec","true","0","1","1","1","8375","1","1","8375","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/ServiceAgentsStatusDegradation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ServiceAgentsStatusDegradation.spec.ts","spec","true","0","4","4","4","20507","4","4","20507","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/SettingsNavigationPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SettingsNavigationPage.spec.ts","spec","true","0","8","8","8","154151","2","2","29383","3","3","66594","1","1","14391","0","0","0","2","2","43783" +"Features/StorageMetadataAgentForm.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/StorageMetadataAgentForm.spec.ts","spec","true","0","5","5","5","32392","2","2","11517","1","1","10684","2","2","10191","0","0","0","0","0","0" +"Features/StoredProcedureServiceBulkFetch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/StoredProcedureServiceBulkFetch.spec.ts","spec","true","0","1","1","1","758","0","0","0","0","0","0","0","0","0","1","1","758","0","0","0" +"Features/SystemCertificationTags.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SystemCertificationTags.spec.ts","spec","true","0","3","3","3","26938","0","0","0","3","3","26938","0","0","0","0","0","0","0","0","0" +"Features/Table.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Table.spec.ts","spec","true","0","15","15","14","241198","11","10","121024","3","3","87667","1","1","32507","0","0","0","0","0","0" +"Features/TableConstraint.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TableConstraint.spec.ts","spec","true","0","1","1","1","28966","0","0","0","1","1","28966","0","0","0","0","0","0","0","0","0" +"Features/TableSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TableSearch.spec.ts","spec","true","0","11","11","11","116069","0","0","0","11","11","116069","0","0","0","0","0","0","0","0","0" +"Features/TableSorting.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TableSorting.spec.ts","spec","true","0","11","11","11","106852","0","0","0","11","11","106852","0","0","0","0","0","0","0","0","0" +"Features/TagsSuggestion.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TagsSuggestion.spec.ts","spec","true","0","7","7","7","176477","0","0","0","0","0","0","0","0","0","0","0","0","7","7","176477" +"Features/Tasks.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks.spec.ts","spec","true","0","13","13","13","144072","6","6","87064","4","4","55246","0","0","0","3","3","1762","0","0","0" +"Features/Tasks/ActivityFeed.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/ActivityFeed.spec.ts","spec","true","0","17","17","17","214051","12","12","146816","5","5","67235","0","0","0","0","0","0","0","0","0" +"Features/Tasks/DomainFiltering.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/DomainFiltering.spec.ts","spec","true","0","8","8","8","61936","4","4","54819","1","1","7046","0","0","0","3","3","71","0","0","0" +"Features/Tasks/TaskAllEntities.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskAllEntities.spec.ts","spec","true","0","4","4","46","30700","0","0","0","0","0","0","0","0","0","4","46","30700","0","0","0" +"Features/Tasks/TaskAssigneeManagement.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskAssigneeManagement.spec.ts","spec","true","0","1","1","1","15305","0","0","0","0","0","0","0","0","0","0","0","0","1","1","15305" +"Features/Tasks/TaskComments.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskComments.spec.ts","spec","true","0","11","11","11","109970","2","2","20103","5","5","62511","2","2","27279","2","2","77","0","0","0" +"Features/Tasks/TaskContainerEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskContainerEntity.spec.ts","spec","true","0","5","5","5","2843","0","0","0","0","0","0","0","0","0","5","5","2843","0","0","0" +"Features/Tasks/TaskCreation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskCreation.spec.ts","spec","true","0","7","7","7","97453","1","1","12988","6","6","84465","0","0","0","0","0","0","0","0","0" +"Features/Tasks/TaskCustomFormWorkflow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskCustomFormWorkflow.spec.ts","spec","true","0","1","1","1","21097","0","0","0","0","0","0","0","0","0","0","0","0","1","1","21097" +"Features/Tasks/TaskDashboardEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskDashboardEntity.spec.ts","spec","true","0","7","7","7","23126","0","0","0","0","0","0","0","0","0","7","7","23126","0","0","0" +"Features/Tasks/TaskEntityResolution.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskEntityResolution.spec.ts","spec","true","0","7","7","7","5230","0","0","0","0","0","0","0","0","0","7","7","5230","0","0","0" +"Features/Tasks/TaskNavigation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskNavigation.spec.ts","spec","true","0","11","11","11","146842","9","9","103824","0","0","0","0","0","0","0","0","0","2","2","43018" +"Features/Tasks/TaskNestedFields.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskNestedFields.spec.ts","spec","true","0","6","6","6","3425","0","0","0","0","0","0","0","0","0","6","6","3425","0","0","0" +"Features/Tasks/TaskPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskPermissions.spec.ts","spec","true","0","13","13","13","101755","6","6","79250","0","0","0","0","0","0","7","7","22505","0","0","0" +"Features/Tasks/TaskPipelineEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskPipelineEntity.spec.ts","spec","true","0","5","5","5","3512","0","0","0","0","0","0","0","0","0","5","5","3512","0","0","0" +"Features/Tasks/TaskResolution.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskResolution.spec.ts","spec","true","0","9","9","9","81749","4","4","57322","1","1","14932","0","0","0","4","4","9495","0","0","0" +"Features/Tasks/TaskSuggestionAPIs.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskSuggestionAPIs.spec.ts","spec","true","0","7","7","7","3710","0","0","0","0","0","0","0","0","0","7","7","3710","0","0","0" +"Features/Tasks/TaskTopicEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TaskTopicEntity.spec.ts","spec","true","0","5","5","5","3013","0","0","0","0","0","0","0","0","0","5","5","3013","0","0","0" +"Features/Tasks/TeamActivity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/TeamActivity.spec.ts","spec","true","0","10","10","10","111415","7","7","79090","3","3","32325","0","0","0","0","0","0","0","0","0" +"Features/TeamSubscriptions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TeamSubscriptions.spec.ts","spec","true","0","17","17","17","204799","9","9","102835","7","7","86519","0","0","0","0","0","0","1","1","15445" +"Features/TeamsDragAndDrop.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TeamsDragAndDrop.spec.ts","spec","true","0","6","6","8","49676","0","0","0","1","1","12840","3","3","19012","0","0","0","2","4","17824" +"Features/TeamsHierarchy.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TeamsHierarchy.spec.ts","spec","true","0","3","3","3","36078","1","1","10175","1","1","15973","0","0","0","0","0","0","1","1","9930" +"Features/TestSuiteMultiPipeline.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TestSuiteMultiPipeline.spec.ts","spec","true","0","2","2","2","27868","0","0","0","1","1","8021","0","0","0","0","0","0","1","1","19847" +"Features/TestSuitePipelineRedeploy.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TestSuitePipelineRedeploy.spec.ts","spec","true","0","1","1","1","7807","0","0","0","0","0","0","0","0","0","0","0","0","1","1","7807" +"Features/TierDropdown.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/TierDropdown.spec.ts","spec","true","0","3","3","3","50681","0","0","0","3","3","50681","0","0","0","0","0","0","0","0","0" +"Features/Topic.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Topic.spec.ts","spec","true","0","4","4","4","43758","1","1","7886","0","0","0","3","3","35872","0","0","0","0","0","0" +"Features/UserProfileOnlineStatus.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/UserProfileOnlineStatus.spec.ts","spec","true","0","5","5","5","55825","3","3","25611","0","0","0","1","1","10151","0","0","0","1","1","20063" +"Features/Workflows/NoOpWorkflowNodeConfig.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Workflows/NoOpWorkflowNodeConfig.spec.ts","spec","true","0","2","2","2","25249","2","2","25249","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Workflows/RecognizerFeedbackSchemaNodeLock.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Workflows/RecognizerFeedbackSchemaNodeLock.spec.ts","spec","true","0","3","3","7","72219","3","7","72219","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Workflows/WorkflowExecutionHistoryEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Workflows/WorkflowExecutionHistoryEntity.spec.ts","spec","true","0","3","3","3","43283","3","3","43283","0","0","0","0","0","0","0","0","0","0","0","0" +"Features/Workflows/WorkflowOssRestrictions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Workflows/WorkflowOssRestrictions.spec.ts","spec","true","0","23","23","23","240738","23","23","240738","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/AddRoleAndAssignToUser.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/AddRoleAndAssignToUser.spec.ts","spec","true","0","3","3","3","25874","0","0","0","0","0","0","0","0","0","0","0","0","3","3","25874" +"Flow/ApiCollection.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ApiCollection.spec.ts","spec","true","0","1","1","1","47225","0","0","0","0","0","0","0","0","0","0","0","0","1","1","47225" +"Flow/ApiDocs.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ApiDocs.spec.ts","spec","true","0","1","1","1","6354","0","0","0","0","0","0","0","0","0","0","0","0","1","1","6354" +"Flow/ApiServiceRest.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ApiServiceRest.spec.ts","spec","true","0","1","1","1","13773","0","0","0","1","1","13773","0","0","0","0","0","0","0","0","0" +"Flow/AppBasic.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/AppBasic.spec.ts","spec","true","0","1","1","1","3288","0","0","0","0","0","0","0","0","0","1","1","3288","0","0","0" +"Flow/Collect.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Collect.spec.ts","spec","true","0","1","1","7","36498","1","7","36498","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/ConditionalPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ConditionalPermissions.spec.ts","spec","true","0","2","2","22","410173","0","0","0","0","0","0","0","0","0","0","0","0","2","22","410173" +"Flow/ConnectionConfigLayout.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ConnectionConfigLayout.spec.ts","spec","true","0","4","4","4","60227","2","2","40011","0","0","0","2","2","20216","0","0","0","0","0","0" +"Flow/CustomizeLandingPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeLandingPage.spec.ts","spec","true","0","4","4","4","87829","2","2","25855","1","1","45087","1","1","16887","0","0","0","0","0","0" +"Flow/CustomizeWidgets.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeWidgets.spec.ts","spec","true","0","9","9","9","540308","0","0","0","9","9","540308","0","0","0","0","0","0","0","0","0" +"Flow/ExploreAggregationCountsMatching.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreAggregationCountsMatching.spec.ts","spec","true","0","1","1","1","18131","0","0","0","1","1","18131","0","0","0","0","0","0","0","0","0" +"Flow/ExploreDiscovery.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ExploreDiscovery.spec.ts","spec","true","0","9","9","9","112190","0","0","0","8","8","88849","0","0","0","0","0","0","1","1","23341" +"Flow/FrequentlyJoined.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/FrequentlyJoined.spec.ts","spec","true","0","2","2","2","23941","2","2","23941","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/GlobalSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/GlobalSearch.spec.ts","spec","true","0","1","1","1","7098","0","0","0","1","1","7098","0","0","0","0","0","0","0","0","0" +"Flow/IngestionBot.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/IngestionBot.spec.ts","spec","true","0","1","1","1","133837","0","0","0","0","0","0","0","0","0","0","0","0","1","1","133837" +"Flow/LineageSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/LineageSettings.spec.ts","spec","true","0","3","3","3","88797","1","1","15173","0","0","0","0","0","0","0","0","0","2","2","73624" +"Flow/Metric.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Metric.spec.ts","spec","true","0","7","7","7","136106","0","0","0","7","7","136106","0","0","0","0","0","0","0","0","0" +"Flow/MetricListSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/MetricListSearch.spec.ts","spec","true","0","1","1","1","8593","0","0","0","1","1","8593","0","0","0","0","0","0","0","0","0" +"Flow/MetricSearch.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/MetricSearch.spec.ts","spec","true","0","1","1","1","7000","0","0","0","0","0","0","0","0","0","1","1","7000","0","0","0" +"Flow/Navbar.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts","spec","true","0","1","1","22","167981","1","22","167981","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/NestedChildrenUpdates.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/NestedChildrenUpdates.spec.ts","spec","true","0","6","6","36","472042","6","36","472042","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/NotificationAlerts.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/NotificationAlerts.spec.ts","spec","true","0","6","6","6","240510","0","0","0","5","5","177067","0","0","0","0","0","0","1","1","63443" +"Flow/ObservabilityAlerts.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ObservabilityAlerts.spec.ts","spec","true","0","5","5","8","292669","0","0","0","3","6","193105","0","0","0","0","0","0","2","2","99564" +"Flow/PersonaDeletionUserProfile.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/PersonaDeletionUserProfile.spec.ts","spec","true","0","1","1","1","20626","0","0","0","0","0","0","0","0","0","0","0","0","1","1","20626" +"Flow/PersonaFlow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/PersonaFlow.spec.ts","spec","true","0","11","11","11","160350","2","2","20099","8","8","91146","0","0","0","0","0","0","1","1","49105" +"Flow/PlatformLineage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/PlatformLineage.spec.ts","spec","true","0","1","1","1","68741","0","0","0","0","0","0","1","1","68741","0","0","0","0","0","0" +"Flow/SchemaTable.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/SchemaTable.spec.ts","spec","true","0","4","4","4","173696","0","0","0","1","1","85027","3","3","88669","0","0","0","0","0","0" +"Flow/SearchRBAC.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/SearchRBAC.spec.ts","spec","true","0","9","9","29","195037","0","0","0","1","1","14505","0","0","0","0","0","0","8","28","180532" +"Flow/ServiceCreationPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ServiceCreationPermissions.spec.ts","spec","true","0","8","8","8","75757","3","3","31320","5","5","44437","0","0","0","0","0","0","0","0","0" +"Flow/ServiceDocPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ServiceDocPanel.spec.ts","spec","true","0","14","14","14","128588","12","12","110654","0","0","0","2","2","17934","0","0","0","0","0","0" +"Flow/ServiceForm.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/ServiceForm.spec.ts","spec","true","0","9","9","9","54234","6","6","34840","2","2","13807","0","0","0","0","0","0","1","1","5587" +"Flow/TestConnectionModal.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/TestConnectionModal.spec.ts","spec","true","0","9","9","9","96347","9","9","96347","0","0","0","0","0","0","0","0","0","0","0","0" +"Flow/Tour.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Tour.spec.ts","spec","true","0","3","3","3","52676","0","0","0","0","0","0","0","0","0","0","0","0","3","3","52676" +"Flow/UsersPagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/UsersPagination.spec.ts","spec","true","0","1","1","1","7333","0","0","0","0","0","0","0","0","0","1","1","7333","0","0","0" +"Http2/SmokeH2.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Http2/SmokeH2.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"Pages/AppRunsHistoryLogs.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/AppRunsHistoryLogs.spec.ts","spec","true","0","1","1","1","10309","1","1","10309","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/AppStopRunModal.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/AppStopRunModal.spec.ts","spec","true","0","3","3","3","19047","3","3","19047","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/AssetHealthWidget.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/AssetHealthWidget.spec.ts","spec","true","0","6","6","6","74035","6","6","74035","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/AuditLogs.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/AuditLogs.spec.ts","spec","true","0","27","27","27","256559","16","16","113032","0","0","0","0","0","0","9","9","116227","2","2","27300" +"Pages/Bots.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Bots.spec.ts","spec","true","0","1","1","1","41338","0","0","0","0","0","0","0","0","0","0","0","0","1","1","41338" +"Pages/CSVImportWithQuotesAndCommas.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CSVImportWithQuotesAndCommas.spec.ts","spec","true","0","1","1","1","76163","0","0","0","0","0","0","0","0","0","0","0","0","1","1","76163" +"Pages/ClassificationConditionalRendering.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ClassificationConditionalRendering.spec.ts","spec","true","0","4","4","4","46042","4","4","46042","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/CustomProperties.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts","spec","true","0","60","60","173","3003123","24","88","1022072","32","81","1906204","4","4","74847","0","0","0","0","0","0" +"Pages/CustomPropertiesApiContract.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomPropertiesApiContract.spec.ts","spec","true","0","3","3","18","83647","0","0","0","0","0","0","0","0","0","3","18","83647","0","0","0" +"Pages/CustomThemeConfig.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomThemeConfig.spec.ts","spec","true","0","3","3","3","20921","1","1","6627","0","0","0","2","2","14294","0","0","0","0","0","0" +"Pages/DataContractInheritance.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContractInheritance.spec.ts","spec","true","0","8","8","8","250977","1","1","24314","3","3","91919","0","0","0","0","0","0","4","4","134744" +"Pages/DataContracts.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts","spec","true","0","14","14","48","2116042","5","5","102350","4","21","875267","0","0","0","2","2","105549","3","20","1032876" +"Pages/DataContractsSemanticRules.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContractsSemanticRules.spec.ts","spec","true","0","41","41","41","1262825","1","1","16672","0","0","0","0","0","0","40","40","1246153","0","0","0" +"Pages/DataInsight.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataInsight.spec.ts","spec","true","0","10","10","10","48102","6","6","29297","3","3","15544","0","0","0","1","1","3261","0","0","0" +"Pages/DataInsightReportApplication.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataInsightReportApplication.spec.ts","spec","true","0","4","4","4","33774","0","0","0","1","1","8151","0","0","0","0","0","0","3","3","25623" +"Pages/DataInsightSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataInsightSettings.spec.ts","spec","true","0","4","4","4","13015","0","0","0","1","1","4533","0","0","0","0","0","0","3","3","8482" +"Pages/DataMarketplace.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataMarketplace.spec.ts","spec","true","0","5","5","5","34164","3","3","19582","2","2","14582","0","0","0","0","0","0","0","0","0" +"Pages/DataMarketplaceAnnouncements.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataMarketplaceAnnouncements.spec.ts","spec","true","0","1","1","1","4939","1","1","4939","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/DataMarketplacePermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataMarketplacePermissions.spec.ts","spec","true","0","2","2","2","16228","2","2","16228","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/DataProductAndSubdomains.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataProductAndSubdomains.spec.ts","spec","true","0","18","18","18","208150","7","7","78829","10","10","116838","0","0","0","0","0","0","1","1","12483" +"Pages/DataProductCertificationFilter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataProductCertificationFilter.spec.ts","spec","true","0","4","4","4","35277","1","1","7776","3","3","27501","0","0","0","0","0","0","0","0","0" +"Pages/DataProductODPS.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataProductODPS.spec.ts","spec","true","0","10","10","10","54483","2","2","20949","2","2","22039","0","0","0","5","5","1026","1","1","10469" +"Pages/DataProducts.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataProducts.spec.ts","spec","true","0","9","9","9","124149","5","5","58275","3","3","40970","0","0","0","0","0","0","1","1","24904" +"Pages/DescriptionVisibility.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DescriptionVisibility.spec.ts","spec","true","0","9","9","9","107627","1","1","8821","0","0","0","8","8","98806","0","0","0","0","0","0" +"Pages/DomainAdvanced.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DomainAdvanced.spec.ts","spec","true","0","22","22","22","277050","7","7","74922","4","4","34928","2","2","20348","0","0","0","9","9","146852" +"Pages/DomainDataProductsRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DomainDataProductsRightPanel.spec.ts","spec","true","0","9","9","9","90467","5","5","47910","4","4","42557","0","0","0","0","0","0","0","0","0" +"Pages/DomainUIInteractions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DomainUIInteractions.spec.ts","spec","true","0","20","20","20","177446","9","9","73689","9","9","88107","1","1","8275","0","0","0","1","1","7375" +"Pages/Domains.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts","spec","true","0","47","47","47","1462792","8","8","150287","16","16","435794","3","3","61093","0","0","0","20","20","815618" +"Pages/EditClassification.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EditClassification.spec.ts","spec","true","0","2","2","2","27234","1","1","13104","1","1","14130","0","0","0","0","0","0","0","0","0" +"Pages/EmailConfiguration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EmailConfiguration.spec.ts","spec","true","0","1","1","1","5128","1","1","5128","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Entity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Entity.spec.ts","spec","true","0","37","37","353","7901108","12","48","841192","19","239","5397125","3","18","254874","0","0","0","3","48","1407917" +"Pages/EntityDataConsumer.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityDataConsumer.spec.ts","spec","true","0","12","12","143","2793585","2","17","306514","9","111","2018154","0","0","0","0","0","0","1","15","468917" +"Pages/EntityDataSteward.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityDataSteward.spec.ts","spec","true","0","13","13","158","2960184","0","0","0","12","143","2510269","0","0","0","0","0","0","1","15","449915" +"Pages/EntityHeaderBreadcrumb.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityHeaderBreadcrumb.spec.ts","spec","true","0","1","1","19","259762","1","19","259762","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/ExploreBrowse.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreBrowse.spec.ts","spec","true","0","11","11","11","113387","10","10","101416","1","1","11971","0","0","0","0","0","0","0","0","0" +"Pages/ExplorePageRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExplorePageRightPanel.spec.ts","spec","true","0","41","41","234","3196405","21","88","870772","17","116","1873557","0","0","0","0","0","0","3","30","452076" +"Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts","spec","true","0","22","22","21","272712","3","3","31505","16","15","184030","0","0","0","0","0","0","3","3","57177" +"Pages/ExploreResilience.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreResilience.spec.ts","spec","true","0","4","4","4","24822","4","4","24822","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/ExploreTree.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExploreTree.spec.ts","spec","true","0","14","14","14","154281","3","3","25374","4","4","36045","4","4","60777","2","2","10497","1","1","21588" +"Pages/Glossary.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Glossary.spec.ts","spec","true","0","45","45","45","907975","11","11","166623","17","17","285239","1","1","7702","0","0","0","16","16","448411" +"Pages/GlossaryFormValidation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/GlossaryFormValidation.spec.ts","spec","true","0","5","5","5","39900","4","4","32511","1","1","7389","0","0","0","0","0","0","0","0","0" +"Pages/GlossaryImportExport.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/GlossaryImportExport.spec.ts","spec","true","0","9","9","9","341827","0","0","0","0","0","0","0","0","0","0","0","0","9","9","341827" +"Pages/GlossaryTermRelationSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/GlossaryTermRelationSettings.spec.ts","spec","true","0","9","9","9","107238","4","4","46542","4","4","52445","0","0","0","1","1","8251","0","0","0" +"Pages/GlossaryTermRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/GlossaryTermRightPanel.spec.ts","spec","true","0","10","10","10","115782","4","4","40898","6","6","74884","0","0","0","0","0","0","0","0","0" +"Pages/HealthCheck.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/HealthCheck.spec.ts","spec","true","0","1","1","1","3962","0","0","0","0","0","0","0","0","0","0","0","0","1","1","3962" +"Pages/IngestionLogStreamLive.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/IngestionLogStreamLive.spec.ts","spec","true","0","1","1","1","3516","0","0","0","0","0","0","0","0","0","0","0","0","1","1","3516" +"Pages/InputOutputPorts.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/InputOutputPorts.spec.ts","spec","true","0","43","43","43","462783","27","27","253665","12","12","168294","3","3","29061","0","0","0","1","1","11763" +"Pages/IntakeForm.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/IntakeForm.spec.ts","spec","true","0","14","14","20","118262","7","7","44757","6","10","60432","0","0","0","0","0","0","1","3","13073" +"Pages/LearningResources.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/LearningResources.spec.ts","spec","true","0","13","13","13","81928","11","11","61890","1","1","9066","0","0","0","0","0","0","1","1","10972" +"Pages/Lineage/DataAssetLineage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/DataAssetLineage.spec.ts","spec","true","0","8","8","85","5925790","6","6","68118","0","0","0","0","0","0","0","0","0","2","79","5857672" +"Pages/Lineage/LineageControls.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageControls.spec.ts","spec","true","0","8","8","8","101622","8","8","101622","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Lineage/LineageFilters.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageFilters.spec.ts","spec","true","0","12","12","15","599269","1","1","10623","11","14","588646","0","0","0","0","0","0","0","0","0" +"Pages/Lineage/LineageInteraction.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageInteraction.spec.ts","spec","true","0","17","17","16","330263","12","11","207261","2","2","36088","0","0","0","0","0","0","3","3","86914" +"Pages/Lineage/LineageNodePagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageNodePagination.spec.ts","spec","true","0","5","5","5","43693","5","5","43693","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Lineage/LineageRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageRightPanel.spec.ts","spec","true","0","2","2","17","153399","2","17","153399","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Lineage/PlatformLineage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/PlatformLineage.spec.ts","spec","true","0","4","4","4","44887","3","3","26788","1","1","18099","0","0","0","0","0","0","0","0","0" +"Pages/LiveIndexingTab.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/LiveIndexingTab.spec.ts","spec","true","0","4","4","4","22926","4","4","22926","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Login.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Login.spec.ts","spec","true","0","5","5","5","316169","2","2","14678","0","0","0","0","0","0","0","0","0","3","3","301491" +"Pages/LoginConfiguration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/LoginConfiguration.spec.ts","spec","true","0","2","2","2","13065","0","0","0","2","2","13065","0","0","0","0","0","0","0","0","0" +"Pages/LogsViewer.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/LogsViewer.spec.ts","spec","true","0","1","1","1","9968","1","1","9968","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/ODCSImportExport.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ODCSImportExport.spec.ts","spec","true","0","47","47","47","330007","16","16","104869","6","6","40149","0","0","0","0","0","0","25","25","184989" +"Pages/ODCSImportExportPermissions.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ODCSImportExportPermissions.spec.ts","spec","true","0","13","13","13","130436","5","5","51506","0","0","0","5","5","48739","1","1","6286","2","2","23905" +"Pages/OmdURLConfiguration.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/OmdURLConfiguration.spec.ts","spec","true","0","2","2","2","13773","1","1","7492","1","1","6281","0","0","0","0","0","0","0","0","0" +"Pages/PipelineExecution.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/PipelineExecution.spec.ts","spec","true","0","1","1","1","9542","1","1","9542","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/PipelineValidation.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/PipelineValidation.spec.ts","spec","true","0","2","2","2","51","0","0","0","0","0","0","0","0","0","2","2","51","0","0","0" +"Pages/Policies.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Policies.spec.ts","spec","true","0","3","3","3","38204","1","1","7278","1","1","11700","0","0","0","0","0","0","1","1","19226" +"Pages/ProfilerConfigurationPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ProfilerConfigurationPage.spec.ts","spec","true","0","3","3","3","28453","3","3","28453","0","0","0","0","0","0","0","0","0","0","0","0" +"Pages/Roles.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Roles.spec.ts","spec","true","0","2","2","2","42000","0","0","0","1","1","13768","0","0","0","0","0","0","1","1","28232" +"Pages/SearchIndexApplication.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SearchIndexApplication.spec.ts","spec","true","0","1","1","1","125436","0","0","0","0","0","0","0","0","0","0","0","0","1","1","125436" +"Pages/SearchSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SearchSettings.spec.ts","spec","true","0","11","11","11","108056","4","4","36734","7","7","71322","0","0","0","0","0","0","0","0","0" +"Pages/ServiceEntity.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ServiceEntity.spec.ts","spec","true","0","14","14","135","2712805","1","9","102658","11","112","2189427","0","0","0","0","0","0","2","14","420720" +"Pages/ServiceListing.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ServiceListing.spec.ts","spec","true","0","4","4","4","36540","2","2","11350","2","2","25190","0","0","0","0","0","0","0","0","0" +"Pages/SubDomainPagination.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/SubDomainPagination.spec.ts","spec","true","0","1","1","1","16188","0","0","0","1","1","16188","0","0","0","0","0","0","0","0","0" +"Pages/Tag.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Tag.spec.ts","spec","true","0","21","21","21","576055","8","8","134056","12","12","382726","0","0","0","0","0","0","1","1","59273" +"Pages/TagPageRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TagPageRightPanel.spec.ts","spec","true","0","11","11","11","132579","5","5","43131","6","6","89448","0","0","0","0","0","0","0","0","0" +"Pages/Tags.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Tags.spec.ts","spec","true","0","6","6","6","134263","1","1","16754","4","4","50766","0","0","0","0","0","0","1","1","66743" +"Pages/TaskComments.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TaskComments.spec.ts","spec","true","0","10","10","10","29856","1","1","9687","0","0","0","0","0","0","9","9","20169","0","0","0" +"Pages/TaskFormSettings.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TaskFormSettings.spec.ts","spec","true","0","2","2","2","28672","1","1","11150","1","1","17522","0","0","0","0","0","0","0","0","0" +"Pages/Tasks.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Tasks.spec.ts","spec","true","0","9","9","9","1339","0","0","0","0","0","0","0","0","0","9","9","1339","0","0","0" +"Pages/TasksUIFlow.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TasksUIFlow.spec.ts","spec","true","0","6","6","12","309294","0","0","0","0","0","0","0","0","0","0","0","0","6","12","309294" +"Pages/TeamAssetsRightPanel.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TeamAssetsRightPanel.spec.ts","spec","true","0","10","10","10","114211","4","4","38205","6","6","76006","0","0","0","0","0","0","0","0","0" +"Pages/Teams.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Teams.spec.ts","spec","true","0","21","21","21","342722","5","5","66206","12","12","199187","0","0","0","0","0","0","4","4","77329" +"Pages/TestSuite.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuite.spec.ts","spec","true","0","2","2","2","38053","1","1","9387","0","0","0","0","0","0","0","0","0","1","1","28666" +"Pages/TestSuiteDetailsPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestSuiteDetailsPage.spec.ts","spec","true","0","1","1","0","0","0","0","0","1","0","0","0","0","0","0","0","0","0","0","0" +"Pages/UserCreationWithPersona.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/UserCreationWithPersona.spec.ts","spec","true","0","1","1","1","11532","0","0","0","1","1","11532","0","0","0","0","0","0","0","0","0" +"Pages/UserDetails.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/UserDetails.spec.ts","spec","true","0","9","9","9","89127","2","2","18534","6","6","61313","0","0","0","0","0","0","1","1","9280" +"Pages/Users.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Users.spec.ts","spec","true","0","28","28","28","500774","11","11","133215","11","11","157229","0","0","0","0","0","0","6","6","210330" +"Search/SearchNightly.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Search/SearchNightly.spec.ts","spec","true","0","1","1","1","4411","1","1","4411","0","0","0","0","0","0","0","0","0","0","0","0" +"Search/SearchRelevance.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Search/SearchRelevance.spec.ts","spec","true","0","11","11","11","48870","2","2","11811","2","2","13811","0","0","0","7","7","23248","0","0","0" +"VersionPages/ClassificationVersionPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/ClassificationVersionPage.spec.ts","spec","true","0","1","1","1","15811","0","0","0","1","1","15811","0","0","0","0","0","0","0","0","0" +"VersionPages/EntityVersionPages.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/EntityVersionPages.spec.ts","spec","true","0","5","5","18","605244","4","4","71977","0","0","0","0","0","0","0","0","0","1","14","533267" +"VersionPages/GlossaryVersionPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/GlossaryVersionPage.spec.ts","spec","true","0","7","7","7","128735","5","5","54737","2","2","73998","0","0","0","0","0","0","0","0","0" +"VersionPages/MetricVersionPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/MetricVersionPage.spec.ts","spec","true","0","2","2","2","13091","2","2","13091","0","0","0","0","0","0","0","0","0","0","0","0" +"VersionPages/ServiceEntityVersionPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/ServiceEntityVersionPage.spec.ts","spec","true","0","1","1","12","310832","0","0","0","0","0","0","0","0","0","0","0","0","1","12","310832" +"VersionPages/TestCaseVersionPage.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VersionPages/TestCaseVersionPage.spec.ts","spec","true","0","1","1","1","16799","0","0","0","1","1","16799","0","0","0","0","0","0","0","0","0" +"VisualRegression/entityDetails.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VisualRegression/entityDetails.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","1","0","0","0","0","0","0","0","0" +"VisualRegression/interactiveStates.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VisualRegression/interactiveStates.spec.ts","spec","true","0","2","2","0","0","0","0","0","0","0","0","2","0","0","0","0","0","0","0","0" +"VisualRegression/staticPages.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/VisualRegression/staticPages.spec.ts","spec","true","0","2","2","0","0","0","0","0","0","0","0","2","0","0","0","0","0","0","0","0" +"nightly/AutoClassification.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/nightly/AutoClassification.spec.ts","spec","true","0","1","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","0","0" +"nightly/ContextCenter.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/nightly/ContextCenter.spec.ts","spec","true","0","8","8","0","0","1","0","0","0","0","0","1","0","0","1","0","0","5","0","0" +"nightly/ServiceIngestion.spec.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/nightly/ServiceIngestion.spec.ts","spec","true","0","9","9","0","0","5","0","0","0","0","0","0","0","0","0","0","0","4","0","0" +"Features/SearchSeparation/SearchSeparationSuite.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SearchSeparation/SearchSeparationSuite.ts","supporting-product-definition","true","0","2","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2","0","0" +"bundle.smoke.ts","openmetadata-ui/src/main/resources/ui/playwright/e2e/bundle.smoke.ts","supporting-product-definition","true","0","1","0","0","0","0","0","0","0","0","0","1","0","0","0","0","0","0","0","0" diff --git a/docs/testing/playwright-migration/evidence/all-queue-cases.csv.gz b/docs/testing/playwright-migration/evidence/all-queue-cases.csv.gz new file mode 100644 index 000000000000..c0815f8d6d7a Binary files /dev/null and b/docs/testing/playwright-migration/evidence/all-queue-cases.csv.gz differ diff --git a/docs/testing/playwright-migration/evidence/all-spec-instances.csv.gz b/docs/testing/playwright-migration/evidence/all-spec-instances.csv.gz new file mode 100644 index 000000000000..eb5705aa8bbc Binary files /dev/null and b/docs/testing/playwright-migration/evidence/all-spec-instances.csv.gz differ diff --git a/docs/testing/playwright-migration/evidence/queue-daily-outcomes.csv b/docs/testing/playwright-migration/evidence/queue-daily-outcomes.csv new file mode 100644 index 000000000000..b7395072cf3c --- /dev/null +++ b/docs/testing/playwright-migration/evidence/queue-daily-outcomes.csv @@ -0,0 +1,9 @@ +"date","success","failure","cancelled","in_progress" +"2026-09-02","88","83","0","0" +"2026-09-03","82","140","1","0" +"2026-09-04","114","114","0","0" +"2026-09-05","82","74","0","0" +"2026-09-06","10","6","0","0" +"2026-09-07","126","49","1","0" +"2026-09-08","109","98","0","0" +"2026-09-09","120","34","0","5" diff --git a/docs/testing/playwright-migration/evidence/recent-queue-runs.csv b/docs/testing/playwright-migration/evidence/recent-queue-runs.csv new file mode 100644 index 000000000000..83c48c74504a --- /dev/null +++ b/docs/testing/playwright-migration/evidence/recent-queue-runs.csv @@ -0,0 +1,31 @@ +"id","date","gate","gateMinutes","shards","runnerMinutes","buildMinutes","planMinutes","prepareMinutes","fixtureRebuilt","summaryMinutes","passed","flaky","failed","infraCount","url" +"34355232120","2026-09-09T13:08:41Z","success","60.23","37","719.33","6.85","1.95","20.4","true","2.42","4485","4","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34355232120" +"34355229715","2026-09-09T13:08:40Z","success","57.67","37","716.18","5.98","1.63","20.23","true","2.5","4483","6","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34355229715" +"34355228351","2026-09-09T13:08:39Z","success","55.7","33","676.18","6.8","1.63","15.77","true","2.17","4483","6","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34355228351" +"34355226302","2026-09-09T13:08:38Z","success","53.98","37","705.5","6.72","1.98","16.5","true","2.57","4486","3","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34355226302" +"34355225816","2026-09-09T13:08:37Z","success","56.3","37","708.98","6.1","1.63","19.4","true","2.57","4483","6","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34355225816" +"34354609470","2026-09-09T13:02:39Z","failure","58.22","33","698.18","5.58","2.08","16.43","true","2.38","4483","5","1","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34354609470" +"34350140149","2026-09-09T12:17:11Z","success","74.57","36","703.45","6.63","1.98","18.73","true","2.27","4482","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350140149" +"34350138383","2026-09-09T12:17:10Z","success","69.93","36","698.77","6.8","1.6","16.97","true","2.45","4482","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350138383" +"34350137048","2026-09-09T12:17:09Z","success","63.97","36","701.17","6.7","1.73","16.53","true","2.18","4479","10","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350137048" +"34350134941","2026-09-09T12:17:08Z","success","72.97","36","707.45","6.62","1.7","17.22","true","2.58","4481","8","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350134941" +"34350132380","2026-09-09T12:17:06Z","success","62.83","36","694.08","6.17","1.57","16.43","true","2.67","4482","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350132380" +"34350084849","2026-09-09T12:16:36Z","success","66.87","36","707.3","6.17","1.78","17.47","true","1.78","4485","3","0","1","https://github.com/open-metadata/OpenMetadata/actions/runs/34350084849" +"34350083022","2026-09-09T12:16:35Z","success","62.77","36","697.08","5.97","1.92","16.38","true","2.53","4482","6","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350083022" +"34350081016","2026-09-09T12:16:33Z","failure","67.1","36","702.7","6.27","1.92","16.88","true","2.48","4479","8","1","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350081016" +"34350079167","2026-09-09T12:16:32Z","success","62.23","33","678.32","6.07","1.58","16.97","true","2.75","4478","10","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350079167" +"34350077252","2026-09-09T12:16:31Z","success","51.48","36","683.73","3.48","2.55","15.28","true","2.42","4481","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34350077252" +"34349824126","2026-09-09T12:13:51Z","failure","59.28","37","716.32","5.93","1.63","17.12","true","2.03","4475","11","1","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34349824126" +"34349680912","2026-09-09T12:12:22Z","success","56.42","36","706.38","7.82","1.93","15.17","true","2.42","4476","12","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34349680912" +"34349258398","2026-09-09T12:07:49Z","failure","59.38","36","697.02","8.82","2.17","18.2","true","2.05","4480","6","1","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34349258398" +"34349021136","2026-09-09T12:05:16Z","success","60.32","36","686.25","8.62","2.13","16.55","true","2.32","4481","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34349021136" +"34343850654","2026-09-09T11:07:08Z","success","58.05","36","690.83","6.28","1.6","16.93","true","2.62","4477","11","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343850654" +"34343847993","2026-09-09T11:07:07Z","success","66.48","36","696.12","6.13","1.57","23.05","true","2.65","4479","9","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343847993" +"34343846807","2026-09-09T11:07:06Z","success","64.68","36","682.1","6.57","1.92","18.43","true","2.65","4478","10","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343846807" +"34343844656","2026-09-09T11:07:05Z","failure","60.15","36","685.27","6.1","1.7","17.17","true","2.1","4483","4","1","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343844656" +"34343842775","2026-09-09T11:07:04Z","success","68.83","38","712.62","5.37","1.45","17.6","true","2.48","4482","6","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343842775" +"34343642414","2026-09-09T11:04:53Z","success","69.53","33","692.4","5.63","1.92","27.2","true","2.3","4481","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343642414" +"34343640117","2026-09-09T11:04:52Z","success","67.8","38","709.35","6.58","1.95","19.77","true","2.58","4480","8","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343640117" +"34343639544","2026-09-09T11:04:52Z","success","50.72","38","701.77","6.03","1.92","16.82","true","2.33","4481","7","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343639544" +"34343637075","2026-09-09T11:04:50Z","success","50.75","38","709.98","6.25","1.57","16.97","true","2.18","4484","4","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343637075" +"34343635876","2026-09-09T11:04:49Z","success","61.95","38","698.28","6.3","1.85","19.47","true","2.53","4483","5","0","0","https://github.com/open-metadata/OpenMetadata/actions/runs/34343635876" diff --git a/docs/testing/playwright-migration/evidence/repeated-test-failures.csv b/docs/testing/playwright-migration/evidence/repeated-test-failures.csv new file mode 100644 index 000000000000..cae1657a5ebf --- /dev/null +++ b/docs/testing/playwright-migration/evidence/repeated-test-failures.csv @@ -0,0 +1,26 @@ +"id","file","title","flaky","unexpected","runs" +"53b3e913ac628cc64131-2fe9c1b4e193b0e8a3c1","Pages/TasksUIFlow.spec.ts"," › chromium › Pages/TasksUIFlow.spec.ts › Tasks UI Flow - Multi Entity Tests › Create and resolve description task for Pipeline via UI","21","0","34355232120 34355228351 34354609470 34350140149 34350138383 34350134941 34350132380 34350084849 34350083022 34350081016 34350079167 34350077252 34349824126 34349680912 34349258398 34349021136 34343850654 34343847993 34343846807 34343844656 34343642414" +"2ad9a40f0bef94e8eb21-3536acf272fc1235a483","Flow/CustomizeWidgets.spec.ts"," › chromium › Flow/CustomizeWidgets.spec.ts › KPI Widget","5","0","34355229715 34355226302 34350083022 34350077252 34349680912" +"8b186e385bbdb2574005-42f94f41e925d9ccfe5b","Pages/ExplorePageRightPanel.spec.ts"," › chromium › Pages/ExplorePageRightPanel.spec.ts › Right Panel Test Suite › Explore page right panel tests › Overview panel - Deleted entity verification › Should verify deleted tag not visible in tag selection for searchIndex","4","0","34350140149 34350138383 34350137048 34350132380" +"877ab5ffd9592be99930-fec525a76b0cc14929bb","Features/DomainTierCertificationVoting.spec.ts"," › chromium › Features/DomainTierCertificationVoting.spec.ts › Domain & DataProduct - Tier, Certification, and Voting › Admin operations › Domain - Tier assign, update, and remove","4","0","34350084849 34343847993 34343844656 34343642414" +"8b186e385bbdb2574005-4043f9e1c36ea0ea6a60","Pages/ExplorePageRightPanel.spec.ts"," › chromium › Pages/ExplorePageRightPanel.spec.ts › Right Panel Test Suite › Explore page right panel tests › Overview panel - Deleted entity verification › Should verify deleted tag not visible in tag selection for container","4","0","34350077252 34349680912 34349258398 34343642414" +"877ab5ffd9592be99930-c82d83f43577ab6478e0","Features/DomainTierCertificationVoting.spec.ts"," › chromium › Features/DomainTierCertificationVoting.spec.ts › Domain & DataProduct - Tier, Certification, and Voting › Admin operations › Domain - Certification assign, update, and remove","3","0","34355228351 34343850654 34343846807" +"4c305ec854f9593f5dca-0acd98f891080c27eb0d","Features/DataQuality/TableLevelTests.spec.ts"," › chromium › Features/DataQuality/TableLevelTests.spec.ts › Table Level Data Quality Test Cases › Custom SQL Query","3","0","34350137048 34349680912 34349021136" +"bb377aba08770f6c0b47-1b8a5e65cdef61c06560","Features/OntologyStudioIntegration.spec.ts"," › chromium › Features/OntologyStudioIntegration.spec.ts › Ontology Studio - Data Mode Asset Cards › data mode renders tagged assets from the ontology data response","3","0","34350137048 34350079167 34343847993" +"d6fb355c03fdea638db7-305911a4b7881aaba0c1","Features/GlobalPageSize.spec.ts"," › chromium › Features/GlobalPageSize.spec.ts › Table & Data Model columns table pagination › Page size should persist across different pages","1","2","34350081016 34343844656 34343642414" +"b211ed4e71c38f212b54-c332ba9a2b88fe69b9cd","Pages/DataProductAndSubdomains.spec.ts"," › chromium › Pages/DataProductAndSubdomains.spec.ts › Data Product Comprehensive Tests › Create data product via UI with description","3","0","34350079167 34349824126 34343635876" +"20371b414745b84fa481-d2d654438df91f046bde","Features/IncidentManager.spec.ts"," › Ingestion › Features/IncidentManager.spec.ts › Incident Manager › Complete Incident lifecycle with table owner","3","0","34349680912 34343850654 34343637075" +"72d52555450cf448e344-083dec8015a3843e7cd2","Pages/Lineage/LineageInteraction.spec.ts"," › Basic › Pages/Lineage/LineageInteraction.spec.ts › Lineage Interactions › Verify cycle lineage should be handled properly","2","0","34355229715 34355226302" +"a4ae799e0b6b8a382617-4bc0e6edaa3ee5e42269","Features/Topic.spec.ts"," › chromium › Features/Topic.spec.ts › Topic entity specific tests › Copy field link should have valid URL format","2","0","34355228351 34343639544" +"53b3e913ac628cc64131-a6b2c6fca32681720e0d","Pages/TasksUIFlow.spec.ts"," › chromium › Pages/TasksUIFlow.spec.ts › Tasks UI Flow - Multi Entity Tests › Create and reject tag task for Dashboard via UI","2","0","34355225816 34350137048" +"dfe16293eef39cdaf975-b00abfec58cbc6f25ba5","Features/Glossary/GlossaryHierarchy.spec.ts"," › chromium › Features/Glossary/GlossaryHierarchy.spec.ts › Glossary Hierarchy › should cancel move operation","2","0","34355225816 34350140149" +"5a5bc63dc66e3147e5e8-39708973ea128903f12a","Pages/Domains.spec.ts"," › chromium › Pages/Domains.spec.ts › Domains › Verify domain and subdomain asset count accuracy","2","0","34350140149 34343842775" +"14bd5adb6df9a88c340f-6aef0428615488839b7e","Features/Glossary/GlossaryAdvancedOperations.spec.ts"," › chromium › Features/Glossary/GlossaryAdvancedOperations.spec.ts › Glossary Advanced Operations › should create glossary with multiple owners (users + teams)","2","0","34350138383 34350137048" +"8f00f316c6c46c156a1c-a506eaeb50a155ae247d","Features/ContextCenterMemories.spec.ts"," › chromium › Features/ContextCenterMemories.spec.ts › Context Center - Memories › Edit Memory — Each Field › editing memory type persists after save","2","0","34350138383 34350079167" +"c345246d55609214620c-b8223a97360afdf32065","Pages/DataContracts.spec.ts"," › chromium › Pages/DataContracts.spec.ts › Data Contracts With Persona Dashboard › Contract Status badge should be visible on condition if Contract Tab is present/hidden by Persona","2","0","34350138383 34350079167" +"8b186e385bbdb2574005-564cf22c841556fb5bfb","Pages/ExplorePageRightPanel.spec.ts"," › chromium › Pages/ExplorePageRightPanel.spec.ts › Right Panel Test Suite › Explore page right panel tests › Overview panel - Deleted entity verification › Should verify deleted tag not visible in tag selection for mlmodel","2","0","34350134941 34349824126" +"6f9684bba76ed22e1a8c-dcee5e388fad4727090e","Pages/DataContractsSemanticRules.spec.ts"," › chromium › Pages/DataContractsSemanticRules.spec.ts › Data Contracts Semantics Rule Description › Validate Description Rule Is_Set","2","0","34350132380 34343640117" +"9de335d5f17b18a6dcce-68f33945efb071cc7b3c","Features/ActivityFeed.spec.ts"," › chromium › Features/ActivityFeed.spec.ts › ActivityFeed: activity + conversation merge (regression #25894) › All badge, header and rendered list agree on the count","2","0","34350132380 34349680912" +"8b186e385bbdb2574005-cf77fd2cc064e138e21d","Pages/ExplorePageRightPanel.spec.ts"," › chromium › Pages/ExplorePageRightPanel.spec.ts › Right Panel Test Suite › Explore page right panel tests › Overview panel - Deleted entity verification › Should verify deleted glossary term not visible in selection for container","2","0","34350084849 34350081016" +"719a1c77382793645da8-e627170fb572721ecd2c","Pages/EntityDataConsumer.spec.ts"," › chromium › Pages/EntityDataConsumer.spec.ts › Topic › Tier Add, Update and Remove","2","0","34350081016 34343640117" +"5a5bc63dc66e3147e5e8-058d4f127752c8b36927","Pages/Domains.spec.ts"," › chromium › Pages/Domains.spec.ts › Domains › Verify duplicate domain creation","2","0","34350079167 34343642414" diff --git a/docs/testing/playwright-migration/evidence/representative-spec-costs.csv b/docs/testing/playwright-migration/evidence/representative-spec-costs.csv new file mode 100644 index 000000000000..c6f660aa7b16 --- /dev/null +++ b/docs/testing/playwright-migration/evidence/representative-spec-costs.csv @@ -0,0 +1,357 @@ +"file","tests","workerMinutes","retryWorkerMinutes" +"Pages/Entity.spec.ts","353","131.685","0.000" +"Pages/Lineage/DataAssetLineage.spec.ts","85","98.763","0.000" +"Pages/ExplorePageRightPanel.spec.ts","234","53.273","0.296" +"Pages/CustomProperties.spec.ts","173","50.052","0.000" +"Pages/EntityDataSteward.spec.ts","158","49.336","0.000" +"Pages/EntityDataConsumer.spec.ts","143","46.560","0.000" +"Features/AdvancedSearch.spec.ts","130","45.453","0.000" +"Pages/ServiceEntity.spec.ts","135","45.213","0.570" +"Pages/DataContracts.spec.ts","48","35.267","0.000" +"Features/BulkImport.spec.ts","6","24.900","0.000" +"Pages/Domains.spec.ts","47","24.380","0.000" +"Pages/DataContractsSemanticRules.spec.ts","41","21.047","0.650" +"Features/ContextCenterArticles.spec.ts","41","16.292","0.000" +"Pages/Glossary.spec.ts","45","15.133","0.000" +"Features/CuratedAssets.spec.ts","23","13.532","0.000" +"Features/DataAssetRulesDisabled.spec.ts","34","12.326","0.000" +"Features/Permissions/EntityPermissions.spec.ts","46","12.067","0.000" +"Features/AutoPilot.spec.ts","12","11.784","0.000" +"Features/CustomizeDetailPage.spec.ts","25","10.387","0.000" +"VersionPages/EntityVersionPages.spec.ts","18","10.087","0.000" +"Features/ContextCenterMemories.spec.ts","55","10.062","0.000" +"Pages/Lineage/LineageFilters.spec.ts","15","9.988","0.000" +"Pages/Tag.spec.ts","21","9.601","0.000" +"Features/SearchSeparation/SearchSeparationSuite.ts","22","9.586","0.000" +"Features/Permissions/ServiceEntityPermissions.spec.ts","44","9.319","0.000" +"Flow/CustomizeWidgets.spec.ts","9","9.005","0.000" +"Features/DataQuality/TestCaseImportExportE2eFlow.spec.ts","2","8.637","0.000" +"Pages/Users.spec.ts","28","8.346","0.000" +"Features/DomainFilterQueryFilter.spec.ts","13","8.009","0.000" +"Features/ContextCenterPermission.spec.ts","34","7.999","0.000" +"Flow/NestedChildrenUpdates.spec.ts","36","7.867","0.000" +"Features/RestoreEntityInheritedFields.spec.ts","11","7.830","0.000" +"Pages/InputOutputPorts.spec.ts","43","7.713","0.000" +"Features/ColumnBulkOperations.spec.ts","25","7.697","0.000" +"Features/DataAssetRulesEnabled.spec.ts","31","7.473","0.000" +"Features/Glossary/GlossaryAdvancedOperations.spec.ts","28","7.272","0.000" +"Features/DataQuality/DataQualityPermissions.spec.ts","25","7.269","0.000" +"Features/Pagination.spec.ts","35","7.172","0.000" +"Flow/ConditionalPermissions.spec.ts","22","6.836","0.000" +"Features/ImpactAnalysis.spec.ts","23","6.448","0.000" +"Features/ContextCenterDocument.spec.ts","30","6.160","0.000" +"Features/BulkEditEntity.spec.ts","6","5.883","0.000" +"Features/ActivityFeed.spec.ts","17","5.740","0.000" +"Pages/Teams.spec.ts","21","5.712","0.000" +"Pages/GlossaryImportExport.spec.ts","9","5.697","0.000" +"Pages/Lineage/LineageInteraction.spec.ts","16","5.504","0.000" +"Pages/ODCSImportExport.spec.ts","47","5.500","0.000" +"Pages/Login.spec.ts","5","5.269","0.000" +"VersionPages/ServiceEntityVersionPage.spec.ts","12","5.181","0.000" +"Pages/TasksUIFlow.spec.ts","12","5.155","0.514" +"Flow/ObservabilityAlerts.spec.ts","8","4.878","0.000" +"Features/ExploreSortOrderFilter.spec.ts","17","4.792","0.000" +"Features/DataQuality/ColumnLevelTests.spec.ts","16","4.745","0.000" +"Features/Permissions/GlossaryPermissions.spec.ts","9","4.743","0.000" +"Features/LandingPageWidgets/DomainDataProductsWidgets.spec.ts","6","4.649","0.000" +"Pages/DomainAdvanced.spec.ts","22","4.617","0.000" +"Features/PersonaAIContext.spec.ts","29","4.558","0.000" +"Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts","21","4.545","0.000" +"Features/BulkImportWithDotInName.spec.ts","8","4.520","0.000" +"Pages/EntityHeaderBreadcrumb.spec.ts","19","4.329","0.000" +"Pages/AuditLogs.spec.ts","27","4.276","0.000" +"Pages/DataContractInheritance.spec.ts","8","4.183","0.000" +"Features/Table.spec.ts","14","4.020","0.000" +"Features/Workflows/WorkflowOssRestrictions.spec.ts","23","4.012","0.000" +"Flow/NotificationAlerts.spec.ts","6","4.008","0.000" +"Features/Glossary/GlossaryMutualExclusivity.spec.ts","11","3.986","0.000" +"Features/LandingPageWidgets/FollowingWidget.spec.ts","11","3.935","0.000" +"Features/DataQuality/TestCaseResultPermissions.spec.ts","11","3.925","0.000" +"Features/Glossary/GlossaryRelationsGraph.spec.ts","17","3.861","0.000" +"Features/Glossary/GlossaryWorkflow.spec.ts","10","3.783","0.000" +"Features/MetricBulkImportExportEdit.spec.ts","24","3.774","0.000" +"Features/ExploreQuickFilters.spec.ts","17","3.643","0.000" +"Features/Tasks/ActivityFeed.spec.ts","17","3.568","0.000" +"Features/SSOConfiguration.spec.ts","42","3.562","0.000" +"Features/EntitySummaryPanel.spec.ts","19","3.545","0.000" +"Pages/DataProductAndSubdomains.spec.ts","18","3.469","0.000" +"Features/DataQuality/TestCaseImportExportBasic.spec.ts","24","3.442","0.000" +"Features/TeamSubscriptions.spec.ts","17","3.413","0.000" +"Features/DataQuality/TableLevelTests.spec.ts","8","3.411","0.000" +"Features/Glossary/GlossaryTermRelationsGraph.spec.ts","12","3.277","0.000" +"Flow/SearchRBAC.spec.ts","29","3.251","0.000" +"Features/DataQuality/DataQualityDashboard.spec.ts","11","3.247","0.000" +"Features/ExploreFilterComposition.spec.ts","7","3.178","0.000" +"Features/DataQuality/TestLibrary.spec.ts","15","3.161","0.000" +"Features/Glossary/GlossaryStatusFilterLargeDataset.spec.ts","19","3.138","0.000" +"Pages/DomainUIInteractions.spec.ts","20","2.957","0.000" +"Features/TagsSuggestion.spec.ts","7","2.941","0.000" +"Flow/SchemaTable.spec.ts","4","2.895","0.000" +"Features/Glossary/GlossaryAssets.spec.ts","10","2.890","0.000" +"Features/RecentlyViewed.spec.ts","11","2.823","0.000" +"Flow/Navbar.spec.ts","22","2.800","0.000" +"Features/ExploreUrlState.spec.ts","7","2.747","0.000" +"Features/DescriptionSuggestion.spec.ts","7","2.695","0.000" +"Flow/PersonaFlow.spec.ts","11","2.672","0.000" +"Features/ActivityAPI.spec.ts","10","2.616","0.000" +"Pages/ExploreTree.spec.ts","14","2.571","0.000" +"Features/SettingsNavigationPage.spec.ts","8","2.569","0.000" +"Features/EntityRenameConsolidation.spec.ts","9","2.568","0.000" +"Pages/Lineage/LineageRightPanel.spec.ts","17","2.557","0.000" +"Features/SampleDataTableOperations.spec.ts","11","2.530","0.000" +"Features/Glossary/GlossaryMiscOperations.spec.ts","5","2.479","0.000" +"Features/Glossary/GlossaryStatusFilterNestedTerms.spec.ts","15","2.455","0.000" +"Features/Tasks/TaskNavigation.spec.ts","11","2.447","0.000" +"Features/Tasks.spec.ts","13","2.401","0.000" +"Features/DataQuality/IncidentManagerDateFilter.spec.ts","11","2.381","0.000" +"Features/DataQuality/DataQuality.spec.ts","9","2.306","0.000" +"Features/BulkEditImportPermissions.spec.ts","4","2.290","0.000" +"Flow/Metric.spec.ts","7","2.268","0.000" +"Pages/Tags.spec.ts","6","2.238","0.000" +"Flow/IngestionBot.spec.ts","1","2.231","0.000" +"Pages/TagPageRightPanel.spec.ts","11","2.210","0.000" +"Pages/ODCSImportExportPermissions.spec.ts","13","2.174","0.000" +"Features/Glossary/GlossaryP3Tests.spec.ts","20","2.159","0.000" +"Features/Glossary/GlossaryHierarchy.spec.ts","6","2.158","0.000" +"VersionPages/GlossaryVersionPage.spec.ts","7","2.146","0.000" +"Flow/ServiceDocPanel.spec.ts","14","2.143","0.000" +"Features/Glossary/GlossaryMutualExclusivityDataProductTree.spec.ts","7","2.115","0.000" +"Features/ContextCenterDashboard.spec.ts","9","2.108","0.000" +"Pages/SearchIndexApplication.spec.ts","1","2.091","0.000" +"Pages/DataProducts.spec.ts","9","2.069","0.000" +"Features/Glossary/GlossaryNavigation.spec.ts","9","2.048","0.000" +"Features/NestedColumnsExpandCollapse.spec.ts","11","2.027","0.000" +"Features/BulkEditOperationBadges.spec.ts","6","2.017","0.000" +"Features/PersonaAIContextRules.spec.ts","7","1.994","0.000" +"Features/Glossary/GlossaryRemoveOperations.spec.ts","6","1.992","0.000" +"Features/OntologyStudioE2E.spec.ts","15","1.981","0.000" +"Pages/IntakeForm.spec.ts","20","1.971","0.000" +"Features/Glossary/GlossaryCRUDOperations.spec.ts","13","1.947","0.000" +"Features/TableSearch.spec.ts","11","1.934","0.000" +"Pages/GlossaryTermRightPanel.spec.ts","10","1.930","0.000" +"Pages/TeamAssetsRightPanel.spec.ts","10","1.904","0.000" +"Pages/ExploreBrowse.spec.ts","11","1.890","0.000" +"Features/CsvJobsTray.spec.ts","11","1.876","0.000" +"Features/ArticleReviewerWorkflow.spec.ts","1","1.870","0.000" +"Flow/ExploreDiscovery.spec.ts","9","1.870","0.000" +"Features/Tasks/TeamActivity.spec.ts","10","1.857","0.000" +"Features/Glossary/LargeGlossaryPerformance.spec.ts","9","1.852","0.000" +"Features/Tasks/TaskComments.spec.ts","11","1.833","0.000" +"Features/Container.spec.ts","12","1.816","0.000" +"Features/ChangeSummaryBadge.spec.ts","5","1.813","0.000" +"Pages/SearchSettings.spec.ts","11","1.801","0.000" +"Pages/DescriptionVisibility.spec.ts","9","1.794","0.000" +"Pages/GlossaryTermRelationSettings.spec.ts","9","1.787","0.000" +"Features/TableSorting.spec.ts","11","1.781","0.000" +"Features/Permission.spec.ts","1","1.769","0.000" +"Features/Glossary/GlossaryTermDetails.spec.ts","7","1.729","0.000" +"Features/DataProductRenameConsolidation.spec.ts","4","1.723","0.000" +"Features/Tasks/TaskPermissions.spec.ts","13","1.696","0.000" +"Pages/Lineage/LineageControls.spec.ts","8","1.694","0.000" +"Features/ActivityFeedTabBadge.spec.ts","4","1.673","0.000" +"Features/DataQuality/TestDefinitionPermissions.spec.ts","7","1.669","0.000" +"Features/DataProductRename.spec.ts","4","1.644","0.000" +"Features/IncidentManager.spec.ts","5","1.644","0.000" +"Features/DomainTierCertificationVoting.spec.ts","8","1.641","0.000" +"Features/ActivityStream.spec.ts","5","1.641","0.000" +"Features/Tasks/TaskCreation.spec.ts","7","1.624","0.000" +"Features/SearchExport.spec.ts","7","1.621","0.000" +"Features/DataQuality/DataObservabilityGovernanceTab.spec.ts","14","1.618","0.000" +"Flow/TestConnectionModal.spec.ts","9","1.606","0.000" +"Features/Glossary/GlossaryTermRelatedTerms.spec.ts","6","1.587","0.000" +"Features/Glossary/GlossaryP2Tests.spec.ts","5","1.528","0.000" +"Features/MultipleRename.spec.ts","4","1.514","0.000" +"Pages/DomainDataProductsRightPanel.spec.ts","9","1.508","0.000" +"Features/DataQuality/TestDefinitionFilters.spec.ts","7","1.498","0.000" +"Pages/UserDetails.spec.ts","9","1.485","0.000" +"Flow/LineageSettings.spec.ts","3","1.480","0.000" +"Flow/CustomizeLandingPage.spec.ts","4","1.464","0.000" +"Features/DataQuality/TestCaseIncidentPermissions.spec.ts","8","1.420","0.000" +"Features/OntologyStudioInteractions.spec.ts","9","1.419","0.000" +"Pages/CustomPropertiesApiContract.spec.ts","18","1.394","0.000" +"Features/AdvancedSearchSuggestions.spec.ts","9","1.367","0.000" +"Pages/LearningResources.spec.ts","13","1.365","0.000" +"Features/AppMode/AppModeResolver.spec.ts","6","1.364","0.000" +"Features/Tasks/TaskResolution.spec.ts","9","1.362","0.000" +"Features/OntologyStudioCardinality.spec.ts","10","1.310","0.000" +"Features/CertificationDropdown.spec.ts","4","1.270","0.000" +"Pages/CSVImportWithQuotesAndCommas.spec.ts","1","1.269","0.000" +"Flow/ServiceCreationPermissions.spec.ts","8","1.263","0.000" +"Features/Permissions/DataProductPermissions.spec.ts","3","1.249","0.000" +"Features/DataProductDomainMigration.spec.ts","3","1.241","0.000" +"Features/AppMode/AppModeSettings.spec.ts","6","1.241","0.000" +"Pages/AssetHealthWidget.spec.ts","6","1.234","0.000" +"Features/Workflows/RecognizerFeedbackSchemaNodeLock.spec.ts","7","1.204","0.000" +"Features/Announcements/AnnouncementEntity.spec.ts","3","1.181","0.000" +"Features/NavigationBlocker.spec.ts","5","1.151","0.000" +"Flow/PlatformLineage.spec.ts","1","1.146","0.000" +"Features/Dashboards.spec.ts","4","1.110","0.000" +"Features/QueryEntity.spec.ts","3","1.104","0.000" +"Features/OnlineUsers.spec.ts","7","1.095","0.000" +"Features/AppMode/AppModePrecedence.spec.ts","5","1.093","0.000" +"Features/Announcements/EntityHeaderAnnouncements.spec.ts","3","1.084","0.000" +"dataInsightApp.ts","1","1.077","0.000" +"Features/ColumnBulkOperationsTagsGlossary.spec.ts","2","1.075","0.000" +"Features/ContextCenterArchive.spec.ts","3","1.074","0.000" +"Features/Glossary/GlossaryApprovalAfterMove.spec.ts","2","1.063","0.000" +"Features/LandingPageWidgets/DataAssetsWidget.spec.ts","7","1.061","0.000" +"Features/DataQuality/AddTestCaseNewFlow.spec.ts","4","1.043","0.000" +"Features/Tasks/DomainFiltering.spec.ts","8","1.032","0.000" +"Features/OntologyStudio.spec.ts","7","1.031","0.000" +"Flow/ConnectionConfigLayout.spec.ts","4","1.004","0.000" +"Features/Glossary/GlossaryBulkOperations.spec.ts","4","0.963","0.000" +"Features/Glossary/GlossaryTermInverseRelation.spec.ts","4","0.946","0.000" +"Features/Glossary/GlossaryVoting.spec.ts","3","0.942","0.000" +"Features/Permissions/DomainPermissions.spec.ts","2","0.931","0.000" +"Features/UserProfileOnlineStatus.spec.ts","5","0.930","0.000" +"Features/SSOTestLogin.spec.ts","8","0.925","0.000" +"Features/OntologyStudioIntegration.spec.ts","7","0.921","0.000" +"Pages/DataProductODPS.spec.ts","10","0.908","0.000" +"Flow/ServiceForm.spec.ts","9","0.904","0.000" +"Flow/Tour.spec.ts","3","0.878","0.000" +"Features/TierDropdown.spec.ts","3","0.845","0.000" +"Features/PersonaAIContextRuleCardAndStates.spec.ts","6","0.842","0.000" +"Features/ColumnSorting.spec.ts","7","0.841","0.000" +"Features/CustomMetric.spec.ts","2","0.840","0.000" +"Features/DataQuality/Profiler.spec.ts","4","0.832","0.000" +"Features/TeamsDragAndDrop.spec.ts","8","0.828","0.000" +"Search/SearchRelevance.spec.ts","11","0.815","0.000" +"Pages/DataInsight.spec.ts","10","0.802","0.000" +"Features/DataQuality/ProfilerIngestionForm.spec.ts","7","0.796","0.000" +"Flow/ApiCollection.spec.ts","1","0.787","0.000" +"Features/LandingPageWidgets/DomainWidgetFilter.spec.ts","2","0.780","0.000" +"Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts","4","0.777","0.000" +"Pages/ClassificationConditionalRendering.spec.ts","4","0.767","0.000" +"Features/DataQuality/TestCaseSoftDeleteRestore.spec.ts","3","0.756","0.000" +"Pages/Lineage/PlatformLineage.spec.ts","4","0.748","0.000" +"Features/Topic.spec.ts","4","0.729","0.000" +"Pages/Lineage/LineageNodePagination.spec.ts","5","0.728","0.000" +"Features/Glossary/GlossaryPagination.spec.ts","6","0.728","0.000" +"Features/DataProductPersonaCustomization.spec.ts","2","0.724","0.000" +"Features/Workflows/WorkflowExecutionHistoryEntity.spec.ts","3","0.721","0.000" +"Features/Glossary/GlossaryExpandAllWithStatusFilter.spec.ts","4","0.721","0.000" +"Pages/Roles.spec.ts","2","0.700","0.000" +"Pages/Bots.spec.ts","1","0.689","0.000" +"Pages/GlossaryFormValidation.spec.ts","5","0.665","0.000" +"Pages/Policies.spec.ts","3","0.637","0.000" +"Features/DataQuality/IncidentManagerLocaleLayout.spec.ts","7","0.635","0.000" +"Pages/TestSuite.spec.ts","2","0.634","0.000" +"Features/CustomizeNavigationNewItems.spec.ts","2","0.622","0.000" +"Pages/ServiceListing.spec.ts","4","0.609","0.000" +"Flow/Collect.spec.ts","7","0.608","0.000" +"Features/TeamsHierarchy.spec.ts","3","0.601","0.000" +"Pages/DataProductCertificationFilter.spec.ts","4","0.588","0.000" +"Features/ClassificationImportExport.spec.ts","4","0.585","0.000" +"Features/DataQuality/BundleSuiteBulkOperations.spec.ts","3","0.577","0.000" +"Pages/DataMarketplace.spec.ts","5","0.569","0.000" +"Pages/DataInsightReportApplication.spec.ts","4","0.563","0.000" +"Features/DataQuality/CertificationFilter.spec.ts","4","0.560","0.000" +"Features/AppMode/AppModeRouteIsolation.spec.ts","2","0.552","0.000" +"Features/StorageMetadataAgentForm.spec.ts","5","0.540","0.000" +"Features/GlobalPageSize.spec.ts","1","0.534","0.000" +"Features/Glossary/GlossaryPersonaCustomization.spec.ts","3","0.527","0.000" +"Features/ExploreQueryBar.spec.ts","3","0.523","0.000" +"Features/Tasks/TaskAllEntities.spec.ts","46","0.512","0.000" +"Pages/TaskComments.spec.ts","10","0.498","0.000" +"Features/RTL.spec.ts","2","0.496","0.000" +"Features/TableConstraint.spec.ts","1","0.483","0.000" +"Pages/TaskFormSettings.spec.ts","2","0.478","0.000" +"Features/SampleDataDomainDataProduct.spec.ts","3","0.475","0.000" +"Pages/ProfilerConfigurationPage.spec.ts","3","0.474","0.000" +"Features/AppMode/AppModeCrossDevice.spec.ts","1","0.467","0.000" +"Features/TestSuiteMultiPipeline.spec.ts","2","0.464","0.000" +"Features/PersonaSessionPersistence.spec.ts","2","0.463","0.000" +"Pages/EditClassification.spec.ts","2","0.454","0.000" +"Features/SystemCertificationTags.spec.ts","3","0.449","0.000" +"Features/AppMode/AppModePreferenceRoundTrip.spec.ts","2","0.445","0.000" +"Flow/AddRoleAndAssignToUser.spec.ts","3","0.431","0.000" +"Features/ServiceAgentsDeploymentSummary.spec.ts","5","0.422","0.000" +"Features/Workflows/NoOpWorkflowNodeConfig.spec.ts","2","0.421","0.000" +"Features/DomainIsolation/DomainLineageIsolation.spec.ts","3","0.416","0.000" +"Features/BlockEditorMathEquations.spec.ts","1","0.416","0.000" +"Pages/ExploreResilience.spec.ts","4","0.414","0.000" +"Flow/FrequentlyJoined.spec.ts","2","0.399","0.000" +"Features/DataQuality/IncidentManagerAfterOwnerChange.spec.ts","1","0.398","0.000" +"Features/Tasks/TaskDashboardEntity.spec.ts","7","0.385","0.000" +"Pages/LiveIndexingTab.spec.ts","4","0.382","0.000" +"Features/LineagePipelineAnnotator.spec.ts","4","0.380","0.000" +"Features/Glossary/GlossaryInheritedReviewerApproval.spec.ts","2","0.365","0.000" +"Features/AgentLogStreamHandover.spec.ts","3","0.352","0.000" +"Features/Tasks/TaskCustomFormWorkflow.spec.ts","1","0.352","0.000" +"Pages/CustomThemeConfig.spec.ts","3","0.349","0.000" +"Features/IncidentManagerPagination.spec.ts","2","0.346","0.000" +"Flow/PersonaDeletionUserProfile.spec.ts","1","0.344","0.000" +"Features/ServiceAgentsStatusDegradation.spec.ts","4","0.342","0.000" +"Features/DomainIsolation/DomainListingIsolation.spec.ts","3","0.339","0.000" +"Pages/AppStopRunModal.spec.ts","3","0.317","0.000" +"Features/PersonaAIContextPermissions.spec.ts","2","0.317","0.000" +"Features/AppMode/AppModeAiPersonaLandsAtRoot.spec.ts","1","0.310","0.000" +"Features/EntityRightCollapsablePanel.spec.ts","1","0.308","0.000" +"Flow/ExploreAggregationCountsMatching.spec.ts","1","0.302","0.000" +"Features/DataQuality/IncidentManagerAfterSoftDelete.spec.ts","1","0.288","0.000" +"Features/ServiceAgentsLiveProgress.spec.ts","3","0.281","0.000" +"VersionPages/TestCaseVersionPage.spec.ts","1","0.280","0.000" +"Pages/DataMarketplacePermissions.spec.ts","2","0.270","0.000" +"Pages/SubDomainPagination.spec.ts","1","0.270","0.000" +"VersionPages/ClassificationVersionPage.spec.ts","1","0.264","0.000" +"Features/BlockEditorEmbedLink.spec.ts","1","0.263","0.000" +"Features/FailedTestCaseSampleData.spec.ts","2","0.258","0.000" +"Features/Tasks/TaskAssigneeManagement.spec.ts","1","0.255","0.000" +"Features/IngestionListNameSorting.spec.ts","2","0.247","0.000" +"Features/DomainIsolation/DomainIncidentIsolation.spec.ts","2","0.245","0.000" +"Features/MetricCustomUnitFlow.spec.ts","1","0.239","0.000" +"Features/Glossary/GlossaryRelationsGraphPerf.spec.ts","1","0.234","0.000" +"Features/DataQuality/TableTestCasePagination.spec.ts","1","0.233","0.000" +"Features/GlobalSearchSuggestions.spec.ts","1","0.233","0.000" +"Flow/ApiServiceRest.spec.ts","1","0.230","0.000" +"Pages/OmdURLConfiguration.spec.ts","2","0.230","0.000" +"Features/DomainIsolation/DomainDropdownIsolation.spec.ts","2","0.222","0.000" +"Features/LanguageOverride.spec.ts","1","0.219","0.000" +"VersionPages/MetricVersionPage.spec.ts","2","0.218","0.000" +"Pages/LoginConfiguration.spec.ts","2","0.218","0.000" +"Features/LineageExportPNGSnapshot.spec.ts","1","0.217","0.000" +"Pages/DataInsightSettings.spec.ts","4","0.217","0.000" +"Features/DomainIsolation/DomainSearchIsolation.spec.ts","3","0.201","0.000" +"Features/MutuallyExclusiveColumnTags.spec.ts","1","0.200","0.000" +"Pages/UserCreationWithPersona.spec.ts","1","0.192","0.000" +"Features/DataQuality/Dimensionality.spec.ts","1","0.181","0.000" +"Pages/AppRunsHistoryLogs.spec.ts","1","0.172","0.000" +"Features/DomainIsolation/DomainTaskIsolation.spec.ts","3","0.168","0.000" +"Pages/LogsViewer.spec.ts","1","0.166","0.000" +"Pages/PipelineExecution.spec.ts","1","0.159","0.000" +"Features/Markdown.spec.ts","1","0.147","0.000" +"Features/CronValidations.spec.ts","1","0.146","0.000" +"Flow/MetricListSearch.spec.ts","1","0.143","0.000" +"Features/SchemaDefinition.spec.ts","1","0.142","0.000" +"Features/ServiceAgentsRefresh.spec.ts","1","0.140","0.000" +"Features/OntologyStudioIsolatedToggle.spec.ts","1","0.132","0.000" +"Features/TestSuitePipelineRedeploy.spec.ts","1","0.130","0.000" +"Features/SearchIndexNestedColumns.spec.ts","1","0.126","0.000" +"Flow/UsersPagination.spec.ts","1","0.122","0.000" +"Flow/GlobalSearch.spec.ts","1","0.118","0.000" +"Flow/MetricSearch.spec.ts","1","0.117","0.000" +"Flow/ApiDocs.spec.ts","1","0.106","0.000" +"Features/SchemaSearch.spec.ts","1","0.099","0.000" +"Features/ServiceAgentsPauseResume.spec.ts","1","0.089","0.000" +"Features/Tasks/TaskEntityResolution.spec.ts","7","0.087","0.000" +"Pages/EmailConfiguration.spec.ts","1","0.085","0.000" +"Pages/DataMarketplaceAnnouncements.spec.ts","1","0.082","0.000" +"Search/SearchNightly.spec.ts","1","0.074","0.000" +"Pages/HealthCheck.spec.ts","1","0.066","0.000" +"Features/Tasks/TaskSuggestionAPIs.spec.ts","7","0.062","0.000" +"Pages/IngestionLogStreamLive.spec.ts","1","0.059","0.000" +"Features/Tasks/TaskPipelineEntity.spec.ts","5","0.059","0.000" +"Features/Tasks/TaskNestedFields.spec.ts","6","0.057","0.000" +"Flow/AppBasic.spec.ts","1","0.055","0.000" +"Features/AppMode/AppModeAuthGating.spec.ts","8","0.052","0.000" +"Features/Tasks/TaskTopicEntity.spec.ts","5","0.050","0.000" +"Features/Tasks/TaskContainerEntity.spec.ts","5","0.047","0.000" +"Features/DataQuality/TestCaseStatusAfterReindex.spec.ts","1","0.033","0.000" +"Features/SearchSeparation/GlossaryRenameCascade.spec.ts","1","0.027","0.000" +"Pages/Tasks.spec.ts","9","0.022","0.000" +"Features/SearchSeparation/GlossaryRenamePrefixCascade.spec.ts","1","0.016","0.000" +"Features/DataQuality/TestSuiteListAfterReindex.spec.ts","1","0.016","0.000" +"Features/DataQuality/TestSuiteSummaryAfterReindex.spec.ts","1","0.014","0.000" +"Features/SearchSeparation/DomainRenamePrefixCascade.spec.ts","1","0.014","0.000" +"Features/StoredProcedureServiceBulkFetch.spec.ts","1","0.013","0.000" +"Pages/PipelineValidation.spec.ts","2","0.001","0.000" diff --git a/docs/testing/playwright-migration/evidence/summary.json b/docs/testing/playwright-migration/evidence/summary.json new file mode 100644 index 000000000000..60a6ad999f8e --- /dev/null +++ b/docs/testing/playwright-migration/evidence/summary.json @@ -0,0 +1,1422 @@ +{ + "sourceCommit": "44823acde1c85ccc20d9f62c588169567fc28c90", + "representativeRun": "34355232120", + "scope": { + "specFiles": 394, + "supportingProductFiles": 2, + "uniqueDefinitions": 2884, + "specInstantiatedDefinitions": 2903, + "queueCases": 4488, + "queueDurationMs": 81271980, + "queueDurationHours": 22.57555, + "matchedQueueCases": 4488, + "definitionsPresentInQueue": 2747, + "owningSpecsPresentInQueue": 365, + "qualityFlaggedSource": 77, + "queueOutcomes": { + "expected": 4483, + "flaky": 4, + "skipped": 1 + } + }, + "categories": { + "U": { + "label": "Strong UI component/page integration candidate", + "reason": "Observable behavior is frontend rendering, local state, validation, routing or request construction. Exercise real UI with controlled HTTP boundaries.", + "uniqueDefinitions": 1239, + "sourcePct": 42.961, + "specInstantiatedDefinitions": 1239, + "instantiatedPct": 42.68, + "queueCases": 1589, + "queuePct": 35.406, + "queueDurationMs": 18829188, + "queueDurationHours": 5.23033, + "queueDurationPct": 23.168, + "retryDurationMs": 0, + "qualityFlaggedSource": 56, + "qualityFlaggedQueue": 71 + }, + "M": { + "label": "Mixed: extract UI checks; preserve backend integration", + "reason": "UI behavior is combined with a real save, search, persistence or server contract. Extract UI variants while retaining API integration or a representative end-to-end check.", + "uniqueDefinitions": 839, + "sourcePct": 29.092, + "specInstantiatedDefinitions": 839, + "instantiatedPct": 28.901, + "queueCases": 1778, + "queuePct": 39.617, + "queueDurationMs": 34059479, + "queueDurationHours": 9.460966388888888, + "queueDurationPct": 41.908, + "retryDurationMs": 34214, + "qualityFlaggedSource": 6, + "qualityFlaggedQueue": 6 + }, + "B": { + "label": "Retain browser; may isolate from backend", + "reason": "Primary coverage relies on browser layout, canvas/editor interaction, clipboard, downloads, screenshots or built-app execution.", + "uniqueDefinitions": 138, + "sourcePct": 4.785, + "specInstantiatedDefinitions": 137, + "instantiatedPct": 4.719, + "queueCases": 145, + "queuePct": 3.231, + "queueDurationMs": 1962285, + "queueDurationHours": 0.5450791666666667, + "queueDurationPct": 2.414, + "retryDurationMs": 0, + "qualityFlaggedSource": 1, + "qualityFlaggedQueue": 1 + }, + "A": { + "label": "Backend/API contract; not UI component migration", + "reason": "Primary assertions concern server semantics or API responses. API/service integration is the appropriate alternative, not mocked UI tests.", + "uniqueDefinitions": 231, + "sourcePct": 8.01, + "specInstantiatedDefinitions": 231, + "instantiatedPct": 7.957, + "queueCases": 254, + "queuePct": 5.66, + "queueDurationMs": 1977487, + "queueDurationHours": 0.5493019444444445, + "queueDurationPct": 2.433, + "retryDurationMs": 39011, + "qualityFlaggedSource": 9, + "qualityFlaggedQueue": 8 + }, + "E": { + "label": "Retain integrated journey in initial migration", + "reason": "Coverage spans real authentication, background work, persistence/cascades, file round-trips or multiple application contexts. Retain representative integrated coverage during UI migration.", + "uniqueDefinitions": 437, + "sourcePct": 15.153, + "specInstantiatedDefinitions": 457, + "instantiatedPct": 15.742, + "queueCases": 722, + "queuePct": 16.087, + "queueDurationMs": 24443541, + "queueDurationHours": 6.7898725, + "queueDurationPct": 30.076, + "retryDurationMs": 48586, + "qualityFlaggedSource": 5, + "qualityFlaggedQueue": 5 + } + }, + "strong": { + "cases": 1589, + "pct": 35.406, + "durationPct": 23.168 + }, + "strongPlusMixed": { + "cases": 3367, + "pct": 75.022, + "durationPct": 65.076 + }, + "strongWithoutQualityFlags": { + "cases": 1518, + "pct": 33.824 + }, + "topStrongFiles": [ + { + "file": "Pages/CustomProperties.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 60, + "specInstantiatedDefinitions": 60, + "queueCases": 173, + "queueDurationMs": 3003123, + "U_sourceDefinitions": 24, + "U_queueCases": 88, + "U_durationMs": 1022072, + "M_sourceDefinitions": 32, + "M_queueCases": 81, + "M_durationMs": 1906204, + "B_sourceDefinitions": 4, + "B_queueCases": 4, + "B_durationMs": 74847, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/ExplorePageRightPanel.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExplorePageRightPanel.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 41, + "specInstantiatedDefinitions": 41, + "queueCases": 234, + "queueDurationMs": 3196405, + "U_sourceDefinitions": 21, + "U_queueCases": 88, + "U_durationMs": 870772, + "M_sourceDefinitions": 17, + "M_queueCases": 116, + "M_durationMs": 1873557, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 30, + "E_durationMs": 452076 + }, + { + "file": "Pages/Entity.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Entity.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 37, + "specInstantiatedDefinitions": 37, + "queueCases": 353, + "queueDurationMs": 7901108, + "U_sourceDefinitions": 12, + "U_queueCases": 48, + "U_durationMs": 841192, + "M_sourceDefinitions": 19, + "M_queueCases": 239, + "M_durationMs": 5397125, + "B_sourceDefinitions": 3, + "B_queueCases": 18, + "B_durationMs": 254874, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 48, + "E_durationMs": 1407917 + }, + { + "file": "Features/Permissions/EntityPermissions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/EntityPermissions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 6, + "specInstantiatedDefinitions": 6, + "queueCases": 46, + "queueDurationMs": 723999, + "U_sourceDefinitions": 6, + "U_queueCases": 46, + "U_durationMs": 723999, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/Permissions/ServiceEntityPermissions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/ServiceEntityPermissions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 7, + "specInstantiatedDefinitions": 7, + "queueCases": 44, + "queueDurationMs": 559111, + "U_sourceDefinitions": 7, + "U_queueCases": 44, + "U_durationMs": 559111, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Flow/NestedChildrenUpdates.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/NestedChildrenUpdates.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 6, + "specInstantiatedDefinitions": 6, + "queueCases": 36, + "queueDurationMs": 472042, + "U_sourceDefinitions": 6, + "U_queueCases": 36, + "U_durationMs": 472042, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/ColumnBulkOperations.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 25, + "specInstantiatedDefinitions": 25, + "queueCases": 25, + "queueDurationMs": 461822, + "U_sourceDefinitions": 25, + "U_queueCases": 25, + "U_durationMs": 461822, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/DataQuality/DataQualityPermissions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQualityPermissions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 25, + "specInstantiatedDefinitions": 25, + "queueCases": 25, + "queueDurationMs": 436135, + "U_sourceDefinitions": 25, + "U_queueCases": 25, + "U_durationMs": 436135, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/Pagination.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Pagination.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 35, + "specInstantiatedDefinitions": 35, + "queueCases": 35, + "queueDurationMs": 430318, + "U_sourceDefinitions": 35, + "U_queueCases": 35, + "U_durationMs": 430318, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/ContextCenterMemories.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterMemories.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 55, + "specInstantiatedDefinitions": 55, + "queueCases": 55, + "queueDurationMs": 603702, + "U_sourceDefinitions": 31, + "U_queueCases": 31, + "U_durationMs": 314665, + "M_sourceDefinitions": 23, + "M_queueCases": 23, + "M_durationMs": 279319, + "B_sourceDefinitions": 1, + "B_queueCases": 1, + "B_durationMs": 9718, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/EntityDataConsumer.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityDataConsumer.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 12, + "specInstantiatedDefinitions": 12, + "queueCases": 143, + "queueDurationMs": 2793585, + "U_sourceDefinitions": 2, + "U_queueCases": 17, + "U_durationMs": 306514, + "M_sourceDefinitions": 9, + "M_queueCases": 111, + "M_durationMs": 2018154, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 15, + "E_durationMs": 468917 + }, + { + "file": "Pages/EntityHeaderBreadcrumb.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityHeaderBreadcrumb.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 1, + "specInstantiatedDefinitions": 1, + "queueCases": 19, + "queueDurationMs": 259762, + "U_sourceDefinitions": 1, + "U_queueCases": 19, + "U_durationMs": 259762, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/Permissions/GlossaryPermissions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Permissions/GlossaryPermissions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 9, + "specInstantiatedDefinitions": 9, + "queueCases": 9, + "queueDurationMs": 284597, + "U_sourceDefinitions": 8, + "U_queueCases": 8, + "U_durationMs": 259404, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 25193 + }, + { + "file": "Pages/InputOutputPorts.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/InputOutputPorts.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 43, + "specInstantiatedDefinitions": 43, + "queueCases": 43, + "queueDurationMs": 462783, + "U_sourceDefinitions": 27, + "U_queueCases": 27, + "U_durationMs": 253665, + "M_sourceDefinitions": 12, + "M_queueCases": 12, + "M_durationMs": 168294, + "B_sourceDefinitions": 3, + "B_queueCases": 3, + "B_durationMs": 29061, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 11763 + }, + { + "file": "Features/ActivityFeed.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ActivityFeed.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 17, + "specInstantiatedDefinitions": 17, + "queueCases": 17, + "queueDurationMs": 344411, + "U_sourceDefinitions": 14, + "U_queueCases": 14, + "U_durationMs": 245977, + "M_sourceDefinitions": 1, + "M_queueCases": 1, + "M_durationMs": 15079, + "B_sourceDefinitions": 1, + "B_queueCases": 1, + "B_durationMs": 27670, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 55685 + }, + { + "file": "Features/Workflows/WorkflowOssRestrictions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Workflows/WorkflowOssRestrictions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 23, + "specInstantiatedDefinitions": 23, + "queueCases": 23, + "queueDurationMs": 240738, + "U_sourceDefinitions": 23, + "U_queueCases": 23, + "U_durationMs": 240738, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/PersonaAIContext.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/PersonaAIContext.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 29, + "specInstantiatedDefinitions": 29, + "queueCases": 29, + "queueDurationMs": 273458, + "U_sourceDefinitions": 25, + "U_queueCases": 25, + "U_durationMs": 234867, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 2, + "B_queueCases": 2, + "B_durationMs": 28550, + "A_sourceDefinitions": 1, + "A_queueCases": 1, + "A_durationMs": 605, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 9436 + }, + { + "file": "Features/SSOConfiguration.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/SSOConfiguration.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 42, + "specInstantiatedDefinitions": 42, + "queueCases": 42, + "queueDurationMs": 213725, + "U_sourceDefinitions": 42, + "U_queueCases": 42, + "U_durationMs": 213725, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Lineage/LineageInteraction.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageInteraction.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 17, + "specInstantiatedDefinitions": 17, + "queueCases": 16, + "queueDurationMs": 330263, + "U_sourceDefinitions": 12, + "U_queueCases": 11, + "U_durationMs": 207261, + "M_sourceDefinitions": 2, + "M_queueCases": 2, + "M_durationMs": 36088, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 3, + "E_durationMs": 86914 + }, + { + "file": "Features/EntitySummaryPanel.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/EntitySummaryPanel.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 9, + "specInstantiatedDefinitions": 9, + "queueCases": 19, + "queueDurationMs": 212679, + "U_sourceDefinitions": 8, + "U_queueCases": 18, + "U_durationMs": 195096, + "M_sourceDefinitions": 1, + "M_queueCases": 1, + "M_durationMs": 17583, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/ContextCenterPermission.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ContextCenterPermission.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 34, + "specInstantiatedDefinitions": 34, + "queueCases": 34, + "queueDurationMs": 479944, + "U_sourceDefinitions": 17, + "U_queueCases": 17, + "U_durationMs": 194157, + "M_sourceDefinitions": 14, + "M_queueCases": 14, + "M_durationMs": 226352, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 3, + "E_durationMs": 59435 + }, + { + "file": "Features/Glossary/GlossaryMutualExclusivity.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryMutualExclusivity.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 11, + "specInstantiatedDefinitions": 11, + "queueCases": 11, + "queueDurationMs": 239187, + "U_sourceDefinitions": 8, + "U_queueCases": 8, + "U_durationMs": 171504, + "M_sourceDefinitions": 3, + "M_queueCases": 3, + "M_durationMs": 67683, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Flow/Navbar.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/Navbar.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 1, + "specInstantiatedDefinitions": 1, + "queueCases": 22, + "queueDurationMs": 167981, + "U_sourceDefinitions": 1, + "U_queueCases": 22, + "U_durationMs": 167981, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Glossary.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Glossary.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 45, + "specInstantiatedDefinitions": 45, + "queueCases": 45, + "queueDurationMs": 907975, + "U_sourceDefinitions": 11, + "U_queueCases": 11, + "U_durationMs": 166623, + "M_sourceDefinitions": 17, + "M_queueCases": 17, + "M_durationMs": 285239, + "B_sourceDefinitions": 1, + "B_queueCases": 1, + "B_durationMs": 7702, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 16, + "E_queueCases": 16, + "E_durationMs": 448411 + }, + { + "file": "Pages/Lineage/LineageRightPanel.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageRightPanel.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 2, + "specInstantiatedDefinitions": 2, + "queueCases": 17, + "queueDurationMs": 153399, + "U_sourceDefinitions": 2, + "U_queueCases": 17, + "U_durationMs": 153399, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Domains.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 47, + "specInstantiatedDefinitions": 47, + "queueCases": 47, + "queueDurationMs": 1462792, + "U_sourceDefinitions": 8, + "U_queueCases": 8, + "U_durationMs": 150287, + "M_sourceDefinitions": 16, + "M_queueCases": 16, + "M_durationMs": 435794, + "B_sourceDefinitions": 3, + "B_queueCases": 3, + "B_durationMs": 61093, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 20, + "E_queueCases": 20, + "E_durationMs": 815618 + }, + { + "file": "Features/Tasks/ActivityFeed.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Tasks/ActivityFeed.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 17, + "specInstantiatedDefinitions": 17, + "queueCases": 17, + "queueDurationMs": 214051, + "U_sourceDefinitions": 12, + "U_queueCases": 12, + "U_durationMs": 146816, + "M_sourceDefinitions": 5, + "M_queueCases": 5, + "M_durationMs": 67235, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/DataQuality/DataQualityDashboard.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/DataQualityDashboard.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 11, + "specInstantiatedDefinitions": 11, + "queueCases": 11, + "queueDurationMs": 194837, + "U_sourceDefinitions": 9, + "U_queueCases": 9, + "U_durationMs": 145302, + "M_sourceDefinitions": 1, + "M_queueCases": 1, + "M_durationMs": 38247, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 11288 + }, + { + "file": "Features/DataQuality/IncidentManagerDateFilter.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataQuality/IncidentManagerDateFilter.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 11, + "specInstantiatedDefinitions": 11, + "queueCases": 11, + "queueDurationMs": 142844, + "U_sourceDefinitions": 11, + "U_queueCases": 11, + "U_durationMs": 142844, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/BulkEditImportPermissions.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/BulkEditImportPermissions.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 4, + "specInstantiatedDefinitions": 4, + "queueCases": 4, + "queueDurationMs": 137387, + "U_sourceDefinitions": 4, + "U_queueCases": 4, + "U_durationMs": 137387, + "M_sourceDefinitions": 0, + "M_queueCases": 0, + "M_durationMs": 0, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + } + ], + "topMixedFiles": [ + { + "file": "Pages/Entity.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Entity.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 37, + "specInstantiatedDefinitions": 37, + "queueCases": 353, + "queueDurationMs": 7901108, + "U_sourceDefinitions": 12, + "U_queueCases": 48, + "U_durationMs": 841192, + "M_sourceDefinitions": 19, + "M_queueCases": 239, + "M_durationMs": 5397125, + "B_sourceDefinitions": 3, + "B_queueCases": 18, + "B_durationMs": 254874, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 48, + "E_durationMs": 1407917 + }, + { + "file": "Features/AdvancedSearch.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 28, + "specInstantiatedDefinitions": 28, + "queueCases": 130, + "queueDurationMs": 2727165, + "U_sourceDefinitions": 6, + "U_queueCases": 6, + "U_durationMs": 84753, + "M_sourceDefinitions": 22, + "M_queueCases": 124, + "M_durationMs": 2642412, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/EntityDataSteward.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityDataSteward.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 13, + "specInstantiatedDefinitions": 13, + "queueCases": 158, + "queueDurationMs": 2960184, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 12, + "M_queueCases": 143, + "M_durationMs": 2510269, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 15, + "E_durationMs": 449915 + }, + { + "file": "Pages/ServiceEntity.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ServiceEntity.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 14, + "specInstantiatedDefinitions": 14, + "queueCases": 135, + "queueDurationMs": 2712805, + "U_sourceDefinitions": 1, + "U_queueCases": 9, + "U_durationMs": 102658, + "M_sourceDefinitions": 11, + "M_queueCases": 112, + "M_durationMs": 2189427, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 2, + "E_queueCases": 14, + "E_durationMs": 420720 + }, + { + "file": "Pages/EntityDataConsumer.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/EntityDataConsumer.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 12, + "specInstantiatedDefinitions": 12, + "queueCases": 143, + "queueDurationMs": 2793585, + "U_sourceDefinitions": 2, + "U_queueCases": 17, + "U_durationMs": 306514, + "M_sourceDefinitions": 9, + "M_queueCases": 111, + "M_durationMs": 2018154, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 15, + "E_durationMs": 468917 + }, + { + "file": "Pages/CustomProperties.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 60, + "specInstantiatedDefinitions": 60, + "queueCases": 173, + "queueDurationMs": 3003123, + "U_sourceDefinitions": 24, + "U_queueCases": 88, + "U_durationMs": 1022072, + "M_sourceDefinitions": 32, + "M_queueCases": 81, + "M_durationMs": 1906204, + "B_sourceDefinitions": 4, + "B_queueCases": 4, + "B_durationMs": 74847, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/ExplorePageRightPanel.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/ExplorePageRightPanel.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 41, + "specInstantiatedDefinitions": 41, + "queueCases": 234, + "queueDurationMs": 3196405, + "U_sourceDefinitions": 21, + "U_queueCases": 88, + "U_durationMs": 870772, + "M_sourceDefinitions": 17, + "M_queueCases": 116, + "M_durationMs": 1873557, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 30, + "E_durationMs": 452076 + }, + { + "file": "Pages/DataContracts.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 14, + "specInstantiatedDefinitions": 14, + "queueCases": 48, + "queueDurationMs": 2116042, + "U_sourceDefinitions": 5, + "U_queueCases": 5, + "U_durationMs": 102350, + "M_sourceDefinitions": 4, + "M_queueCases": 21, + "M_durationMs": 875267, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 2, + "A_queueCases": 2, + "A_durationMs": 105549, + "E_sourceDefinitions": 3, + "E_queueCases": 20, + "E_durationMs": 1032876 + }, + { + "file": "Features/CuratedAssets.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CuratedAssets.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 6, + "specInstantiatedDefinitions": 6, + "queueCases": 23, + "queueDurationMs": 811934, + "U_sourceDefinitions": 1, + "U_queueCases": 1, + "U_durationMs": 18294, + "M_sourceDefinitions": 5, + "M_queueCases": 22, + "M_durationMs": 793640, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Lineage/LineageFilters.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Lineage/LineageFilters.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 12, + "specInstantiatedDefinitions": 12, + "queueCases": 15, + "queueDurationMs": 599269, + "U_sourceDefinitions": 1, + "U_queueCases": 1, + "U_durationMs": 10623, + "M_sourceDefinitions": 11, + "M_queueCases": 14, + "M_durationMs": 588646, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/DataAssetRulesDisabled.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataAssetRulesDisabled.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 7, + "specInstantiatedDefinitions": 7, + "queueCases": 34, + "queueDurationMs": 739574, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 4, + "M_queueCases": 31, + "M_durationMs": 560498, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 3, + "E_queueCases": 3, + "E_durationMs": 179076 + }, + { + "file": "Flow/CustomizeWidgets.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/CustomizeWidgets.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 9, + "specInstantiatedDefinitions": 9, + "queueCases": 9, + "queueDurationMs": 540308, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 9, + "M_queueCases": 9, + "M_durationMs": 540308, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Features/CustomizeDetailPage.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/CustomizeDetailPage.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 10, + "specInstantiatedDefinitions": 10, + "queueCases": 25, + "queueDurationMs": 623212, + "U_sourceDefinitions": 4, + "U_queueCases": 4, + "U_durationMs": 44160, + "M_sourceDefinitions": 4, + "M_queueCases": 19, + "M_durationMs": 517171, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 2, + "E_queueCases": 2, + "E_durationMs": 61881 + }, + { + "file": "Features/DataAssetRulesEnabled.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataAssetRulesEnabled.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 4, + "specInstantiatedDefinitions": 4, + "queueCases": 31, + "queueDurationMs": 448396, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 4, + "M_queueCases": 31, + "M_durationMs": 448396, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Domains.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 47, + "specInstantiatedDefinitions": 47, + "queueCases": 47, + "queueDurationMs": 1462792, + "U_sourceDefinitions": 8, + "U_queueCases": 8, + "U_durationMs": 150287, + "M_sourceDefinitions": 16, + "M_queueCases": 16, + "M_durationMs": 435794, + "B_sourceDefinitions": 3, + "B_queueCases": 3, + "B_durationMs": 61093, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 20, + "E_queueCases": 20, + "E_durationMs": 815618 + }, + { + "file": "Features/DomainFilterQueryFilter.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DomainFilterQueryFilter.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 13, + "specInstantiatedDefinitions": 13, + "queueCases": 13, + "queueDurationMs": 480556, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 11, + "M_queueCases": 11, + "M_durationMs": 393205, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 1, + "A_queueCases": 1, + "A_durationMs": 53678, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 33673 + }, + { + "file": "Features/Glossary/GlossaryAdvancedOperations.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/Glossary/GlossaryAdvancedOperations.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 28, + "specInstantiatedDefinitions": 28, + "queueCases": 28, + "queueDurationMs": 436340, + "U_sourceDefinitions": 4, + "U_queueCases": 4, + "U_durationMs": 51562, + "M_sourceDefinitions": 24, + "M_queueCases": 24, + "M_durationMs": 384778, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Tag.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Tag.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 21, + "specInstantiatedDefinitions": 21, + "queueCases": 21, + "queueDurationMs": 576055, + "U_sourceDefinitions": 8, + "U_queueCases": 8, + "U_durationMs": 134056, + "M_sourceDefinitions": 12, + "M_queueCases": 12, + "M_durationMs": 382726, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 1, + "E_queueCases": 1, + "E_durationMs": 59273 + }, + { + "file": "Features/ExploreSortOrderFilter.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ExploreSortOrderFilter.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 1, + "specInstantiatedDefinitions": 1, + "queueCases": 17, + "queueDurationMs": 287515, + "U_sourceDefinitions": 0, + "U_queueCases": 0, + "U_durationMs": 0, + "M_sourceDefinitions": 1, + "M_queueCases": 17, + "M_durationMs": 287515, + "B_sourceDefinitions": 0, + "B_queueCases": 0, + "B_durationMs": 0, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 0, + "E_queueCases": 0, + "E_durationMs": 0 + }, + { + "file": "Pages/Glossary.spec.ts", + "path": "openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Glossary.spec.ts", + "kind": "spec", + "reviewed": true, + "parseErrors": 0, + "uniqueDefinitions": 45, + "specInstantiatedDefinitions": 45, + "queueCases": 45, + "queueDurationMs": 907975, + "U_sourceDefinitions": 11, + "U_queueCases": 11, + "U_durationMs": 166623, + "M_sourceDefinitions": 17, + "M_queueCases": 17, + "M_durationMs": 285239, + "B_sourceDefinitions": 1, + "B_queueCases": 1, + "B_durationMs": 7702, + "A_sourceDefinitions": 0, + "A_queueCases": 0, + "A_durationMs": 0, + "E_sourceDefinitions": 16, + "E_queueCases": 16, + "E_durationMs": 448411 + } + ] +} \ No newline at end of file diff --git a/docs/testing/playwright-migration/migration-cases.csv b/docs/testing/playwright-migration/migration-cases.csv new file mode 100644 index 000000000000..bada6be22137 --- /dev/null +++ b/docs/testing/playwright-migration/migration-cases.csv @@ -0,0 +1,212 @@ +"queueCaseId","definitionKey","sourceFile","sourceLine","title","status","replacementTestFile","replacementTestName","rationale","observedWorkerDurationMs" +"1a7cffc95ce4e87fc41d-0088ed46eab587c90371","T0198","Features/ColumnBulkOperations.spec.ts","273"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should restore filters from URL on page load","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","restores the %s URL filter in the chip and HTTP request","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","19508" +"1a7cffc95ce4e87fc41d-014321099028e71df84c","T0194","Features/ColumnBulkOperations.spec.ts","184"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Page Load & Stats › should load the page with stats cards and grid data","retained-browser-contract","","","Retain assembled application: authenticated column page, live grid endpoint and page rendering.","12158" +"1a7cffc95ce4e87fc41d-170dbfd48cfc4dd5c106","T0203","Features/ColumnBulkOperations.spec.ts","467"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should show Service filter chip from URL","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","restores the %s URL filter in the chip and HTTP request","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","14481" +"1a7cffc95ce4e87fc41d-185597b794db3ab6912c","T0214","Features/ColumnBulkOperations.spec.ts","899"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Bulk Update Flow › should update display name and propagate to all occurrences","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","submits exactly one update per selected occurrence and tracks the pending job","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","27308" +"1a7cffc95ce4e87fc41d-239c0f77e33ddb02ed00","T0199","Features/ColumnBulkOperations.spec.ts","294"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should search columns with server-side API call","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","renders an empty result after searching and sends the typed query to the server","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","9688" +"1a7cffc95ce4e87fc41d-23c5e0255a245d7bd4a2","T0201","Features/ColumnBulkOperations.spec.ts","356"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should clear individual filter and update URL","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","applies and clears a metadata filter through the real dropdown, URL and request","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","28369" +"1a7cffc95ce4e87fc41d-2e96f151f46e62aaae33","T0217","Features/ColumnBulkOperations.spec.ts","1070"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Nested STRUCT Columns › should select and edit nested STRUCT field","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","expands nested STRUCT rows and opens the edit form for the exact child","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","29514" +"1a7cffc95ce4e87fc41d-32b4d960f036903b8b97","T0212","Features/ColumnBulkOperations.spec.ts","810"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should open edit drawer when clicking on aggregate row","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","opens the drawer by clicking the aggregate column name","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","5167" +"1a7cffc95ce4e87fc41d-39e4bd843402570f4339","T0215","Features/ColumnBulkOperations.spec.ts","978"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Bulk Update Flow › should show success notification after bulk update","retained-browser-contract","","","Retain real server background job and notification; component HTTP stubs cannot establish persistence.","28564" +"1a7cffc95ce4e87fc41d-3ef93584d85256069ad4","T0195","Features/ColumnBulkOperations.spec.ts","199"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Page Load & Stats › should show no results when searching for nonexistent column","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","renders an empty result after searching and sends the typed query to the server","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","13758" +"1a7cffc95ce4e87fc41d-3ff3cebfc11e44e7369b","T0204","Features/ColumnBulkOperations.spec.ts","526"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should show disabled edit button when no columns are selected","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","renders supplied columns and exact stats, with editing disabled until selection","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","10725" +"1a7cffc95ce4e87fc41d-4a4df818cbe72b56fd42","T0200","Features/ColumnBulkOperations.spec.ts","313"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should not reset stats to zero while search request is loading","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","keeps previous totals while a search is pending, then renders the new totals","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","10358" +"1a7cffc95ce4e87fc41d-59c5f8a31c7199210394","T0206","Features/ColumnBulkOperations.spec.ts","566"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should not count aggregate parent row in drawer selected count","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","counts selected occurrences without counting the aggregate parent, and tracks pending edits","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","7318" +"1a7cffc95ce4e87fc41d-5dac5fccf031408603db","T0216","Features/ColumnBulkOperations.spec.ts","1038"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Nested STRUCT Columns › should expand STRUCT column to show nested fields","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","expands nested STRUCT rows and opens the edit form for the exact child","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","28946" +"1a7cffc95ce4e87fc41d-6c8908c3cd1359e50b2b","T0207","Features/ColumnBulkOperations.spec.ts","614"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should show pending progress spinner after submitting bulk update","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","submits exactly one update per selected occurrence and tracks the pending job","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","25061" +"1a7cffc95ce4e87fc41d-7267cda84897fc91f6dd","T0205","Features/ColumnBulkOperations.spec.ts","532"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should update pending changes counter when editing selected columns","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","counts selected occurrences without counting the aggregate parent, and tracks pending edits","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","23240" +"1a7cffc95ce4e87fc41d-797101ebe2b800c4b2a4","T0208","Features/ColumnBulkOperations.spec.ts","667"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should select column, open drawer, and verify form fields","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","opens the real edit form with column identity, display name, description and tag controls","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","28980" +"1a7cffc95ce4e87fc41d-8491c672cd59d38141d9","T0209","Features/ColumnBulkOperations.spec.ts","706"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should show column count for multiple column selection","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","shows the number of independently selected columns in the drawer","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","5062" +"1a7cffc95ce4e87fc41d-8b7eb228bf6a6d35884e","T0196","Features/ColumnBulkOperations.spec.ts","233"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should filter by metadata status and verify API param","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","applies and clears a metadata filter through the real dropdown, URL and request","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","27690" +"1a7cffc95ce4e87fc41d-94fbdadd8c9d95ead874","T0197","Features/ColumnBulkOperations.spec.ts","255"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should filter by entity type (Table)","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","serializes the selected asset type and renders the filtered response","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","15303" +"1a7cffc95ce4e87fc41d-c6b5c6fa386a261c9945","T0210","Features/ColumnBulkOperations.spec.ts","737"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should cancel selection and disable edit button","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","cancels selection and disables editing without sending a mutation","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","23110" +"1a7cffc95ce4e87fc41d-c9cf4dffe0aa3ea711bb","T0213","Features/ColumnBulkOperations.spec.ts","829"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should accept text with spaces in the description field","retained-browser-contract","","","Retain real browser editor input, including spaces and closing the drawer.","21817" +"1a7cffc95ce4e87fc41d-cef1122673da72e852b8","T0218","Features/ColumnBulkOperations.spec.ts","1109"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Pagination › should navigate through pages","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","uses the cursor for the next page, preserves global totals, and resets it for a new search","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","10838" +"1a7cffc95ce4e87fc41d-d2e9a4b29a88686387ab","T0202","Features/ColumnBulkOperations.spec.ts","391"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Filters & Search › should keep latest search results when responses arrive out of order","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","keeps the latest results and totals when an older search resolves last","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","9119" +"1a7cffc95ce4e87fc41d-da1a0b3fd0cc0e01ed6d","T0211","Features/ColumnBulkOperations.spec.ts","757"," › chromium › Features/ColumnBulkOperations.spec.ts › Column Bulk Operations - Selection & Edit Drawer › should discard changes when closing drawer without saving","migrated","openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx","discards unsaved edits on cancel and reopens with the original value","Real component integration at HTTP boundary; consolidated outcome assertions replace this browser variant.","25740" +"1ce96103ecb38ee49d41-081025371a2814b4fb5f","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14369" +"1ce96103ecb38ee49d41-0a4191b4db0efcbae0f8","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Search Index › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14064" +"1ce96103ecb38ee49d41-11ad6728a046d81592e9","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Search Index › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14640" +"1ce96103ecb38ee49d41-16216a857e97288f66c5","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › API Endpoint › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12191" +"1ce96103ecb38ee49d41-1d2ca67614bbdde8e805","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Container › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12035" +"1ce96103ecb38ee49d41-1ea9821cb6097c0ec98f","T1781","Flow/NestedChildrenUpdates.spec.ts","127"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 1 Nested Columns › should update nested column displayName immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13721" +"1ce96103ecb38ee49d41-20781c678687a66fa68b","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Search Index › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12276" +"1ce96103ecb38ee49d41-20f85fdc0656235f5cf7","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Worksheet › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12002" +"1ce96103ecb38ee49d41-2abec9f21a8ea3b2cc4f","T1784","Flow/NestedChildrenUpdates.spec.ts","239"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 2 Deeply Nested Columns › should update nested column displayName immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13636" +"1ce96103ecb38ee49d41-2e08b3569bf413a4b41d","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12396" +"1ce96103ecb38ee49d41-2eee0c93c970f8d07682","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14720" +"1ce96103ecb38ee49d41-38553a39450ce7270e88","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12663" +"1ce96103ecb38ee49d41-4f11e50f706352784b6e","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › File › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13179" +"1ce96103ecb38ee49d41-5bf28053c2a051ccdfa3","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › API Endpoint › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13801" +"1ce96103ecb38ee49d41-693a5a472bbdcd5d7c39","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Worksheet › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","11202" +"1ce96103ecb38ee49d41-6f03ad71cb5cf3694aeb","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Worksheet › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13323" +"1ce96103ecb38ee49d41-70f4e24aa49e1afddd61","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Search Index › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","16267" +"1ce96103ecb38ee49d41-75aab610bb32463cf2dd","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Topic › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12257" +"1ce96103ecb38ee49d41-7930c4d3ae24ea30f63c","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Topic › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","11078" +"1ce96103ecb38ee49d41-7bbb32de38f97fcb06e3","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Topic › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13562" +"1ce96103ecb38ee49d41-7d221bdeacd5afefd2ab","T1784","Flow/NestedChildrenUpdates.spec.ts","239"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 2 Deeply Nested Columns › should update nested column displayName immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","11854" +"1ce96103ecb38ee49d41-88e41b978ee0ef287d92","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Container › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14496" +"1ce96103ecb38ee49d41-8db06fd539e01dd3bbaf","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › File › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","10684" +"1ce96103ecb38ee49d41-a1a032a22693be0119e4","T1781","Flow/NestedChildrenUpdates.spec.ts","127"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 1 Nested Columns › should update nested column displayName immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14203" +"1ce96103ecb38ee49d41-a5652ed373875bbfa978","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › File › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12609" +"1ce96103ecb38ee49d41-a83ffa17458ba063ab54","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","14276" +"1ce96103ecb38ee49d41-a89c14c356526919c60e","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › File › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","11420" +"1ce96103ecb38ee49d41-b9b78692b1500d345e57","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Topic › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13308" +"1ce96103ecb38ee49d41-c458a06a93bfddc93263","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Worksheet › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12991" +"1ce96103ecb38ee49d41-cf44adf2e574fb2cbc19","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Data Model › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","16476" +"1ce96103ecb38ee49d41-cfdcfe160d3952303e12","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Container › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12181" +"1ce96103ecb38ee49d41-d1725f195b4f94165c61","T1780","Flow/NestedChildrenUpdates.spec.ts","87"," › chromium › Flow/NestedChildrenUpdates.spec.ts › API Endpoint › Level 1 Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12770" +"1ce96103ecb38ee49d41-d3a1704a85d2cfaf31cd","T1782","Flow/NestedChildrenUpdates.spec.ts","176"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 2 Deeply Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13685" +"1ce96103ecb38ee49d41-d636fe1feb6796f668e6","T1779","Flow/NestedChildrenUpdates.spec.ts","62"," › chromium › Flow/NestedChildrenUpdates.spec.ts › API Endpoint › Level 1 Nested Columns › should update nested column description immediately without page refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","10947" +"1ce96103ecb38ee49d41-f2418d8c375a80d46f69","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Container › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","13895" +"1ce96103ecb38ee49d41-fd849b08a1243d3a9494","T1783","Flow/NestedChildrenUpdates.spec.ts","201"," › chromium › Flow/NestedChildrenUpdates.spec.ts › Table › Level 2 Deeply Nested Columns › should add and remove tags to nested column immediately without refresh","follow-up-retained","","","Follow-up: actual entity-specific nested-row rendering and mutation-response propagation across eight entity types. Shared nested-array utility coverage alone is insufficient.","12865" +"4b386b55f31c66fcf0a6-06daeb511ef00f84fd29","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Deny permissions › Database Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15321" +"4b386b55f31c66fcf0a6-0c4645d7bb089c1e321f","T1295","Features/Permissions/ServiceEntityPermissions.spec.ts","102"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Allow permissions › Database Service allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15581" +"4b386b55f31c66fcf0a6-14321144181f9ce47f79","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Api Service Permissions › Allow permissions › Api Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18930" +"4b386b55f31c66fcf0a6-17cd90767af0966bd36c","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Pipeline Service Permissions › Deny permissions › Pipeline Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15615" +"4b386b55f31c66fcf0a6-18ede5fe24ff674006aa","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Mlmodel Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9771" +"4b386b55f31c66fcf0a6-2e5ac8793860549aeacb","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Pipeline Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10347" +"4b386b55f31c66fcf0a6-343573554ec0d8268d70","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9761" +"4b386b55f31c66fcf0a6-3484dd5baeedfabcdc0d","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9476" +"4b386b55f31c66fcf0a6-35a725698998eb2a47f8","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › SearchIndex Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10086" +"4b386b55f31c66fcf0a6-38f5f03eb5cf5ae7f033","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › SearchIndex Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10879" +"4b386b55f31c66fcf0a6-395e69814743ba2cb187","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › SearchIndex Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10590" +"4b386b55f31c66fcf0a6-3a1ec3677e129e362fbc","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Messaging Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10383" +"4b386b55f31c66fcf0a6-3ae259c0d22b1e1ce4d8","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Messaging Service Permissions › Allow permissions › Messaging Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14433" +"4b386b55f31c66fcf0a6-432352edf3dca06c2ef7","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9995" +"4b386b55f31c66fcf0a6-436873586de451fe96d5","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Allow permissions › Dashboard Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15650" +"4b386b55f31c66fcf0a6-4c6ea164e911bb693213","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Api Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11709" +"4b386b55f31c66fcf0a6-5f11cfb879248cf34e4c","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Messaging Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9419" +"4b386b55f31c66fcf0a6-622ca29cccba013730a4","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10735" +"4b386b55f31c66fcf0a6-7b3743d684cf6e117d91","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Storage Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10686" +"4b386b55f31c66fcf0a6-835d301c730efbe11b34","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Storage Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9367" +"4b386b55f31c66fcf0a6-8ddcec058984ec203d3f","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Storage Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10114" +"4b386b55f31c66fcf0a6-8f1bafe670518bc9e83c","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Pipeline Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10397" +"4b386b55f31c66fcf0a6-91a5d646919b4d9597e3","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Pipeline Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10606" +"4b386b55f31c66fcf0a6-93d0ad051bf724091eae","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Messaging Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10974" +"4b386b55f31c66fcf0a6-a475e3ade77b9e387765","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Api Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11023" +"4b386b55f31c66fcf0a6-ae6752ff147b57846fac","T1295","Features/Permissions/ServiceEntityPermissions.spec.ts","102"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Allow permissions › Dashboard Service allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15761" +"4b386b55f31c66fcf0a6-afc719e0143260d4e040","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Storage Service Permissions › Allow permissions › Storage Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14990" +"4b386b55f31c66fcf0a6-b77edf9e143ef601fbf9","T1298","Features/Permissions/ServiceEntityPermissions.spec.ts","192"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Mlmodel Service Permissions › Deny Trigger permissions › AutoPilot trigger button is hidden with denied trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","8909" +"4b386b55f31c66fcf0a6-bcc6de800ae0018c8e35","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Mlmodel Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","9470" +"4b386b55f31c66fcf0a6-c3aca2c5c8c2d82180af","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Api Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11294" +"4b386b55f31c66fcf0a6-c552350b1e2fa95be986","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Allow permissions › Database Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16389" +"4b386b55f31c66fcf0a6-c7c8619b266099fc4f70","T1297","Features/Permissions/ServiceEntityPermissions.spec.ts","163"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › View only permissions › AutoPilot trigger button is hidden with view-only permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10660" +"4b386b55f31c66fcf0a6-cdae34958cb93081829a","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › SearchIndex Service Permissions › Allow permissions › SearchIndex Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15412" +"4b386b55f31c66fcf0a6-d59b19f223a8f2cc1bbb","T1296","Features/Permissions/ServiceEntityPermissions.spec.ts","134"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Allow Trigger permissions › AutoPilot trigger button is visible with Trigger permission","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10490" +"4b386b55f31c66fcf0a6-dd662649178d493876e0","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Storage Service Permissions › Deny permissions › Storage Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15222" +"4b386b55f31c66fcf0a6-ef980385b808a5c01753","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Api Service Permissions › Deny permissions › Api Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16965" +"4b386b55f31c66fcf0a6-f03031217bd696b25733","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Mlmodel Service Permissions › Allow permissions › Mlmodel Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15786" +"4b386b55f31c66fcf0a6-f14d138df6e533dcf29d","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Mlmodel Service Permissions › Deny permissions › Mlmodel Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14535" +"4b386b55f31c66fcf0a6-f4ee16bcc2057c7cbe8f","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › SearchIndex Service Permissions › Deny permissions › SearchIndex Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14528" +"4b386b55f31c66fcf0a6-fb8dab4d2fd36f28599c","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Deny permissions › Dashboard Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15211" +"4b386b55f31c66fcf0a6-fc44283d14ba6c42806c","T1300","Features/Permissions/ServiceEntityPermissions.spec.ts","233"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Database Service Permissions › Deny permissions › Database Service deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","17771" +"4b386b55f31c66fcf0a6-fc52cf1b230c7de377b5","T1294","Features/Permissions/ServiceEntityPermissions.spec.ts","93"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Pipeline Service Permissions › Allow permissions › Pipeline Service allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16956" +"4b386b55f31c66fcf0a6-fee0d4a9f268927eb49b","T1300","Features/Permissions/ServiceEntityPermissions.spec.ts","233"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Dashboard Service Permissions › Deny permissions › Dashboard Service deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","13626" +"4b386b55f31c66fcf0a6-ff25baa5e6705fd87e3c","T1299","Features/Permissions/ServiceEntityPermissions.spec.ts","224"," › chromium › Features/Permissions/ServiceEntityPermissions.spec.ts › Messaging Service Permissions › Deny permissions › Messaging Service deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","13288" +"69f04d167d027522a57a-0d63c51a5b8439797ec4","T1271","Features/Pagination.spec.ts","1270"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Table version page column pagination › should test search on Table version page columns","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","6116" +"69f04d167d027522a57a-1afaf40ca75b9169745f","T1269","Features/Pagination.spec.ts","1200"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pipeline Tasks page pagination › should display at most pageSize rows on each page and total matches task count","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","5911" +"69f04d167d027522a57a-1effafa017fa24dae3a8","T1240","Features/Pagination.spec.ts","124"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Database Schema Tables page pagination › should test Database Schema Tables normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","13240" +"69f04d167d027522a57a-270586167806dc7a45d7","T1248","Features/Pagination.spec.ts","418"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Notification Alerts page › should test pagination on Notification Alerts page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11291" +"69f04d167d027522a57a-4536ce90c513ea40babb","T1243","Features/Pagination.spec.ts","199"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Table columns page pagination › should test Table columns complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","20598" +"69f04d167d027522a57a-4849a60b7f9b9c75970b","T1253","Features/Pagination.spec.ts","607"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Stored Procedures page › should test Stored Procedures complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12716" +"69f04d167d027522a57a-4a9e844a35462eb4ed53","T1250","Features/Pagination.spec.ts","519"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for API Collection Endpoints page › should test API Collection normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11211" +"69f04d167d027522a57a-522675c74c67c05389c8","T1272","Features/Pagination.spec.ts","1320"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Service version page › should test pagination on Service version page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","8075" +"69f04d167d027522a57a-569e6236bb343a798340","T1270","Features/Pagination.spec.ts","1260"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Table version page column pagination › should test pagination on Table version page columns","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12771" +"69f04d167d027522a57a-5976c978fb8e0412cae3","T1246","Features/Pagination.spec.ts","337"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Classification Tags page › should test pagination on Classification Tags page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11202" +"69f04d167d027522a57a-5a0809981ccad3fac96a","T1263","Features/Pagination.spec.ts","1021"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Spreadsheets page › should test Spreadsheets normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11497" +"69f04d167d027522a57a-5b1b1a14ee145e3320a2","T1259","Features/Pagination.spec.ts","807"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Directories page › should test Directories complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","14308" +"69f04d167d027522a57a-5deca5d41faf8cf09f92","T1238","Features/Pagination.spec.ts","66"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Users page › should test pagination on Users page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11606" +"69f04d167d027522a57a-61c3a2cd143654c345ea","T1262","Features/Pagination.spec.ts","881"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Files page › should reset pagination when switching between Files and Spreadsheets tabs and also verify the api is called with correct payload","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12284" +"69f04d167d027522a57a-62a7e49254bc5ed1c0fd","T1261","Features/Pagination.spec.ts","867"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Files page › should test Files complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12608" +"69f04d167d027522a57a-65a356df11068eb892a9","T1257","Features/Pagination.spec.ts","749"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Dashboard Data Models page › should test Data Models complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","13351" +"69f04d167d027522a57a-6ccab878d5d132496901","T1242","Features/Pagination.spec.ts","190"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Table columns page pagination › should test pagination on Table columns","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","21531" +"69f04d167d027522a57a-70eff9216ce9baf67def","T1255","Features/Pagination.spec.ts","664"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Database Schemas page › should test Database Schemas complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","14119" +"69f04d167d027522a57a-7230a3d6ac8be6c0b43b","T1267","Features/Pagination.spec.ts","1154"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Bots page › should test pagination on Bots page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","10979" +"69f04d167d027522a57a-755acad3b9ae48868e50","T1244","Features/Pagination.spec.ts","245"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Service Databases page pagination › should test pagination on Service Databases page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","13365" +"69f04d167d027522a57a-7f9d55e3f06664f27de6","T1264","Features/Pagination.spec.ts","1032"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Spreadsheets page › should test Spreadsheets complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","13188" +"69f04d167d027522a57a-81562d6199750c91eedf","T1252","Features/Pagination.spec.ts","577"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Stored Procedures page › should test Stored Procedures normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12014" +"69f04d167d027522a57a-95f815f4af52e846761f","T1256","Features/Pagination.spec.ts","721"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Dashboard Data Models page › should test Data Models normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12386" +"69f04d167d027522a57a-ac4a045699a81c56318d","T1245","Features/Pagination.spec.ts","293"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Service Databases page pagination › should test Service Database Tables complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","13679" +"69f04d167d027522a57a-b9120310e2cedd8c5bf0","T1254","Features/Pagination.spec.ts","655"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Database Schemas page › should test Database Schemas normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12341" +"69f04d167d027522a57a-be507602cb869bf3d3a4","T1265","Features/Pagination.spec.ts","1087"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Roles page › should test pagination on Roles page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11483" +"69f04d167d027522a57a-c0e169775cd894d676f8","T1247","Features/Pagination.spec.ts","372"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Metrics page › should test pagination on Metrics page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11185" +"69f04d167d027522a57a-c5300a813856c71be56c","T1268","Features/Pagination.spec.ts","1192"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pipeline Tasks page pagination › should test Pipeline Tasks normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11765" +"69f04d167d027522a57a-cf38d16dc446f8c57869","T1266","Features/Pagination.spec.ts","1124"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Policies page › should test pagination on Policies page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11141" +"69f04d167d027522a57a-d09956c0604ead156107","T1239","Features/Pagination.spec.ts","71"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Users page › should test Users complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12381" +"69f04d167d027522a57a-d28067dfec2215fc2a1f","T1251","Features/Pagination.spec.ts","528"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for API Collection Endpoints page › should test API Collection complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11475" +"69f04d167d027522a57a-d4ee9d0888330156246e","T1241","Features/Pagination.spec.ts","135"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Database Schema Tables page pagination › should test Database Schema Tables complete flow with search","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","14182" +"69f04d167d027522a57a-d6cd483f8e72dec2aab6","T1249","Features/Pagination.spec.ts","474"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Observability Alerts page › should test pagination on Observability Alerts page","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","10365" +"69f04d167d027522a57a-dbd8d16a665a04625901","T1258","Features/Pagination.spec.ts","796"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Directories page › should test Directories normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","12560" +"69f04d167d027522a57a-fa33d3888c5145159d4c","T1260","Features/Pagination.spec.ts","862"," › Basic › Features/Pagination.spec.ts › Pagination Tests › Pagination tests for Drive Service Files page › should test Files normal pagination","follow-up-retained","","","Follow-up: actual listing consumer with HTTP pages and URL state. A usePaging test alone does not cover the 35 distinct consumer/search/version variants.","11394" +"8ee4c71fd1ee04fef09a-00f9606596c3016580e0","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DashboardDataModel Permissions › Allow permissions › DashboardDataModel allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","17447" +"8ee4c71fd1ee04fef09a-020742af52a481d6b34a","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Database Permissions › Allow permissions › Database allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10844" +"8ee4c71fd1ee04fef09a-02e76560310002da73e9","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › File Permissions › Deny permissions › File deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15631" +"8ee4c71fd1ee04fef09a-048cd5bb07db0b092c46","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › MlModel Permissions › Deny permissions › MlModel deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15077" +"8ee4c71fd1ee04fef09a-07b9537cf71ed31371ed","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Table Permissions › Allow permissions › Table allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18472" +"8ee4c71fd1ee04fef09a-09a091accaad0d82c91e","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DashboardDataModel Permissions › Allow permissions › DashboardDataModel allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20936" +"8ee4c71fd1ee04fef09a-0af671909bde7a013f64","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Topic Permissions › Deny permissions › Topic deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16179" +"8ee4c71fd1ee04fef09a-0cc373dd04ff8030233f","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Worksheet Permissions › Deny permissions › Worksheet deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16469" +"8ee4c71fd1ee04fef09a-10deae907d09b964fcfa","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Database Permissions › Deny permissions › Database deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11127" +"8ee4c71fd1ee04fef09a-13452946d5045d9f0db4","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Pipeline Permissions › Allow permissions › Pipeline allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16707" +"8ee4c71fd1ee04fef09a-18ae617d79e5d7b7f079","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › File Permissions › Allow permissions › File allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16171" +"8ee4c71fd1ee04fef09a-1f326d25e5fc9a9637ce","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Dashboard Permissions › Allow permissions › Dashboard allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15041" +"8ee4c71fd1ee04fef09a-393b9b78f8201b11c857","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Pipeline Permissions › Deny permissions › Pipeline deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15892" +"8ee4c71fd1ee04fef09a-3ad159e3ed8c31713208","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Database Permissions › Allow permissions › Database allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11645" +"8ee4c71fd1ee04fef09a-3c9a28545246bbdc73fb","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Metric Permissions › Allow permissions › Metric allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16518" +"8ee4c71fd1ee04fef09a-45a17df84917860b8165","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Spreadsheet Permissions › Deny permissions › Spreadsheet deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14715" +"8ee4c71fd1ee04fef09a-4d8f171e51cb0d2e42e1","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Worksheet Permissions › Allow permissions › Worksheet allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16746" +"8ee4c71fd1ee04fef09a-5bfaabe1489bae588f50","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Table Permissions › Allow permissions › Table allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19484" +"8ee4c71fd1ee04fef09a-638c851f124e342a619e","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Pipeline Permissions › Deny permissions › Pipeline deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15668" +"8ee4c71fd1ee04fef09a-6b2b0ce6cc129f162e51","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Metric Permissions › Deny permissions › Metric deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16779" +"8ee4c71fd1ee04fef09a-7103f95de221bffd41e4","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › SearchIndex Permissions › Allow permissions › SearchIndex allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","12924" +"8ee4c71fd1ee04fef09a-76eeb463ff3652b7951f","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Table Permissions › Deny permissions › Table deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19432" +"8ee4c71fd1ee04fef09a-7ae5321fb8e02ddc6a2c","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › MlModel Permissions › Allow permissions › MlModel allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16609" +"8ee4c71fd1ee04fef09a-7afc5f7035b8498c6583","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Dashboard Permissions › Deny permissions › Dashboard deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15862" +"8ee4c71fd1ee04fef09a-82058782f5a5195dbf14","T1279","Features/Permissions/EntityPermissions.spec.ts","217"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DataAsset Header – EditTier / EditOwners / EditCertification permissions › EditAll allowed but EditTier, EditOwners, EditCertification denied – edit buttons not visible","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11605" +"8ee4c71fd1ee04fef09a-8497ba3282344447e2e7","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Container Permissions › Deny permissions › Container deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","17757" +"8ee4c71fd1ee04fef09a-852f1640c17c28a14391","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Dashboard Permissions › Deny permissions › Dashboard deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14921" +"8ee4c71fd1ee04fef09a-8cde431a28f77402aa93","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Container Permissions › Allow permissions › Container allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18605" +"8ee4c71fd1ee04fef09a-98622cead2f44658d0c6","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DashboardDataModel Permissions › Deny permissions › DashboardDataModel deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20200" +"8ee4c71fd1ee04fef09a-9ecf0c8e4c89f192c4df","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Table Permissions › Deny permissions › Table deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","17590" +"8ee4c71fd1ee04fef09a-9ed49d22924150c2919d","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › SearchIndex Permissions › Deny permissions › SearchIndex deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","13501" +"8ee4c71fd1ee04fef09a-a21c41bd3db9957ede73","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Directory Permissions › Allow permissions › Directory allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15305" +"8ee4c71fd1ee04fef09a-af9cea942959e42519d9","T1280","Features/Permissions/EntityPermissions.spec.ts","230"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DataAsset Header – EditTier / EditOwners / EditCertification permissions › EditTier, EditOwners, EditCertification allowed but EditAll denied – edit buttons not visible","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","12323" +"8ee4c71fd1ee04fef09a-b23b07500ce1df682796","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › MlModel Permissions › Allow permissions › MlModel allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16350" +"8ee4c71fd1ee04fef09a-b6907275b5a16eba27dc","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Topic Permissions › Deny permissions › Topic deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16029" +"8ee4c71fd1ee04fef09a-be98efca59a108071401","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › SearchIndex Permissions › Deny permissions › SearchIndex deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","13594" +"8ee4c71fd1ee04fef09a-c7b1063f20150b9224a9","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Spreadsheet Permissions › Allow permissions › Spreadsheet allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14906" +"8ee4c71fd1ee04fef09a-cdc7161e3a6adaa0c2e4","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Directory Permissions › Deny permissions › Directory deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16246" +"8ee4c71fd1ee04fef09a-ddfdf503467d77c54ffc","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › SearchIndex Permissions › Allow permissions › SearchIndex allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14032" +"8ee4c71fd1ee04fef09a-de36bce534daf48cb1ed","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › DashboardDataModel Permissions › Deny permissions › DashboardDataModel deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","17121" +"8ee4c71fd1ee04fef09a-e064b13617abbe309243","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Dashboard Permissions › Allow permissions › Dashboard allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16686" +"8ee4c71fd1ee04fef09a-e4e4e805ca158b580f5f","T1281","Features/Permissions/EntityPermissions.spec.ts","278"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Topic Permissions › Allow permissions › Topic allow common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16700" +"8ee4c71fd1ee04fef09a-e5bb4189f7681667f866","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Pipeline Permissions › Allow permissions › Pipeline allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15766" +"8ee4c71fd1ee04fef09a-e84df0a6339c03bd5290","T1283","Features/Permissions/EntityPermissions.spec.ts","325"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Database Permissions › Deny permissions › Database deny common operations permissions","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11862" +"8ee4c71fd1ee04fef09a-ee4a0b3aec10677417e2","T1282","Features/Permissions/EntityPermissions.spec.ts","288"," › chromium › Features/Permissions/EntityPermissions.spec.ts › Topic Permissions › Allow permissions › Topic allow entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","15857" +"8ee4c71fd1ee04fef09a-f2f190d2e4df85e59203","T1284","Features/Permissions/EntityPermissions.spec.ts","335"," › chromium › Features/Permissions/EntityPermissions.spec.ts › MlModel Permissions › Deny permissions › MlModel deny entity-specific permission operations","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","14668" +"b2111489ddf56841564e-023d22dc39c48e8d53f4","T0550","Features/DataQuality/DataQualityPermissions.spec.ts","573"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase GET Endpoints › User with TEST_CASE.VIEW_BASIC can view test case in UI","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19442" +"b2111489ddf56841564e-225d15df6f71e5d6038d","T0538","Features/DataQuality/DataQualityPermissions.spec.ts","402"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User with TEST_CASE.CREATE cannot delete test cases","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19015" +"b2111489ddf56841564e-2344f0d9500623421fb8","T0536","Features/DataQuality/DataQualityPermissions.spec.ts","378"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Standard Roles (Negative Scenarios) › Data Consumer cannot create or delete test suites","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10670" +"b2111489ddf56841564e-36d66c70ea2381068e2d","T0534","Features/DataQuality/DataQualityPermissions.spec.ts","339"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Standard Roles (Negative Scenarios) › Data Consumer can VIEW test cases but sees no edit controls in UI","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18258" +"b2111489ddf56841564e-3b2675937f5dccd75d2f","T0545","Features/DataQuality/DataQualityPermissions.spec.ts","491"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase CRUD › User with TEST_CASE.DELETE can see delete option for test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20737" +"b2111489ddf56841564e-41cfeb97e29ffcfe25f5","T0554","Features/DataQuality/DataQualityPermissions.spec.ts","634"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestSuite › User with TEST_SUITE.VIEW_ALL can view test suite CONTENT but cannot add test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11655" +"b2111489ddf56841564e-505fe28532602c99aab7","T0537","Features/DataQuality/DataQualityPermissions.spec.ts","388"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Standard Roles (Negative Scenarios) › Data Consumer cannot edit test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20659" +"b2111489ddf56841564e-597de0139daf1d0e4d01","T0535","Features/DataQuality/DataQualityPermissions.spec.ts","359"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Standard Roles (Negative Scenarios) › Data Steward cannot create or delete test cases (default)","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","16979" +"b2111489ddf56841564e-7805715b82208927b353","T0557","Features/DataQuality/DataQualityPermissions.spec.ts","668"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Admin Full Access › Admin can see Data Quality UI controls (add test case, add test suite)","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","24028" +"b2111489ddf56841564e-7a64848a6500dadc0c80","T0539","Features/DataQuality/DataQualityPermissions.spec.ts","420"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User with TEST_CASE.DELETE cannot create test cases","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20792" +"b2111489ddf56841564e-7a85c789b019754693f6","T0552","Features/DataQuality/DataQualityPermissions.spec.ts","615"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestSuite › User with TEST_SUITE.CREATE can see Add test suite button","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10625" +"b2111489ddf56841564e-867f3068db9da0d14660","T0547","Features/DataQuality/DataQualityPermissions.spec.ts","524"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase Edit/PATCH › User with TEST_CASE.EDIT_ALL can see edit action on test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18859" +"b2111489ddf56841564e-8d4b1e27cb6ab75b49f4","T0540","Features/DataQuality/DataQualityPermissions.spec.ts","431"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User with TEST_CASE.VIEW_BASIC cannot edit test cases","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","23227" +"b2111489ddf56841564e-9d7d81e12e2bea1146ad","T0544","Features/DataQuality/DataQualityPermissions.spec.ts","478"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase CRUD › User with TEST_CASE.CREATE can see Add button for test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","18122" +"b2111489ddf56841564e-a12338af018616a5c43d","T0553","Features/DataQuality/DataQualityPermissions.spec.ts","623"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestSuite › User with TEST_SUITE.VIEW_ALL can view test suites page and list suites","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10659" +"b2111489ddf56841564e-bf3ff4cd06cdb0ec6934","T0551","Features/DataQuality/DataQualityPermissions.spec.ts","586"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase GET Endpoints › User with TEST_CASE.VIEW_BASIC can view test case CONTENT details in UI","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","36149" +"b2111489ddf56841564e-c53bcbe763c0939caa91","T0555","Features/DataQuality/DataQualityPermissions.spec.ts","645"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestSuite › User with TEST_SUITE.EDIT_ALL can see add test case button on suite details","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","12089" +"b2111489ddf56841564e-cfbd7e7f4484702c01f0","T0556","Features/DataQuality/DataQualityPermissions.spec.ts","653"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestSuite › User with TABLE.VIEW_TESTS can view test suites page (alternative permission)","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10130" +"b2111489ddf56841564e-cfbe5dcb809fce114ce5","T0549","Features/DataQuality/DataQualityPermissions.spec.ts","558"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase Edit/PATCH › User with VIEW_BASIC cannot see edit action in UI","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","22199" +"b2111489ddf56841564e-d7319bc5b90ed2cb0a11","T0543","Features/DataQuality/DataQualityPermissions.spec.ts","466"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User without TEST_SUITE.EDIT cannot add test case to logical suite","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","11043" +"b2111489ddf56841564e-e280555757f349c72854","T0533","Features/DataQuality/DataQualityPermissions.spec.ts","320"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Standard Roles (Negative Scenarios) › Data Consumer cannot create or delete test cases","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19944" +"b2111489ddf56841564e-e4e1a2ebe615aae2117c","T0548","Features/DataQuality/DataQualityPermissions.spec.ts","541"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase Edit/PATCH › User with TABLE.EDIT_TESTS can see edit action on test case","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","19275" +"b2111489ddf56841564e-eae7b64629c9d1a12de2","T0542","Features/DataQuality/DataQualityPermissions.spec.ts","455"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User without TEST_SUITE.DELETE cannot delete test suites","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10547" +"b2111489ddf56841564e-f34cdcd4f8d4edd4cdfe","T0541","Features/DataQuality/DataQualityPermissions.spec.ts","445"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Cross-Permission Negative Scenarios › User without TEST_SUITE.CREATE cannot create test suites","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","10062" +"b2111489ddf56841564e-ffe3f0d85ac3d552eb09","T0546","Features/DataQuality/DataQualityPermissions.spec.ts","507"," › chromium › Features/DataQuality/DataQualityPermissions.spec.ts › Observability Permission Coverage › Granular Permissions - TestCase CRUD › User with TABLE.CREATE_TESTS can see Add button (Table Permission)","follow-up-retained","","","Follow-up: actual page/header permission matrix with real providers and children; retain backend authorization enforcement. Shared permission utility coverage alone does not replace these controls.","20970" diff --git a/openmetadata-ui/src/main/resources/ui/eslint-suppressions.json b/openmetadata-ui/src/main/resources/ui/eslint-suppressions.json index 2026be488945..efbeca28c179 100644 --- a/openmetadata-ui/src/main/resources/ui/eslint-suppressions.json +++ b/openmetadata-ui/src/main/resources/ui/eslint-suppressions.json @@ -76,7 +76,7 @@ }, "playwright/e2e/Features/ColumnBulkOperations.spec.ts": { "om-playwright/no-positional-locator": { - "count": 7 + "count": 2 } }, "playwright/e2e/Features/ColumnBulkOperationsTagsGlossary.spec.ts": { diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts index 9a6854243d75..b9ac1fdb1ec4 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/ColumnBulkOperations.spec.ts @@ -11,50 +11,35 @@ * limitations under the License. */ import { APIRequestContext, Page } from '@playwright/test'; -import { SidebarItem } from '../../constant/sidebar'; +import { ColumnGridResponse } from '../../../src/generated/api/data/columnGridResponse'; import { TableClass } from '../../support/entity/TableClass'; import { expect, test } from '../../support/fixtures/base'; import { createNewPage, fullUuid, - redirectToHomePage, + getApiContext, uuid, } from '../../utils/common'; import { waitForAllLoadersToDisappear } from '../../utils/entity'; -import { sidebarClick } from '../../utils/sidebar'; test.use({ storageState: 'playwright/.auth/admin.json' }); -const COLUMN_BULK_OPERATIONS_URL = '/column-bulk-operations'; -const METADATA_STATUS_FILTER_TESTID = 'search-dropdown-Has / Missing Metadata'; +// The UI state matrix lives in ColumnGrid.integration.test.tsx. These cases +// retain assembled-page, browser-editor and real background-job contracts. const GRID_API_URL = '/api/v1/columns/grid'; -const BULK_UPDATE_API_URL = '/api/v1/columns/bulk-update-async'; - -async function waitForGridRequest(page: Page, timeout = 15000) { - return page.waitForRequest((r) => r.url().includes(GRID_API_URL), { - timeout, - }); -} async function visitColumnBulkOperationsPage(page: Page) { - await redirectToHomePage(page); - // Register before sidebarClick so the listener is active before navigation fires. - const responsePromise = page.waitForResponse( - (r) => r.url().includes(GRID_API_URL), - { timeout: 30000 } - ); - await sidebarClick(page, SidebarItem.COLUMN_BULK_OPERATIONS); - const response = await responsePromise; + const [response] = await Promise.all([ + page.waitForResponse((r) => r.url().includes(GRID_API_URL), { + timeout: 30000, + }), + page.goto('/column-bulk-operations'), + ]); expect(response.status()).toBe(200); await waitForAllLoadersToDisappear(page); } -async function searchColumn( - page: Page, - columnName: string, - options: { expectResults?: boolean } = {} -) { - const expectResults = options.expectResults ?? true; +async function searchColumn(page: Page, columnName: string) { const searchInput = page.getByPlaceholder('Search columns'); const matchingRowLocator = page.getByTestId(`column-row-${columnName}`); @@ -78,13 +63,6 @@ async function searchColumn( return matchingRowLocator.count(); }; - if (!expectResults) { - await runSearch(); - await waitForAllLoadersToDisappear(page); - - return; - } - await expect .poll( async () => { @@ -125,13 +103,6 @@ async function waitForColumnInGridIndex( .toBeGreaterThanOrEqual(minOccurrences); } -async function getPendingChangesValue(page: Page) { - return ( - (await page.getByTestId('pending-changes-value').textContent())?.trim() ?? - '' - ); -} - function getColumnRowCheckbox(page: Page, rowId: string) { return page .locator(`[data-row-id="${rowId}"]`) @@ -139,43 +110,6 @@ function getColumnRowCheckbox(page: Page, rowId: string) { .locator('[slot="selection"]'); } -function buildMockColumnGridResponse(columnName: string) { - return { - columns: [ - { - columnName, - hasVariations: false, - metadataStatus: 'MISSING', - totalOccurrences: 1, - groups: [ - { - groupId: `${columnName}-group`, - occurrenceCount: 1, - metadataStatus: 'MISSING', - displayName: columnName, - description: `${columnName} description`, - dataType: 'VARCHAR', - tags: [], - occurrences: [ - { - columnFQN: `sample_data.ecommerce_db.shopify.dim_address.${columnName}`, - entityFQN: 'sample_data.ecommerce_db.shopify.dim_address', - entityType: 'table', - serviceName: 'sample_data', - databaseName: 'ecommerce_db', - schemaName: 'shopify', - }, - ], - }, - ], - }, - ], - totalUniqueColumns: 1, - totalOccurrences: 1, - cursor: null, - }; -} - test.describe('Column Bulk Operations - Page Load & Stats', () => { test.beforeEach(async ({ page }) => { await visitColumnBulkOperationsPage(page); @@ -195,297 +129,6 @@ test.describe('Column Bulk Operations - Page Load & Stats', () => { await expect(page.getByTestId('table-view-container')).toBeVisible(); }); }); - - test('should show no results when searching for nonexistent column', async ({ - page, - }) => { - await test.step('Search for a nonexistent column name', async () => { - await searchColumn(page, 'zzz_nonexistent_column_xyz_12345', { - expectResults: false, - }); - }); - - await test.step('Verify empty state or zero rows', async () => { - await expect - .poll( - async () => { - const noRecordsText = page.getByText( - /no records found|no data|no results/i - ); - const tableRows = page.locator('tbody tr'); - const noResultsCount = await noRecordsText.count(); - const rowCount = await tableRows.count(); - - return noResultsCount > 0 || rowCount === 0; - }, - { timeout: 10000, intervals: [500, 1000, 2000] } - ) - .toBe(true); - }); - }); -}); - -test.describe('Column Bulk Operations - Filters & Search', () => { - test.beforeEach(async ({ page }) => { - await visitColumnBulkOperationsPage(page); - }); - - test('should filter by metadata status and verify API param', async ({ - page, - }) => { - await test.step('Open metadata status filter and select MISSING', async () => { - await page.getByTestId(METADATA_STATUS_FILTER_TESTID).click(); - await page.getByTestId('MISSING').click(); - // Register before update-btn click so the listener is active when the request fires. - const gridReq = waitForGridRequest(page); - await page.getByTestId('update-btn').click(); - await gridReq; - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify filter chip is displayed', async () => { - const metadataStatusChip = page.getByTestId('filter-chip-metadataStatus'); - - await expect(metadataStatusChip).toBeVisible(); - await expect(metadataStatusChip).toContainText('Has / Missing Metadata'); - await expect(metadataStatusChip).toContainText(/Missing|MISSING/); - }); - }); - - test('should filter by entity type (Table)', async ({ page }) => { - await test.step('Open Asset Type filter and select Table', async () => { - const apiCallPromise = page.waitForRequest( - (request) => - request.url().includes(GRID_API_URL) && - request.url().includes('entityTypes='), - { timeout: 10000 } - ); - - await page.getByRole('button', { name: 'Asset Type' }).click(); - await page.getByRole('menuitem', { name: 'Table' }).click(); - await page.getByRole('button', { name: 'Update' }).click(); - - const apiRequest = await apiCallPromise; - expect(apiRequest.url()).toContain('entityTypes=table'); - }); - }); - - test('should restore filters from URL on page load', async ({ page }) => { - await test.step('Navigate to page with metadataStatus in URL', async () => { - const dataReq = waitForGridRequest(page); - await page.goto( - `${COLUMN_BULK_OPERATIONS_URL}?metadataStatus=INCONSISTENT` - ); - await dataReq; - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify filter chip is restored', async () => { - const metadataStatusChip = page.getByTestId('filter-chip-metadataStatus'); - - await expect(metadataStatusChip).toBeVisible(); - await expect(metadataStatusChip).toContainText('Has / Missing Metadata'); - await expect(metadataStatusChip).toContainText( - /Inconsistent|INCONSISTENT/ - ); - }); - }); - - test('should search columns with server-side API call', async ({ page }) => { - await test.step('Type search query and verify API call', async () => { - const searchInput = page.getByPlaceholder('Search columns'); - await expect(searchInput).toBeVisible(); - - const apiCallPromise = page.waitForRequest( - (request) => - request.url().includes(GRID_API_URL) && - request.url().includes('columnNamePattern='), - { timeout: 15000 } - ); - - await searchInput.fill('address'); - const apiRequest = await apiCallPromise; - - expect(apiRequest.url()).toContain('columnNamePattern=address'); - }); - }); - - test('should not reset stats to zero while search request is loading', async ({ - page, - }) => { - const totalUniqueLocator = page.getByTestId('total-unique-columns-value'); - const totalOccurrencesLocator = page.getByTestId('total-occurrences-value'); - - const initialUnique = - (await totalUniqueLocator.textContent())?.trim() ?? ''; - const initialOccurrences = - (await totalOccurrencesLocator.textContent())?.trim() ?? ''; - - let releaseDelayedResponse: (() => void) | undefined; - const delayedResponse = new Promise((resolve) => { - releaseDelayedResponse = resolve; - }); - - await page.route(`**${GRID_API_URL}**`, async (route) => { - const requestUrl = route.request().url(); - if (requestUrl.includes('columnNamePattern=')) { - await delayedResponse; - } - await route.continue(); - }); - - const searchInput = page.getByPlaceholder('Search columns'); - await searchInput.clear(); - await searchInput.fill(`address_${uuid().slice(0, 8)}`); - - await page.waitForRequest( - (request) => - request.url().includes(GRID_API_URL) && - request.url().includes('columnNamePattern='), - { timeout: 15000 } - ); - - await expect(totalUniqueLocator).toHaveText(initialUnique); - await expect(totalOccurrencesLocator).toHaveText(initialOccurrences); - - releaseDelayedResponse?.(); - await waitForAllLoadersToDisappear(page); - await page.unroute(`**${GRID_API_URL}**`); - }); - - test('should clear individual filter and update URL', async ({ page }) => { - await test.step('Navigate with metadataStatus filter in URL', async () => { - // Use waitForRequest (not waitForResponse) so we don't depend on response - // status code — the UI filter chip is driven by URL params, not response data. - const dataReq = waitForGridRequest(page); - await page.goto(`${COLUMN_BULK_OPERATIONS_URL}?metadataStatus=MISSING`); - await dataReq; - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify filter chip is present', async () => { - const metadataStatusChip = page.getByTestId('filter-chip-metadataStatus'); - - await expect(metadataStatusChip).toBeVisible(); - await expect(metadataStatusChip).toContainText(/Missing|MISSING/); - }); - - await test.step('Deselect the MISSING filter', async () => { - await page.getByTestId(METADATA_STATUS_FILTER_TESTID).click(); - await page.getByTestId('MISSING').click(); - // Register before button click so listener is active when the request fires. - const gridReq = waitForGridRequest(page); - await page.getByTestId('update-btn').click(); - await gridReq; - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify filter chip removed and URL updated', async () => { - await expect( - page.getByTestId('filter-chip-metadataStatus') - ).not.toBeVisible(); - expect(page.url()).not.toContain('metadataStatus=MISSING'); - }); - }); - - test('should keep latest search results when responses arrive out of order', async ({ - page, - }) => { - const staleQuery = `stale_${uuid().slice(0, 8)}`; - const freshQuery = `fresh_${uuid().slice(0, 8)}`; - const staleColumn = `stale_col_${uuid().slice(0, 8)}`; - const freshColumn = `fresh_col_${uuid().slice(0, 8)}`; - - let releaseStaleResponse: (() => void) | undefined; - const staleResponseGate = new Promise((resolve) => { - releaseStaleResponse = resolve; - }); - - await page.route(`**${GRID_API_URL}**`, async (route) => { - const url = route.request().url(); - if (url.includes(`columnNamePattern=${encodeURIComponent(staleQuery)}`)) { - await staleResponseGate; - await route.fulfill({ - status: 200, - contentType: 'application/json', - body: JSON.stringify(buildMockColumnGridResponse(staleColumn)), - }); - - return; - } - if (url.includes(`columnNamePattern=${encodeURIComponent(freshQuery)}`)) { - await route.fulfill({ - status: 200, - contentType: 'application/json', - body: JSON.stringify(buildMockColumnGridResponse(freshColumn)), - }); - - return; - } - - await route.continue(); - }); - - const searchInput = page.getByPlaceholder('Search columns'); - - await searchInput.clear(); - await searchInput.fill(staleQuery); - await page.waitForRequest( - (request) => - request.url().includes(GRID_API_URL) && - request - .url() - .includes(`columnNamePattern=${encodeURIComponent(staleQuery)}`), - { timeout: 15000 } - ); - - await searchInput.clear(); - await searchInput.fill(freshQuery); - await page.waitForRequest( - (request) => - request.url().includes(GRID_API_URL) && - request - .url() - .includes(`columnNamePattern=${encodeURIComponent(freshQuery)}`), - { timeout: 15000 } - ); - - releaseStaleResponse?.(); - - await waitForAllLoadersToDisappear(page); - - await expect( - page.getByTestId('column-name-cell').filter({ hasText: freshColumn }) - ).toBeVisible(); - await expect( - page.getByTestId('column-name-cell').filter({ hasText: staleColumn }) - ).toHaveCount(0); - - await page.unroute(`**${GRID_API_URL}**`); - }); - - test('should show Service filter chip from URL', async ({ page }) => { - await test.step('Navigate with service filter in URL', async () => { - const dataReq = waitForGridRequest(page); - await page.goto( - `${COLUMN_BULK_OPERATIONS_URL}?service.displayName.keyword=${encodeURIComponent( - 'sample_data' - )}` - ); - await dataReq; - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify service chip is visible', async () => { - const serviceChip = page.getByTestId( - 'filter-chip-service.displayName.keyword' - ); - - await expect(serviceChip).toBeVisible(); - await expect(serviceChip).toContainText('Service'); - await expect(serviceChip).toContainText('sample_data'); - }); - }); }); test.describe('Column Bulk Operations - Selection & Edit Drawer', () => { @@ -523,309 +166,6 @@ test.describe('Column Bulk Operations - Selection & Edit Drawer', () => { await visitColumnBulkOperationsPage(page); }); - test('should show disabled edit button when no columns are selected', async ({ - page, - }) => { - await expect(page.getByTestId('edit-button-disabled')).toBeVisible(); - }); - - test('should update pending changes counter when editing selected columns', async ({ - page, - }) => { - await test.step('Search and select a shared column', async () => { - await searchColumn(page, sharedColumnName); - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - await test.step('Open drawer and edit display name', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const displayNameInput = drawer - .getByTestId('display-name-input') - .locator('input'); - await displayNameInput.fill(`PendingCounter_${uuid()}`); - await displayNameInput.blur(); - }); - - await test.step('Verify pending changes value shows edited/selected count', async () => { - const value = await getPendingChangesValue(page); - expect(value).toMatch(/^\d+\/\d+$/); - const [edited, selected] = value.split('/').map(Number); - expect(edited).toBeGreaterThan(0); - expect(selected).toBeGreaterThan(0); - }); - }); - - test('should not count aggregate parent row in drawer selected count', async ({ - page, - }) => { - let expectedOccurrences = 0; - - await test.step('Search and select shared grouped column', async () => { - const searchInput = page.getByPlaceholder('Search columns'); - await searchInput.clear(); - await searchInput.fill(sharedColumnName); - await waitForAllLoadersToDisappear(page); - - const groupRow = page - .locator(`[data-row-id="${sharedColumnName}"]`) - .first(); - await expect(groupRow).toBeVisible(); - - const columnNameCellText = - (await groupRow.getByTestId('column-name-cell').textContent()) ?? ''; - const match = columnNameCellText.match(/\((\d+)\)/); - - expect(match).not.toBeNull(); - expectedOccurrences = Number(match?.[1] ?? '0'); - expect(expectedOccurrences).toBeGreaterThan(1); - - const checkbox = groupRow.locator('[slot="selection"]'); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - await test.step('Open drawer and verify selected count matches occurrences', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - await expect(drawer.getByTestId('form-heading')).toContainText( - String(expectedOccurrences).padStart(2, '0') - ); - await expect( - drawer.getByTestId('column-name-input').locator('input') - ).toHaveValue( - new RegExp(`${expectedOccurrences}\\s+columns selected`, 'i') - ); - }); - }); - - test('should show pending progress spinner after submitting bulk update', async ({ - page, - }) => { - await page.route(`**${BULK_UPDATE_API_URL}`, async (route) => { - await new Promise((resolve) => setTimeout(resolve, 400)); - await route.fulfill({ - status: 200, - contentType: 'application/json', - body: JSON.stringify({ - jobId: `pw-job-${uuid()}`, - message: 'Bulk column update is in progress.', - }), - }); - }); - - await test.step('Search, select, and open edit drawer', async () => { - await searchColumn(page, sharedColumnName); - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - }); - - await test.step('Submit update request', async () => { - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const displayNameInput = drawer - .getByTestId('display-name-input') - .locator('input'); - await displayNameInput.fill(`PendingProgress_${uuid()}`); - - const updateButton = drawer.getByRole('button', { name: 'Update' }); - await expect(updateButton).toBeEnabled(); - await updateButton.click(); - }); - - await test.step('Verify pending progress indicator and counter are visible', async () => { - await expect( - page.getByTestId('column-bulk-operations-form-drawer') - ).not.toBeVisible({ timeout: 10000 }); - - const loaders = page.getByTestId('loader'); - await expect(loaders.first()).toBeVisible(); - - const value = await getPendingChangesValue(page); - expect(value).toMatch(/^\d+\/\d+$/); - }); - }); - - test('should select column, open drawer, and verify form fields', async ({ - page, - }) => { - await test.step('Search for shared column', async () => { - await searchColumn(page, sharedColumnName); - }); - - await test.step('Select the column checkbox', async () => { - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - await test.step('Verify edit button is enabled and click it', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeVisible(); - await expect(editButton).toBeEnabled(); - await editButton.click(); - }); - - await test.step('Verify drawer opens with all form fields', async () => { - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - await expect(drawer.getByTestId('form-heading')).toContainText(/Edit/); - await expect(drawer.getByTestId('display-name-input')).toBeVisible(); - await expect(drawer.getByTestId('description-field')).toBeVisible(); - await expect(drawer.getByTestId('tags-field')).toBeVisible(); - await expect(drawer.getByTestId('glossary-terms-field')).toBeVisible(); - }); - - await test.step('Close drawer with Escape', async () => { - await page.keyboard.press('Escape'); - await expect( - page.getByTestId('column-bulk-operations-form-drawer') - ).not.toBeVisible(); - }); - }); - - test('should show column count for multiple column selection', async ({ - page, - }) => { - await test.step('Select two columns via header checkbox then individual', async () => { - const headerSelection = page.locator('thead [slot="selection"]'); - await expect(headerSelection).toBeVisible(); - await headerSelection.click(); - }); - - await test.step('Open drawer and verify multi-select title', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const columnNameInput = drawer.getByTestId('column-name-input'); - await expect(columnNameInput).toBeVisible(); - - const inputEl = columnNameInput.locator('input'); - const value = await inputEl.inputValue(); - - expect(value).toContain('columns selected'); - }); - - await test.step('Close drawer', async () => { - await page.keyboard.press('Escape'); - }); - }); - - test('should cancel selection and disable edit button', async ({ page }) => { - await test.step('Search and select a column', async () => { - await searchColumn(page, sharedColumnName); - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - await test.step('Cancel selection', async () => { - const cancelButton = page.getByTestId('cancel-selection-button'); - await expect(cancelButton).toBeVisible(); - await cancelButton.click(); - await waitForAllLoadersToDisappear(page); - }); - - await test.step('Verify edit button is disabled again', async () => { - await expect(page.getByTestId('edit-button-disabled')).toBeVisible(); - }); - }); - - test('should discard changes when closing drawer without saving', async ({ - page, - }) => { - await test.step('Search and select a column', async () => { - await searchColumn(page, sharedColumnName); - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - await test.step('Open drawer and enter a display name', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const displayNameInput = drawer - .getByTestId('display-name-input') - .locator('input'); - await displayNameInput.fill('Temporary Display Name'); - await expect(displayNameInput).toHaveValue('Temporary Display Name'); - }); - - await test.step('Close drawer without saving', async () => { - await page.getByTestId('cancel-btn').click(); - await expect( - page.getByTestId('column-bulk-operations-form-drawer') - ).not.toBeVisible(); - }); - - await test.step('Reopen drawer and verify changes were discarded', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const displayNameInput = drawer - .getByTestId('display-name-input') - .locator('input'); - await expect(displayNameInput).toBeVisible(); - - await expect(displayNameInput).not.toHaveValue('Temporary Display Name'); - }); - - await test.step('Close drawer', async () => { - await page.keyboard.press('Escape'); - }); - }); - - test('should open edit drawer when clicking on aggregate row', async ({ - page, - }) => { - await test.step('Click on a column name cell to open drawer', async () => { - const firstNameCell = page.getByTestId('column-name-cell').first(); - await expect(firstNameCell).toBeVisible(); - await firstNameCell.click(); - }); - - await test.step('Verify drawer opens', async () => { - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - }); - - await test.step('Close drawer', async () => { - await page.keyboard.press('Escape'); - }); - }); - test('should accept text with spaces in the description field', async ({ page, }) => { @@ -896,88 +236,10 @@ test.describe('Column Bulk Operations - Bulk Update Flow', () => { await afterAction(); }); - test('should update display name and propagate to all occurrences', async ({ - page, - }) => { - await visitColumnBulkOperationsPage(page); - - await test.step('Search for shared column', async () => { - await searchColumn(page, sharedColumnName); - }); - - await test.step('Select the column', async () => { - const checkbox = getColumnRowCheckbox(page, sharedColumnName); - await expect(checkbox).toBeVisible(); - await checkbox.click(); - }); - - const displayName = `SharedDisplayName_${uuid()}`; - - await test.step('Open drawer and fill display name', async () => { - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - - const displayNameInput = drawer - .getByTestId('display-name-input') - .locator('input'); - await displayNameInput.fill(displayName); - }); - - await test.step('Submit update and verify API request', async () => { - interface BulkUpdateRequestBody { - columnUpdates?: Array<{ - columnFQN?: string; - displayName?: string; - }>; - } - - let requestBody: BulkUpdateRequestBody | null = null; - - const requestPromise = page.waitForRequest((request) => { - if (request.url().includes(BULK_UPDATE_API_URL)) { - try { - requestBody = - request.postDataJSON() as unknown as BulkUpdateRequestBody; - } catch { - // Ignore JSON parse errors - } - - return true; - } - - return false; - }); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - const updateButton = drawer.getByRole('button', { name: 'Update' }); - await expect(updateButton).toBeEnabled(); - await updateButton.click(); - - await requestPromise; - - expect(requestBody).not.toBeNull(); - const body = requestBody as unknown as BulkUpdateRequestBody; - expect(body.columnUpdates).toBeDefined(); - - const updates = body.columnUpdates ?? []; - expect(updates.length).toBeGreaterThanOrEqual(2); - - for (const update of updates) { - expect(update.displayName).toBe(displayName); - expect(update.columnFQN?.toLowerCase()).toContain( - sharedColumnName.toLowerCase() - ); - } - }); - }); - test('should show success notification after bulk update', async ({ page, }) => { + const displayName = `BulkTest_${uuid()}`; await visitColumnBulkOperationsPage(page); await test.step('Search and select column', async () => { @@ -999,7 +261,7 @@ test.describe('Column Bulk Operations - Bulk Update Flow', () => { const displayNameInput = drawer .getByTestId('display-name-input') .locator('input'); - await displayNameInput.fill(`BulkTest_${uuid()}`); + await displayNameInput.fill(displayName); const updateButton = drawer.getByRole('button', { name: 'Update' }); await expect(updateButton).toBeEnabled(); @@ -1011,120 +273,36 @@ test.describe('Column Bulk Operations - Bulk Update Flow', () => { page.getByText(/bulk update (initiated|completed)/i) ).toBeVisible({ timeout: 10000 }); }); - }); -}); - -test.describe('Column Bulk Operations - Nested STRUCT Columns', () => { - test.setTimeout(120000); - - const table = new TableClass(); - let structColumnName: string; - - test.beforeAll('Setup table with STRUCT columns', async ({ browser }) => { - const { apiContext, afterAction } = await createNewPage(browser); - await table.create(apiContext); - structColumnName = table.columnsName[2]; - - await waitForColumnInGridIndex(apiContext, structColumnName); - await afterAction(); - }); - - test.afterAll('Cleanup STRUCT test data', async ({ browser }) => { - const { apiContext, afterAction } = await createNewPage(browser); - await table.delete(apiContext); - await afterAction(); - }); - - test('should expand STRUCT column to show nested fields', async ({ - page, - }) => { - await visitColumnBulkOperationsPage(page); - - await test.step('Search for STRUCT column', async () => { - await searchColumn(page, structColumnName); - }); - - await test.step('Verify STRUCT row is visible', async () => { - const structRow = page.getByTestId(`column-row-${structColumnName}`); - await expect(structRow).toBeVisible(); - }); - - await test.step('Expand the STRUCT row', async () => { - const structRow = page.getByTestId(`column-row-${structColumnName}`); - const expandButton = structRow.getByRole('button').first(); - - // STRUCT rows should have expand button - if ((await expandButton.count()) > 0) { - const initialRowCount = await page.locator('tbody tr').count(); - await expandButton.click(); + await test.step('Verify both column occurrences were updated in the server index', async () => { + const { apiContext, afterAction } = await getApiContext(page); + try { await expect - .poll(() => page.locator('tbody tr').count(), { - timeout: 10000, - }) - .toBeGreaterThan(initialRowCount); - } - }); - }); - - test('should select and edit nested STRUCT field', async ({ page }) => { - await visitColumnBulkOperationsPage(page); - - await test.step('Search for STRUCT column', async () => { - await searchColumn(page, structColumnName); - }); - - await test.step('Expand STRUCT row', async () => { - const structRow = page.getByTestId(`column-row-${structColumnName}`); - const expandButton = structRow.getByRole('button').first(); - - if ((await expandButton.count()) > 0) { - await expandButton.click(); - } - }); - - await test.step('Select a nested child column', async () => { - const childColumnName = table.columnsName[3]; - const childRowId = `${structColumnName}-struct-${childColumnName}`; - const childCheckbox = getColumnRowCheckbox(page, childRowId); - - if ((await childCheckbox.count()) > 0) { - await childCheckbox.click(); - - const editButton = page.getByTestId('edit-button'); - await expect(editButton).toBeEnabled(); - await editButton.click(); - - const drawer = page.getByTestId('column-bulk-operations-form-drawer'); - await expect(drawer).toBeVisible(); - await expect(drawer.getByTestId('display-name-input')).toBeVisible(); - - await page.keyboard.press('Escape'); - } - }); - }); -}); - -test.describe('Column Bulk Operations - Pagination', () => { - test('should navigate through pages', async ({ page }) => { - await visitColumnBulkOperationsPage(page); - - const nextButton = page.getByRole('button', { name: 'Next' }); - - await test.step('Click Next and verify Previous becomes enabled', async () => { - const isNextEnabled = await nextButton.isEnabled(); - - if (isNextEnabled) { - const dataReq = waitForGridRequest(page); - await nextButton.click(); - await dataReq; - await waitForAllLoadersToDisappear(page); - - const prevButton = page.getByRole('button', { name: 'Previous' }); - await expect(prevButton).toBeEnabled(); - - await prevButton.click(); - await waitForAllLoadersToDisappear(page); + .poll( + async () => { + const response = await apiContext.get( + `${GRID_API_URL}?size=1000&columnNamePattern=${encodeURIComponent( + sharedColumnName + )}` + ); + expect(response.ok()).toBe(true); + const result: ColumnGridResponse = await response.json(); + const column = result.columns.find( + ({ columnName }) => columnName === sharedColumnName + ); + + return ( + column?.groups + .filter((group) => group.displayName === displayName) + .reduce((count, group) => count + group.occurrenceCount, 0) ?? + 0 + ); + }, + { timeout: 30000 } + ) + .toBe(2); + } finally { + await afterAction(); } }); }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/eslint-rules/tests/corpus.test.mjs b/openmetadata-ui/src/main/resources/ui/playwright/eslint-rules/tests/corpus.test.mjs index 05f59f45adce..b597f1e3d1f0 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/eslint-rules/tests/corpus.test.mjs +++ b/openmetadata-ui/src/main/resources/ui/playwright/eslint-rules/tests/corpus.test.mjs @@ -41,7 +41,7 @@ test('the suppressions baseline matches its recorded state exactly', () => { // of the same rule in the same file stays invisible here. const EXPECTED = { 'om-playwright/justified-rule-disable': 12, - 'om-playwright/no-positional-locator': 1304, + 'om-playwright/no-positional-locator': 1299, 'om-playwright/require-assertion-per-test': 1, 'playwright/no-skipped-test': 4, 'playwright/no-wait-for-selector': 35, diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx new file mode 100644 index 000000000000..4a4a59062a5b --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ColumnBulkOperations/ColumnGrid/ColumnGrid.integration.test.tsx @@ -0,0 +1,674 @@ +/* + * Copyright 2026 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ToastProvider, toastQueue } from '@openmetadata/ui-core-components'; +import { act, cleanup, screen, waitFor, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { BrowserRouter } from 'react-router-dom'; +import { + ColumnGridResponse, + MetadataStatus, +} from '../../../generated/api/data/columnGridResponse'; +import { + createHttpTestServer, + deferredResponse, +} from '../../../test/unit/HttpTestServer.utils'; +import { renderWithQueryClient } from '../../../test/unit/test-utils'; +import ColumnGrid from './ColumnGrid.component'; + +jest.unmock('../../../utils/ToastUtils'); + +const gridResponse = ( + name = 'customer_id', + occurrenceCount = 1 +): ColumnGridResponse => ({ + columns: [ + { + columnName: name, + hasVariations: false, + metadataStatus: MetadataStatus.Missing, + totalOccurrences: occurrenceCount, + groups: [ + { + groupId: `${name}-group`, + occurrenceCount, + metadataStatus: MetadataStatus.Missing, + dataType: 'VARCHAR', + tags: [], + occurrences: Array.from({ length: occurrenceCount }, (_, index) => ({ + columnFQN: `service.db.schema.customers_${index}.${name}`, + entityFQN: `service.db.schema.customers_${index}`, + entityType: 'table', + serviceName: 'service', + databaseName: 'db', + schemaName: 'schema', + })), + }, + ], + }, + ], + totalUniqueColumns: 1, + totalOccurrences: occurrenceCount, +}); + +describe('Column grid with real controls, routing and HTTP requests', () => { + let server: ReturnType; + let user: ReturnType; + + beforeEach(() => { + window.history.replaceState({}, '', '/column-bulk-operations'); + server = createHttpTestServer(); + user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + server.on('GET', '/api/v1/columns/grid', () => ({ data: gridResponse() })); + server.on('GET', '/api/v1/search/query', () => ({ + data: { hits: { hits: [], total: { value: 0 } } }, + })); + server.on('GET', '/api/v1/glossaries', () => ({ + data: { data: [], paging: { total: 0 } }, + })); + }); + + afterEach(async () => { + cleanup(); + toastQueue.clear(); + await act(async () => jest.runOnlyPendingTimers()); + server.restore(); + }); + + const renderGrid = async (query = '') => { + window.history.replaceState({}, '', `/column-bulk-operations${query}`); + await act(async () => { + renderWithQueryClient( + + + + + ); + }); + }; + + const searchFor = async (query: string) => { + const search = screen.getByPlaceholderText('label.search-columns'); + await user.clear(search); + await user.type(search, query); + await act(async () => jest.advanceTimersByTime(300)); + }; + + const lastGridRequest = () => + server.requests + .filter(({ url }) => url.pathname === '/api/v1/columns/grid') + .slice(-1)[0]; + + const selectColumn = async (name = 'customer_id') => { + const row = screen.getByRole('row', { name: new RegExp(name) }); + await user.click(within(row).getByRole('checkbox')); + }; + + const openEditor = async () => { + await selectColumn(); + await user.click(screen.getByTestId('edit-button')); + + return screen.findByTestId('column-bulk-operations-form-drawer'); + }; + + it('renders supplied columns and exact stats, with editing disabled until selection', async () => { + await renderGrid(); + await waitFor(() => expect(server.requests).toHaveLength(1)); + + expect(await screen.findByText('customer_id')).toBeVisible(); + expect(screen.getByTestId('total-unique-columns-value')).toHaveTextContent( + '1' + ); + expect(screen.getByTestId('total-occurrences-value')).toHaveTextContent( + '1' + ); + expect(screen.getByTestId('pending-changes-value')).toHaveTextContent('0'); + expect(screen.getByTestId('edit-button-disabled')).toBeDisabled(); + }); + + it('renders an empty result after searching and sends the typed query to the server', async () => { + server.on('GET', '/api/v1/columns/grid', ({ url }) => ({ + data: url.searchParams.has('columnNamePattern') + ? { columns: [], totalUniqueColumns: 0, totalOccurrences: 0 } + : gridResponse(), + })); + await renderGrid(); + await screen.findByText('customer_id'); + await user.type( + screen.getByPlaceholderText('label.search-columns'), + 'nonexistent' + ); + + expect( + await screen.findByText('label.no-matching-result-plural') + ).toBeVisible(); + expect(screen.queryByText('customer_id')).not.toBeInTheDocument(); + expect(lastGridRequest().url.searchParams.get('columnNamePattern')).toBe( + 'nonexistent' + ); + expect(new URLSearchParams(window.location.search).get('q')).toBe( + 'nonexistent' + ); + }); + + it.each([ + ['metadataStatus', 'INCONSISTENT', 'metadataStatus'], + ['service.displayName.keyword', 'warehouse', 'serviceName'], + ])( + 'restores the %s URL filter in the chip and HTTP request', + async (field, value, apiField) => { + await renderGrid(`?${field}=${value}`); + + expect( + await screen.findByTestId(`filter-chip-${field}`) + ).toHaveTextContent(value); + expect(lastGridRequest().url.searchParams.get(apiField)).toBe(value); + expect(screen.getByText('customer_id')).toBeVisible(); + } + ); + + it('applies and clears a metadata filter through the real dropdown, URL and request', async () => { + await renderGrid(); + await user.click( + screen.getByRole('button', { name: 'label.metadata-status' }) + ); + await user.click(screen.getByTestId('MISSING')); + await user.click(screen.getByTestId('update-btn')); + + expect( + await screen.findByTestId('filter-chip-metadataStatus') + ).toHaveTextContent('MISSING'); + expect(lastGridRequest().url.searchParams.get('metadataStatus')).toBe( + 'MISSING' + ); + expect( + new URLSearchParams(window.location.search).get('metadataStatus') + ).toBe('MISSING'); + + await user.click( + screen.getByRole('button', { name: /label.metadata-status/ }) + ); + await user.click(screen.getByTestId('MISSING')); + await user.click(screen.getByTestId('update-btn')); + await waitFor(() => + expect( + screen.queryByTestId('filter-chip-metadataStatus') + ).not.toBeInTheDocument() + ); + + expect(lastGridRequest().url.searchParams.has('metadataStatus')).toBe( + false + ); + expect( + new URLSearchParams(window.location.search).has('metadataStatus') + ).toBe(false); + }); + + it('serializes the selected asset type and renders the filtered response', async () => { + server.on('GET', '/api/v1/columns/grid', ({ url }) => ({ + data: gridResponse( + url.searchParams.has('entityTypes') ? 'table_column' : 'customer_id' + ), + })); + await renderGrid(); + await user.click(screen.getByRole('button', { name: 'label.asset-type' })); + await user.click(screen.getByRole('checkbox', { name: 'Table' })); + await user.click(screen.getByTestId('update-btn')); + + expect(await screen.findByText('table_column')).toBeVisible(); + expect(lastGridRequest().url.searchParams.get('entityTypes')).toBe('table'); + expect(screen.queryByText('customer_id')).not.toBeInTheDocument(); + }); + + it('keeps previous totals while a search is pending, then renders the new totals', async () => { + const pending = deferredResponse<{ data: ColumnGridResponse }>(); + server.on('GET', '/api/v1/columns/grid', ({ url }) => + url.searchParams.has('columnNamePattern') + ? pending.promise + : { data: gridResponse() } + ); + await renderGrid(); + await searchFor('account'); + + expect(lastGridRequest().url.searchParams.get('columnNamePattern')).toBe( + 'account' + ); + expect(screen.getByTestId('total-unique-columns-value')).toHaveTextContent( + '1' + ); + expect(screen.getByTestId('total-occurrences-value')).toHaveTextContent( + '1' + ); + + await act(async () => + pending.resolve({ + data: { + ...gridResponse('account_id'), + totalUniqueColumns: 7, + totalOccurrences: 21, + }, + }) + ); + + expect(await screen.findByText('account_id')).toBeVisible(); + expect(screen.getByTestId('total-unique-columns-value')).toHaveTextContent( + '7' + ); + expect(screen.getByTestId('total-occurrences-value')).toHaveTextContent( + '21' + ); + }); + + it('keeps the latest results and totals when an older search resolves last', async () => { + const stale = deferredResponse<{ data: ColumnGridResponse }>(); + server.on('GET', '/api/v1/columns/grid', ({ url }) => { + const query = url.searchParams.get('columnNamePattern'); + + return query === 'stale' + ? stale.promise + : { + data: gridResponse( + query === 'fresh' ? 'fresh_column' : 'customer_id' + ), + }; + }); + await renderGrid(); + await searchFor('stale'); + + expect(lastGridRequest().url.searchParams.get('columnNamePattern')).toBe( + 'stale' + ); + + await searchFor('fresh'); + + expect(await screen.findByText('fresh_column')).toBeVisible(); + + await act(async () => + stale.resolve({ + data: { + ...gridResponse('stale_column'), + totalUniqueColumns: 99, + totalOccurrences: 99, + }, + }) + ); + + expect(screen.queryByText('stale_column')).not.toBeInTheDocument(); + expect(screen.getByText('fresh_column')).toBeVisible(); + expect(screen.getByTestId('total-unique-columns-value')).toHaveTextContent( + /^1$/ + ); + expect(new URLSearchParams(window.location.search).get('q')).toBe('fresh'); + }); + + it('cancels selection and disables editing without sending a mutation', async () => { + await renderGrid(); + await selectColumn(); + + expect(screen.getByTestId('edit-button')).toBeEnabled(); + + await user.click(screen.getByTestId('cancel-selection-button')); + + expect(screen.getByTestId('edit-button-disabled')).toBeDisabled(); + expect(screen.queryAllByRole('checkbox', { checked: true })).toHaveLength( + 0 + ); + expect(server.requests.filter(({ method }) => method !== 'GET')).toEqual( + [] + ); + }); + + it('opens the real edit form with column identity, display name, description and tag controls', async () => { + await renderGrid(); + const drawer = await openEditor(); + + expect( + within(drawer).getByTestId('column-name-input').querySelector('input') + ).toHaveValue('customer_id'); + expect( + within(drawer).getByTestId('display-name-input').querySelector('input') + ).toHaveValue(''); + expect(within(drawer).getByTestId('description-field')).toBeVisible(); + expect(within(drawer).getByTestId('tags-field')).toBeVisible(); + expect(within(drawer).getByTestId('glossary-terms-field')).toBeVisible(); + }); + + it('counts selected occurrences without counting the aggregate parent, and tracks pending edits', async () => { + server.on('GET', '/api/v1/columns/grid', () => ({ + data: gridResponse('customer_id', 2), + })); + await renderGrid(); + const drawer = await openEditor(); + + expect(within(drawer).getByTestId('form-heading')).toHaveTextContent('02'); + expect( + within(within(drawer).getByTestId('column-name-input')).getByRole( + 'textbox' + ) + ).toHaveValue('2 label.column-lowercase-plural label.selected-lowercase'); + + await user.type( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ), + 'Customer' + ); + await user.tab(); + + expect(screen.getByTestId('pending-changes-value')).toHaveTextContent( + '2/2' + ); + }); + + it('shows the number of independently selected columns in the drawer', async () => { + server.on('GET', '/api/v1/columns/grid', () => ({ + data: { + columns: [ + ...gridResponse().columns, + ...gridResponse('account_id').columns, + ], + totalUniqueColumns: 2, + totalOccurrences: 2, + }, + })); + await renderGrid(); + await selectColumn(); + await selectColumn('account_id'); + await user.click(screen.getByTestId('edit-button')); + const drawer = await screen.findByTestId( + 'column-bulk-operations-form-drawer' + ); + + expect(within(drawer).getByTestId('form-heading')).toHaveTextContent('02'); + expect( + within(within(drawer).getByTestId('column-name-input')).getByRole( + 'textbox' + ) + ).toHaveValue('2 label.column-lowercase-plural label.selected-lowercase'); + }); + + it('discards unsaved edits on cancel and reopens with the original value', async () => { + await renderGrid(); + const drawer = await openEditor(); + await user.type( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ), + 'Temporary display name' + ); + await user.tab(); + + expect(screen.getByTestId('pending-changes-value')).toHaveTextContent( + '1/1' + ); + + await user.click(within(drawer).getByTestId('cancel-btn')); + await waitFor(() => + expect( + screen.queryByTestId('column-bulk-operations-form-drawer') + ).not.toBeInTheDocument() + ); + + expect(screen.getByTestId('pending-changes-value')).toHaveTextContent( + /^0$/ + ); + + await user.click(screen.getByTestId('edit-button')); + const reopened = await screen.findByTestId( + 'column-bulk-operations-form-drawer' + ); + + expect( + within(within(reopened).getByTestId('display-name-input')).getByRole( + 'textbox' + ) + ).toHaveValue(''); + expect(server.requests.filter(({ method }) => method === 'POST')).toEqual( + [] + ); + }); + + it('opens the drawer by clicking the aggregate column name', async () => { + server.on('GET', '/api/v1/columns/grid', () => ({ + data: gridResponse('customer_id', 2), + })); + await renderGrid(); + await user.click(screen.getByRole('button', { name: 'customer_id (2)' })); + + expect( + await screen.findByTestId('column-bulk-operations-form-drawer') + ).toBeVisible(); + expect(screen.getByTestId('form-heading')).toHaveTextContent('02'); + }); + + it('submits exactly one update per selected occurrence and tracks the pending job', async () => { + const submission = deferredResponse<{ + data: { jobId: string; message: string }; + }>(); + server.on('GET', '/api/v1/columns/grid', () => ({ + data: gridResponse('customer_id', 2), + })); + server.on( + 'POST', + '/api/v1/columns/bulk-update-async', + () => submission.promise + ); + await renderGrid(); + const drawer = await openEditor(); + await user.type( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ), + 'Customer' + ); + await user.click(within(drawer).getByTestId('save-btn')); + await waitFor(() => + expect( + server.requests.filter(({ method }) => method === 'POST') + ).toHaveLength(1) + ); + + expect( + server.requests.find(({ method }) => method === 'POST')?.body + ).toEqual({ + columnUpdates: [ + { + columnFQN: 'service.db.schema.customers_0.customer_id', + entityType: 'table', + displayName: 'Customer', + }, + { + columnFQN: 'service.db.schema.customers_1.customer_id', + entityType: 'table', + displayName: 'Customer', + }, + ], + }); + expect( + within(screen.getByTestId('pending-changes-card')).getByTestId('loader') + ).toBeVisible(); + + await act(async () => + submission.resolve({ data: { jobId: 'bulk-job', message: 'accepted' } }) + ); + await waitFor(() => + expect( + screen.queryByTestId('column-bulk-operations-form-drawer') + ).not.toBeInTheDocument() + ); + + expect( + within(screen.getByTestId('pending-changes-card')).getByTestId('loader') + ).toBeVisible(); + expect(screen.getByTestId('pending-changes-value')).toHaveTextContent( + '0/2' + ); + }); + + it('preserves edits and allows retry when submission fails', async () => { + server.on('POST', '/api/v1/columns/bulk-update-async', () => ({ + status: 500, + data: { message: 'temporary failure' }, + })); + await renderGrid(); + const drawer = await openEditor(); + await user.type( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ), + 'Customer' + ); + await user.click(within(drawer).getByTestId('save-btn')); + await waitFor(() => + expect(within(drawer).getByTestId('save-btn')).toBeEnabled() + ); + + expect( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ) + ).toHaveValue('Customer'); + expect( + within(screen.getByTestId('pending-changes-card')).queryByTestId('loader') + ).not.toBeInTheDocument(); + expect( + server.requests.filter(({ method }) => method === 'POST') + ).toHaveLength(1); + expect( + await screen.findByText('server.entity-updating-error') + ).toBeVisible(); + + server.on('POST', '/api/v1/columns/bulk-update-async', () => ({ + data: { jobId: 'retry-job', message: 'accepted' }, + })); + await user.click(within(drawer).getByTestId('save-btn')); + await waitFor(() => + expect( + screen.queryByTestId('column-bulk-operations-form-drawer') + ).not.toBeInTheDocument() + ); + const submissions = server.requests.filter( + ({ method }) => method === 'POST' + ); + + expect(submissions).toHaveLength(2); + expect(submissions[1].body).toEqual(submissions[0].body); + }); + + it('uses the cursor for the next page, preserves global totals, and resets it for a new search', async () => { + server.on('GET', '/api/v1/columns/grid', ({ url }) => ({ + data: url.searchParams.has('cursor') + ? { ...gridResponse('second_page_column'), totalUniqueColumns: 1 } + : { + ...gridResponse( + url.searchParams.has('columnNamePattern') + ? 'search_column' + : 'customer_id' + ), + totalUniqueColumns: 26, + totalOccurrences: 26, + cursor: 'next-cursor', + }, + })); + await renderGrid(); + + expect(screen.getByTestId('previous')).toBeDisabled(); + expect(screen.getByTestId('next')).toBeEnabled(); + + await user.click(screen.getByTestId('next')); + await waitFor(() => + expect(lastGridRequest().url.searchParams.get('cursor')).toBe( + 'next-cursor' + ) + ); + + expect(await screen.findByText('second_page_column')).toBeVisible(); + expect(screen.queryByText('customer_id')).not.toBeInTheDocument(); + expect(lastGridRequest().url.searchParams.get('cursor')).toBe( + 'next-cursor' + ); + expect(screen.getByTestId('total-unique-columns-value')).toHaveTextContent( + '26' + ); + expect(screen.getByTestId('page-indicator')).toHaveTextContent( + 'label.page 2 label.of 2' + ); + + await user.click(screen.getByTestId('previous')); + + expect(await screen.findByText('customer_id')).toBeVisible(); + + await user.click(screen.getByTestId('next')); + + expect(await screen.findByText('second_page_column')).toBeVisible(); + + await searchFor('search'); + + expect(await screen.findByText('search_column')).toBeVisible(); + expect(lastGridRequest().url.searchParams.has('cursor')).toBe(false); + expect(screen.getByTestId('page-indicator')).toHaveTextContent( + 'label.page 1' + ); + }); + + it('expands nested STRUCT rows and opens the edit form for the exact child', async () => { + const response = gridResponse('address'); + response.columns[0].groups[0].dataType = 'STRUCT'; + response.columns[0].groups[0].children = [ + { + name: 'city', + dataType: 'VARCHAR', + fullyQualifiedName: 'service.db.schema.customers_0.address.city', + }, + ]; + server.on('GET', '/api/v1/columns/grid', () => ({ data: response })); + await renderGrid(); + + expect(screen.queryByText('city')).not.toBeInTheDocument(); + + const structRow = screen.getByTestId('column-row-address'); + await user.click(within(structRow).getAllByRole('button')[0]); + + expect(await screen.findByText('city')).toBeVisible(); + + const childRow = screen.getByRole('row', { name: /city/ }); + await user.click(within(childRow).getByRole('checkbox')); + await user.click(screen.getByTestId('edit-button')); + const drawer = await screen.findByTestId( + 'column-bulk-operations-form-drawer' + ); + + expect( + within(within(drawer).getByTestId('column-name-input')).getByRole( + 'textbox' + ) + ).toHaveValue('city'); + expect( + within(within(drawer).getByTestId('display-name-input')).getByRole( + 'textbox' + ) + ).toBeEnabled(); + }); + + it('rejects an unchanged submission without scheduling a bulk job', async () => { + await renderGrid(); + const drawer = await openEditor(); + await user.click(within(drawer).getByTestId('save-btn')); + + expect(await screen.findByText('message.no-changes-to-save')).toBeVisible(); + expect(server.requests.filter(({ method }) => method === 'POST')).toEqual( + [] + ); + expect(drawer).toBeVisible(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/test/unit/HttpTestServer.utils.ts b/openmetadata-ui/src/main/resources/ui/src/test/unit/HttpTestServer.utils.ts new file mode 100644 index 000000000000..b1d7c99a7fb9 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/test/unit/HttpTestServer.utils.ts @@ -0,0 +1,112 @@ +/* + * Copyright 2026 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AxiosError, InternalAxiosRequestConfig } from 'axios'; +// eslint-disable-next-line openmetadata-imports/no-internal-barrel-imports -- Client singleton, not a barrel. +import APIClient from '../../rest/index'; + +interface HttpRequest { + method: string; + url: URL; + body: unknown; +} + +interface HttpResponse { + data: unknown; + status?: number; +} + +type HttpHandler = ( + request: HttpRequest +) => HttpResponse | Promise; + +/** Keeps the real REST client and interceptors; replaces only network transport. */ +export function createHttpTestServer() { + const originalAdapter = APIClient.defaults.adapter; + const routes: { method: string; path: string; handler: HttpHandler }[] = []; + const requests: HttpRequest[] = []; + const unhandled: string[] = []; + let requestLimitExceeded = false; + + APIClient.defaults.adapter = async (config: InternalAxiosRequestConfig) => { + const request: HttpRequest = { + method: (config.method ?? 'get').toUpperCase(), + url: new URL(APIClient.getUri(config), 'http://localhost'), + body: + typeof config.data === 'string' && + String(config.headers.getContentType()).includes('application/json') + ? JSON.parse(config.data) + : config.data, + }; + + if (requests.length >= 500) { + requestLimitExceeded = true; + + throw new Error( + 'HTTP test exceeded 500 requests; check for a render loop' + ); + } + requests.push(request); + const route = routes.find( + ({ method, path }) => + method === request.method && path === request.url.pathname + ); + if (!route) { + const message = `Unhandled HTTP request: ${request.method} ${request.url}`; + unhandled.push(message); + + throw new Error(message); + } + const { data, status = 200 } = await route.handler(request); + const response = { + config, + data, + status, + statusText: String(status), + headers: {}, + }; + if (status >= 400) { + throw new AxiosError( + `HTTP ${status}`, + undefined, + config, + undefined, + response + ); + } + + return response; + }; + + return { + requests, + on(method: string, path: string, handler: HttpHandler) { + routes.unshift({ method, path, handler }); + }, + restore() { + APIClient.defaults.adapter = originalAdapter; + + expect(unhandled).toEqual([]); + expect(requestLimitExceeded).toBe(false); + }, + }; +} + +export function deferredResponse() { + let resolve!: (value: T) => void; + const promise = new Promise((complete) => { + resolve = complete; + }); + + return { promise, resolve }; +}