Testing through the DOM rather than the component instance

A test that reaches into component state asserts on the implementation, and every refactor that changed nothing observable breaks it.

// asserts on internals
expect(wrapper.state('loading')).toBe(false);
expect(wrapper.find('Spinner')).toHaveLength(0);

// asserts on what a user can see
expect(screen.queryByRole('status')).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: /pay/i })).toBeEnabled();

await userEvent.click(screen.getByRole('button', { name: /pay/i }));

Querying by role rather than by test id is the part that pays twice: the test breaks when the accessibility tree changes, which is usually a real regression, and writing the query forces you to notice when an element has no role at all. findBy queries return a promise and retry, which removes most of the arbitrary waiting that makes component tests flaky.