Skip to content

Commit ec8a369

Browse files
authored
Merge pull request #22 from Gpx/dblclick
Dblclick
2 parents 728deae + d7a01a7 commit ec8a369

File tree

4 files changed

+230
-81
lines changed

4 files changed

+230
-81
lines changed

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ userEvent.click(getByText("Check"));
7373
expect(getByTestId("checkbox")).toHaveAttribute("checked", true);
7474
```
7575

76+
### `dblClick(element)`
77+
78+
Clicks `element` twice, depending on what `element` is it can have different
79+
side effects.
80+
81+
```jsx
82+
import React from "react";
83+
import { render } from "react-testing-library";
84+
import userEvent from "user-event";
85+
86+
test("double click", () => {
87+
const onChange = jest.fn();
88+
const { getByTestId } = render(
89+
<input type="checkbox" id="checkbox" onChange={onChange} />
90+
);
91+
const checkbox = getByTestId("checkbox");
92+
userEvent.dblClick(checkbox);
93+
expect(onChange).toHaveBeenCalledTimes(2);
94+
expect(checkbox).toHaveProperty("checked", false);
95+
});
96+
```
97+
7698
### `type(element, text, [options])`
7799

78100
Writes `text` inside an `<input>` or a `<textarea>`. `options` accepts one

__tests__/click.js

+50-81
Original file line numberDiff line numberDiff line change
@@ -5,122 +5,91 @@ import userEvent from "../src";
55

66
afterEach(cleanup);
77

8-
describe("fireEvent.click", () => {
8+
describe("userEvent.click", () => {
99
it.each(["input", "textarea"])(
1010
"should fire the correct events for <%s>",
1111
type => {
12-
const onMouseOver = jest.fn();
13-
const onMouseMove = jest.fn();
14-
const onMouseDown = jest.fn();
15-
const onFocus = jest.fn();
16-
const onMouseUp = jest.fn();
17-
const onClick = jest.fn();
12+
const events = [];
13+
const eventsHandler = jest.fn(evt => events.push(evt.type));
1814
const { getByTestId } = render(
1915
React.createElement(type, {
2016
"data-testid": "element",
21-
onMouseOver: onMouseOver,
22-
onMouseMove: onMouseMove,
23-
onMouseDown: onMouseDown,
24-
onFocus: onFocus,
25-
onMouseUp: onMouseUp,
26-
onClick: onClick
17+
onMouseOver: eventsHandler,
18+
onMouseMove: eventsHandler,
19+
onMouseDown: eventsHandler,
20+
onFocus: eventsHandler,
21+
onMouseUp: eventsHandler,
22+
onClick: eventsHandler
2723
})
2824
);
2925

30-
expect(onMouseOver).not.toHaveBeenCalled();
31-
expect(onMouseMove).not.toHaveBeenCalled();
32-
expect(onMouseDown).not.toHaveBeenCalled();
33-
expect(onFocus).not.toHaveBeenCalled();
34-
expect(onMouseUp).not.toHaveBeenCalled();
35-
expect(onClick).not.toHaveBeenCalled();
36-
3726
userEvent.click(getByTestId("element"));
3827

39-
expect(onMouseOver).toHaveBeenCalledTimes(1);
40-
expect(onMouseMove).toHaveBeenCalledTimes(1);
41-
expect(onMouseDown).toHaveBeenCalledTimes(1);
42-
expect(onFocus).toHaveBeenCalledTimes(1);
43-
expect(onMouseUp).toHaveBeenCalledTimes(1);
44-
expect(onClick).toHaveBeenCalledTimes(1);
28+
expect(events).toEqual([
29+
"mouseover",
30+
"mousemove",
31+
"mousedown",
32+
"focus",
33+
"mouseup",
34+
"click"
35+
]);
4536
}
4637
);
4738

4839
it('should fire the correct events for <input type="checkbox">', () => {
49-
const onMouseOver = jest.fn();
50-
const onMouseMove = jest.fn();
51-
const onMouseDown = jest.fn();
52-
const onFocus = jest.fn();
53-
const onMouseUp = jest.fn();
54-
const onClick = jest.fn();
55-
const onChange = jest.fn();
40+
const events = [];
41+
const eventsHandler = jest.fn(evt => events.push(evt.type));
5642
const { getByTestId } = render(
5743
<input
5844
data-testid="element"
5945
type="checkbox"
60-
onMouseOver={onMouseOver}
61-
onMouseMove={onMouseMove}
62-
onMouseDown={onMouseDown}
63-
onFocus={onFocus}
64-
onMouseUp={onMouseUp}
65-
onClick={onClick}
66-
onChange={onChange}
46+
onMouseOver={eventsHandler}
47+
onMouseMove={eventsHandler}
48+
onMouseDown={eventsHandler}
49+
onFocus={eventsHandler}
50+
onMouseUp={eventsHandler}
51+
onClick={eventsHandler}
52+
onChange={eventsHandler}
6753
/>
6854
);
6955

70-
expect(onMouseOver).not.toHaveBeenCalled();
71-
expect(onMouseMove).not.toHaveBeenCalled();
72-
expect(onMouseDown).not.toHaveBeenCalled();
73-
expect(onFocus).not.toHaveBeenCalled();
74-
expect(onMouseUp).not.toHaveBeenCalled();
75-
expect(onClick).not.toHaveBeenCalled();
76-
expect(onChange).not.toHaveBeenCalled();
77-
7856
userEvent.click(getByTestId("element"));
7957

80-
expect(onMouseOver).toHaveBeenCalledTimes(1);
81-
expect(onMouseMove).toHaveBeenCalledTimes(1);
82-
expect(onMouseDown).toHaveBeenCalledTimes(1);
83-
expect(onFocus).not.toHaveBeenCalledTimes(1);
84-
expect(onMouseUp).toHaveBeenCalledTimes(1);
85-
expect(onClick).toHaveBeenCalledTimes(1);
86-
expect(onChange).toHaveBeenCalledTimes(1);
58+
expect(events).toEqual([
59+
"mouseover",
60+
"mousemove",
61+
"mousedown",
62+
"mouseup",
63+
"click",
64+
"change"
65+
]);
66+
8767
expect(getByTestId("element")).toHaveProperty("checked", true);
8868
});
8969

9070
it("should fire the correct events for <div>", () => {
91-
const onMouseOver = jest.fn();
92-
const onMouseMove = jest.fn();
93-
const onMouseDown = jest.fn();
94-
const onFocus = jest.fn();
95-
const onMouseUp = jest.fn();
96-
const onClick = jest.fn();
71+
const events = [];
72+
const eventsHandler = jest.fn(evt => events.push(evt.type));
9773
const { getByTestId } = render(
9874
<div
9975
data-testid="div"
100-
onMouseOver={onMouseOver}
101-
onMouseMove={onMouseMove}
102-
onMouseDown={onMouseDown}
103-
onFocus={onFocus}
104-
onMouseUp={onMouseUp}
105-
onClick={onClick}
76+
onMouseOver={eventsHandler}
77+
onMouseMove={eventsHandler}
78+
onMouseDown={eventsHandler}
79+
onFocus={eventsHandler}
80+
onMouseUp={eventsHandler}
81+
onClick={eventsHandler}
10682
/>
10783
);
10884

109-
expect(onMouseOver).not.toHaveBeenCalled();
110-
expect(onMouseMove).not.toHaveBeenCalled();
111-
expect(onMouseDown).not.toHaveBeenCalled();
112-
expect(onFocus).not.toHaveBeenCalled();
113-
expect(onMouseUp).not.toHaveBeenCalled();
114-
expect(onClick).not.toHaveBeenCalled();
115-
11685
userEvent.click(getByTestId("div"));
117-
118-
expect(onMouseOver).toHaveBeenCalledTimes(1);
119-
expect(onMouseMove).toHaveBeenCalledTimes(1);
120-
expect(onMouseDown).toHaveBeenCalledTimes(1);
121-
expect(onFocus).not.toHaveBeenCalled();
122-
expect(onMouseUp).toHaveBeenCalledTimes(1);
123-
expect(onClick).toHaveBeenCalledTimes(1);
86+
expect(events).toEqual([
87+
"mouseover",
88+
"mousemove",
89+
"mousedown",
90+
"mouseup",
91+
"click"
92+
]);
12493
});
12594

12695
it("toggles the focus", () => {

__tests__/dblclick.js

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import React from "react";
2+
import { render, cleanup } from "react-testing-library";
3+
import "jest-dom/extend-expect";
4+
import userEvent from "../src";
5+
6+
afterEach(cleanup);
7+
8+
describe("userEvent.dblClick", () => {
9+
it.each(["input", "textarea"])(
10+
"should fire the correct events for <%s>",
11+
type => {
12+
const events = [];
13+
const eventsHandler = jest.fn(evt => events.push(evt.type));
14+
const { getByTestId } = render(
15+
React.createElement(type, {
16+
"data-testid": "element",
17+
onMouseOver: eventsHandler,
18+
onMouseMove: eventsHandler,
19+
onMouseDown: eventsHandler,
20+
onFocus: eventsHandler,
21+
onMouseUp: eventsHandler,
22+
onClick: eventsHandler,
23+
onDoubleClick: eventsHandler
24+
})
25+
);
26+
27+
userEvent.dblClick(getByTestId("element"));
28+
29+
expect(events).toEqual([
30+
"mouseover",
31+
"mousemove",
32+
"mousedown",
33+
"focus",
34+
"mouseup",
35+
"click",
36+
"mousedown",
37+
"mouseup",
38+
"click",
39+
"dblclick"
40+
]);
41+
}
42+
);
43+
44+
it('should fire the correct events for <input type="checkbox">', () => {
45+
const events = [];
46+
const eventsHandler = jest.fn(evt => events.push(evt.type));
47+
const { getByTestId } = render(
48+
<input
49+
data-testid="element"
50+
type="checkbox"
51+
onMouseOver={eventsHandler}
52+
onMouseMove={eventsHandler}
53+
onMouseDown={eventsHandler}
54+
onFocus={eventsHandler}
55+
onMouseUp={eventsHandler}
56+
onClick={eventsHandler}
57+
onChange={eventsHandler}
58+
/>
59+
);
60+
61+
userEvent.dblClick(getByTestId("element"));
62+
63+
expect(events).toEqual([
64+
"mouseover",
65+
"mousemove",
66+
"mousedown",
67+
"mouseup",
68+
"click",
69+
"change",
70+
"mousedown",
71+
"mouseup",
72+
"click",
73+
"change"
74+
]);
75+
76+
expect(getByTestId("element")).toHaveProperty("checked", false);
77+
});
78+
79+
it("should fire the correct events for <div>", () => {
80+
const events = [];
81+
const eventsHandler = jest.fn(evt => events.push(evt.type));
82+
const { getByTestId } = render(
83+
<div
84+
data-testid="div"
85+
onMouseOver={eventsHandler}
86+
onMouseMove={eventsHandler}
87+
onMouseDown={eventsHandler}
88+
onFocus={eventsHandler}
89+
onMouseUp={eventsHandler}
90+
onClick={eventsHandler}
91+
/>
92+
);
93+
94+
userEvent.dblClick(getByTestId("div"));
95+
expect(events).toEqual([
96+
"mouseover",
97+
"mousemove",
98+
"mousedown",
99+
"mouseup",
100+
"click",
101+
"mousedown",
102+
"mouseup",
103+
"click"
104+
]);
105+
});
106+
});

src/index.js

+52
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,35 @@ function clickElement(element) {
4545
labelAncestor && clickLabel(labelAncestor);
4646
}
4747

48+
function dblClickElement(element) {
49+
fireEvent.mouseOver(element);
50+
fireEvent.mouseMove(element);
51+
fireEvent.mouseDown(element);
52+
element.focus();
53+
fireEvent.mouseUp(element);
54+
fireEvent.click(element);
55+
fireEvent.mouseDown(element);
56+
fireEvent.mouseUp(element);
57+
fireEvent.click(element);
58+
fireEvent.dblClick(element);
59+
60+
const labelAncestor = findTagInParents(element, "LABEL");
61+
labelAncestor && clickLabel(labelAncestor);
62+
}
63+
64+
function dblClickCheckbox(checkbox) {
65+
fireEvent.mouseOver(checkbox);
66+
fireEvent.mouseMove(checkbox);
67+
fireEvent.mouseDown(checkbox);
68+
fireEvent.mouseUp(checkbox);
69+
fireEvent.click(checkbox);
70+
fireEvent.change(checkbox);
71+
fireEvent.mouseDown(checkbox);
72+
fireEvent.mouseUp(checkbox);
73+
fireEvent.click(checkbox);
74+
fireEvent.change(checkbox);
75+
}
76+
4877
const userEvent = {
4978
click(element) {
5079
const focusedElement = document.activeElement;
@@ -70,6 +99,29 @@ const userEvent = {
7099

71100
wasAnotherElementFocused && focusedElement.blur();
72101
},
102+
103+
dblClick(element) {
104+
const focusedElement = document.activeElement;
105+
const wasAnotherElementFocused =
106+
focusedElement !== document.body && focusedElement !== element;
107+
if (wasAnotherElementFocused) {
108+
fireEvent.mouseMove(focusedElement);
109+
fireEvent.mouseLeave(focusedElement);
110+
}
111+
112+
switch (element.tagName) {
113+
case "INPUT":
114+
if (element.type === "checkbox") {
115+
dblClickCheckbox(element);
116+
break;
117+
}
118+
default:
119+
dblClickElement(element);
120+
}
121+
122+
wasAnotherElementFocused && focusedElement.blur();
123+
},
124+
73125
type(element, text, userOpts = {}) {
74126
const defaultOpts = { allAtOnce: false };
75127
const opts = Object.assign(defaultOpts, userOpts);

0 commit comments

Comments
 (0)