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

fix: Fix actionability when element has scroll-behavior: smooth #15453

Merged
merged 2 commits into from Mar 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/driver/cypress/integration/commands/actions/click_spec.js
Expand Up @@ -1607,6 +1607,24 @@ describe('src/cy/commands/actions/click', () => {
expect(args[2]).to.eq(animationDistanceThreshold)
})
})

describe('scroll-behavior', () => {
afterEach(() => {
cy.get('html').invoke('css', 'scrollBehavior', 'inherit')
})

// https://github.com/cypress-io/cypress/issues/3200
it('can scroll to and click elements in html with scroll-behavior: smooth', () => {
cy.get('html').invoke('css', 'scrollBehavior', 'smooth')
cy.get('#table tr:first').click()
})

// https://github.com/cypress-io/cypress/issues/3200
it('can scroll to and click elements in ancestor element with scroll-behavior: smooth', () => {
cy.get('#dom').invoke('css', 'scrollBehavior', 'smooth')
cy.get('#table tr:first').click()
})
})
})

describe('assertion verification', () => {
Expand Down
32 changes: 31 additions & 1 deletion packages/driver/src/cy/actionability.js
Expand Up @@ -309,6 +309,32 @@ const verify = function (cy, $el, options, callbacks) {
}
}

// scroll-behavior: smooth delays scrolling and causes the actionability
// check to fail, so the only solution is to remove the behavior and
// make scrolling occur instantly. we do this by adding a style tag
// and then removing it after we finish scrolling
// https://github.com/cypress-io/cypress/issues/3200
const addScrollBehaviorFix = () => {
let style

try {
const doc = $el.get(0).ownerDocument

style = doc.createElement('style')
style.innerHTML = '* { scroll-behavior: inherit !important; }'
// there's guaranteed to be a <script> tag, so that's the safest thing
// to query for and add the style tag after
doc.querySelector('script').after(style)
} catch (err) {
// the above shouldn't error, but out of an abundance of caution, we
// ignore any errors since this fix isn't worth failing the test over
}

return () => {
if (style) style.remove()
}
}

return Promise.try(() => {
let retryActionability
const coordsHistory = []
Expand All @@ -329,8 +355,12 @@ const verify = function (cy, $el, options, callbacks) {
// scroll the element into view
const scrollBehavior = scrollBehaviorOptionsMap[options.scrollBehavior]

$el.get(0).scrollIntoView({ block: scrollBehavior })
const removeScrollBehaviorFix = addScrollBehaviorFix()

debug('scrollIntoView:', $el[0])
$el.get(0).scrollIntoView({ block: scrollBehavior })

removeScrollBehaviorFix()

if (onScroll) {
onScroll($el, 'element')
Expand Down