0

I currently going through a book to learn selenium and I can't get some of the code examples to run correctly. The below code is supposed to click 3 tiles but it only ever clicks the first 2 . . .

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.*;

public class MoveByOffSetAndClick {
    public static void main(String... args){
        WebDriver driver = new FirefoxDriver();
        driver.get("file:///C:/Selectable.html");
        WebElement one = driver.findElement(By.name("one"));
        WebElement eleven = driver.findElement(By.name("eleven"));
        WebElement six = driver.findElement(By.name("six"));

        int borderWidth = 1;        
        Actions builder = new Actions(driver);

        builder.moveByOffset(one.getLocation().getX() + borderWidth, 
                one.getLocation().getY() + borderWidth).click();
        builder.build().perform();

        builder.moveByOffset(six.getLocation().getX() + borderWidth, 
                six.getLocation().getY() + borderWidth).click();    
        builder.build().perform();

        builder.moveByOffset(eleven.getLocation().getX() + borderWidth, 
                eleven.getLocation().getY() + borderWidth).click();
        builder.build().perform();

        driver.quit();

    }
}

Anybody got any ideas to why this is happening ??

OS: Windows 7 Professional 64 bit Java: 7u71 x64 Eclipse: Luna Service Release 1 (4.4.1) 64 bit

Here'sthe HTML it is working on...

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Selectable - Display as grid</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
#feedback { font-size: 1.4em; }
#selectable .ui-selecting { background: #FECA40; }
#selectable .ui-selected { background: #F39814; color: white; }
#selectable { list-style-type: none; margin: 0; padding: 0; width: 450px; }
#selectable li { float: left; width: 100px; height: 80px; font-size: 4em; text-align: center; }
</style>
<script>
$(function() {
$( "#selectable" ).selectable();
});
</script>
</head>
<body>
<ol id="selectable">
<li class="ui-state-default" name="one">1</li>
<li class="ui-state-default" name="two">2</li>
<li class="ui-state-default" name="three">3</li>
<li class="ui-state-default" name="four">4</li>
<li class="ui-state-default" name="five">5</li>
<li class="ui-state-default" name="six">6</li>
<li class="ui-state-default" name="seven">7</li>
<li class="ui-state-default" name="eight">8</li>
<li class="ui-state-default" name="nine">9</li>
<li class="ui-state-default" name="ten">10</li>
<li class="ui-state-default" name="eleven">11</li>
<li class="ui-state-default" name="twelve">12</li>
</ol>
</body>
</html>
Louis
  • 146,715
  • 28
  • 274
  • 320
Paddykool
  • 15
  • 2
  • 6
  • Can you please tell what exception are you getting while executing the code above? – Subh Dec 07 '14 at 12:28
  • Hi. I'm not getting any exception. The code just clicks on the first 2 tiles and then finishes :( – Paddykool Dec 07 '14 at 15:32
  • Your code should work. I don't see any problem with it. Can you add the HTML code snippet inside **Selectable.html** please ? Will try at my end and check for the anomaly. Thanks. – Subh Dec 07 '14 at 15:37
  • I've added in the HTML. Much appreciated Subh if you can take a look – Paddykool Dec 07 '14 at 16:47
  • 1
    This is not helping. I am not able to know if it is even clicking the first one or not. How are you determining if an element is cliked ? Does its color changes or something ? In addition to that probably adding the CSS of the class **ui-state-default** will help too. Thanks.. – Subh Dec 07 '14 at 17:13
  • Yah, sorry. Ok, I'll paste the entire HTML file . . . – Paddykool Dec 07 '14 at 20:57
  • Sorry. I am stumped here. The only thing working for me is when I use `moveToElement()` and then `click()`. Using this `moveToOffset` and `click()` is not resulting in any click on the element(s). Googled and found that this issue hasn't been fixed yet. Links: [https://code.google.com/p/selenium/issues/detail?id=5233](https://code.google.com/p/selenium/issues/detail?id=5233) , [http://stackoverflow.com/a/27049281/4193730](http://stackoverflow.com/a/27049281/4193730). **[FYI, I was using FF-31.2.0 ESR with Selenium 2.44.0]** – Subh Dec 08 '14 at 08:16

3 Answers3

2

The approach you are using cannot ever work the way you intend to use it. The documentation for moveByOffset says:

Moves the mouse from its current position (or 0,0) by the given offset.

That is, it moves the mouse by an offset relative to the current mouse position. In your code you call it with coordinates relative to the document. It works the first time because if no mouse position has been established yet, then initial mouse coordinates are taken to be 0, 0. It works the second time too because when you make your second call, the mouse is inside your first list item and thus still close to 0, 0. When you click, the mouse click is not happening where you mean it but it is still inside six, so it is not enough to make your code miss six. By the time of the third call, however, the mouse coordinates before the call are in six. This is such that the third call to moveByOffset will move the mouse way off outside eleven.

This is true bug or no bug.

Generally, you don't need to worry about borders when clicking inside elements. The click() method will automatically move the mouse to the center point of the element you care about and so will normally work without any need on your part to adjust the mouse position. In special instance, you may need to worry about offsets, but you've not shown a situation in which you need to worry about it.

Louis
  • 146,715
  • 28
  • 274
  • 320
0

Yah Subh,

Yah - I used the following code to get around it. Many thanks for your input!

WebDriver driver = new FirefoxDriver();
driver.get("file:///C:/Selectable.html");
WebElement one = driver.findElement(By.name("one"));
WebElement eleven = driver.findElement(By.name("eleven"));
WebElement six = driver.findElement(By.name("six"));

Actions builder = new Actions(driver);

builder.click(one).click(six).click(eleven);
builder.build().perform();
Paddykool
  • 15
  • 2
  • 6
0

Since you have define an action Actions builder = new Actions(driver); and you use this action to call moveByOffset several times, the offset will accumulated until you clear or reset the Action object, or create a new one for each move.

This is by design.

Here is the example(in Python):

//calculate offset
distance = get_distance()

#divide distance to small step
track = get_track(distance)
action = ActionChains(browser) #new action

action.click_and_hold(slide).perform()

#do slide 
for step in track:
    action.move_by_offset(xoffset=step, yoffset=0).perform()
    print(step,slide.location['x'])
action.release().perform()

I expect it should move a slider with distance however it move more than distance

Program output:

1 23
1 25
2 29
2 35
2 43
3 54
3 68
3 85

As you can see. The left is the offset I expect to move and the right is actual coordination. ** For each move it accurate all previous move**

To solve this is simple, Just reset the action, for example you can put action = ActionChains(browser) #new action inside For loop. In your case you may can addbuilder = new Actions(driver); after first/second move.

ref https://github.com/SeleniumHQ/selenium/issues/5747

hoyho
  • 21
  • 4