diff --git a/packages/driver/cypress/fixtures/type-enter.html b/packages/driver/cypress/fixtures/type-enter.html
new file mode 100644
index 000000000000..421e2683d19d
--- /dev/null
+++ b/packages/driver/cypress/fixtures/type-enter.html
@@ -0,0 +1,75 @@
+
+
+
+ type('{enter}')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 138dde30501c..28ef1155efe2 100644
--- a/packages/driver/cypress/integration/commands/actions/type_spec.js
+++ b/packages/driver/cypress/integration/commands/actions/type_spec.js
@@ -557,6 +557,53 @@ describe('src/cy/commands/actions/type - #type', () => {
})
})
+ // https://github.com/cypress-io/cypress/issues/19541
+ describe(`type('{enter}') and click event on button-like elements`, () => {
+ beforeEach(() => {
+ cy.visit('fixtures/type-enter.html')
+ })
+
+ describe('triggers', () => {
+ const targets = [
+ 'button-tag',
+ 'input-button',
+ 'input-image',
+ 'input-reset',
+ 'input-submit',
+ ]
+
+ targets.forEach((targetId) => {
+ it(`${targetId}`, () => {
+ cy.get(`#target-${targetId}`).focus()
+ cy.get(`#target-${targetId}`).type('{enter}')
+
+ 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', 'click')
+ cy.get('li').eq(3).should('have.text', 'keyup')
+ })
+ })
+ })
+
+ describe('does not trigger', () => {
+ const targets = [
+ 'input-checkbox',
+ 'input-radio',
+ ]
+
+ targets.forEach((targetId) => {
+ it(`${targetId}`, () => {
+ cy.get(`#target-${targetId}`).focus()
+ cy.get(`#target-${targetId}`).type('{enter}')
+
+ 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('tabindex', () => {
beforeEach(function () {
this.$div = cy.$$('#tabindex')
diff --git a/packages/driver/src/cy/commands/actions/type.ts b/packages/driver/src/cy/commands/actions/type.ts
index d6d18c9445de..4e3e8a3a0322 100644
--- a/packages/driver/src/cy/commands/actions/type.ts
+++ b/packages/driver/src/cy/commands/actions/type.ts
@@ -272,6 +272,11 @@ export default function (Commands, Cypress, cy, state, config) {
const isContentEditable = $elements.isContentEditable(options.$el.get(0))
const isTextarea = $elements.isTextarea(options.$el.get(0))
+ // click event is only fired on button, image, submit, reset elements.
+ // That's why we cannot use $elements.isButtonLike() here.
+ const type = (type) => $elements.isInputType(options.$el.get(0), type)
+ const sendClickEvent = type('button') || type('image') || type('submit') || type('reset')
+
return keyboard.type({
$el: options.$el,
chars,
@@ -347,22 +352,33 @@ export default function (Commands, Cypress, cy, state, config) {
})
},
- onEnterPressed (id) {
+ onEnterPressed (el) {
// dont dispatch change events or handle
// submit event if we've pressed enter into
// a textarea or contenteditable
-
if (isTextarea || isContentEditable) {
return
}
+ // https://github.com/cypress-io/cypress/issues/19541
+ // Send click event on type('{enter}')
+ if (sendClickEvent) {
+ // Firefox sends a click event automatically.
+ if (!Cypress.isBrowser('firefox')) {
+ const ctor = $dom.getDocumentFromElement(el).defaultView?.PointerEvent
+ const event = new ctor('click')
+
+ el.dispatchEvent(event)
+ }
+ }
+
// if our value has changed since our
// element was activated we need to
// fire a change event immediately
const changeEvent = state('changeEvent')
if (changeEvent) {
- changeEvent(id)
+ changeEvent()
}
// handle submit event handler here
diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts
index 5e28c5329f56..f03306b6fa21 100644
--- a/packages/driver/src/cy/keyboard.ts
+++ b/packages/driver/src/cy/keyboard.ts
@@ -582,7 +582,7 @@ const simulatedDefaultKeyMap: { [key: string]: SimulatedDefault } = {
$selection.replaceSelectionContents(el, '\n')
}
- options.onEnterPressed && options.onEnterPressed()
+ options.onEnterPressed && options.onEnterPressed(el)
},
Delete: (el, key) => {
key.events.input = $selection.deleteRightOfCursor(el)