Skip to content
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

Merged
merged 75 commits into from
Aug 25, 2022

Conversation

tbiethman
Copy link
Contributor

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

  • Have tests been added/updated?
  • Has the original issue (or this PR, if no issue exists) been tagged with a release in ZenHub? (user-facing changes only)
  • Has a PR for user-facing changes been opened in cypress-documentation?
  • Have API changes been updated in the type definitions?

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Aug 23, 2022

Thanks for taking the time to open a PR!

@tbiethman tbiethman mentioned this pull request Aug 23, 2022
21 tasks
@tbiethman tbiethman changed the title fix: driver updates for clicking/typing actions and related tests for WebKit chore(webkit): driver updates for clicking/typing actions and related tests for WebKit Aug 23, 2022
@tbiethman tbiethman changed the title chore(webkit): driver updates for clicking/typing actions and related tests for WebKit chore(webkit): driver updates for clicking/typing actions and related tests Aug 23, 2022
@@ -4064,12 +4062,28 @@ describe('mouse state', { browser: '!webkit' }, () => {
y: 10,
}

const coordsWebKit = {
Copy link
Contributor Author

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.

@cypress
Copy link

cypress bot commented Aug 23, 2022



Test summary

47 0 11 0Flakiness 0


Run details

Project cypress
Status Passed
Commit 31cb6fd
Started Aug 25, 2022 1:39 PM
Ended Aug 25, 2022 1:50 PM
Duration 10:39 💡
OS Linux Debian - 11.3
Browser Chrome 100

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) {
Copy link
Contributor Author

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 = [
Copy link
Contributor Author

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')
})
Copy link
Contributor Author

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).

Copy link
Contributor

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.

Copy link
Contributor Author

@tbiethman tbiethman Aug 24, 2022

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:
Screen Shot 2022-08-24 at 8 12 43 AM

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.

This PR ensures both tables are rendered from arrays:
Screen Shot 2022-08-24 at 8 25 22 AM

Copy link
Contributor

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')
Copy link
Contributor Author

@tbiethman tbiethman Aug 23, 2022

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?).

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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).

@tbiethman tbiethman marked this pull request as ready for review August 24, 2022 04:01
@tbiethman tbiethman requested a review from flotwig August 24, 2022 04:01
.focus()
.then(($input) => $input[0].setSelectionRange(0, 0))
Copy link
Contributor Author

@tbiethman tbiethman Aug 24, 2022

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).

Copy link
Contributor

@lmiller1990 lmiller1990 left a 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
Copy link
Contributor

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) => {
Copy link
Contributor

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?

Copy link
Contributor Author

@tbiethman tbiethman Aug 24, 2022

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()

Copy link
Contributor

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')
Copy link
Contributor

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')
})
Copy link
Contributor

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.

Copy link
Contributor

@flotwig flotwig left a 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')
Copy link
Contributor

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.
Copy link
Contributor

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?

Copy link
Contributor Author

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.

// 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)
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

@tbiethman tbiethman merged commit 2fcecbf into develop Aug 25, 2022
@tbiethman tbiethman deleted the tbiethman/webkit-tests branch August 25, 2022 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants