From 585f1dfa82adf31908d85b9dc1980b5029152ed2 Mon Sep 17 00:00:00 2001 From: Marco Moretti Date: Wed, 13 May 2020 22:54:44 +0200 Subject: [PATCH] fix(click/dblClick): prevent blur when clicking the same element (#265) --- __tests__/react/click.js | 9 +++++++++ __tests__/react/dblclick.js | 9 +++++++++ src/index.js | 26 ++++++++++++++++---------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/__tests__/react/click.js b/__tests__/react/click.js index b8a5fdec..7fe140ee 100644 --- a/__tests__/react/click.js +++ b/__tests__/react/click.js @@ -408,6 +408,15 @@ describe("userEvent.click", () => { expect(onSubmit).not.toHaveBeenCalled(); }); + it("should not fire blur on current element if is the same as previous", () => { + const onBlur = jest.fn(); + const { getByText } = render(); + userEvent.click(getByText("Blur")); + expect(onBlur).not.toHaveBeenCalled(); + userEvent.click(getByText("Blur")); + expect(onBlur).not.toHaveBeenCalled(); + }); + it.each(["input", "textarea"])( "should not give focus for <%s> when mouseDown is prevented", (type) => { diff --git a/__tests__/react/dblclick.js b/__tests__/react/dblclick.js index 33ca399a..8feb37dd 100644 --- a/__tests__/react/dblclick.js +++ b/__tests__/react/dblclick.js @@ -105,6 +105,15 @@ describe("userEvent.dblClick", () => { ]); }); + it("should not fire blur on current element if is the same as previous", () => { + const onBlur = jest.fn(); + const { getByText } = render(); + userEvent.dblClick(getByText("Blur")); + expect(onBlur).not.toHaveBeenCalled(); + userEvent.dblClick(getByText("Blur")); + expect(onBlur).not.toHaveBeenCalled(); + }); + it("should not blur when mousedown prevents default", () => { let events = []; const eventsHandler = jest.fn((evt) => events.push(evt.type)); diff --git a/src/index.js b/src/index.js index f628ea33..44582d47 100644 --- a/src/index.js +++ b/src/index.js @@ -44,10 +44,13 @@ function clickBooleanElement(element) { function clickElement(element, previousElement, init) { fireEvent.mouseOver(element); fireEvent.mouseMove(element); + const wasAnotherElementFocused = + previousElement !== element.ownerDocument.body && + previousElement !== element; const continueDefaultHandling = fireEvent.mouseDown(element); if (continueDefaultHandling) { - previousElement && previousElement.blur(); - element.focus(); + wasAnotherElementFocused && previousElement.blur(); + previousElement !== element && element.focus(); } fireEvent.mouseUp(element); fireEvent.click(element, init); @@ -59,10 +62,13 @@ function clickElement(element, previousElement, init) { function dblClickElement(element, previousElement) { fireEvent.mouseOver(element); fireEvent.mouseMove(element); + const wasAnotherElementFocused = + previousElement !== element.ownerDocument.body && + previousElement !== element; const continueDefaultHandling = fireEvent.mouseDown(element); if (continueDefaultHandling) { - previousElement && previousElement.blur(); - element.focus(); + wasAnotherElementFocused && previousElement.blur(); + previousElement !== element && element.focus(); } fireEvent.mouseUp(element); fireEvent.click(element); @@ -106,21 +112,21 @@ function fireChangeEvent(event) { } const Keys = { - Backspace: { keyCode: 8, code: "Backspace", key: "Backspace" } + Backspace: { keyCode: 8, code: "Backspace", key: "Backspace" }, }; function backspace(element) { const eventOptions = { key: Keys.Backspace.key, keyCode: Keys.Backspace.keyCode, - which: Keys.Backspace.keyCode + which: Keys.Backspace.keyCode, }; fireEvent.keyDown(element, eventOptions); fireEvent.keyUp(element, eventOptions); if (!element.readOnly) { fireEvent.input(element, { - inputType: "deleteContentBackward" + inputType: "deleteContentBackward", }); element.value = ""; // when we add special keys to API, will need to respect selected range } @@ -152,7 +158,7 @@ const userEvent = { break; } default: - clickElement(element, wasAnotherElementFocused && focusedElement, init); + clickElement(element, focusedElement, init); } }, @@ -172,7 +178,7 @@ const userEvent = { break; } default: - dblClickElement(element, wasAnotherElementFocused && focusedElement); + dblClickElement(element, focusedElement); } }, @@ -185,7 +191,7 @@ const userEvent = { fireEvent.mouseLeave(focusedElement); } - clickElement(element, wasAnotherElementFocused && focusedElement); + clickElement(element, focusedElement); const valArray = Array.isArray(values) ? values : [values]; const selectedOptions = Array.from(