Reputation: 699
Maybe it's an easy one, but my Cypress
tests fail to test locked scrolling functionality.
So I have this React
modal component which sets document.body.style.overflow = 'hidden'
upon mount (client side only)
I have the following Cypress
's test suite:
it('page cant scroll when modal is open', () => {
cy.get('[data-testid="button"]')
.first()
.click();
cy.window().scrollTo('bottom');
// scroll should be disabled
cy.window()
.its('scrollY')
.should('equal', 0);
// cy.get('[data-testid="modal"]')
// .scrollTo('bottom')
// .its('scrollY')
// .should('not.equal', 0);
});
Error message: Timed out retrying after 4000ms: expected 802 to equal 0
Looks like Cypress is able to scroll the window
even though this not possible when manually scrolling the page.
Any idea what the issue could be?
OP's edit: Scrolling the page programmatically still works (window.scrollTo()
). The overflow
property hides the scrollbar but this doesn't mean the scroll functionality is actually blocked (beyond a simple user interaction)
I was advised to use another approach for testing the scroll freeze through pagedown
and pageup
key navigation. Using the mentioned keys will be blocked on the actual page and user won't be able to scroll.
it('page cant scroll when modal is open', () => {
cy.get('[data-testid="button"]')
.first()
.click();
cy.get('body').type('{pagedown}');
cy.window()
.its('scrollY')
.should('equal', 0);
cy.get('[data-testid="overlay"]').click();
cy.get('body').type('{pagedown}');
cy.window()
.its('scrollY')
.should('not.equal', 0);
});
As with the previous code example, it makes sense for this snippet to throw error as well. Timed out retrying after 4000ms: expected 46 to equal 0
.
Upvotes: 2
Views: 2388
Reputation: 6534
This is my solution to verify if the horizontal scroll is enabled:
it('should guarantee that the horizontal scroll is not activated', () => {
// Try to scroll the page to the right
cy.scrollTo('right', { offset: 100 })
// Get the horizontal scroll position
cy.window().then((win) => {
const scrollLeft = win.scrollX || win.pageXOffset
// Check if the horizontal scroll position is at the beginning (equal to zero)
expect(scrollLeft).to.equal(0)
})
})
Upvotes: 0
Reputation: 23463
It seems to me that testing that expect($el.document.body.style.overflow).to.eq('hidden')
is not very useful because you already know that to be the case. You say
I have this React modal component which sets
document.body.style.overflow = 'hidden'
upon mount
Are you testing the React Modal component or how it interacts with the app?
Taking a look at the Material-UI Modal (Simple Modal demo), when I click on the "Open Modal" button it applies the same style to body
<body dir="ltr" style="padding-right: 16px; overflow: hidden;">
Visually the scrollbar has gone when the modal is open.
The best approach I found was to measure widths before and after opening the modal. The scrollbar is actually attached to the html
element, so this is what I measured (relative to the window)
cy.visit('https://material-ui.com/components/modal/');
cy.window().then(win => {
const htmlWidth = Cypress.$('html')[0].scrollWidth;
const scrollBarWidth = win.innerWidth - htmlWidth;
expect(scrollBarWidth).to.be.gt(0); // scrollbar is present
})
cy.contains('button', 'Open Modal').click(); // open the modal
cy.window().then(win => {
const htmlWidth = Cypress.$('html')[0].scrollWidth;
const scrollBarWidth = win.innerWidth - htmlWidth;
expect(scrollBarWidth).to.be.eq(0); // scrollbar is absent
})
Upvotes: 4
Reputation: 6312
You can disable a scroll behavior on a web page by setting the overflow
property to hidden
like so window.document.body.style.overflow = 'hidden'
.
Assuming the React
modal component sets document.body.style.overflow = 'hidden'
as you mentioned previously.
You could assert that scrolling
is not enabled with one-liner
like so:
cy.window().then(($el) => expect($el.document.body.style.overflow).to.eq('hidden'));
Upvotes: 1