cypress: Inconsistant and invalid Events Typing using cypress
Current behavior:
Testing a code who used event instanceof KeyboardEvent, I’ve seen some strange behavior, digging up, it seems that there is some strange inconsistencies between the events triggered and also into the way they are sent to the eventListener.
Desired behavior:
Consistent behavior:
.type.trigger({..., type: 'keydown'}).get('#element').then(element.dispatchEvent(new KeyboardEvent('keydown', ...)))
Should all send a KeyboardEvent type event.
And the eventListener:
element.addEventListener('keydown', (event) => (event instanceof KeyboardEvent));
Should always return true.
Steps to reproduce: (app code and test code)
I’ve tested three different methods: cy.type, cy.trigger, cy.get('#element').then( element.dispatchEvent).
And two different eventListener for each test:
- One directly into a <script> inside the html page itself
- One created into the test itself using
cy.get -> addEventListener
You can find MWE here: https://github.com/avallete/cypress-test-tiny-event-bug
Simply run:
npm install
npm run cypress:open
# Then run the test and check the console.log inside the debuging tools.
# Each test is a specific case the 2 first show that event is type Event instead of KeyboardEvent.
# The third test show the inconsistency of the same eventListener if it's declared inside the test or outside (into the html <script>).
Versions
3.6.1, Linux, Chromium 78 / Electron 73
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 17 (14 by maintainers)
I’m running into this issue because I have some Rust code which uses typed bindings to DOM APIs. The bindings provide a number of type definitions generated from WebIDL, and it’s possible to cast between JS types. By default those casts use
instanceofchecks before returning to catch common bugs.I have event handler helpers that take a typed callback and perform the conversion under the hood for the user. Elsewhere there are definitions mapping strings like
"keydown"to types so that the callbacks always have the correct type. This works quite nicely “in production” so far but breaks when using cypress to enter text due to this issue.I’ve had mixed results with removing the checks as it seems the bindings may rely on prototypes for doing their property lookups. The easiest fix that’d allow me to use cypress would be to emit an event with the correct prototype in its chain.
EDIT: I should also note that https://github.com/cypress-io/cypress/pull/8255 will address the most common cases.
There are 3 problems in this issue:
Event-> `KeyboardEvent: Actually, this is also the solution for the #6125. I need to investigate what’s the real problem in that code. And it’ll be fixed with it. => #8255cy.window()issue: I think it should be written in FAQ, cy.window(), and/or The Test Runner. => cypress-io/cypress-documentation#3073.triggerissue: it should be treated separately.Investigating a little bit on this issue, I’ve been able to found what seem to be the root of the behaviour I describe on this issue:
https://github.com/cypress-io/cypress/blob/6749a0edc69a0052497e3a12766723274d78a135/packages/driver/src/cy/keyboard.ts#L892
Replacing the
win['Event']bywin['KeyboardEvent']on this line, make the.typefunction to properly send an event which isinstanceof KeyboardEventinto the tests.But looking on the comment on top of this line, this fix may lead to some regression on Chrome < 63.