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

Migrate to using @testing-library/user-event #175

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const { getByRole, getByLabelText } = render(
expect(getByRole("form")).toHaveFormValues({ food: "" });

// start typing to trigger the `loadOptions`
fireEvent.change(getByLabelText("Food"), { target: { value: "Choc" } });
userEvent.type(getByLabelText("Food"), "Choc");
await selectEvent.select(getByLabelText("Food"), "Chocolate");
expect(getByRole("form")).toHaveFormValues({
food: ["chocolate"],
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
},
"homepage": "https://github.com/romgain/react-select-event#readme",
"dependencies": {
"@testing-library/dom": ">=7"
"@testing-library/dom": ">=7",
"@testing-library/user-event": ">=14"
},
"devDependencies": {
"@babel/core": "^7.4.5",
Expand All @@ -46,14 +47,14 @@
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"@testing-library/jest-dom": "^5.0.1",
"@testing-library/react": "^12.1.5",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.1.2",
"@types/react": "^17.0.47",
"@types/react": "^18.2.6",
"@types/react-select": "^5.0.1",
"jest": "^27.0.4",
"prettier": "^2.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-select": "^5.0.0",
"rimraf": "^3.0.0",
"rollup": "^2.0.3",
Expand Down
264 changes: 230 additions & 34 deletions src/__tests__/select-event.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "@testing-library/jest-dom/extend-expect";

import { fireEvent, render } from "@testing-library/react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import React from "react";
import Select from "react-select";
Expand Down Expand Up @@ -56,27 +57,55 @@ const renderForm = (select: React.ReactNode) => {
};

describe("The openMenu event helper", () => {
it("opens the menu", () => {
it("opens the menu", async () => {
const { getByLabelText, queryByText } = renderForm(
<Select {...defaultProps} />
);
// option is not yet visible
expect(queryByText("Chocolate")).toBeNull();
selectEvent.openMenu(getByLabelText("Food"));
await selectEvent.openMenu(getByLabelText("Food"));
// option can now be seen because menu is open
expect(queryByText("Chocolate")).toBeInTheDocument();
});

it("does not prevent selecting options", async () => {
const { form, input, getByText } = renderForm(<Select {...defaultProps} />);
selectEvent.openMenu(input);
await selectEvent.openMenu(input);
expect(getByText("Chocolate")).toBeInTheDocument();
expect(getByText("Vanilla")).toBeInTheDocument();
expect(getByText("Strawberry")).toBeInTheDocument();
expect(getByText("Mango")).toBeInTheDocument();
await selectEvent.select(input, "Strawberry");
expect(form).toHaveFormValues({ food: "strawberry" });
});

it("allows passing custom userEvent option", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const { input } = renderForm(<Select {...defaultProps} />);

await selectEvent.openMenu(input, { user });

expect(user.click).toHaveBeenCalledWith(input);
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");
});

it("allows passing custom userEvent option with setup", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const userSelectEvent = selectEvent.setup(user);

const { input } = renderForm(<Select {...defaultProps} />);

await userSelectEvent.openMenu(input);

expect(user.click).toHaveBeenCalledWith(input);
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");
});
});

describe("The select event helpers", () => {
Expand Down Expand Up @@ -240,6 +269,7 @@ describe("The select event helpers", () => {
});

it("selects an option in an async input", async () => {
const user = userEvent.setup();
const loadOptions = (_: string, callback: Callback) =>
setTimeout(() => callback(OPTIONS), 100);
const { form, input } = renderForm(
Expand All @@ -248,7 +278,7 @@ describe("The select event helpers", () => {
expect(form).toHaveFormValues({ food: "" });

// start typing to trigger the `loadOptions`
fireEvent.change(input, { target: { value: "Choc" } });
await user.type(input, "Choc");
await selectEvent.select(input, "Chocolate");
expect(form).toHaveFormValues({ food: "chocolate" });
});
Expand Down Expand Up @@ -344,6 +374,42 @@ describe("The select event helpers", () => {
expect(form).toHaveFormValues({ food: "vanilla" });
});

it("allows passing custom userEvent option", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const { input } = renderForm(<Select {...defaultProps} />);

await selectEvent.select(input, "Chocolate", { user });

// Open the dropdown
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");
expect(user.click).toHaveBeenNthCalledWith(1, input);

// Difficult to get correct element here but it's fine as long as we get an element
expect(user.click).toHaveBeenNthCalledWith(2, expect.any(HTMLDivElement));
});

it("allows passing custom userEvent option with setup", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const userSelectEvent = selectEvent.setup(user);

const { input } = renderForm(<Select {...defaultProps} />);

await userSelectEvent.select(input, "Chocolate");

// Open the dropdown
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");
expect(user.click).toHaveBeenNthCalledWith(1, input);

// Difficult to get correct element here but it's fine as long as we get an element
expect(user.click).toHaveBeenNthCalledWith(2, expect.any(HTMLDivElement));
});

describe("when asynchronously generating the list of options", () => {
// from https://github.com/JedWatson/react-select/blob/v3.0.0/docs/examples/CreatableAdvanced.js
// mixed with Async Creatable Example from https://react-select.com/creatable
Expand Down Expand Up @@ -416,6 +482,56 @@ describe("The select event helpers", () => {

expect(form).toHaveFormValues({ food: "papaya" });
});

it("allows passing custom userEvent option", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const { input } = renderForm(<CreatableAdvanced {...defaultProps} />);

await selectEvent.create(input, "papaya", { user });

// Open the dropdown
expect(user.click).toHaveBeenNthCalledWith(1, input);
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");

// Create option
expect(user.type).toHaveBeenNthCalledWith(2, input, "papaya");

// Open dropdown again
expect(user.click).toHaveBeenNthCalledWith(2, input);

// Select the new option
// Difficult to get correct element here but it's fine as long as we get an element
expect(user.click).toHaveBeenNthCalledWith(3, expect.any(HTMLDivElement));
});

it("allows passing custom userEvent option with setup", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");
jest.spyOn(user, "type");

const userSelectEvent = selectEvent.setup(user);

const { input } = renderForm(<CreatableAdvanced {...defaultProps} />);

await userSelectEvent.create(input, "papaya");

// Open the dropdown
expect(user.click).toHaveBeenNthCalledWith(1, input);
expect(user.type).toHaveBeenCalledWith(input, "{ArrowDown}");

// Create option
expect(user.type).toHaveBeenNthCalledWith(2, input, "papaya");

// Open dropdown again
expect(user.click).toHaveBeenNthCalledWith(2, input);

// Select the new option
// Difficult to get correct element here but it's fine as long as we get an element
expect(user.click).toHaveBeenNthCalledWith(3, expect.any(HTMLDivElement));
});
});

describe("when rendering the dropdown in a portal", () => {
Expand Down Expand Up @@ -452,39 +568,119 @@ describe("The select event helpers", () => {
await selectEvent.create(input, "papaya", { container: document.body });
expect(form).toHaveFormValues({ food: "papaya" });
});
});
});

it("clears the first item in a multi-select dropdown", async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});

await selectEvent.clearFirst(input);
expect(form).toHaveFormValues({ food: ["vanilla", "strawberry"] });
describe("clearFirst", () => {
it("clears the first item in a multi-select dropdown", async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});

it("clears all items", async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});
await selectEvent.clearFirst(input);
expect(form).toHaveFormValues({ food: ["vanilla", "strawberry"] });
});

await selectEvent.clearAll(input);
expect(form).toHaveFormValues({ food: "" });
it("allows passing custom userEvent option", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");

const { input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);

await selectEvent.clearFirst(input, { user });

expect(user.click).toHaveBeenCalledWith(expect.any(SVGSVGElement));
});

it("allows passing custom userEvent option with setup", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");

const userSelectEvent = selectEvent.setup(user);

const { input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);

await userSelectEvent.clearFirst(input);

expect(user.click).toHaveBeenCalledWith(expect.any(SVGSVGElement));
});
});

describe("clearAll", () => {
it("clears all items", async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});

await selectEvent.clearAll(input);
expect(form).toHaveFormValues({ food: "" });
});

it("allows passing custom userEvent option", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");

const { input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);

await selectEvent.clearAll(input, { user });

expect(user.click).toHaveBeenCalledWith(expect.any(SVGSVGElement));
});

it("allows passing custom userEvent option with setup", async () => {
const user = userEvent.setup();
jest.spyOn(user, "click");

const userSelectEvent = selectEvent.setup(user);

const { input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
menuPortalTarget={document.body}
/>
);

await userSelectEvent.clearAll(input);

expect(user.click).toHaveBeenCalledWith(expect.any(SVGSVGElement));
});
});
26 changes: 0 additions & 26 deletions src/act-compat.ts

This file was deleted.

Loading