lightsoutAlpha

testing-user-interactions

an interaction test that groups the target query with arrange instead of the act

Agent checkadvisory by defaultreacttests

The argument

Testing User Interactions

userEvent is async — create the user in the test and await the interaction. The query that locates the interaction target groups with the act (the userEvent call), not with arrange:

test('calls the dismiss handler when the dismiss button is clicked', async () => {
	const { onDismiss } = setupBanner();
	const user = userEvent.setup();

	const dismissButton = screen.getByRole('button', { name: /dismiss/i });
	await user.click(dismissButton);

	expect(onDismiss).toHaveBeenCalledTimes(1);
});

When the package lacks @testing-library/user-event, use fireEvent instead — synchronous, no setup object: fireEvent.click(dismissButton);. The same grouping rule applies: the target query groups with the act.

The proof

failsrc/notifications/NotificationBanner.unit.test.tsx
import { expect, describe, test, jest } from '@jest/globals';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { NotificationBanner } from './NotificationBanner';

const setupNotificationBanner = () => {
	const onDismiss = jest.fn<() => void>();
	render(<NotificationBanner onDismiss={onDismiss} />);

	return { onDismiss };
};

describe('NotificationBanner', () => {
	test('calls the dismiss handler when the dismiss button is clicked', async () => {
		const { onDismiss } = setupNotificationBanner();
		// the target query grouped with arrange, and the interaction left unawaited
		const dismissButton = screen.getByRole('button', { name: /dismiss/i });
		const user = userEvent.setup();

		user.click(dismissButton);

		expect(onDismiss).toHaveBeenCalledTimes(1);
	});
});
passsrc/notifications/NotificationBanner.unit.test.tsx
import { expect, describe, test, jest } from '@jest/globals';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { NotificationBanner } from './NotificationBanner';

const setupNotificationBanner = () => {
	const onDismiss = jest.fn<() => void>();
	render(<NotificationBanner onDismiss={onDismiss} />);

	return { onDismiss };
};

describe('NotificationBanner', () => {
	test('calls the dismiss handler when the dismiss button is clicked', async () => {
		const { onDismiss } = setupNotificationBanner();
		const user = userEvent.setup();

		const dismissButton = screen.getByRole('button', { name: /dismiss/i });
		await user.click(dismissButton);

		expect(onDismiss).toHaveBeenCalledTimes(1);
	});
});

Turn it down

Both lines go in your lightsout.config.json.

"standards-checks": { "testing-user-interactions": "advisory" }
"standards-checks": { "testing-user-interactions": "off" }