Skip to content

Fix flaky UnreadIndicators mark-as-unread test#92125

Draft
neil-marcellini wants to merge 1 commit into
mainfrom
neil-marcellini/fix-flaky-unread-indicators-test
Draft

Fix flaky UnreadIndicators mark-as-unread test#92125
neil-marcellini wants to merge 1 commit into
mainfrom
neil-marcellini/fix-flaky-unread-indicators-test

Conversation

@neil-marcellini
Copy link
Copy Markdown
Contributor

Explanation of Change

(Neil's AI agent)
Fixes a flaky CI test: Unread Indicators › Mark the chat as unread on clicking "Mark as unread" on an item in LHN when the last message of the chat was deleted by another user in tests/ui/UnreadIndicatorsTest.tsx.

Failure observed on CI

expect(received).toHaveLength(expected)
Expected length: 1
Received length: 0
Received array:  []
  at tests/ui/UnreadIndicatorsTest.tsx:831

Root cause
The assertion read the rendered LHN synchronously, immediately after a single await waitForBatchedUpdates():

await waitForBatchedUpdates();
const displayNameTexts = screen.queryAllByLabelText(hintText);
expect(displayNameTexts).toHaveLength(1);

The preceding steps fire several async Onyx.merge calls plus markCommentAsUnread, which triggers an LHN recompute/re-sort. A single waitForBatchedUpdates() does not guarantee the chat row has re-mounted, so the synchronous query can run before the row renders and find 0. Other UI assertions in this same file already wrap reads in waitFor(...) (e.g. lines 285, 453, 487) to avoid this exact race.

Fix
Wrap the assertion in waitFor(...) so it retries until the LHN row renders. This is strictly more tolerant of render timing and never less correct.

Fixed Issues

$ #92122
PROPOSAL: N/A (flaky test fix)

For #92118

Tests

(Neil's AI agent)

Evidence of flakiness (before the fix) — the same test, at the same line, failed on two unrelated main merges within ~3 hours, neither of which touches this test or the LHN:

The failure is a CI-only timing flake and does not reproduce in local single-file loops (expected for timing flakes). To prove the failure mechanism the fix targets, a throwaway test confirmed that a synchronous queryAllByLabelText misses an element that renders one tick later (reproducing Received length: 0), while the waitFor version passes:

✕ OLD pattern: synchronous query can miss the row   -> Received length: 0
✓ NEW pattern: waitFor retries until the row renders

Proof of stability (after the fix) — ran the full UnreadIndicatorsTest.tsx file 25× under heavy CPU load (8 stressors) to simulate CI contention:

DONE after pass=25 fail=0

(Before the fix, the same loop was also green locally — 25/25 — confirming the flake is CI-only, not a local hard failure.)

Reviewer can reproduce:

  1. npx jest tests/ui/UnreadIndicatorsTest.tsx --runInBand
  2. Verify the suite passes.
  • Verify that no errors appear in the JS console

Offline tests

N/A — test-only change.

QA Steps

N/A — test-only change. [No QA]

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.

Screenshots/Videos

N/A — test-only change.

Made with Cursor

… render

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant