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(driver): Sticky elements within a fixed container will not prevent an element from being scrolled to #18441

Merged
merged 31 commits into from
Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
271dcbd
add test
davidmunechika Oct 6, 2021
43fb341
try other scroll behavior options
davidmunechika Oct 11, 2021
496945b
refactor scroll until visible
davidmunechika Oct 11, 2021
f3d05c6
allow overriding with scrollBehavior
davidmunechika Oct 12, 2021
c833f0b
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 12, 2021
95d2211
add comment
davidmunechika Oct 13, 2021
0195ca0
rename userSetScrollBehavior
davidmunechika Oct 13, 2021
4f254e6
refactor if else
davidmunechika Oct 13, 2021
5af31e0
add custom scroll behavior test
davidmunechika Oct 13, 2021
d57dd85
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 13, 2021
3d0cebb
add tests for other scrolling commands
davidmunechika Oct 15, 2021
5e8deda
Merge branch 'issue-4233-click-sticky-element' of https://github.com/…
davidmunechika Oct 15, 2021
5d688da
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 15, 2021
2bd2851
refactor scrollBehavior option
davidmunechika Oct 18, 2021
1f83d11
Merge branch 'issue-4233-click-sticky-element' of https://github.com/…
davidmunechika Oct 18, 2021
f0ddb9b
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 18, 2021
28834b5
refactor ensure visibility
davidmunechika Oct 27, 2021
3d8eb4c
Merge branch 'issue-4233-click-sticky-element' of https://github.com/…
davidmunechika Oct 27, 2021
2f9a14f
remove chai import
davidmunechika Oct 27, 2021
981f297
fix trigger test
davidmunechika Oct 27, 2021
7a0b1c1
remove user set scroll behavior
davidmunechika Oct 27, 2021
2e9207c
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 27, 2021
15a22b5
fix clear spec
davidmunechika Oct 27, 2021
2bccbff
fix error message
davidmunechika Oct 27, 2021
b0b348b
fix select case
davidmunechika Oct 28, 2021
8330767
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Oct 28, 2021
f2a4b1f
update tests
davidmunechika Nov 1, 2021
dbbe481
Merge branch 'issue-4233-click-sticky-element' of https://github.com/…
davidmunechika Nov 1, 2021
1de8681
add comment
davidmunechika Nov 1, 2021
1d0f1f7
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Nov 1, 2021
5aa6dc7
Merge branch 'develop' into issue-4233-click-sticky-element
davidmunechika Nov 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/driver/cypress/fixtures/sticky-header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<body>
<div class="overlay-background" style="position: fixed; width: 300px">
<div class="sidepanel" style="position: absolute; height: 300px; overflow: auto;">
<header class="sticky-header" style="position: sticky; top: 0; left: 0; height: 40px; background-color: blue;">
sticky header
</header>
<div style="height: 500px">
<p>content to scroll to</p>
</div>
</div>
</div>
</body>
</html>
20 changes: 20 additions & 0 deletions packages/driver/cypress/integration/commands/actions/click_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,26 @@ describe('src/cy/commands/actions/click', () => {
cy.get('#overflow-auto-container').contains('quux').click()
})

// https://github.com/cypress-io/cypress/issues/4233
it('can click an element behind a sticky header', () => {
cy.viewport(400, 400)
cy.visit('./fixtures/sticky-header.html')
cy.get('p').click()
})

// https://github.com/cypress-io/cypress/issues/4233
it('allows users to pass in a custom scroll behavior', (done) => {
davidmunechika marked this conversation as resolved.
Show resolved Hide resolved
cy.on('fail', (err) => {
expect(err.message).contain('failed because this element is not visible')
expect(err.message).contain('it has CSS property: `position: fixed` and it\'s being covered by another element')
done()
})

cy.viewport(400, 400)
cy.visit('./fixtures/sticky-header.html')
cy.get('p').click({ scrollBehavior: 'top' })
})

it('does not scroll when being forced', () => {
const scrolled = []

Expand Down
55 changes: 39 additions & 16 deletions packages/driver/src/cy/actionability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,35 @@ const verify = function (cy, $el, options, callbacks) {
}
}

const scrollElementIntoView = ($el, scrollBehaviorOption) => {
if (scrollBehaviorOption !== false) {
// scroll the element into view
const scrollBehavior = scrollBehaviorOptionsMap[scrollBehaviorOption]

const removeScrollBehaviorFix = addScrollBehaviorFix()

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

removeScrollBehaviorFix()

if (onScroll) {
onScroll($el, 'element')
}
}
}

const scrollUntilVisible = ($el, scrollOptions) => {
try {
cy.ensureVisibility($el, _log)
} catch (err) {
if (!scrollOptions[0]) throw err

scrollElementIntoView($el, scrollOptions[0])
scrollUntilVisible($el, scrollOptions.slice(1))
}
}

return Promise.try(() => {
const coordsHistory = []

Expand All @@ -365,27 +394,21 @@ const verify = function (cy, $el, options, callbacks) {
cy.ensureNotDisabled($el, _log)
}

if (options.scrollBehavior !== false) {
// scroll the element into view
const scrollBehavior = scrollBehaviorOptionsMap[options.scrollBehavior]

const removeScrollBehaviorFix = addScrollBehaviorFix()

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

removeScrollBehaviorFix()
if (options.ensure.visibility) {
// if the user specified the scroll behavior explicitly, stick with that and don't try other scroll behaviors
if (options.userSetScrollBehavior) {
cy.ensureVisibility($el, _log)
} else {
// if not already visible, try remaining scroll behavior options
// https://github.com/cypress-io/cypress/issues/4233
const scrollOptions = Object.keys(scrollBehaviorOptionsMap).filter((option) => option !== options.scrollBehavior)

if (onScroll) {
onScroll($el, 'element')
scrollUntilVisible($el, scrollOptions)
}
}

// ensure its visible
if (options.ensure.visibility) {
cy.ensureVisibility($el, _log)
}

if (options.ensure.notReadonly) {
cy.ensureNotReadonly($el, _log)
}
Expand Down
5 changes: 4 additions & 1 deletion packages/driver/src/cy/commands/actions/click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ export default (Commands, Cypress, cy, state, config) => {
// properties like `total` and `_retries` are mutated by
// $actionability.verify and retrying, but each click should
// have its own full timeout
const individualOptions = { ... options }
const individualOptions = {
userSetScrollBehavior: userOptions.scrollBehavior !== undefined,
...options,
}

// must use callbacks here instead of .then()
// because we're issuing the clicks synchronously
Expand Down