1

I have a page with an iframe. Inside the iframe is a table. When the user moves the mouse over this table, some elements appear. I'd like to click one of those elements.

I think some of my first steps should be to select the iframe, and then moveToElement(table). But this results in a MoveTargetOutOfBoundsError.

The strange thing is that I'm able to select the iframe and click on the table. The click doesn't complain about the element's x,y coordinates but moveToElement complains. Why? (Unfortunately clicking on the table performs an action which causes those buttons I want to disappear so this is not an option.)

And how can I accomplish what I want (select iframe, hover over table, wait for buttons to appear, click one of the buttons)?

version info:

Build info: version: '2.28.0', revision: '18309', time: '2012-12-11 15:53:30'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.6.0_37'

Here's the java code that succeeds in clicking the table:

driver.switchTo().defaultContent();
driver.switchTo().frame("frameId");
WebElement e = driver.findElement(By.id("foo"));
e.click();

Here's the java code that complains about the location of the table:

driver.switchTo().defaultContent();
driver.switchTo().frame("frameId");
WebElement e = driver.findElement(By.id("foo"));
Actions builder = new Actions(driver);
builder.moveToElement(e).build().perform(); // error happens in moveToElement()
user1011471
  • 1,090
  • 2
  • 14
  • 34

1 Answers1

3

I think you have to scroll into view:

if (element instanceof Locatable) {
    Locatable remoteElement = (Locatable) inputElement;          
    remoteElement.getLocationOnScreenOnceScrolledIntoView();
}

If you want to hover on an element, you have to extend the above a bit:

if (element instanceof Locatable) {
    Locatable hoverItem = (Locatable) element;
    hoverItem.getLocationOnScreenOnceScrolledIntoView();
    Mouse mouse = ((HasInputDevices) webDriver).getMouse(); 
    mouse.mouseMove(hoverItem.getCoordinates());
}
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • Interesting... It is locatable. The location is (33,314) which is different from the location it complains about (1077,127). But if I create an Actions object after the getLocationOnScreenOnceScrolledIntoView() and ask the Actions object to moveToElement(e).build().perform(); it still complains about (1077,127). What should I do instead? – user1011471 Jan 04 '13 at 22:15
  • Do you need to use moveToElement? getLocationOnScreenOnceScrolledIntoView() should normally center the display on the element. And what browser are you testing in? – asgoth Jan 04 '13 at 22:24
  • I'm testing in Firefox 17.0.1 but my hope is that I'll end up with something that's valid for any browser. `getLocationOnScreenOnceScrolledIntoView()` does scroll until the table is top+center but it doesn't have the hovering effect that causes the buttons to appear (or at least it's not perceptible when I'm watching it). Is there something I can use other than `moveToElement()` to do the hovering? – user1011471 Jan 05 '13 at 03:12
  • Wait a minute, now (in a later attempt) `moveToElement()` doesn't complain. Maybe I can get this to work after all. – user1011471 Jan 05 '13 at 03:21
  • Latest results: `getLocationOnScreenOnceScrolledIntoView()` followed by an Actions chain that starts with `moveToElement(table)` gets the buttons to appear briefly as if the user is hovering over the table. But any attempt to put `moveToElement(button)` or `click(button)` or even a `dragAndDrop(table,button)` in the Actions chain right after the `moveToElement(table)` results in `MoveTargetOutOfBoundsError`... – user1011471 Jan 05 '13 at 04:37
  • I've added a section in my answer. That code should hover on an element. – asgoth Jan 05 '13 at 10:57
  • Yes that hovers, but the hovering effect ends when `mouse.mouseMove()` returns and so far my attempts to click after the hover still result in MoveTargetOutOfBoundsError. It feels like the hovering over the table and the clicking of the button need to be chained somehow, or the hovering needs to be done in a way that persists for the next action. – user1011471 Jan 06 '13 at 03:42
  • Works just fine in Google Chrome and Firefox 6 (!) but not in Firefox 17 – user1011471 Jan 10 '13 at 14:49
  • To the previous comment: Firefox is picky with iframes. Sometimes you need to use a JavaScriptExecutor to access a element inside a iframe. – djangofan Mar 20 '13 at 20:52