Skip to content

Commit

Permalink
fix: πŸ› click on label works on textarea
Browse files Browse the repository at this point in the history
  • Loading branch information
Gpx committed Sep 22, 2018
1 parent a7f3503 commit d1f6734
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 164 deletions.
266 changes: 139 additions & 127 deletions __tests__/events.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,57 @@
import React from "react";
import { render, cleanup } from "react-testing-library";
import "jest-dom/extend-expect";
import userEvent from "../src";

afterEach(cleanup);

describe("fireEvent.click", () => {
it("should fire the correct events for <input>", () => {
const onMouseOver = jest.fn();
const onMouseMove = jest.fn();
const onMouseDown = jest.fn();
const onFocus = jest.fn();
const onMouseUp = jest.fn();
const onClick = jest.fn();
const { getByTestId } = render(
<input
data-testid="input"
onMouseOver={onMouseOver}
onMouseMove={onMouseMove}
onMouseDown={onMouseDown}
onFocus={onFocus}
onMouseUp={onMouseUp}
onClick={onClick}
/>
);

expect(onMouseOver).not.toHaveBeenCalled();
expect(onMouseMove).not.toHaveBeenCalled();
expect(onMouseDown).not.toHaveBeenCalled();
expect(onFocus).not.toHaveBeenCalled();
expect(onMouseUp).not.toHaveBeenCalled();
expect(onClick).not.toHaveBeenCalled();

userEvent.click(getByTestId("input"));

expect(onMouseOver).toHaveBeenCalledTimes(1);
expect(onMouseMove).toHaveBeenCalledTimes(1);
expect(onMouseDown).toHaveBeenCalledTimes(1);
expect(onFocus).toHaveBeenCalledTimes(1);
expect(onMouseUp).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledTimes(1);
});

it("should fire the correct events for <div>", () => {
const onMouseOver = jest.fn();
const onMouseMove = jest.fn();
const onMouseDown = jest.fn();
const onFocus = jest.fn();
const onMouseUp = jest.fn();
const onClick = jest.fn();
import React from 'react'
import { render, cleanup } from 'react-testing-library'
import 'jest-dom/extend-expect'
import userEvent from '../src'

afterEach(cleanup)

describe('fireEvent.click', () => {
it.each(['input', 'textarea'])(
'should fire the correct events for <%s>',
type => {
const onMouseOver = jest.fn()
const onMouseMove = jest.fn()
const onMouseDown = jest.fn()
const onFocus = jest.fn()
const onMouseUp = jest.fn()
const onClick = jest.fn()
const { getByTestId } = render(
React.createElement(type, {
'data-testid': 'element',
onMouseOver: onMouseOver,
onMouseMove: onMouseMove,
onMouseDown: onMouseDown,
onFocus: onFocus,
onMouseUp: onMouseUp,
onClick: onClick,
})
)

expect(onMouseOver).not.toHaveBeenCalled()
expect(onMouseMove).not.toHaveBeenCalled()
expect(onMouseDown).not.toHaveBeenCalled()
expect(onFocus).not.toHaveBeenCalled()
expect(onMouseUp).not.toHaveBeenCalled()
expect(onClick).not.toHaveBeenCalled()

userEvent.click(getByTestId('element'))

expect(onMouseOver).toHaveBeenCalledTimes(1)
expect(onMouseMove).toHaveBeenCalledTimes(1)
expect(onMouseDown).toHaveBeenCalledTimes(1)
expect(onFocus).toHaveBeenCalledTimes(1)
expect(onMouseUp).toHaveBeenCalledTimes(1)
expect(onClick).toHaveBeenCalledTimes(1)
}
)

it('should fire the correct events for <div>', () => {
const onMouseOver = jest.fn()
const onMouseMove = jest.fn()
const onMouseDown = jest.fn()
const onFocus = jest.fn()
const onMouseUp = jest.fn()
const onClick = jest.fn()
const { getByTestId } = render(
<div
data-testid="div"
Expand All @@ -59,84 +62,93 @@ describe("fireEvent.click", () => {
onMouseUp={onMouseUp}
onClick={onClick}
/>
);

expect(onMouseOver).not.toHaveBeenCalled();
expect(onMouseMove).not.toHaveBeenCalled();
expect(onMouseDown).not.toHaveBeenCalled();
expect(onFocus).not.toHaveBeenCalled();
expect(onMouseUp).not.toHaveBeenCalled();
expect(onClick).not.toHaveBeenCalled();

userEvent.click(getByTestId("div"));

expect(onMouseOver).toHaveBeenCalledTimes(1);
expect(onMouseMove).toHaveBeenCalledTimes(1);
expect(onMouseDown).toHaveBeenCalledTimes(1);
expect(onFocus).not.toHaveBeenCalled();
expect(onMouseUp).toHaveBeenCalledTimes(1);
expect(onClick).toHaveBeenCalledTimes(1);
});

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

expect(onMouseOver).not.toHaveBeenCalled()
expect(onMouseMove).not.toHaveBeenCalled()
expect(onMouseDown).not.toHaveBeenCalled()
expect(onFocus).not.toHaveBeenCalled()
expect(onMouseUp).not.toHaveBeenCalled()
expect(onClick).not.toHaveBeenCalled()

userEvent.click(getByTestId('div'))

expect(onMouseOver).toHaveBeenCalledTimes(1)
expect(onMouseMove).toHaveBeenCalledTimes(1)
expect(onMouseDown).toHaveBeenCalledTimes(1)
expect(onFocus).not.toHaveBeenCalled()
expect(onMouseUp).toHaveBeenCalledTimes(1)
expect(onClick).toHaveBeenCalledTimes(1)
})

it('toggles the focus', () => {
const { getByTestId } = render(
<React.Fragment>
<input data-testid="A" />
<input data-testid="B" />
</React.Fragment>
);

const a = getByTestId("A");
const b = getByTestId("B");

expect(a).not.toHaveFocus();
expect(b).not.toHaveFocus();

userEvent.click(a);
expect(a).toHaveFocus();
expect(b).not.toHaveFocus();

userEvent.click(b);
expect(a).not.toHaveFocus();
expect(a).not.toHaveFocus();
});

it("gives focus when clicking a <label> with htmlFor", () => {
const { getByTestId } = render(
<React.Fragment>
<label htmlFor="input" data-testid="label">
Label
</label>
<input id="input" data-testid="input" />
</React.Fragment>
);
userEvent.click(getByTestId("label"));
expect(getByTestId("input")).toHaveFocus();
});

it("gives focus when clicking a <label> without htmlFor", () => {
const { getByTestId } = render(
<React.Fragment>
<label data-testid="label">
Label
<input data-testid="input" />
</label>
</React.Fragment>
);
userEvent.click(getByTestId("label"));
expect(getByTestId("input")).toHaveFocus();
});

it("gives focus when clicking on an element contained within a <label>", () => {
const { getByText, getByTestId } = render(
<React.Fragment>
<label htmlFor="input" data-testid="label">
<span>Label</span>
</label>
<input id="input" data-testid="input" />
</React.Fragment>
);
userEvent.click(getByText("Label"));
//expect(getByTestId('input')).toHaveFocus()
});
});
)

const a = getByTestId('A')
const b = getByTestId('B')

expect(a).not.toHaveFocus()
expect(b).not.toHaveFocus()

userEvent.click(a)
expect(a).toHaveFocus()
expect(b).not.toHaveFocus()

userEvent.click(b)
expect(a).not.toHaveFocus()
expect(a).not.toHaveFocus()
})

it.each(['input', 'textarea'])(
'gives focus to <%s> when clicking a <label> with htmlFor',
type => {
const { getByTestId } = render(
<React.Fragment>
<label htmlFor="input" data-testid="label">
Label
</label>
{React.createElement(type, { id: 'input', 'data-testid': 'input' })}
</React.Fragment>
)
userEvent.click(getByTestId('label'))
expect(getByTestId('input')).toHaveFocus()
}
)

it.each(['input', 'textarea'])(
'gives focus to <%s> when clicking a <label> without htmlFor',
type => {
const { getByTestId } = render(
<React.Fragment>
<label data-testid="label">
Label
{React.createElement(type, { 'data-testid': 'input' })}
</label>
</React.Fragment>
)
userEvent.click(getByTestId('label'))
expect(getByTestId('input')).toHaveFocus()
}
)

it.each(['input', 'textarea'])(
'gives focus to <%s> when clicking on an element contained within a <label>',
type => {
const { getByText, getByTestId } = render(
<React.Fragment>
<label htmlFor="input" data-testid="label">
<span>Label</span>
</label>
{React.createElement(type, { id: 'input', 'data-testid': 'input' })}
</React.Fragment>
)
userEvent.click(getByText('Label'))
expect(getByTestId('input')).toHaveFocus()
}
)
})
74 changes: 37 additions & 37 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
import { fireEvent } from "dom-testing-library";
import { fireEvent } from 'dom-testing-library'

function findTagInParents(element, tagName) {
if (element.parentNode == null) return undefined;
if (element.parentNode.tagName === tagName) return element.parentNode;
return findTagInParents(element.parentNode, tagName);
if (element.parentNode == null) return undefined
if (element.parentNode.tagName === tagName) return element.parentNode
return findTagInParents(element.parentNode, tagName)
}

function clickLabel(label) {
fireEvent.mouseOver(label);
fireEvent.mouseMove(label);
fireEvent.mouseDown(label);
fireEvent.mouseUp(label);
fireEvent.click(label);
fireEvent.mouseOver(label)
fireEvent.mouseMove(label)
fireEvent.mouseDown(label)
fireEvent.mouseUp(label)
fireEvent.click(label)

if (label.htmlFor) {
const input = document.getElementById(label.htmlFor);
input.focus();
fireEvent.click(label);
const input = document.getElementById(label.htmlFor)
input.focus()
fireEvent.click(label)
} else {
const input = label.querySelector("input");
input.focus();
label.focus();
fireEvent.click(input);
fireEvent.click(label);
const input = label.querySelector('input,textarea')
input.focus()
label.focus()
fireEvent.click(input)
fireEvent.click(label)
}
}

function clickElement(element) {
fireEvent.mouseOver(element);
fireEvent.mouseMove(element);
fireEvent.mouseDown(element);
element.focus();
fireEvent.mouseUp(element);
fireEvent.click(element);

const labelAncestor = findTagInParents(element, "LABEL");
labelAncestor && clickLabel(labelAncestor);
fireEvent.mouseOver(element)
fireEvent.mouseMove(element)
fireEvent.mouseDown(element)
element.focus()
fireEvent.mouseUp(element)
fireEvent.click(element)

const labelAncestor = findTagInParents(element, 'LABEL')
labelAncestor && clickLabel(labelAncestor)
}

const userEvent = {
click(element) {
const focusedElement = document.activeElement;
const focusedElement = document.activeElement
const wasAnotherElementFocused =
focusedElement !== document.body && focusedElement !== element;
focusedElement !== document.body && focusedElement !== element
if (wasAnotherElementFocused) {
fireEvent.mouseMove(focusedElement);
fireEvent.mouseLeave(focusedElement);
fireEvent.mouseMove(focusedElement)
fireEvent.mouseLeave(focusedElement)
}

if (element.tagName === "LABEL") {
clickLabel(element);
if (element.tagName === 'LABEL') {
clickLabel(element)
} else {
clickElement(element);
clickElement(element)
}

wasAnotherElementFocused && focusedElement.blur();
}
};
wasAnotherElementFocused && focusedElement.blur()
},
}

export default userEvent;
export default userEvent

0 comments on commit d1f6734

Please sign in to comment.