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

Fix/onchange text input #147

Merged
merged 2 commits into from Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 14 additions & 5 deletions __tests__/react/type.js
@@ -1,5 +1,5 @@
import React from "react";
import { cleanup, render, wait } from "@testing-library/react";
import { cleanup, render, wait, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import userEvent from "../../src";

Expand Down Expand Up @@ -35,31 +35,40 @@ describe("userEvent.type", () => {
expect(getByTestId("input")).not.toHaveProperty("value", text);
});

it("should delayed the typing when opts.dealy is not 0", async () => {
it("should delay the typing when opts.delay is not 0", async () => {
jest.useFakeTimers();
const onChange = jest.fn();
const onInput = jest.fn();
const { getByTestId } = render(
React.createElement("input", {
"data-testid": "input",
onChange: onChange
onInput,
onChange
})
);
const text = "Hello, world!";
const delay = 10;
// Attach a native change listener because React cannot listen for text input change events
userEvent.type(getByTestId("input"), text, {
delay
});
expect(onChange).not.toHaveBeenCalled();
expect(onInput).not.toHaveBeenCalled();
expect(getByTestId("input")).not.toHaveProperty("value", text);

for (let i = 0; i < text.length; i++) {
jest.advanceTimersByTime(delay);
await wait(() => expect(onChange).toHaveBeenCalledTimes(i + 1));
await wait(() => expect(onInput).toHaveBeenCalledTimes(i + 1));
expect(onChange).toHaveBeenCalledTimes(i + 1);
expect(getByTestId("input")).toHaveProperty(
"value",
text.slice(0, i + 1)
);
}
// Blurring the input "commits" the value, React's onChange should not fire
fireEvent.blur(getByTestId("input"));
await wait(() => expect(onChange).toHaveBeenCalledTimes(text.length), {
timeout: 300
});
});

it.each(["input", "textarea"])(
Expand Down
20 changes: 12 additions & 8 deletions src/index.js
Expand Up @@ -90,11 +90,17 @@ function selectOption(option) {
option.selected = true;
}

function fireChangeEvent(event) {
fireEvent.change(event.target);
event.target.removeEventListener("blur", fireChangeEvent);
}

const userEvent = {
click(element) {
const focusedElement = document.activeElement;
const focusedElement = element.ownerDocument.activeElement;
const wasAnotherElementFocused =
focusedElement !== document.body && focusedElement !== element;
focusedElement !== element.ownerDocument.body &&
focusedElement !== element;
if (wasAnotherElementFocused) {
fireEvent.mouseMove(focusedElement);
fireEvent.mouseLeave(focusedElement);
Expand Down Expand Up @@ -172,10 +178,8 @@ const userEvent = {
};
const opts = Object.assign(defaultOpts, userOpts);
if (opts.allAtOnce) {
fireEvent.change(element, { target: { value: text } });
fireEvent.input(element, { target: { value: text } });
} else {
const typedCharacters = text.split("");

let actuallyTyped = "";
for (let index = 0; index < text.length; index++) {
const char = text[index];
Expand All @@ -193,12 +197,11 @@ const userEvent = {
const pressEvent = fireEvent.keyPress(element, {
key: key,
keyCode,
charCode: keyCode,
keyCode: keyCode
charCode: keyCode
});
if (pressEvent) {
actuallyTyped += key;
fireEvent.change(element, {
fireEvent.input(element, {
target: {
value: actuallyTyped
},
Expand All @@ -215,6 +218,7 @@ const userEvent = {
});
}
}
element.addEventListener("blur", fireChangeEvent);
}
};

Expand Down