1

I am trying to scroll inside an element using the moveByOffset method of Actions class:

HTML code:

<html>
<head>
<meta charset="utf-8">   
<style>
#container
{
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
    overflow-x: scroll;
}
#content
{
    margin:4px, 4px; 
    padding:4px; 
    width: 500px; 
    height:500px; 
    text-align:justify; 
    background-color: #ccc;
}
</style>
</head>
<body>
<div id="container">
  <div id="content">Click the button to slide right!</div>
</div>

<script>
const button = document.getElementById('slide');
button.onclick = function ()
{
document.getElementById('container').scrollLeft += 20;
};
</script>
</body>
</html>

Selenium code:

Actions ac = new Actions(driver);
// Scroll down
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(0, 100).release().build().perform();
// Scroll up
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(0, -100).release().build().perform();
// Scroll right
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(100, 0).release().build().perform();
// Scroll left
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(-100, 0).release().build().perform();

It is throwing MoveTargetOutOfBoundsException whenever we give negative value in the moveByOffset method.

Note: I know I can use javascript, but I want to do it using Actions class.

Please help.

1 Answer 1

1

As per https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/interactions/Actions.html

Actions.clickAndHold(element)

Clicks (without releasing) in the middle of the given element. This is equivalent to: Actions.moveToElement(onElement).clickAndHold()

Actions.moveToElement()

Moves the mouse to the middle of the element. The element is scrolled into view and its location is calculated using getBoundingClientRect.

So one your clickandhold(element) the mouse pointer is at coordinate 50:50 (middle of container, and not edge) , so the movetoelement bound value will be -50 to +50 , not 0 to 100.

so if you want to move to left or right , or top or bottom, you have to give -50 and +50 . if you give -100 will be equal to 50+ -100 which will be less than 0 which is out of bound.

-100 +50 (where 50 is the current location)

Fix 1: ( use current position as (50,50) and move +50 and -50 pixel only)

Actions ac = new Actions(driver);
// Scroll down
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(-50, -50).release().build().perform();
// Scroll up
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(-50, 50).release().build().perform();
// Scroll right
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(50, -50).release().build().perform();
// Scroll left
ac.clickAndHold(driver.findElement(By.cssSelector("div[id='container']"))).moveByOffset(-50, -50).release().build().perform();

Fix 2: (Explicitly move element to containers (0,0) coordinate)

   Actions ac = new Actions(driver);
    // Scroll down ( already down )
    ac. moveToElement(driver.findElement(By.cssSelector("div[id='container']")), 0, 0).clickAndHold().moveByOffset(0, 0).release().build().perform();
    // Scroll up
        ac. moveToElement(driver.findElement(By.cssSelector("div[id='container']")), 0, 0).clickAndHold().moveByOffset(0, 100).release().build().perform();    

// Scroll right
        ac. moveToElement(driver.findElement(By.cssSelector("div[id='container']")), 0, 0).clickAndHold().moveByOffset(100, 0).release().build().perform();

    // Scroll left (Already at left)
        ac. moveToElement(driver.findElement(By.cssSelector("div[id='container']")), 0, 0).clickAndHold().moveByOffset(0, 0).release().build().perform();
1
  • 1
    Thanks for clear and concise explanation. Sep 12, 2020 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.