Skip to content

Commit

Permalink
feat: add userEvent.clear
Browse files Browse the repository at this point in the history
  • Loading branch information
wachunga committed Mar 11, 2020
1 parent 38e3c22 commit e73333e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
70 changes: 70 additions & 0 deletions __tests__/react/clear.js
@@ -0,0 +1,70 @@
import React from "react";
import { cleanup, render, wait, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import userEvent from "../../src";

afterEach(cleanup);

describe("userEvent.clear", () => {
it.each(["input", "textarea"])("should clear text in <%s>", type => {
const onChange = jest.fn();
const { getByTestId } = render(
React.createElement(type, {
"data-testid": "input",
onChange: onChange,
value: "Hello, world!"
})
);

const input = getByTestId("input");
userEvent.clear(input);
expect(input.value).toBe("");
});

it.each(["input", "textarea"])(
"should not clear when <%s> is disabled",
type => {
const text = "Hello, world!";
const onChange = jest.fn();
const { getByTestId } = render(
React.createElement(type, {
"data-testid": "input",
onChange: onChange,
value: text,
disabled: true
})
);

const input = getByTestId("input");
userEvent.clear(input);
expect(input).toHaveProperty("value", text);
}
);

it.each(["input", "textarea"])(
"should not clear when <%s> is readOnly",
type => {
const onChange = jest.fn();
const onKeyDown = jest.fn();
const onKeyUp = jest.fn();

const text = "Hello, world!";
const { getByTestId } = render(
React.createElement(type, {
"data-testid": "input",
onChange,
onKeyDown,
onKeyUp,
value: text,
readOnly: true
})
);

const input = getByTestId("input");
userEvent.clear(input);
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(onKeyUp).toHaveBeenCalledTimes(1);
expect(input).toHaveProperty("value", text);
}
);
});
58 changes: 58 additions & 0 deletions src/index.js
Expand Up @@ -105,6 +105,56 @@ function fireChangeEvent(event) {
event.target.removeEventListener("blur", fireChangeEvent);
}

function getSelectionBounds(element) {
return {
start: element.selectionStart,
end: element.selectionEnd
};
}

function deleteLeftOfCursor(element) {
const { start, end } = getSelectionBounds(element);
if (start === end) {
if (start === 0) {
// there's nothing left of cursor
return;
}
element.setSelectionRange(start - 1, end);
}

const value = element.value || "";
const updatedValue = value.substring(0, start) + value.substring(end);
element.value = updatedValue;

element.setSelectionRange(start, start);
}

const Keys = {
Backspace: { keyCode: 8, code: "Backspace", key: "Backspace" }
};

function backspace(element) {
const eventOptions = {
key: Keys.Backspace.key,
keyCode: Keys.Backspace.keyCode,
which: Keys.Backspace.keyCode
};
fireEvent.keyDown(element, eventOptions);
fireEvent.keyUp(element, eventOptions);

if (!element.readOnly) {
fireEvent.input(element, {
inputType: "deleteContentBackward"
});
deleteLeftOfCursor(element);
}
}

function selectAll(element) {
userEvent.dblClick(element); // simulate events (will not actually select)
element.setSelectionRange(0, element.value.length);
}

const userEvent = {
click(element) {
const focusedElement = element.ownerDocument.activeElement;
Expand Down Expand Up @@ -175,6 +225,14 @@ const userEvent = {
}
},

clear(element) {
if (element.disabled) return;

selectAll(element);
backspace(element);
element.addEventListener("blur", fireChangeEvent);
},

async type(element, text, userOpts = {}) {
if (element.disabled) return;
const defaultOpts = {
Expand Down

0 comments on commit e73333e

Please sign in to comment.