Correct way to focus an element in Selenium WebDriver using Java
Asked Answered
K

7

58

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.

Kirstinkirstyn answered 5/7, 2012 at 2:57 Comment(0)
C
69

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.

Cariotta answered 5/7, 2012 at 4:51 Comment(5)
@Kirstinkirstyn "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.Elizbeth
How can I verify that focus/cursor is present on a text field?Vernation
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.Delineation
Safari does not support moveToElement, but does support element.sendKeys(). This is a good argument for using element.sendKeys() - if you want to test against Safari.Tumefy
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.Giordano
V
18

You can use JS as below:

WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("document.getElementById('elementid').focus();");
Vernation answered 28/1, 2013 at 10:48 Comment(0)
M
8

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();");
Mousse answered 6/6, 2018 at 18:13 Comment(1)
It provide hover or it move (or scroll) the window to the element?Jadotville
R
4

The focus only works if the window is focused.

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

Rasure answered 2/2, 2017 at 16:25 Comment(1)
thanks, that solved my problem that the jquery datepicker did not open in firefoxRencontre
A
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.

Austro answered 4/7, 2015 at 17:56 Comment(0)
P
2

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);
Prosperous answered 1/10, 2020 at 12:29 Comment(0)
U
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 :)

Unproductive answered 26/7, 2019 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.