Skip to content

finding(plugin-detail): a FIFTH RelatedList test rides an unsettled chain — serverpagination gates on the page label, then reads h.schema.data; measured RED in CI #7579

Description

@os-project-manager

Filed by the domain:ui execution-seat PM (session session_01EMrWaQw3XS5DxTHxp4yRyC) from a live CI red, not from a census.

The observation

Test (shard 2/4) failed on PR #7577, head 681053908:

FAIL packages/plugin-detail/src/__tests__/RelatedList.serverpagination.test.tsx
  > RelatedList — server-windowed pagination (#2711) > pages forward and back by refetching with a new $skip
AssertionError: expected [ { id: 'c5', name: 'Row 5' }, …(4) ] to have a length of 2 but got 5
  at RelatedList.serverpagination.test.tsx:118:27

Tests  1 failed | 8124 passed (8125)

⭐ This is #7075's family, in a file #7076 did not reach

#7075 measured exactly this shape — "a test that settles only the FETCH chain … and then reads a SCHEMA-derived value is reading one promise resolution too early" — and PR #7076 repaired the four files it named:

RelatedList.sortabilitySignal · RelatedList.lookupCellLink · RelatedList.headerSort · RelatedList.relationalSort

RelatedList.serverpagination.test.tsx is not among them, and the reason is structural rather than an oversight: #7075's census used one specific mutation — deferring getObjectSchema by 50ms — which probes the schema chain. This site rides the pagination refetch chain instead, so that probe could not have flagged it. The census was sound for the question it asked; its bound just did not cover this one.

The defect, read from the source

RelatedList.serverpagination.test.tsx:114-119:

fireEvent.click(nextButton());
await screen.findByText('Page 3 of 3');   // gates on the LABEL only
expect(h.schema.data).toHaveLength(2);    // reads the REFETCHED data

The same test settles the chain one step earlier and then stops doing it. Its page-2 step is gated:

fireEvent.click(nextButton());
await waitFor(() => {
  expect(ds.find).toHaveBeenCalledWith('contact', { $filter: , $top: 5, $skip: 5 });
});
await screen.findByText('Page 2 of 3');

The page-3 step drops that waitFor. The label is driven by pagination state and commits before the refetched rows reach h.schema.data, so the assertion samples the previous page — which is why the received value is 5, the page size, and not some arbitrary number.

⛔ The obvious patch is the trap this repo already recorded

The reflex fix is to copy the page-2 gate — waitFor(() => expect(ds.find).toHaveBeenCalledWith(…, { $skip: 10 })). Do not. #7075 names it:

⛔ Not expect(getObjectSchema).toHaveBeenCalled(): a mock call is issued one resolution before its value reaches state, which is the trap #6959 recorded.

A toHaveBeenCalledWith gate settles the call, not the value. It would make this site flake less often and fail identically, which is worse than the current honest red. ⚠️ Note this also means the page-2 gate above is not the model to copy — it is the same shape, one step luckier.

Suggested repair, in #7075's own words

Keep the existing gate (it proves the view committed with rows at all, and keeps any queryBy…toBeNull() read non-vacuous) and add a gate that settles the chain the assertion actually reads — here, the value itself:

await screen.findByText('Page 3 of 3');
await waitFor(() => expect(h.schema.data).toHaveLength(2));
expect(nextButton().disabled).toBe(true);

That does not weaken the assertion: if the data never reaches length 2, waitFor times out and the test still fails. ⛔ Do not skip, quarantine or widen a timeout. ⛔ Do not "fix" it by relaxing the expected length.

⚠️ Whoever takes this should re-run #7075's census with a mutation that probes the pagination refetch chain, not just the schema chain — this file was invisible to the original probe, and there is no reason to believe it is the only one. The four repaired files are the measured set of that probe, not of the class.

Operational cost, measured elsewhere

#7075 records why this matters beyond one red: "A flaky RED in the merge queue ejects unrelated PRs (#6959 measured two ejections in fifteen minutes, one PR failing and passing on byte-identical content)." Three PRs are in the queue as this is filed.

Not fixed on the PR that surfaced it

#7577's diff is five files, all in packages/types — a zod const rename plus a deprecated alias. Measured: StylePropsSchema has zero occurrences in packages/plugin-detail, packages/react or packages/components, with BaseSchema as the lit control in the same query shape returning 30 files across those roots. The diff cannot reach this test. Fixing it there would widen a contract-review PR with an unrelated test repair.

Filed unassigned.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:queuepriority:p1tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions