【问题标题】:Selenium click link multiple timesSelenium 多次点击链接
【发布时间】:2014-10-06 08:26:02
【问题描述】:

我在 Selenium WebDriver for C# 中自动测试我们的 web 应用程序。我们的一个测试场景发现了一个问题,即多次单击保存按钮会导致多个相同的记录。

标准IWebElement.Click() 导致 Selenium 阻塞,直到页面完全加载。这意味着当我们第二次点击执行时,回发已经执行,我们不再在表单页面上。

有谁知道“手动”单击不会导致 Selenium 阻塞的元素的方法?

【问题讨论】:

  • 你试过用 DoubleClick() 代替 Click() 吗?

标签: c# selenium selenium-webdriver


【解决方案1】:

您可以等待预定的时间来加载页面:

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

...或者更动态并等待您的按钮出现:

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

来源:https://stackoverflow.com/a/7811812/2006048

Selenium 也有类似第二种方法的源码:http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/ExpectedConditions.cs

让我知道它是否适合你。我个人将这些选项与WatiN 一起使用:

browser.WaitForComplete();

...或:

browser.WaitUntilContainsText("Text");

很遗憾 Selenium 没有第一个。

【讨论】:

  • 我不是在等待按钮加载,恰恰相反。我需要能够在执行回发时单击该按钮。 Selenium 通常会在此时阻止执行;我正在努力克服这一点。
【解决方案2】:

您需要做的是通过 javascript 点击。在java中是这样完成的:

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

我实际上想象它非常相似,这不会阻塞 selenium,你应该能够在页面返回之前链接一些。

如果这种较新的方法太慢,您可能会更快地在 js 中完成所有操作,例如

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

【讨论】:

  • 方法是正确的,但是有一个小问题。单击按钮会导致页面刷新,这也意味着将单击发送到 WebElement 会导致元素引用过时。我设法找到了一个触发点击事件的变体,我将发布。
  • 如果它只是一个陈旧的元素,我会将代码更改为上面的代码而不是使用点,基本上我们只会搜索两次元素。
【解决方案3】:

如果我们使用 JavaScript 发送我们的点击事件,Selenium 将不会被阻止,我们可以点击多次。但是,因为我们的点击触发了页面加载,所以我们不能直接引用该元素。相反,我们需要指定点击位置,然后触发我们的点击事件。

因为我们的 WebApp 使用 JQuery,所以我能够使用此处指定的代码: How to simulate a click by using x,y coordinates in JavaScript?

所以最终我们的 C# 逻辑看起来像这样:

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);

虽然这会发送点击事件,但我不能 100% 确定元素是否接收到它;我会做一些实验看看。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多