From 2c88f0c58ec3c1bd8421a05259fc2ab893191f99 Mon Sep 17 00:00:00 2001 From: Tyler Biethman Date: Sat, 12 Feb 2022 16:57:07 -0600 Subject: [PATCH] fix: Update `.type(' ')` to not emit clicks when the keyup event has been prevented (#20156) * fix: Update `.type(' ')` to not emit clicks when the keyup event has been prevented * cleanup test for click event not firing while preventing default Co-authored-by: Brian Mann --- .../cypress/fixtures/click-event-by-type.html | 4 +- .../integration/commands/actions/type_spec.js | 92 ++++++++++++++++--- .../driver/src/cy/commands/actions/type.ts | 4 +- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/packages/driver/cypress/fixtures/click-event-by-type.html b/packages/driver/cypress/fixtures/click-event-by-type.html index 5999d152f00a..69a53b00c86a 100644 --- a/packages/driver/cypress/fixtures/click-event-by-type.html +++ b/packages/driver/cypress/fixtures/click-event-by-type.html @@ -66,10 +66,10 @@ target.addEventListener("click", () => { updateLog("click"); }); - target.addEventListener("keyup", () => { + target.addEventListener("keyup", (event) => { updateLog("keyup"); }); }); - \ No newline at end of file + diff --git a/packages/driver/cypress/integration/commands/actions/type_spec.js b/packages/driver/cypress/integration/commands/actions/type_spec.js index c63a0e954bb7..90e10798bb7a 100644 --- a/packages/driver/cypress/integration/commands/actions/type_spec.js +++ b/packages/driver/cypress/integration/commands/actions/type_spec.js @@ -574,8 +574,7 @@ describe('src/cy/commands/actions/type - #type', () => { targets.forEach((targetId) => { it(`${targetId}`, () => { - cy.get(`#target-${targetId}`).focus() - cy.get(`#target-${targetId}`).type('{enter}') + cy.get(`#target-${targetId}`).focus().type('{enter}') cy.get('li').eq(0).should('have.text', 'keydown') cy.get('li').eq(1).should('have.text', 'keypress') @@ -593,8 +592,7 @@ describe('src/cy/commands/actions/type - #type', () => { targets.forEach((targetId) => { it(`${targetId}`, () => { - cy.get(`#target-${targetId}`).focus() - cy.get(`#target-${targetId}`).type('{enter}') + cy.get(`#target-${targetId}`).focus().type('{enter}') cy.get('li').eq(0).should('have.text', 'keydown') cy.get('li').eq(1).should('have.text', 'keypress') @@ -610,17 +608,30 @@ describe('src/cy/commands/actions/type - #type', () => { }) const targets = [ - 'button-tag', - 'input-button', - 'input-image', - 'input-reset', - 'input-submit', + '#target-button-tag', + '#target-input-button', + '#target-input-image', + '#target-input-reset', + '#target-input-submit', ] describe(`triggers with single space`, () => { - targets.forEach((targetId) => { - it(targetId, () => { - cy.get(`#target-${targetId}`).focus().type(' ') + targets.forEach((target) => { + it(target, () => { + const events = [] + + $(target).on('keydown keypress keyup click', (evt) => { + events.push(evt.type) + }) + + cy.get(target).focus().type(' ').then(() => { + expect(events).to.deep.eq([ + 'keydown', + 'keypress', + 'keyup', + 'click', + ]) + }) cy.get('li').eq(0).should('have.text', 'keydown') cy.get('li').eq(1).should('have.text', 'keypress') @@ -630,10 +641,61 @@ describe('src/cy/commands/actions/type - #type', () => { }) }) + describe(`does not trigger if keyup prevented`, () => { + targets.forEach((target) => { + it(`${target} does not fire click event`, () => { + const events = [] + + $(target) + .on('keydown keypress keyup click', (evt) => { + events.push(evt.type) + }) + .on('keyup', (evt) => { + evt.preventDefault() + }) + + cy.get(target).focus().type(' ').then(() => { + expect(events).to.deep.eq([ + 'keydown', + 'keypress', + 'keyup', + ]) + }) + + cy.get('li').should('have.length', 3) + cy.get('li').eq(0).should('have.text', 'keydown') + cy.get('li').eq(1).should('have.text', 'keypress') + cy.get('li').eq(2).should('have.text', 'keyup') + }) + }) + }) + describe('triggers after other characters', () => { - targets.forEach((targetId) => { - it(targetId, () => { - cy.get(`#target-${targetId}`).focus().type('asd ') + targets.forEach((target) => { + it(target, () => { + const events = [] + + $(target).on('keydown keypress keyup click', (evt) => { + events.push(evt.type) + }) + + cy.get(target).focus().type('asd ').then(() => { + expect(events).to.deep.eq([ + 'keydown', + 'keypress', + 'keyup', + 'keydown', + 'keypress', + 'keyup', + 'keydown', + 'keypress', + 'keyup', + 'keydown', + 'keypress', + 'keyup', + 'click', + ]) + }) cy.get('li').eq(12).should('have.text', 'click') }) diff --git a/packages/driver/src/cy/commands/actions/type.ts b/packages/driver/src/cy/commands/actions/type.ts index 7d255a65d668..edeebb49186f 100644 --- a/packages/driver/src/cy/commands/actions/type.ts +++ b/packages/driver/src/cy/commands/actions/type.ts @@ -342,7 +342,9 @@ export default function (Commands, Cypress, cy, state, config) { // event.target is null when used with shadow DOM. (event.target && $elements.isButtonLike(event.target)) && // When a space key is pressed for input radio elements, the click event is only fired when it's not checked. - !(event.target.tagName === 'INPUT' && event.target.type === 'radio' && event.target.checked === true) + !(event.target.tagName === 'INPUT' && event.target.type === 'radio' && event.target.checked === true) && + // When event is prevented, the click event should not be emitted + !event.defaultPrevented ) { fireClickEvent(event.target) }