(Neil's AI agent)
Problem
The 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 (tests/ui/UnreadIndicatorsTest.tsx:831) is flaky. It regularly passes but intermittently fails on main.
Failure output:
expect(received).toHaveLength(expected)
Expected length: 1
Received length: 0
Received array: []
at Object.toHaveLength (tests/ui/UnreadIndicatorsTest.tsx:831:34)
The LHN chat row's display name has not rendered yet, so screen.queryAllByLabelText('accessibilityHints.chatUserDisplayNames') returns [].
Evidence it is flaky (fails on unrelated PRs)
The same test, at the same line, failed on two unrelated main merges within ~3 hours:
Neither PR touches UnreadIndicatorsTest.tsx or the LHN rendering logic, and the test file itself has not changed since 2026-05-13.
Surfaced from the workflow-failure issue #92118.
Likely root cause (hypothesis)
The assertion reads the rendered LHN synchronously after a single await waitForBatchedUpdates():
markCommentAsUnread(REPORT_ID, reportActions, {reportActionID: -1} as unknown as ReportAction, USER_A_ACCOUNT_ID);
await waitForBatchedUpdates();
const hintText = TestHelper.translateLocal('accessibilityHints.chatUserDisplayNames');
const displayNameTexts = screen.queryAllByLabelText(hintText);
expect(displayNameTexts).toHaveLength(1);
The preceding steps fire several async Onyx.merge calls (two report actions, lastVisibleActionCreated set twice, last message html cleared) plus markCommentAsUnread, which triggers LHN recomputation and re-sort. A single waitForBatchedUpdates() does not guarantee the LHN row has re-mounted, so the synchronous query can run before the row renders. Other UI assertions in this same file already wrap reads in waitFor(...) (e.g. lines 285, 453, 487) to avoid this exact race.
Solution
Determine the root cause and fix it. A likely fix is to wrap the assertion in waitFor so it retries until the row renders:
const hintText = TestHelper.translateLocal('accessibilityHints.chatUserDisplayNames');
await waitFor(() => {
const displayNameTexts = screen.queryAllByLabelText(hintText);
expect(displayNameTexts).toHaveLength(1);
expect((displayNameTexts.at(0)?.props?.style as TextStyle)?.fontWeight).toBe(FontUtils.fontWeight.bold);
});
Validate stability by running the test in a loop locally (e.g. npm test -- UnreadIndicatorsTest -i, ~10–20x).
Context
This test was introduced by @c3024 in #61374.
Issue Owner
Current Issue Owner: @c3024
(Neil's AI agent)
Problem
The 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(tests/ui/UnreadIndicatorsTest.tsx:831) is flaky. It regularly passes but intermittently fails onmain.Failure output:
The LHN chat row's display name has not rendered yet, so
screen.queryAllByLabelText('accessibilityHints.chatUserDisplayNames')returns[].Evidence it is flaky (fails on unrelated PRs)
The same test, at the same line, failed on two unrelated
mainmerges within ~3 hours:Neither PR touches
UnreadIndicatorsTest.tsxor the LHN rendering logic, and the test file itself has not changed since 2026-05-13.Surfaced from the workflow-failure issue #92118.
Likely root cause (hypothesis)
The assertion reads the rendered LHN synchronously after a single
await waitForBatchedUpdates():The preceding steps fire several async
Onyx.mergecalls (two report actions,lastVisibleActionCreatedset twice, last messagehtmlcleared) plusmarkCommentAsUnread, which triggers LHN recomputation and re-sort. A singlewaitForBatchedUpdates()does not guarantee the LHN row has re-mounted, so the synchronous query can run before the row renders. Other UI assertions in this same file already wrap reads inwaitFor(...)(e.g. lines 285, 453, 487) to avoid this exact race.Solution
Determine the root cause and fix it. A likely fix is to wrap the assertion in
waitForso it retries until the row renders:Validate stability by running the test in a loop locally (e.g.
npm test -- UnreadIndicatorsTest -i, ~10–20x).Context
This test was introduced by @c3024 in #61374.
Issue Owner
Current Issue Owner: @c3024