diff --git a/packages/driver/cypress/fixtures/issue-6125.html b/packages/driver/cypress/fixtures/issue-6125.html
new file mode 100644
index 000000000000..d4a63a75c1ce
--- /dev/null
+++ b/packages/driver/cypress/fixtures/issue-6125.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Sign In | Simple
+
+
+
+
+
+
diff --git a/packages/driver/cypress/fixtures/issue-6125.js b/packages/driver/cypress/fixtures/issue-6125.js
new file mode 100644
index 000000000000..cca9307836a3
--- /dev/null
+++ b/packages/driver/cypress/fixtures/issue-6125.js
@@ -0,0 +1,12 @@
+// Extracted the code that causes the problem in signin.simple.com
+// The cause was overriding the Event class.
+
+(function() {
+ this.Event = function(n, i) {
+ const r = n.type
+
+ if (r.indexOf("key")) {
+ // do something
+ }
+ }
+})()
diff --git a/packages/driver/cypress/integration/commands/actions/type_spec.js b/packages/driver/cypress/integration/commands/actions/type_spec.js
index fdc823b6a283..3ae5a4a3039c 100644
--- a/packages/driver/cypress/integration/commands/actions/type_spec.js
+++ b/packages/driver/cypress/integration/commands/actions/type_spec.js
@@ -177,6 +177,28 @@ describe('src/cy/commands/actions/type - #type', () => {
.should('have.value', 'foobar')
})
+ // https://github.com/cypress-io/cypress/issues/6125
+ it('works even if Event class is overridden', () => {
+ cy.visit('fixtures/issue-6125.html')
+ cy.get('#login_username')
+ .type('foobar')
+ })
+
+ // https://github.com/cypress-io/cypress/issues/5650
+ it('should trigger KeyboardEvent, not Event, for event listeners', (done) => {
+ cy.$$('input:first').on('keydown', (e) => {
+ if (e.originalEvent instanceof e.currentTarget.ownerDocument.defaultView.KeyboardEvent) {
+ done()
+
+ return
+ }
+
+ throw new Error('event was not instanceOf KeyboardEvent')
+ })
+
+ cy.get('input:first').type('A')
+ })
+
describe('actionability', () => {
it('can forcibly type + click even when element is invisible', () => {
const $txt = cy.$$(':text:first').hide()
diff --git a/packages/driver/src/cy/commands/actions/type.js b/packages/driver/src/cy/commands/actions/type.js
index b58504a6bc21..7a5754e2d073 100644
--- a/packages/driver/src/cy/commands/actions/type.js
+++ b/packages/driver/src/cy/commands/actions/type.js
@@ -202,19 +202,25 @@ module.exports = function (Commands, Cypress, cy, state, config) {
return
}
- // issue the click event to the 'default button' of the form
- // we need this to be synchronous so not going through our
- // own click command
- // as of now, at least in Chrome, causing the click event
- // on the button will indeed trigger the form submit event
- // so we dont need to fire it manually anymore!
- if (!clickedDefaultButton(defaultButton)) {
- // if we werent able to click the default button
- // then synchronously fire the submit event
- // currently this is sync but if we use a waterfall
- // promise in the submit command it will break again
- // consider changing type to a Promise and juggle logging
- return cy.now('submit', form, { log: false, $el: form })
+ // In Firefox, submit event is automatically fired
+ // when we send {Enter} KeyboardEvent to the input fields.
+ // Because of that, we don't have to click the submit buttons.
+ // Otherwise, we trigger submit events twice.
+ if (!Cypress.isBrowser('firefox')) {
+ // issue the click event to the 'default button' of the form
+ // we need this to be synchronous so not going through our
+ // own click command
+ // as of now, at least in Chrome, causing the click event
+ // on the button will indeed trigger the form submit event
+ // so we dont need to fire it manually anymore!
+ if (!clickedDefaultButton(defaultButton)) {
+ // if we werent able to click the default button
+ // then synchronously fire the submit event
+ // currently this is sync but if we use a waterfall
+ // promise in the submit command it will break again
+ // consider changing type to a Promise and juggle logging
+ return cy.now('submit', form, { log: false, $el: form })
+ }
}
}
diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts
index 2152422ff2a6..dfdb62f7f40a 100644
--- a/packages/driver/src/cy/keyboard.ts
+++ b/packages/driver/src/cy/keyboard.ts
@@ -900,10 +900,15 @@ export class Keyboard {
// or is IE
} else {
- // For some reason we can't set certain props on Keyboard Events in chrome < 63.
- // So we'll use the plain Event constructor
- // event = new win[eventConstructor](eventType, eventOptions)
- event = new win['Event'](eventType, eventOptions)
+ let constructor = win[eventConstructor]
+
+ // When event constructor doesn't exist, fallback to KeyboardEvent.
+ // It's necessary because Firefox doesn't support InputEvent.
+ if (typeof constructor !== 'function') {
+ constructor = win['KeyboardEvent']
+ }
+
+ event = new constructor(eventType, eventOptions)
_.extend(event, eventOptions)
}