41

When using the IE driver with IE9, occasionally the Click method will only select a button, it wont do the action of the Click(). Note this only happens occasionally, so i don't think it is the code that is the problem. Using the Firefox driver with Firefox4 has no problems. I am also having an issue where elements are not being found occasionally too, but only in IE again, not Firefox.

if (Driver.FindElement(By.Name("username")) == null) {
    //sometimes gets here in IE, never gets here in Firefox
}
Driver.FindElement(By.Name("username")).SendKeys(username);
Driver.FindElement(By.Name("surname")).SendKeys(surname);
Driver.FindElement(By.Name("firstname")).SendKeys(firstname);
string url = Driver.Url;
Driver.FindElement(By.Name("cmd")).Click();
if (Driver.Url == url) {
    //if the page didnt change, click the link again
    Driver.FindElement(By.Name("cmd")).Click();
}

I have seen this similar questions (http://stackoverflow.com/questions/4737205/selenium-webdriver-ie-button-issue), but i do not have dynamicly generated ids.

djeeg
  • 6,685
  • 3
  • 25
  • 28

18 Answers18

28

I have found the same thing on Internet Explorer 8 when attempting to click links using .Click() - even though I can see Selenium clicking on the link. From my experience it appears that if the browser does not have focus then the initial click doesn't work.

A workaround to this is to send a .Click() to another element on the page, so that the browser gets the focus, before attempting to click the link, e.g. it's parent:

Driver.FindElement(By.Id("Logout")).FindElement(By.XPath("..")).Click();
Driver.FindElement(By.Id("Logout")).Click();
Farvardin
  • 5,336
  • 5
  • 33
  • 54
Naishy
  • 1,805
  • 16
  • 15
  • I appreciate the easy solution, and also the reason why. That helps me figure out the best solution to the problem. – Tony Mar 08 '12 at 19:48
  • 8
    I ran into a problem where I couldn't click on the parent of the element I had selected. Clicking on the same element twice worked, but I was afraid that if the window already had focus it could cause unwanted behavior. This slight change to the selected solution worked for me: (in C#) `driver.FindElement(By.TagName("body")).Click();` – Tony Mar 08 '12 at 20:49
  • Also check the zoom factor of your IE. It is important that the zomm factor is always set to 100% ! – Ralph Jun 27 '12 at 12:35
  • @Naishy: what language have you used for clicking using WebDriver? Is it Java? or what? – Ripon Al Wasim Aug 08 '12 at 10:05
  • @RiponAlWasim: I've been using C#. – Naishy Aug 15 '12 at 12:55
  • What happens if the browser does have focus and the first click works? This doesn't seem like a reasonable solution to me, just a cheap hack. – evanmcdonnal Mar 10 '14 at 22:44
  • @evanmcdonnal The first click is targeted at the parent of the element you actually want to click on, in order to gain focus. The second click is on the element you actually wanted to click. If the browser already had focus then the first click would have no affect. Is it a hack? Yes, because it was almost certainly an issue with the IE webdriver component, which may well be fixed now – Naishy Mar 11 '14 at 10:53
  • I'm having success with using SendKeys(Keys.Tab) – he_the_great Jul 21 '14 at 23:20
16

I find the IE driver buggy and the same version of my code behaves differently on different machines with the same version of IE.

To get consistently before each action I do the following.

   driver.SwitchTo().Window(driver.CurrentWindowHandle);//Force Focus

For me this makes the IE driver behave more as expected.

Simon
  • 578
  • 1
  • 9
  • 18
8

Got the same problem, click does not work with my IE. I found a workaround where I do a Driver.FindElement(By.Name("...")).sendKeys("\n") to perform the click (basically I just press enter on the button). Not very clean but it works until the problem is fixed!

7

None of the above solutions worked for me. This did the trick tho:

Java

element.sendKeys(org.openqa.selenium.Keys.CONTROL);
element.click();

Groovy

element << org.openqa.selenium.Keys.CONTROL
element.click()

Geb

Or, if you're using Geb, there's an even better solution that's completely unobtrusive:

(tested with IE7 and Geb 0.7.0)

abstract class BaseSpec extends geb.spock.GebSpec
{
    static
    {
        def oldClick = geb.navigator.NonEmptyNavigator.metaClass.getMetaMethod("click")
        def metaclass = new geb.navigator.AttributeAccessingMetaClass(new ExpandoMetaClass(geb.navigator.NonEmptyNavigator))

        // Wrap the original click method
        metaclass.click = {->
            delegate << org.openqa.selenium.Keys.CONTROL
            oldClick.invoke(delegate)
        }

        metaclass.initialize()

        geb.navigator.NonEmptyNavigator.metaClass = metaclass
    }
}

class ClickSpec extends BaseSpec
{
    def "verify click"()
    {
        given:
        to HomePage

        expect:
        waitFor { at HomePage }

        when:
        dialog.dismiss()
        // Call the wrapped .click() method normally
        $('#someLink').click()

        then:
        waitFor { at SomePage }
    }
}

class HomePage extends geb.Page
{
    static url = "index.html"
    static at = { title == "Home - Example.com" }
    static content = {
        dialog { module DialogModule }
    }
}

class SomePage extends geb.Page { ... }
class DialogModule extends geb.Module { def dismiss() { ... } }

In my case, clicking in IE7 appeared to fail whenever it was preceded by the closing of an animated modal overlay (we're using jQuery Tools Overlay Modal Dialog). The Geb method above solved this problem.

Andy Dvorak
  • 491
  • 6
  • 11
  • in C# this worked for me for IE driver (but not for others like chrome): Element.SendKeys(Keys.CONTROL); Element.Click(); – mojjj Jun 27 '13 at 10:08
  • Can you elaborate on why you're sending Control? Won't this open every clicked link in a new window? – Mark Mayo Mar 26 '14 at 04:25
  • The above code simulates a key _press_ (key _down_ followed by key _up_) on the target element. By the time `oldClick` is invoked, the simulated Ctrl key has already been released, so the link will not open in a new tab/window. – Andy Dvorak Mar 26 '14 at 19:32
  • Note that my answer is based on Emmanuel's solution: Sending a key press event to the target element appears to be enough to give it focus. I chose the `Ctrl` key because it doesn't trigger any default browser behavior, and it is unlikely that any JavaScript event handlers would be looking for only that key. – Andy Dvorak Mar 26 '14 at 19:39
  • Works for me with java and IE. Could you please explain me what does the instruction element.sendKeys(org.openqa.selenium.Keys.CONTROL); do? – Enrico Giurin Apr 25 '16 at 11:29
  • Enrico, sending a CONTROL key press to the element is just a hack to force IE to give the element focus, so that the subsequent `click()` call will actually work as intended. – Andy Dvorak Apr 28 '16 at 18:59
7

I have refactored my solution based on referencing Selenium WebDriver 2.15.0 in my project and using a Selenium WebDriver Server 2.16.0 and I have made the following observations:

  • The click event does fire correctly when using the FirefoxDriver
  • The click event does not fire correctly for certain controls when using the RemoteWebDriver for the DesiredCapabilities.Firefox
  • The click event does fire correctly when using the RemoteWebDriver for the DesiredCapabilities.HtmlUnit and DesiredCapabilities.HtmlUnitWithJavaScript
  • The InternetExplorerDriver and the RemoteWebDriver with DesiredCapabilities.InternetExplorer (really the same thing) are still giving me inconsistent results that I am finding difficult to nail down.

My solution to the first three points has been to create my own classes that extend RemoteWebDriver and RemoteWebElement so that I can hide my custom behaviour from the test code that continues to reference IRemoteWebDriver and IWebElement.

I have below my current "tweaks", but if you go with these custom classes you will be able tweak your driver and web element behaviour to your heart's content without having to change your test code.

public class MyRemoteWebDriver : RemoteWebDriver
{
    //Constructors...

    protected override RemoteWebElement CreateElement(string elementId)
    {
        return new MyWebElement(this, elementId);
    }
}

public class MyWebElement : RemoteWebElement, IWebElement
{
    //Constructor...

    void IWebElement.Click()
    {
        if (Settings.Default.WebDriver.StartsWith("HtmlUnit"))
        {
            Click();
            return;
        }

        if (TagName == "a")
        {
            SendKeys("\n");
            Thread.Sleep(100);
            return;
        }

        if (TagName == "input")
        {
            switch (GetAttribute("type"))
            {
                case "submit":
                case "image":
                    Submit();
                    return;
                case "checkbox":
                case "radio":
                    //Send the 'spacebar' keystroke
                    SendKeys(" ");
                    return;
            }
        }

        //If no special conditions are detected, just run the normal click
        Click();
    }
}
Brian Hinchey
  • 3,601
  • 1
  • 39
  • 36
  • `(TagName == "input")` doesn't cover every case - there's also the [ – Joel Purra Jan 13 '12 at 07:18
  • Also, if(...HtmlUnit...) the function sends `Click()` for every element, while it does not fall back to `Click()` in other cases. – Joel Purra Jan 13 '12 at 07:25
2

Try setting Internet Options -> Security -> Enable Protected Mode to the same setting for all zones, see http://www.mail-archive.com/watir-general@googlegroups.com/msg13482.html. This is from the Watir googlegroup, but in my Selenium 2 tests IE button clicks seem to work better after applying this.

onl
  • 21
  • 1
1

I am using IE version: 9 Was facing the same issue. The following worked in my case

element.sendKeys(Keys.ENTER);
element.click();
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

Absolutely none of the other things worked for me. Some InternetExplorerDriver click()s were working for me, some weren't. Then I discovered I had missed one line in the documentation: the browser's zoom level must be set to 100%.

I'm sure all of the other answers refer to cases where the zoom level is at 100% already, but it did fix my case. So do check that first.

reinierpost
  • 8,425
  • 1
  • 38
  • 70
1

Another one:

v2.29.0

WebDriver: * Firefox 18 support. * IEDriver supports "requireWindowFocus" desired capability. When using this and native events, the IE driver will demand focus and user interactions will use SendInput() for simulating user interactions. Note that this will mean you MUST NOT use the machine running IE for anything else as the tests are running.

gonella
  • 186
  • 1
  • 6
1

PHPUnit + facebook / php-webdriver sometimes the function click() doesn't check checkbox element.

my solution is:

$Element = $WebDriver->findElement(
    WebDriverBy::id('checkbox_id')
);

if(false === $Element->isSelected())
{
    $Element->sendKeys(WebDriverKeys::SPACE);
}
Paul Zahra
  • 9,522
  • 8
  • 54
  • 76
darkling
  • 11
  • 1
1

Short answer:
If you're running an automated Selenium test in IE11 with the browser window open on a touch screen monitor (e.g. Windows 8 touch laptop), try running the test with the browser window open in a non-touch screen.
The original .click() method should work fine without all the code workarounds.

Answer background:
I worked with a tester in our QA team to investigate a similar issue. After trying most of the code solutions here and at selenium webdriver IE button issue, we eventually found the problem only happened in IE (version 11 for us) on the tester's Windows 8 laptop touch screen.
Running the Selenium test with the IE window running on their external Dell monitor allowed the test to run fine every time, even using just the standard .click() call.
We were also failing on the click event for a button in a Magnific Popup (http://dimsemenov.com/plugins/magnific-popup/) dialog.

My hypothesis: there is a problem with how IE11 (not sure about other versions) handles the translation of touch events to/from mouse click events on touch screens.

Community
  • 1
  • 1
Jason Snelders
  • 5,471
  • 4
  • 34
  • 40
0

A better way to force the focus on the element is to use Javascript. This works when your elements are tagged with id attribute. If they're not, get the developers to change it.

Find the element using whatever locator/properties you need. Once the element is retrieved, check to see if it contains an ID attribute. If it does, then execute the following code which will force focus to the element:

JavascriptExecutor executor = (JavascriptExecutor) webDriver();
executor.executeScript("document.getElementById('" + element.GetAttribute("id") + "').focus()");

Using this, almost all the issues with missed clicks were resolved when using the InternetExplorerDriver.

Nathan Dace
  • 1,545
  • 9
  • 21
0

I resolved problem whith .click() next way. I used JS and executeScript(JS, WebElement el) instead of .click().
Example:

protected void clickForIE(WebElement element){  
        ((JavascriptExecutor)wd).executeScript("var tmp = arguments[0];
          tmp.click()", element);  
    }

But after using this method we should wait while page loading. And that's why I used next method:

protected synchronized void pageWaitLoad() {  
        String str = null;
        try {
            str = (String)((JavascriptExecutor)wd).executeScript("return document.readyState");
        }
        catch (Exception e) {
// it's need when JS isn't worked
            pageWaitLoad();
            return;
        }
        System.out.println("ttt " + str);
        while(!str.equals("complete")){
            try {
                Thread.currentThread().sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            str = (String)((JavascriptExecutor)wd).executeScript("return document.readyState");
        }
    }

You must call pageWaitLoad() every time after clickForIE().

Alexander
  • 857
  • 6
  • 10
0

My solution was:

Selenium WebDriver 2.29.0 (JAVA), TESTED with FF16 and IE9

Before to make a findElement, I did a maxime browser screen. It works fine.

public void maximeBrowser() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension screenResolution = new Dimension((int)toolkit.getScreenSize().getWidth(), (int)toolkit.getScreenSize().getHeight());

        //Maximize the browser
        logger.info("Maximizing the browser : getWidth ["+screenResolution.getWidth()+"] - getHeight ["+screenResolution.getHeight()+"]");
        getDriver().manage().window().maximize();
    }
gonella
  • 186
  • 1
  • 6
0

I used, as workaround, SendKeys with an empty string before each Click:

element.SendKeys("");
element.Click();
zeroha
  • 11
0

WebdriverJS

In IE when you are attempting to perform an click() action, the URL keeps blink on status bar. It means the driver is focusing on the element and trying to perform click() action. In order to complete its click() action, i used sleep() method before and after every click action.

Try this example.

var webdriver = require('..'), By = webdriver.By, until = webdriver.until;
var driver = new webdriver.Builder().usingServer().withCapabilities({'browserName': 'ie' }).build();

driver.get('http://www.google.com')
.then(function(){
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(1000 * 3);
    driver.findElement(By.name('q')).sendKeys('webdriver');
    driver.findElement(By.name('btnG')).then(function(button){
    button.click();
    });
})
.then(function(){
    driver.findElement(By.css('div[class="gb_Zb"] a[title="Google Apps"]')).then(function(apps){
        apps.click();       
        driver.findElements(By.css('a[class="gb_O"]')).then(function(appsList){
        console.log("apps : "+appsList.length);
        for(var i = 0; i < appsList.length; i++){
        console.log('applications : '+i);
        if(i == 5) {
        var element = appsList[i];
        driver.sleep(1000 * 5);
        driver.executeScript("var tmp = arguments[0]; tmp.click()", element);
        driver.sleep(1000 * 5);
        } } })  
    })
})
.then(null, function(err) {
  console.error("An error was thrown! By Promise... " + err);
});
driver.quit();

to perform click we can use any of these, tested on IE

element.click(); 
driver.actions().click(element).perform();
driver.executeScript("var tmp = arguments[0]; tmp.click()", element);
Community
  • 1
  • 1
Yash
  • 9,250
  • 2
  • 69
  • 74
0

After a bit more searching i found two things that seem to have helped in repeatable tests:

First i added an ImplicitlyWait of 5 seconds. Not sure if this is applied to all FindElement functions, but I have stopped getting most of the NoSuchElementException i was getting.

OpenQA.Selenium.IE.InternetExplorerDriver driver = new OpenQA.Selenium.IE.InternetExplorerDriver();
driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 0, 5, 0));
//driver.Manage().Speed = Speed.Medium;

Second i was having trouble with a Logout function and changed the code to:

public LoginPageObject Logout() {
    Driver.FindElement(By.LinkText("Logout")).Click();

    OpenQA.Selenium.Support.UI.IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(Driver, TimeSpan.FromSeconds(5));
    IWebElement element = wait.Until(driver => driver.FindElement(By.Name("username")));

    LoginPageObject lpage = new LoginPageObject(Driver);
    return lpage;
}

The explicit wait seems to handle what the ImplicitlyWait doesn't catch (i think because of redirects).

http://code.google.com/p/selenium/source/browse/trunk/support/src/csharp/webdriver-support/UI/WebDriverWait.cs?r=10855

djeeg
  • 6,685
  • 3
  • 25
  • 28
0

I'm experiencing this with 2.0rc2, IE8, Java as well. The problem I have with implementing a solution that can send multiple clicks is that sometimes it does work. In those cases clicking my objects twice does not let the rest of my test move forward. Sending the "Enter" keystroke does not work on our controls either.

There is a similar issue logged for this, but my objects are not necessarily near the "viewpoint". Any more suggestions would be greatly appreciated.

NathanChristie
  • 2,374
  • 21
  • 20