.click()
and .check()
methods with the following error:CypressError: Timed out retrying: cy.click() failed because the center of this element is hidden from view:
html {
scroll-behavior: smooth;
}
.click()
or .check()
methodsCypress version 3.1.4, Mac OSX, Chrome
A huge thank you to all of the contributors on this project. It's a great great tool!
Hey @nicklemmon, I've opened a PR for this - writing a failing test for this behavior here: https://github.com/cypress-io/cypress/pull/3213
Now someone will need to look into why this failure occurs and fix Cypress calculations. Just from watching the test run, it looks as if the scroll is happening after the .click
command has errored.
The error is being thrown at this line of code: https://github.com/cypress-io/cypress/blob/issue-3200-scroll-behavior-smooth/packages/driver/src/cy/ensures.coffee#L224
@Bkucera Brian was hoping you could pick this issue up as well as part of 3.1.6. 馃檹 Thank you!
@jennifer-shehane this issue can't be fixed by simply passing options into scrollIntoView
, it seems the css property will force all calls to scrollIntoView
to be smooth.
The solution is to mutate the styles of the element with scroll-behavior:smooth
just before the call to scrollIntoView
, and then change it back right after.
I'm not sure why this would be a priority and need to go in the next patch, currently you can just work around this bug by removing that style
I start having this issue when updated to Cypress 3.1.4 and I solved it by adding to cy.visit
the following:
cy.visit('/', {
onBeforeLoad(win) {
cy.stub(win, 'scrollTo').as('windowScroll');
}
});
cc. @jennifer-shehane Hope this helps you.
Same bug here, ended up disabling the style with the following snippet:
/**
* Disable css smooth scroll, that doesn't plays nice with cypress.
* See https://github.com/cypress-io/cypress/issues/3200
*/
const disableSmoothScroll = () => {
cy.document().then(document => {
const node = document.createElement('style');
node.innerHTML = 'html { scroll-behavior: inherit !important; }';
document.body.appendChild(node);
});
};
describe('test', () => {
it('does stuff', () => {
cy.visit(...);
disableSmoothScroll();
cy.get(...).scrollIntoView();
})
})
I've solved this by adding class e2e
to the html element when running in test mode, and setting
html:not(.e2e) {
scroll-behavior: smooth;
}
Use only window.scrollTo(0,0);
Old model phone dont work if use window.scrollTo({top: 0, behavior: 'smooth'});
Reproduction app:
https://github.com/gtsop/cypress-scroll-behaviour-smooth-bug-app
@jennifer-shehane Can I suggest we at least give out a warning when scroll-behaviour: smooth is in use and scrolling happens? I spent an hour trying to figure out why a simple test case didn't work, we can help a lot of people save time. I am willing to issue a PR with a little guidance regarding the appropriate place in the codebase to throw such a warning.
Ideally fixing the issue as @Bkucera described would be the best solution. https://github.com/cypress-io/cypress/issues/3200#issuecomment-461595024
There is already a PR open with a failing test case if someone would like to make a PR using that test case as a base. https://github.com/cypress-io/cypress/pull/3213/files
It is not just because of cypress itself. I have the same issue when I use nothing, but plain JS on Chrome, too. Seems to be a problem with the Chrome browser.
Just wanted to highlight what this issue is more clearly.
index.html
<html style="scroll-behavior: smooth">
<body>
<div style="height: 4000px; background-color: red;"></div>
<div style="height: 200px; background-color: green;">TEST</div>
</body>
</html>
it('should be able to find and click', () => {
cy.visit('index.html')
cy.get('div:last')
.click()
})
If you remove the scroll-behavior: smooth
, it correctly clicks.
Hello,
I'm having a very tough time using the workaround. I don't have a single page app, so every time Cypress goes to a different route in my specs I have to re-disable smooth scrolling since the workaround above is dependant on injecting a style tag in the existing DOM.
Any suggestions? I tried putting disableSmoothScroll
into a Cypress.on("window:load"
but I got an error about a promise within a promise or something 馃
If you're using this workaround - you would have to call disableSmoothScroll
after the cy.visit()
https://github.com/cypress-io/cypress/issues/3200#issuecomment-505965470, so yes you would need to call this after every cy.visit()
.
You could also write a custom command so this is always called after your visit. https://on.cypress.io/custom-commands#Overwrite-Existing-Commands
Cypress.Commands.add('visitApp', (url) => {
cy.visit(url)
cy.document().then(document => {
const node = document.createElement('style');
node.innerHTML = 'html { scroll-behavior: inherit !important; }';
document.body.appendChild(node);
});
})
it('test', () => {
cy.visitApp('https://...')
})
Thanks @jennifer-shehane
I think this will work for now. Unfortunately if any of my specs click on links I also have to remember to invoke this 馃槥
Hopefully a fix comes out someday 馃憖
This work around is great!
I personally adapted it slightly only to allow the site to continue to work as expected. This a "toggle" approach:
Maybe this will help others as it did me until something else comes in :)
in commands add a new function:
Cypress.Commands.add("toggleSmoothScrollStyle", () => {
cy.document().then((document) => {
let element = document.getElementById("smoothScroll_disable");
if (typeof element != "undefined" && element != null) {
element.remove();
} else {
const node = document.createElement("style");
node.innerHTML = "html { scroll-behavior: inherit !important; }";
node.setAttribute("id", "smoothScroll_disable");
document.body.appendChild(node);
}
});
});
Then use this before and after to add and then remove this styling change from the DOM
it("A test name", () => {
cy.toggleSmoothScrollStyle(); //Adds
cy.get(".className").scrollIntoView().click();
cy.toggleSmoothScrollStyle(); // Removes
});
Thanks everyone for providing workarounds; they do seem to work.
That said, I do really wish that the original issue were to be resolved. Having to factor this workaround into tests is quite arduous. Yes, you can write your own custom command to use the workaround after a cy.visit
, but this doesn't account for uses of cy.reload
or cy.go
for which you also need to write custom commands. Furthermore, if your application sends you to a new page during a test (as a result of clicking a button or some other user interaction) you also have to deliberately apply the workaround in those instances since the scroll behaviour will have been reset to smooth.
It is not impossible to deal with, but it is much more work than I would expect to have to do in order to be able to write basic tests out of the box on a page that uses smooth scrolling.
Just my two cents.
Most helpful comment
Same bug here, ended up disabling the style with the following snippet: