How to Use Cypress scrollIntoView() Command
Himanshu Sheth
Posted On: March 17, 2025
2934 Views
8 Min Read
The scrollIntoView() command scrolls the webpage until a specific DOM element enters the viewport’s visible area. Cypress waits for 4 seconds (by default) for the elements to become visible on the page. Though this wait duration is customizable, you might need to add some more cushioning for handling elements that are not currently in the viewport.
This is where the Cypress scrollIntoView() command can be leveraged to reduce test flakiness for pages with hidden elements, dynamic content, lazy-loaded images, and infinite content. In this blog, we’ll explore how to effectively use Cypress to scroll elements into the view, ensuring that the tests accurately mimic real user interactions.
TABLE OF CONTENTS
What Is Cypress scrollIntoView() Command?
Before diving deeper into the Cypress scrollIntoView() command, let’s look at the why aspect of the command. Consider a scenario where you have to automate interaction with an element in an infinite-scrolling website.
Since the website has dynamically loaded content, clicking on any element that is not in the viewport involves scrolling followed by actions (e.g., clicking, typing, etc.). Failure to do so results in an exception, as the resultant element is not present in the DOM.
Shown below is an example of a Cypress test that results in an exception:
The Cypress scrollIntoView() command, when used in such scenarios, helps in handling interactions with hidden elements, dynamically loaded content, and reducing flakiness caused by the default viewport or changes in the UI layout.
scrollIntoView() Syntax
As seen in the Cypress scrollIntoView() syntax, the command needs to be used in conjunction with the cy.get() or cy.find() commands.
1 |
cy.get('selector').scrollIntoView(options) |
Arguments:
options (Object) An object to customize the behavior of the Cypress scrollIntoView() command.
Option | Default | Description |
---|---|---|
duration | 0 | Time (in ms) for the scroll animation |
easing | swing | Scrolls into the viewport with an easing animation |
log | TRUE | Displays command in the Command Log |
offset | {top: 0, left: 0} | Pixels to be scrolled after the element is scrolled into the view |
timeout | defaultCommandTimeout | Time the command waits to resolve before it results in a timeout |
Assertions can also be chained with the Cypress scrollIntoView() command. This means that Cypress ensures that scrolling into the view (of the desired element) is completed and the element is in the expected state before continuing with the rest of the interactions.
As seen in the below example, the visibility of the located element is checked after scrolling into the view of the viewport. This is how a chained assertion is used to verify an element’s state (e.g., visibility, clickability, etc.) after the .scrollIntoView() action.
1 2 3 |
cy.get('element-locator') .scrollIntoView({ easing: 'linear' }) .should('be.visible') |
scrollIntoView() Usage
scrollIntoView() scrolls an element into the visible area of the viewport. It can be chained with assertions or actions like click(), type(), etc. As stated in the official documentation on the Cypress scrollIntoView() command, it is not a good practice to chain further commands that rely on the subject after scrollIntoView().
Example: Correct usage
1 2 |
/* Correct usage - scrollIntoView */ cy.get('element').scrollIntoView() |
Here, the element is first located using the get() command. You can also use the cy.find() command to retrieve the DOM element. Post that, the Cypress scrollIntoView() command scrolls the element into the visible area of the viewport.
Example: Incorrect usage
scrollIntoView() is not a standalone command and needs a WebElement to be scrolled-into for performing any further actions.
1 2 3 |
/* Incorrect usage - scrollIntoView */ cy.scrollIntoView('element') cy.window().scrollIntoView() |
The second example shown above also fails, as the Cypress scrollIntoView() command is only applicable on a DOM element, not the window object. The cy.scrollTo() command should be used for scrolling the entire window!

Test and automate scrolling with Cypress across real browsers. Try LambdaTest Today!
scrollIntoView() Examples
Here are some of the commonly-used scenarios that can be realized with the Cypress scrollIntoView() command:
Scrolling to an Element
The WebElement is first located with the cy.get() command. Post that, a vertical scroll into the element is performed and the click() command is chained with the scroll to click on the located element.
1 2 3 |
cy.get('element-locator') .scrollIntoView() .click() |
Scrolling to an Element using the linear easing animation
The web browser’s default native scrolling implementation can be overridden to ease animation with the easing option of the Cypress scrollIntoView() command. In the sample shown below, easing is set to linear (i.e., scrolling at a constant speed).
1 2 3 |
cy.get('element-locator') .scrollIntoView({ easing: 'linear' }) .click() |
Alternatively, a custom JavaScript implementation can be used to change the animation type (e.g., the easing option) in Cypress.
Scrolling with a custom duration
Instead of instant scrolling, the scroll duration can be customized by setting the duration option of the Cypress scrollIntoView() command.
In the example below, scrolling to the element with locator element-locator is performed over a duration of 4000 ms (or 4 seconds) seconds with a linear animation. Once inside the element, the Cypress click() command is triggered to click on the located element.
1 2 3 |
cy.get('element-locator') .scrollIntoView({ duration: 4000, easing: 'linear' }) .click() |
Scrolling into a lazy loaded image
Nowadays, websites heavily rely on lazy-loaded images and dynamic content to improve performance and user experience. As lazy-loaded images appear after a scroll(s), the Cypress scrollIntoView() command can be extremely effective for realizing the scroll and its respective action.
In the below example, the element with the class .lazy-element is located within the DOM. After scrolling into the visible portion of the viewport, the element is checked for its visibility. An assert is raised if the element is hidden by CSS (e.g., display: none;) or overlapping with another element.
1 2 3 4 5 6 |
cy.get('.lazy-element') .scrollIntoView() .should('be.visible') .parent() .contains(/Apple iPhone/i) .click() |
With .parent, Cypress moves up to the parent element of .lazy-element in the DOM hierarchy. Next, a case-insensitive search is performed within the parent element for any child element containing the text matching the regex (i.e. /Apple iPhone/i). Finally, the chained click() command mimics the click on the element matching the required search criteria.
We suggest reading the official Cypress scrollIntoView() documentation to gain insights into command logs, snapshots, and more.
Demonstration: Using Cypress scrollIntoView() Command
We will be using the following websites to demonstrate the usage of the Cypress scrollIntoView() command:
The tests demonstrated in this section can either be run locally or on the Cypress cloud offered by the LambdaTest platform.
LambdaTest is an AI-native test execution platform that allows you to run Cypress tests across real browsers and OS. With LambdaTest, you can test if WebElements scroll into view as intended over different browser environments.
To get started, head over to this guide on Cypress testing with LambdaTest.
Project Structure
We are using Cypress v13.3.3 (& above) for execution.
{ | |
"name": "canvas-automation-cypress", | |
"version": "1.0.0", | |
"description": "ScrollIntoView Demo with Cypress", | |
"main": "index.js", | |
"scripts": { | |
"cypress:open": "cypress open", | |
"cypress:chrome": "cypress run --browser=chrome" | |
}, | |
"keywords": [ | |
"cypress", | |
"test", | |
"automation", | |
"web", | |
"automation", | |
"testing" | |
], | |
"author": "Himanshu Jagdish Sheth", | |
"license": "ISC", | |
"devDependencies": { | |
"cypress": "^13.3.3" | |
}, | |
"dependencies": { | |
"dotenv": "^16.4.5" | |
} | |
} |
For improved maintainability and reusability, we have used Cypress fixtures for holding static data for the tests. In our case, the urls.json holds the two test URLs used for demonstration.
{ | |
"url1": "https://ecommerce-playground.lambdatest.io/", | |
"url2": "https://scrapingclub.com/exercise/list_infinite_scroll/" | |
} |
You can have a look at the video below that deep dives into the nuances of fixtures in Cypress.
Subscribe to the LambdaTest YouTube Channel for more such videos.
Actions associated with Cypress installation (via npm on the local machine), cleanup, and triggering tests are done via a Makefile. Before triggering make install, it is recommended to set the environment variables ${LT_USERNAME} & ${LT_ACCESS_KEY} from the terminal. You can find your LambdaTest credentials in the LambdaTest Profile Dashboard.
To install the required dependencies and set up the necessary environment variables, trigger make install (from the root folder) on the terminal.
Demonstration: Using scrollIntoView() for Lazy-Loaded Images
Lazy-loaded images are loaded only when they are inside the visible area of the viewport. Interacting with an image that is not yet loaded results in an exception, which is where you can make use of the Cypress scrollIntoView() command.
The command ensures that the target image is fully loaded and scrolled into before performing any interaction. Once the image is in the viewport, its visibility can be checked for delivering consistent results.
Test Scenario:
|
Implementation:
it('Window ScrollIntoView Demo - Lazy Loaded Images', () => | |
{ | |
const cameraImage = '#mz-product-listing-image-39217984-0-2 > div > div.carousel-item.active > img'; | |
cy.visit(urls.url1); | |
/* Wait till the DOM contents are loaded */ | |
/* in this case, it is only the canvas element */ | |
cy.document().should((doc) => { | |
expect(doc.readyState).to.equal('complete'); | |
}); | |
/* Scroll to the bottom */ | |
cy.scrollTo('bottom'); | |
cy.wait(1000); | |
/* Scroll back to the top */ | |
cy.scrollTo('top'); | |
/* Additional cushioning for page loading */ | |
cy.wait(2000); | |
/* Scroll into the view */ | |
/* Doc - https://docs.cypress.io/api/commands/scrollintoview#Use-linear-easing-animation-to-scroll */ | |
cy.get(cameraImage) | |
.scrollIntoView({ easing: 'linear' }) | |
.invoke('css', { | |
position: 'relative', /* Ensure proper positioning */ | |
zIndex: '1000', /* Bring it to the front */ | |
backgroundColor: 'rgba(128, 128, 128, 0.5)', /* Light grey background */ | |
transition: 'background-color 2.5s ease' /* Smooth transition */ | |
}); | |
/* Only for testing purpose */ | |
cy.wait(2000); | |
/* Check if the image is within the view */ | |
/* Doc - https://docs.cypress.io/api/commands/scrollintoview#Scrolling */ | |
cy.get(cameraImage, { timeout: 2000 }).should('be.visible'); | |
/* Click on the element and verify if the click was successful */ | |
cy.get(cameraImage).click(); | |
/* Verify if the respective product page is open */ | |
cy.url().should('include', 'product_id=29'); | |
cy.log('Window ScrollIntoView Demo Complete') | |
}); |
Code Walkthrough:
Step 1: Once the URL is entered, the should() command in Cypress is used to assert if the document is not fully loaded (before performing further actions).
Step 2: Since the website has lazy-loaded images, the scrollTo() command is invoked for scrolling to a specific position (i.e., Top & Bottom). This is to ensure that all the website assets are loaded before interactions are performed on them.
Step 3: Now that the page load is complete, the required element is located using the CSS Selector locator. Post that, the cy.get() command in Cypress is called to check the existence of the said element.
Now that the element is located, the scrollIntoView() command is invoked to scroll into it, with easing set to linear.
Step 4 [Optional]: AI in test automation is on the rise, and we decided to leverage it to add a hint of visual debugging to the existing code. We used the invoke() command in Cypress to invoke a function on a previously yielded object.
The .invoke(‘css’, {…}) command dynamically applies CSS styles to an element during a test.
The position: ‘relative’ property ensures that the element is positioned relative to its normal flow in the document. The zIndex: ‘1000’ property brings the element to the front of other elements by assigning it a high stacking order. The backgroundColor: ‘rgba(128, 128, 128, 0.5) property sets a semi-transparent light grey background color.
Though this step is optional, it does help in making WebElement visually distinct and accessible for testing.
Step 5: Now that the required element is in the viewport, the next step is to check for its visibility. The should(‘be.visible’) assertion helps ensure that the expected element is displayed correctly (i.e., visible) and in an intractable state.
Lastly, the click() command simulates a click on the element.
Step 6: If the click operation is successful, it should open up the Product Page. The cy.url().should(‘include’) assertion checks if the resultant URL contains (or includes) the substring product_id=29.
Demonstration: Using scrollIntoView() for Infinite Scrolling Website
The Cypress scrollIntoView() command is extremely useful when it comes to automating interactions on an infinite scroll website. In such websites, pagination is eliminated as the page content is loaded dynamically as you scroll down the page.
ScrapingClub Infinite Scroll Website is one such website where the content is loaded on page scroll(s). Once you scroll the web page, the Inspect Tools → Network → Fetch/XHR tab provides detailed information related to new network requests (e.g., XHR or Fetch calls).
Assertions, in conjunction with the Cypress scrollIntoView() command, help simulate user interactions by scrolling into the element and verifying its content after the scroll operation.
Test Scenario:
|
Implementation:
Code Walkthrough:
Since a major part of the implementation remains unchanged, we will only touch base on the essentials in this example. When scrolling into an element on an infinite-scrolling website, we first scroll vertically until the page load is complete.
Since AI is becoming more prevalent in software testing, I decided to use AI to convert my Python test logic into its Cypress equivalent. A Cypress custom command is created for scrolling to the end of the page.
Step 1: First, the cy.window().then(win) command retrieves the window object and then uses a chainable .then() to provide access to the retrieved window object.
Step 2: Let’s look at the implementation of the chainable .then() object! First, we get the height of the entire document (including the one that is not visible in the viewport) via win.document.body.scrollHeight.
Now that we have the window height, we can perform a vertical scroll to the end of the page using the win.scrollTo() command in JavaScript.
Since it is an infinite-scrolling website, the window height is again calculated and stored in a variable named newHeight.
The newly calculated height is compared with the previous height, and the scroll command [i.e., scroll_window()] is called recursively until the end of the page is reached (i.e.,, newHeight > startHeight), where startHeight is also updated on every recursive call.
Finally, the scroll_window() function is invoked to handle the scrolling operation. The recursive function stops when the document reaches the end or no new content is detected for vertical scrolling.
Step 3: In the test method, the custom Cypress command – scrollUntilBottom is invoked for scrolling till the end of the page.
Step 4: Now that the page contents are loaded, the document method querySelector() is used with the CSS Selector of the desired element passed as an argument to it. It returns the first element matching the selector.
Step 5: The expect(element, …).to.exist assertion in Cypress validates the existence of the located element and raises an assertion if the element is not present on the page.
Step 6: The Cypress scrollIntoView() command scrolls the viewport so that the element located in the previous step is visible. The scrolling animation is set to smooth and block: ‘center’ aligns the WebElement’s center with the center of the viewport.
Step 7: Finally, the click() command is invoked on the located element and .should(‘include’, ‘92905-A’) raises an assertion if the resultant URL (post the click operation) does not contain the string 92905-A
Execution
First up, export the environment variables LT_USERNAME and LT_ACCESS_KEY on the terminal.
export LT_USERNAME=
export LT_ACCESS_KEY=
You can get these details from the LambdaTest Password & Security section. In case you have not installed the dependencies, you can do the same by triggering the command make install from the Project’s root folder. You also need to add LambdaTest credentials in lambdatest-config.json
Run the command make cloud-scroll-into-view-cypress on the terminal, post which the tests are executed on the LambdaTest grid.
You can also check the test execution status by visiting the LambdaTest Web Automation dashboard.
The same tests can also be executed on Cypress installed on the local machine by invoking the make local-scroll-into-view-cypress command on the terminal.
We are now done executing the test scenarios. The examples can be further modified to create tests that might align with your test requirements!
Differences Between Cypress scrollIntoView() and scrollTo() Commands
As seen so far, we used Cypress commands – scrollIntoView() and scrollTo() in the examples demonstrated in the blog. However, both these commands serve slightly different purposes!
scrollIntoView() in Cypress scrolls the viewport till the target WebElement is visible inside it. The .scrollIntoView(options) command can be used on the element located using the cy.get() or cy.find() command.
On the other hand, the scrollTo() command in Cypress scrolls the viewport to a specified position. Valid positions are topLeft, top, topRight, left, center, right, bottomLeft, bottom, and bottomRight.
As seen in the scrollTo() syntax, the position_Coordinates parameter specifies the scroll’s position (e.g., top, bottom, center, etc.). The Coordinates specify the scroll’s coordinates in an (X,Y) value pair.
For example, cy.scrollTo(‘top’) scrolls to the top of the page. Whereas cy.scrollTo(20, 200) scrolls to X-20, Y-200, the values of which are calculated from the top-left corner of the viewport.
Here is a brief rundown of the comparison between Cypress scrollIntoView() and scrollTo() commands:
scrollIntoView() | scrollTo() |
---|---|
scrollIntoView() targets a specific element. | scrollTo() targets a particular position or a coordinate pair. |
scrollIntoView() requires an element selector for it to scroll into the viewport. | scrollTo() requires a position or a coordinate pair. |
scrollIntoView() automatically calculates the scroll position if the desired element (to be scrolled to) is located in the DOM. | scrollTo() requires manual specification of the position. |
scrollIntoView() is normally used to ensure the element’s visibility before performing any further actions on it. | scrollTo() is used only to realize horizontal/vertical scrolls. |
In summary, the Cypress scrollIntoView() command interacts with an element after its visibility and scrollTo() is used for realizing precise scrolling operations in the document.
Conclusion
It is a known fact that scrolling and element actions go hand in hand when automating interactions on a page with dynamically loaded content. The Cypress scrollIntoView() command can be used to simulate user-like scrolling behavior while ensuring the visibility of the desired element.
scrollIntoView() and scrollTo() are powerful Cypress commands that can effectively handle websites with lazy-loaded images, infinite scrolls, and more. This helps improve the reliability and accuracy of the AUT in real-world scenarios!
Happy Testing 🙂
Frequently Asked Questions (FAQs)
How to verify the scroll in Cypress?
In Cypress, verifying scrolling can be done using various methods depending on the scenario. You can use .scrollIntoView() to bring an element into view and assert its visibility, ensuring that specific content is accessible.
For page-level scrolling, .scrollTo() allows you to scroll to positions like ‘bottom’ or specific coordinates such as (0,500). To confirm the scroll position, you can check the scrollY value of the window using .its(‘scrollY’) and assert that it exceeds a certain threshold.
What is then() in Cypress?
In Cypress, .then() is used to handle asynchronous operations and work with the resolved value of a Cypress command. Since Cypress commands are inherently asynchronous, .then() allows you to perform operations on elements, extract values, or execute custom logic once a command has been completed.
What is scrollHeight?
scrollHeight is a JavaScript property that represents the total height of an element’s content, including the portion not visible due to scrolling. It measures the full content height inside an element, even if part of it is hidden due to overflow.
Citations
- scrollIntoView: https://docs.cypress.io/api/commands/scrollintoview
- scrollTo: https://docs.cypress.io/api/commands/scrollto
Got Questions? Drop them on LambdaTest Community. Visit now