Smoke
Smoke

Reputation: 285

Selenium click link multiple times

I'm automating tests for our webapp in Selenium WebDriver for C#. One of our test scenarios identified an issue with clicking the save button multiple times resulting in multiple identical records.

The standard IWebElement.Click() causes Selenium to block until the page is fully loaded. That means by the time our second click comes around to executing, the postback has been performed and we're not on the form page anymore.

Does anyone know a means of 'manually' clicking an element that won't cause Selenium to block?

Upvotes: 4

Views: 4233

Answers (3)

Paul Harris
Paul Harris

Reputation: 5809

What you need to do is click via javascript. In java this is done like this:

IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));

I actually imagine it is very similar, this will not block selenium and you should be able to chain a few on before the page comes back.

if this newer approach is too slow you might be quicker doing it all in js, e.g.

IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById(id).click();");
executor.executeScript("document.getElementById(id).click();");

Upvotes: 0

Smoke
Smoke

Reputation: 285

If we use JavaScript to send our click events, Selenium will not be blocked and we can click multiple times. However, because our click triggers a page load, we cannot reference the element directly. Instead, we need to specify the location to click and then fire our click events.

Because our WebApp uses JQuery, I was able to use the code specified here: How to simulate a click by using x,y coordinates in JavaScript?

So in the end our C# logic looks something like this:

IWebElement element = driver.findElement(By.id("foobar"));
Point point = element.Location;
IJavascriptExecutor jscript = (IJavascriptExecutor)driver;
jscript.executeScript("$(document.elementFromPoint(arguments[0], arguments[0])).click();", point.X, point.Y);

Although this sends the click event I'm not 100% sure that the element receives it; I'll run some experiments and see.

Upvotes: 1

B.K.
B.K.

Reputation: 10152

You could either wait for a predetermined amount of time for the page to load:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

...or to be more dynamic and wait for your button to appear:

var driver = new WebDriver();
var wait = new WebDriverWait(driver, TimeSpan(0, 1, 0));
wait.Until(d => d.FindElement(By.Id("button"));

Source: https://stackoverflow.com/a/7811812/2006048

Selenium also has source code that is similar to the second method: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/ExpectedConditions.cs

Let me know if it works out for you. I personally use these options with WatiN:

browser.WaitForComplete();

...or:

browser.WaitUntilContainsText("Text");

It's a shame Selenium does not have the first one.

Upvotes: 1

Related Questions