54

What's the equivalent of selenium.focus() for WebDriver?

element.sendKeys("");

or

new Actions(driver).moveToElement(element).perform();

I have tried both of them and they worked, but which one would always work on all elements?

Which one is the correct way for any elements (such as button, link etc.)? This matters to me because the function will be used on different UI's.

Ripon Al Wasim
  • 34,088
  • 37
  • 146
  • 165
questions
  • 2,197
  • 4
  • 21
  • 37

7 Answers7

64

The following code -

element.sendKeys("");

tries to find an input tag box to enter some information, while

new Actions(driver).moveToElement(element).perform();

is more appropriate as it will work for image elements, link elements, dropdown boxes etc.

Therefore using moveToElement() method makes more sense to focus on any generic WebElement on the web page.

For an input box you will have to click() on the element to focus.

new Actions(driver).moveToElement(element).click().perform();

while for links and images the mouse will be over that particular element,you can decide to click() on it depending on what you want to do.

If the click() on an input tag does not work -

Since you want this function to be generic, you first check if the webElement is an input tag or not by -

if("input".equals(element.getTagName()){
   element.sendKeys("");
} 
else{
   new Actions(driver).moveToElement(element).perform();

}

You can make similar changes based on your preferences.

Hari Reddy
  • 3,708
  • 4
  • 28
  • 40
  • 1
    @questions "`element.sendKeys("");` tries to find an input tag box to enter some information" ... This statement is _definitely not true_. The `sendKeys()` gets focus of the element (additionally, if that element is `input`, it takes cursor to the end of the already present text), then it presses keys (or simulates so) over the element. I think both approaches should work, the `moveToElement()` is arguable cleaner and more readable, but `sendKeys()` won't fail you, too. – Petr Janeček Jul 05 '12 at 11:14
  • How can I verify that focus/cursor is present on a text field? – Ripon Al Wasim Jul 31 '12 at 04:56
  • For C# the above code can written this way: if ("input" == (element.TagName)) { element.SendKeys(""); } else { new Actions(Driver).MoveToElement(element).Perform(); } // where Driver == new ChromeDriver() || new FirefoxDriver() || etc. – Arsen Khachaturyan Dec 19 '13 at 09:04
  • [Safari does not support moveToElement](https://code.google.com/p/selenium/issues/detail?id=4136), but does support element.sendKeys(). This is a good argument for using element.sendKeys() - if you want to test against Safari. – jdhildeb Jun 22 '15 at 21:49
  • I originally went with sendKeys because it was simpler, but I found that it caused unexpected behavior in Firefox when the input used a custom javascript dropdown. The moveToElement method did work though. – frodo2975 Feb 17 '16 at 20:28
16

You can use JS as below:

WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("document.getElementById('elementid').focus();");
Ripon Al Wasim
  • 34,088
  • 37
  • 146
  • 165
3

The focus only works if the window is focused.

Use ((JavascriptExecutor)webDriver).executeScript("window.focus();"); to be sure.

theeuller
  • 41
  • 1
  • 7
3

This code actually doesn't provide focus:

new Actions(driver).moveToElement(element).perform();

It provides a hover effect.

Additionally, the JS code .focus() requires that the window be active in order to work.

js.executeScript("element.focus();");

I have found that this code works:

element.sendKeys(Keys.SHIFT);

For my own code, I use both:

element.sendKeys(Keys.SHIFT);
js.executeScript("element.focus();");
Ahmed Ashour
  • 4,209
  • 10
  • 29
  • 46
JohnP2
  • 1,409
  • 13
  • 13
2

FWIW, I had what I think is a related problem and came up with a workaround: I wrote a Chrome Extension that did an document.execCommand('paste') into a textarea with focus on window unload in order to populate the element with the system clipboard contents. This worked 100% of the time manually, but the execCommand returned false almost all the time when run under Selenium.

I added a driver.refresh() after the initial driver.get( myChromeExtensionURL ), and now it works 100% of the time. This was with Selenium driver version 2.16.333243 and Chrome version 43 on Mac OS 10.9.

When I was researching the problem, I didn't see any mentions of this workaround, so I thought I'd document my discovery for those following in my Selenium/focus/execCommand('paste') footsteps.

Polly
  • 445
  • 4
  • 8
1

C# extension method code, focus element, enter text, call change().

public static void EnterText(this IWebDriver driver, IWebElement element, string textToEnter)
    {
        var js = (IJavaScriptExecutor)driver;
        js.ExecuteScript("arguments[0].focus();", element);
        js.ExecuteScript("arguments[0].setAttribute('value', arguments[1])", element, textToEnter);
        js.ExecuteScript("$(arguments[0]).change();", element);
    }

Called by:

driver.EnterText(element, text);
Rushby
  • 807
  • 9
  • 17
0

We can also focus webelement using below code:

public focusElement(WebElement element){
    String javaScript = "var evObj = document.createEvent('MouseEvents');"
                    + "evObj.initMouseEvent(\"mouseover\",true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);"
                    + "arguments[0].dispatchEvent(evObj);";

            ((JavascriptExecutor) getDriver()).executeScript(javaScript, element);
}

Hope it helps :)

user3181500
  • 371
  • 1
  • 3
  • 11