Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test] Use vitest's userEvent implementation in browser tests #1314

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions packages/react/src/accordion/root/AccordionRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ describe('<Accordion.Root />', () => {
expect(trigger).to.have.attribute('aria-expanded', 'false');
expect(queryByText(PANEL_CONTENT_1)).to.equal(null);

await user.pointer({ keys: '[MouseLeft]', target: trigger });
await user.click(trigger);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vitest doesn't have the pointer method but clicks should work the same way in these cases


expect(trigger).to.have.attribute('aria-expanded', 'true');
expect(trigger).to.have.attribute('data-panel-open');
expect(queryByText(PANEL_CONTENT_1)).to.not.equal(null);
expect(queryByText(PANEL_CONTENT_1)).toBeVisible();
expect(queryByText(PANEL_CONTENT_1)).to.have.attribute('data-open');

await user.pointer({ keys: '[MouseLeft]', target: trigger });
await user.click(trigger);

expect(trigger).to.have.attribute('aria-expanded', 'false');
expect(queryByText(PANEL_CONTENT_1)).to.equal(null);
Expand Down Expand Up @@ -461,7 +461,7 @@ describe('<Accordion.Root />', () => {

const [trigger1, , , trigger4] = getAllByRole('button');

await user.pointer({ keys: '[MouseLeft]', target: trigger4 });
await user.click(trigger4);
expect(trigger4).toHaveFocus();

await user.keyboard('[Home]');
Expand Down Expand Up @@ -528,8 +528,8 @@ describe('<Accordion.Root />', () => {
expect(queryByText(PANEL_CONTENT_1)).to.equal(null);
expect(queryByText(PANEL_CONTENT_2)).to.equal(null);

await user.pointer({ keys: '[MouseLeft]', target: trigger1 });
await user.pointer({ keys: '[MouseLeft]', target: trigger2 });
await user.click(trigger1);
await user.click(trigger2);

expect(queryByText(PANEL_CONTENT_1)).to.have.attribute('data-open');
expect(queryByText(PANEL_CONTENT_2)).to.have.attribute('data-open');
Expand Down Expand Up @@ -562,12 +562,12 @@ describe('<Accordion.Root />', () => {
expect(trigger1).to.not.have.attribute('data-panel-open');
expect(trigger2).to.not.have.attribute('data-panel-open');

await user.pointer({ keys: '[MouseLeft]', target: trigger1 });
await user.click(trigger1);

expect(queryByText(PANEL_CONTENT_1)).to.have.attribute('data-open');
expect(trigger1).to.have.attribute('data-panel-open');

await user.pointer({ keys: '[MouseLeft]', target: trigger2 });
await user.click(trigger2);

expect(queryByText(PANEL_CONTENT_2)).to.have.attribute('data-open');
expect(trigger2).to.have.attribute('data-panel-open');
Expand Down Expand Up @@ -679,12 +679,12 @@ describe('<Accordion.Root />', () => {

expect(onValueChange.callCount).to.equal(0);

await user.pointer({ keys: '[MouseLeft]', target: trigger1 });
await user.click(trigger1);

expect(onValueChange.callCount).to.equal(1);
expect(onValueChange.args[0][0]).to.deep.equal([0]);

await user.pointer({ keys: '[MouseLeft]', target: trigger2 });
await user.click(trigger2);

expect(onValueChange.callCount).to.equal(2);
expect(onValueChange.args[1][0]).to.deep.equal([0, 1]);
Expand Down Expand Up @@ -714,12 +714,12 @@ describe('<Accordion.Root />', () => {

expect(onValueChange.callCount).to.equal(0);

await user.pointer({ keys: '[MouseLeft]', target: trigger2 });
await user.click(trigger2);

expect(onValueChange.callCount).to.equal(1);
expect(onValueChange.args[0][0]).to.deep.equal(['two']);

await user.pointer({ keys: '[MouseLeft]', target: trigger1 });
await user.click(trigger1);

expect(onValueChange.callCount).to.equal(2);
expect(onValueChange.args[1][0]).to.deep.equal(['two', 'one']);
Expand Down Expand Up @@ -749,12 +749,12 @@ describe('<Accordion.Root />', () => {

expect(onValueChange.callCount).to.equal(0);

await user.pointer({ keys: '[MouseLeft]', target: trigger1 });
await user.click(trigger1);

expect(onValueChange.callCount).to.equal(1);
expect(onValueChange.args[0][0]).to.deep.equal(['one']);

await user.pointer({ keys: '[MouseLeft]', target: trigger2 });
await user.click(trigger2);

expect(onValueChange.callCount).to.equal(2);
expect(onValueChange.args[1][0]).to.deep.equal(['two']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ describe('<Collapsible.Root />', () => {
expect(trigger).to.have.attribute('aria-expanded', 'false');
expect(queryByText(PANEL_CONTENT)).to.equal(null);

await user.pointer({ keys: '[MouseLeft]', target: trigger });
await user.click(trigger);

expect(trigger).to.have.attribute('aria-expanded', 'true');
expect(queryByText(PANEL_CONTENT)).to.not.equal(null);
expect(queryByText(PANEL_CONTENT)).toBeVisible();
expect(queryByText(PANEL_CONTENT)).to.have.attribute('data-open');
expect(trigger).to.have.attribute('data-panel-open');

await user.pointer({ keys: '[MouseLeft]', target: trigger });
await user.click(trigger);

expect(trigger).to.not.have.attribute('aria-controls');
expect(trigger).to.have.attribute('aria-expanded', 'false');
Expand Down
40 changes: 19 additions & 21 deletions packages/react/src/dialog/popup/DialogPopup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,27 +282,25 @@ describe('<Dialog.Popup />', () => {
function App() {
const [showNested, setShowNested] = React.useState(true);
return (
<React.Fragment>
<button onClick={() => setShowNested(!showNested)}>toggle</button>
<Dialog.Root>
<Dialog.Trigger>Trigger 0</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup0">
{showNested && (
<Dialog.Root>
<Dialog.Trigger>Trigger 1</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup1">
<Dialog.Close>Close 1</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)}
<Dialog.Close>Close 0</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</React.Fragment>
<Dialog.Root modal={false}>
<Dialog.Trigger>Trigger 0</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup0">
{showNested && (
<Dialog.Root modal={false}>
<Dialog.Trigger>Trigger 1</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup data-testid="popup1">
<button onClick={() => setShowNested(!showNested)}>toggle</button>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vitest functions are more strict about visibility and accessibility of the element to interact with.

<Dialog.Close>Close 1</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)}
<Dialog.Close>Close 0</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
);
}

Expand Down
24 changes: 7 additions & 17 deletions packages/react/src/dialog/root/DialogRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('<Dialog.Root />', () => {
return (
<div>
<button onClick={() => setOpen(false)}>Close</button>
<Dialog.Root open={open}>
<Dialog.Root open={open} modal={false}>
<Dialog.Portal>
<Dialog.Popup />
</Dialog.Portal>
Expand Down Expand Up @@ -120,14 +120,15 @@ describe('<Dialog.Root />', () => {
<div>
{/* eslint-disable-next-line react/no-danger */}
<style dangerouslySetInnerHTML={{ __html: style }} />
<button onClick={() => setOpen(false)}>Close</button>
<Dialog.Root open={open}>
<Dialog.Portal keepMounted>
<Dialog.Popup
className="animation-test-popup"
data-testid="popup"
onAnimationEnd={notifyAnimationFinished}
/>
>
<button onClick={() => setOpen(false)}>Close</button>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</div>
Expand Down Expand Up @@ -514,11 +515,7 @@ describe('<Dialog.Root />', () => {
expect(screen.queryByRole('dialog')).not.to.equal(null);
});

const dialogPopup = screen.getByTestId('dialog-popup');
const dialogInternalBackdrop = dialogPopup.previousElementSibling
?.previousElementSibling as HTMLElement;

await user.click(dialogInternalBackdrop);
await user.click(document.body);

await waitFor(() => {
expect(screen.queryByRole('dialog')).to.equal(null);
Expand Down Expand Up @@ -561,10 +558,7 @@ describe('<Dialog.Root />', () => {
expect(screen.queryByRole('listbox')).not.to.equal(null);
});

const selectPositioner = screen.getByTestId('select-positioner');
const selectInternalBackdrop = selectPositioner.previousElementSibling as HTMLElement;

await user.click(selectInternalBackdrop);
await user.click(document.body);

await waitFor(() => {
expect(screen.queryByRole('listbox')).to.equal(null);
Expand All @@ -573,11 +567,7 @@ describe('<Dialog.Root />', () => {
expect(screen.queryByRole('dialog')).not.to.equal(null);
});

const dialogPopup = screen.getByTestId('dialog-popup');
const dialogInternalBackdrop = dialogPopup.previousElementSibling
?.previousElementSibling as HTMLElement;

await user.click(dialogInternalBackdrop);
await user.click(document.body);

await waitFor(() => {
expect(screen.queryByRole('dialog')).to.equal(null);
Expand Down
19 changes: 9 additions & 10 deletions packages/react/src/field/root/FieldRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import { Slider } from '@base-ui-components/react/slider';
import { RadioGroup } from '@base-ui-components/react/radio-group';
import { Radio } from '@base-ui-components/react/radio';
import { Select } from '@base-ui-components/react/select';
import userEvent from '@testing-library/user-event';
import { act, fireEvent, flushMicrotasks, screen, waitFor } from '@mui/internal-test-utils';
import { expect } from 'chai';
import { createRenderer, describeConformance } from '#test-utils';

const user = userEvent.setup();

describe('<Field.Root />', () => {
const { render } = createRenderer();

Expand Down Expand Up @@ -530,7 +527,7 @@ describe('<Field.Root />', () => {
});

it('supports RadioGroup (blur)', async () => {
await render(
const { user } = await render(
<Field.Root>
<RadioGroup data-testid="group">
<Radio.Root value="1" data-testid="control">
Expand All @@ -545,8 +542,8 @@ describe('<Field.Root />', () => {
const group = screen.getByTestId('group');
const control = screen.getByTestId('control');

await userEvent.tab(); // onto control
await userEvent.tab(); // onto last button
await user.tab(); // onto control
await user.tab(); // onto last button

expect(group).to.have.attribute('data-touched', '');
expect(control).to.have.attribute('data-touched', '');
Expand Down Expand Up @@ -681,10 +678,12 @@ describe('<Field.Root />', () => {
});

it('supports Select', async () => {
await render(
const { user } = await render(
<Field.Root>
<Select.Root>
<Select.Trigger data-testid="trigger" />
<Select.Trigger data-testid="trigger">
<Select.Value placeholder="Select" />
</Select.Trigger>
<Select.Portal>
<Select.Positioner>
<Select.Popup>
Expand All @@ -701,7 +700,7 @@ describe('<Field.Root />', () => {

expect(trigger).not.to.have.attribute('data-dirty');

await userEvent.click(trigger);
await user.click(trigger);

await flushMicrotasks();

Expand All @@ -710,7 +709,7 @@ describe('<Field.Root />', () => {
// Arrow Down to focus the Option 1
await user.keyboard('{ArrowDown}');

await userEvent.click(option);
await user.click(option);

await flushMicrotasks();

Expand Down
7 changes: 2 additions & 5 deletions packages/react/src/menu/positioner/MenuPositioner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { expect } from 'chai';
import userEvent from '@testing-library/user-event';
import { flushMicrotasks } from '@mui/internal-test-utils';
import { Menu } from '@base-ui-components/react/menu';
import { describeConformance, createRenderer, isJSDOM } from '#test-utils';
Expand Down Expand Up @@ -211,10 +210,8 @@ describe('<Menu.Positioner />', () => {
});

describe('prop: keepMounted', () => {
const user = userEvent.setup();

it('when keepMounted=true, should keep the content mounted when closed', async () => {
const { getByRole, queryByRole } = await render(
const { getByRole, queryByRole, user } = await render(
<Menu.Root modal={false}>
<Menu.Trigger>Toggle</Menu.Trigger>
<Menu.Portal keepMounted>
Expand Down Expand Up @@ -244,7 +241,7 @@ describe('<Menu.Positioner />', () => {
});

it('when keepMounted=false, should unmount the content when closed', async () => {
const { getByRole, queryByRole } = await render(
const { getByRole, queryByRole, user } = await render(
<Menu.Root modal={false}>
<Menu.Trigger>Toggle</Menu.Trigger>
<Menu.Portal keepMounted={false}>
Expand Down
Loading
Loading