Skip to content

fix: flaky anvil-cmg biosamples filter-tag e2e test #4800

@frano-m

Description

@frano-m

Problem

The e2e test Check that the filter tags match the selected filter for an arbitrary filter on the BioSamples tab (e2e/anvil/anvil-filters.spec.ts:139) is intermittently failing in CI.

Latest failure

[chromium] › e2e/anvil/anvil-filters.spec.ts:139:5

Error: expect(locator).toBeVisible() failed
  Locator: locator('#sidebar-positioner').getByText('.md5', { exact: true })
  Expected: visible
  Timeout: 15000ms
  Error: element(s) not found

  at testFunctions.ts:632
       630 |     // Click the filter tag
       631 |     const filterTagLocator = getFilterTagLocator(page, firstFilterOptionName);
     > 632 |     await expect(filterTagLocator).toBeVisible();

128/129 passed; 1 failed.

Likely root cause

The shared helper testFilterTags in e2e/testFunctions.ts:608-644 is brittle:

  1. Positional first-option locatorgetFirstFilterOptionLocator(page) selects the first item by index. If the option list re-sorts after a click (selected items often float to the top, or counts change ordering), the helper's subsequent assertions can target the wrong row.
  2. Text-only filter tag lookupgetFilterTagLocator (line 595) does page.locator('#sidebar-positioner').getByText(filterTagName, { exact: true }). For an option name like .md5, this is exact-text in a CSS-positional container with no test-id; it's susceptible to layout/timing differences (chip not rendered yet, surrounding wrapper slightly different).
  3. innerText().split("\n") — the option name is extracted by splitting innerText on newlines and finding the first non-empty piece. Fragile to whitespace/markup changes.
  4. Generic load-state waitspage.waitForLoadState("load") doesn't wait for the post-filter-application UI updates; the chip can still be mid-mount when the assertion runs.

Proposed fix

Rewrite e2e/anvil/anvil-filters.spec.ts (and the shared helpers in e2e/testFunctions.ts it depends on) in the style of the recently updated e2e/anvil-catalog/anvilcatalog-filters.spec.ts:

  • Use test-id-based locators (TEST_IDS.FILTERS, TEST_IDS.FILTER_POPOVER, TEST_IDS.FILTER_ITEM, TEST_IDS.FILTER_TERM) instead of CSS IDs and text-only matches.
  • Extract the option display name via getByTestId(TEST_IDS.FILTER_TERM).innerText() rather than innerText().split("\n").
  • Re-locate selected items by name after each interaction (see namedPopoverFilterItem / namedFilterItem in the catalog spec) so list re-sorts don't desynchronize the assertion target from the actual selected item.
  • Locate filter tags via the MUI Chip class scoped to the filters container (see filterTag() helper in catalog spec) — more specific than #sidebar-positioner text.
  • Add explicit popover open/close waits (expectFilterPopoverOpen / expectFilterPopoverClosed) instead of generic waitForLoadState("load").
  • Escape RegExp special chars in option names with escapeRegExp (option names like .md5 would otherwise be interpreted as regex if matched without exactness).

Acceptance criteria

  • The BioSamples filter-tag test runs reliably in CI (no flakes across multiple runs).
  • The Files tab equivalent (line 129) is migrated to the same pattern.
  • Test-id-based locators replace #sidebar-positioner text lookups in this spec.
  • Helpers shared with this spec in e2e/testFunctions.ts are either updated or replaced with locally-defined helpers in the catalog-spec style.

Reference

  • Failing helper: e2e/testFunctions.ts:608-644 (testFilterTags), e2e/testFunctions.ts:595 (getFilterTagLocator)
  • Reference style: e2e/anvil-catalog/anvilcatalog-filters.spec.ts

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions