Skip to content

Toast: several tests have assertions that never run due to misuse of timers/promises setTimeout #2359

Description

@rheisler-deque

Problem

Two tests in packages/react/src/components/Toast/toast.test.tsx use this pattern:

await waitFor(async () => {
  await setTimeout(undefined, () => {
    expect(...).toHaveClass('is--hidden');
  });
});

setTimeout is imported from timers/promises (line 2). Its signature is setTimeout(delay, value, options) — the second argument is the resolve value, not a callback. The arrow function holding the expect is never invoked. Because the promise resolves without throwing, the outer waitFor succeeds immediately and the inner assertion is dead code.

Affected tests

  1. 'should transition from shown to hidden' (toast.test.tsx:82-111) — runs once per type via Object.entries(toastTypes).forEach(...), so 5 dead-assertion test cases. This is the only named coverage of the show: true → false → 'is--hidden' transition.

  2. 'deactivates aria isolate on unmount' (toast.test.tsx:253-281) — same pattern, plus two additional issues: it renders type="info" (which never instantiates an AriaIsolate, so even if the assertion ran it would fail), and it never actually unmounts the component.

Proposal

For test 1, replace with the standard waitFor form already used elsewhere in this file:

await waitFor(() => {
  expect(screen.getByTestId('toast')).toHaveClass('Toast', 'Toast--info', 'is--hidden');
});

For test 2, rewrite to render type="action-needed" with show={true}, capture the unmount from the render result, and assert AriaIsolate.prototype.deactivate was spied and called after unmount.

Surfacing

Found while reviewing #2349.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions