-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(webkit): driver updates for clicking/typing actions and related tests #23522
Conversation
Co-authored-by: Blue F <[email protected]>
Thanks for taking the time to open a PR!
|
@@ -4064,12 +4062,28 @@ describe('mouse state', { browser: '!webkit' }, () => { | |||
y: 10, | |||
} | |||
|
|||
const coordsWebKit = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The coordinates vary per-browser due to differences in the default stylesheet.
Test summaryRun details
View run in Cypress Dashboard ➡️ This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
return this._logTable({ table }) | ||
}, | ||
) | ||
_logTables (consoleProps: any) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We currently log tables for keyboard and mouse events, and we were creating slightly different data structures within the consoleProps for each. These differences made the existing logic complicated (and made parsing out the elements to avoid the WebKit hang difficult).
So I normalized the inputs and simplified the parsing here a bit, while ensuring that the elements don't make it into the table for WebKit. I'm sure we could simplify this further.
6: { 'Details': '{ code: ControlLeft, which: 17 }', Typed: '{ctrl}', 'Events Fired': 'keyup', 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, | ||
7: { 'Details': '{ code: KeyI, which: 73 }', Typed: 'i', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, | ||
} | ||
const expectedTable = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These were updated as part of the table log normalization mentioned above: https://github.com/cypress-io/cypress/pull/23522/files#r952882550
|
||
expect(KeyboardEventsTable.data[2]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') | ||
expect(KeyboardEventsTable.data[2]).to.have.property('Typed').that.equals('o') | ||
|
||
expect(KeyboardEventsTable.data[3]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') | ||
expect(KeyboardEventsTable.data[3]).to.have.property('Typed').that.equals('o') | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This difference is a result of switching from a number-keyed object (starting with key 1) with an array (indexed at 0).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the source code you changed that led to the need to change this test? I don't see it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The directly relevant change is here: https://github.com/cypress-io/cypress/pull/23522/files#diff-c0edb6eb8f7d6c9276eae18e47f83859d84a34dafaf05ec2a97b6fd5478983a5R91
For reference, this is how the Mouse/Keyboard Events tables are rendered in develop:
Notice that Mouse Events are indexed starting at 0, while Keyboard Events start at 1. I don't think this was intentional, or at least don't have a good reason as to why they'd be different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't even know we could log a table like this, neat.
// WebKit does not round to the step value when calling stepUp/stepDown, | ||
// as we do here for the ArrowUp handler. | ||
// https://bugs.webkit.org/show_bug.cgi?id=244206 | ||
.should('have.value', Cypress.isBrowser('webkit') ? '14.34' : '14') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bug I logged is getting a little traction, but I'm not sure how quick these things get turned around. Do we think it's worth adding our own logic here for WebKit to bring it to parity, or just documenting the issue as a current limitation? Current spec for the step
attribute and stepUp/stepDown
algorithms can be found here, if you're curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option 3 ... Fix WebKt ourselves! But we'd still need something in the (probably long) interim.
If this is a WebKit bug, what you've done make sense to me - if a user runs a test expecting 14, it should fail - since it will fail in production for real users, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if a user runs a test expecting 14, it should fail - since it will fail in production for real users, too
The behavior we're simulating here is a user tapping the up/down arrows inside the input, which does work appropriately in WebKit. The problem is that the stepUp
/stepDown
functions we call to simulate those presses don't work the same way. So this would definitely need to be a documented limitation if we left things as-is.
I did write up the algorithm to handle the step logic ourselves. It's not too intensive, but it'll need a new suite of tests associated to it. I want to make sure we have other critical issues wrapped up before spending much more time on it (unless we consider this critical?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cross-section of users who use .type('{uparrow}')
on a number input who will be using experimental WebKit is probably pretty small, I'd agree that focus should be put elsewhere. How large is the change to fix this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The algorithm isn't very complicated, there are just a lot of bound checks/edge cases that I'd want to write thorough tests for. I'd hate to write a custom handler that introduces yet more bugs 🐛
I think we could wrap it up prior to the initial release if we start looking good on the other issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I say the sooner we ship this, the better - little fixes like this will come up organically, if we don;'t get to them (and we might have other edges cases we don't even know about yet).
.focus() | ||
.then(($input) => $input[0].setSelectionRange(0, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the selection range prior to focusing the input like we did previously will fail, due to the default selection Webkit performs (that we're working around here).
The ordering here for these commands seemed pretty arbitrary given what is asserted, and it generally seems appropriate to focus an input prior to setting a selection within it, so I didn't have too many concerns with this change. But it is technically a difference in behavior.
I did spend a bit of time trying to keep these tests passing as they are, but the resulting changes caused quite a few more focus events to be emitted (and quite a few more tests to fail as a result).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No major blocker, just some questions.
return | ||
} | ||
if (Cypress.isBrowser('webkit')) { | ||
// WebKit will hang when we attempt to log element references |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, major bug in webkit.
|
||
const table = this._getTable(consoleProps) | ||
const getSimplifiedElementDisplay = (element: Element) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems similar to https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/dom/elements/utils.ts#L45 - or are they different enough not to warrant reuse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are pretty close. I wrote the current version to match what Chrome renders in its tables, the util would produce slightly different results. But we could reuse if there are strong feelings either way, it's exposed in app through Cypress.dom.stringify()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to you, I do not have strong feelings about this 💯
// WebKit does not round to the step value when calling stepUp/stepDown, | ||
// as we do here for the ArrowUp handler. | ||
// https://bugs.webkit.org/show_bug.cgi?id=244206 | ||
.should('have.value', Cypress.isBrowser('webkit') ? '14.34' : '14') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option 3 ... Fix WebKt ourselves! But we'd still need something in the (probably long) interim.
If this is a WebKit bug, what you've done make sense to me - if a user runs a test expecting 14, it should fail - since it will fail in production for real users, too.
|
||
expect(KeyboardEventsTable.data[2]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') | ||
expect(KeyboardEventsTable.data[2]).to.have.property('Typed').that.equals('o') | ||
|
||
expect(KeyboardEventsTable.data[3]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') | ||
expect(KeyboardEventsTable.data[3]).to.have.property('Typed').that.equals('o') | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the source code you changed that led to the need to change this test? I don't see it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I appreciate the thorough comments, these will help a lot down the road. Had a few Q's but LGTM.
// WebKit does not round to the step value when calling stepUp/stepDown, | ||
// as we do here for the ArrowUp handler. | ||
// https://bugs.webkit.org/show_bug.cgi?id=244206 | ||
.should('have.value', Cypress.isBrowser('webkit') ? '14.34' : '14') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cross-section of users who use .type('{uparrow}')
on a number input who will be using experimental WebKit is probably pretty small, I'd agree that focus should be put elsewhere. How large is the change to fix this?
@@ -1736,7 +1745,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk | |||
}) | |||
}) | |||
|
|||
it('will not submit the form', function (done) { | |||
// WebKit still emits the submit event on the form in this configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just how WebKit works? It acts the same if a user presses "Enter" on a form with multiple submits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, I recreated this scenario outside of Cypress and found the form was still submitted in this case in WebKit, whereas its not in Chrome/FF.
packages/driver/src/dom/selection.ts
Outdated
// WebKit must use selectAllChildren to ensure selections are made in all use cases. | ||
// Some content, like HTML markup, cannot be selected using a range when inside a contenteditable field. | ||
if (Cypress.isBrowser('webkit')) { | ||
selection.selectAllChildren(el) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I wonder why we aren't just using selectAllChildren
in all browsers, did you check if this works for Cr/FF?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, it does work for the current versions of Chrome/Firefox and Chromium 74, which is the earliest I can grab. Minimum supported Chrome is 64, so there's still a range of supported versions I can't validate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MDN says it's supported since uh.. Chrome... squints Chrome 1. https://developer.mozilla.org/en-US/docs/Web/API/Selection/selectAllChildren#browser_compatibility So it should be safe if the tests pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, straight from the primordial soup. Well we know it won't throw at least! I'll get that change made and verified in CI.
User facing changelog
N/A
Additional details
This PR re-enables driver tests related to clicking and typing for the WebKit browser. Included are some WebKit-specific tweaks to the driver for these actions. In-line doc is included where we deviate, please call out anything that is unclear or could otherwise be expounded on.
Steps to test
Review
driver-integration-tests-webkit
job results in CircleCI for the successful execution of the following specs:type.cy.js
type_errors.cy.js
type_special_chars.cy.js
click.cy.js
How has the user experience changed?
PR Tasks
cypress-documentation
?type definitions
?