This is a problem that is only when running Cypress in interative mode AND not having the window in focus.
What happens is this:
- User blurs the window
- User runs a test
- Test loads the application
- Application code programmatically calls
element.focus() or element.blur()
- Browser changes
activeElement correctly to point to new element (or removes it if blurring)
- Browser checks to see if
document.hasFocus() is true
- When the browser is not in focus, the browser internally queues the element to receive the native
focus or blur event (flagged as dirty) when the window again receives focus
So far... everything is good, all of this is native behavior.
The problem is this...
- When using browser native events, interactive events cause the browser to send dirty focus events if the element should still receive that event. In other words, as long as it's still the
activeElement it would have otherwise had its focus event fired.
- But when using Cypress events, this behavior is not polyfilled in this one specific situation and therefore the application will never receive a
focus event until the user really focuses on the window.
The Desired Behavior
We should polyfill the native event behavior by also internally flagging the element as dirty and needing the focus event - and any action or behavior that would normally cause this to fire, we should fire it.
To note: everything I just mentioned here only affects Cypress in interactive mode via cypress open and only when the browser is out of focus and only when the application code programmatically calls .focus() or .blur(). Any other situation is already accounted for.
This will fix issues such as: #549
This is a problem that is only when running Cypress in interative mode AND not having the window in focus.
What happens is this:
element.focus()orelement.blur()activeElementcorrectly to point to new element (or removes it if blurring)document.hasFocus()is truefocusorblurevent (flagged as dirty) when the window again receives focusSo far... everything is good, all of this is native behavior.
The problem is this...
activeElementit would have otherwise had itsfocusevent fired.focusevent until the user really focuses on the window.The Desired Behavior
We should polyfill the native event behavior by also internally flagging the element as dirty and needing the focus event - and any action or behavior that would normally cause this to fire, we should fire it.
To note: everything I just mentioned here only affects Cypress in interactive mode via
cypress openand only when the browser is out of focus and only when the application code programmatically calls.focus()or.blur(). Any other situation is already accounted for.This will fix issues such as: #549