【问题标题】:selenium webdriver is clearing out fields after sendKeys had previously populated themselenium webdriver 在 sendKeys 之前填充字段后清除字段
【发布时间】:2012-03-19 07:41:47
【问题描述】:

我正在测试的网页正在使用淘汰赛。在我们网站上当前未使用淘汰赛的其他页面上,我没有遇到同样的问题。我的场景是页面打开的地方,我输入各种必填字段并单击保存按钮。在最后一个文本字段中输入值和单击保存按钮之间的某个时间点,以前具有值的字段被清除,因此脚本无法继续。这是我正在运行的代码示例:

driver.findElement(By.id("sku")).clear();
driver.findElement(By.id("sku")).sendKeys(itemNo);
driver.findElement(By.id("desktopThankYouPage")).clear();
driver.findElement(By.id("desktopThankYouPage")).sendKeys(downloadUrl);
driver.findElement(By.id("mobileThankYouPage")).clear();
driver.findElement(By.id("mobileThankYouPage")).sendKeys(mobileDownloadUrl);
driver.findElement(By.id("initialPrice")).clear();
driver.findElement(By.id("initialPrice")).sendKeys(initialPrice);
driver.findElement(By.id("submitSiteChanges")).click();

就像我说的那样,在它在最后一个字段中输入文本的时间和它单击保存之前包含文本的字段之间的时间被清除了,因此我的测试失败了。问题是它并不总是发生。有时测试运行良好,有时却不行。

我试过把 Thread.sleep(x);到处查看是否在某些点暂停可以解决问题。我也尝试过使用 javascript 在后台等待任何可能正在运行的 ajax。还有 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS) 的隐式等待。似乎没有任何区别。

我正在运行 2.13 版的 selenium 服务器,我的所有测试都在 Firefox 8 上运行。

对此的任何帮助将不胜感激!

【问题讨论】:

  • 您如何确认设置的值是实际设置的。单击提交后,您的 KO 代码会发生什么?绑定到 KO 的 dom 元素是否作为模板的一部分呈现?
  • 是的,在单击提交按钮之前,我已验证字段中存在值。事实上,有时测试会通过。提交按钮获取我们绑定的对象并将其转换为 JSON 并通过 ajax 将其发送到我们的 API。看来,在我们创建 JSON 之前,Web 驱动程序正在清除几个字段。
  • 我怀疑网络驱动程序正在清除字段。更有可能的是,由于时间问题或事件处理程序代码中的潜在错误,页面本身正在清除字段,但是您提到添加睡眠似乎并没有解决问题。在任何字段中输入文本之前,您是否添加了很长的睡眠时间(30 秒)以完全排除时间问题?您是否在每个字段中输入文本之间添加了几秒钟的延迟以排除时间问题?
  • 是的,我在页面加载时睡了很长时间,然后在输入文本到下一个字段之间也睡了。

标签: selenium knockout.js webdriver


【解决方案1】:

Firefox 有一个bug,它可以防止在浏览器窗口失焦时执行某些事件。当您运行自动化测试时,这可能是一个问题 - 即使窗口失焦,它也可能正在输入。

关键是通过change 事件触发剔除模型更新(默认情况下)。如果它没有被执行,它的底层模型就不会是最新的。

为了解决这个问题,我“手动”触发了更改事件,将 javascript 注入到我的测试中。:

//suppose "element" is an input field
element.sendKeys("value");
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("$(arguments[0]).change();", element);

您可能已经注意到,我使用 jQuery 来触发更改事件。如果你没有在你的应用程序上使用 jQuery,你可以查看here 如何使用 vanilla javascript 来触发它。

希望对某人有所帮助。

【讨论】:

  • 它确实帮助了我!和 FWIW,在 C# 中是 var jsExecutor = (IJavaScriptExecutor)driver; jsExecutor.ExecuteScript("$(arguments[0]).change();", element);
【解决方案2】:

我遇到了完全相同的问题。我还猜想您的代码在 Chrome 中运行良好,但在 firefox 中运行良好,并且在您手动执行时它总是可以运行?

无论如何,问题很可能在于 Selenium 的行为方式与真实用户的行为方式不同,并且不会触发相同的事件。当您“提交”表单时,它有时不会在文本区域上执行“更改”事件,这意味着它不会更改。

我在测试 Backbone.modelbinding 时遇到了同样的问题,它使用“change”事件从表单更新模型。 Knockout 也使用了“change”事件,不过好在它也可以使用“keyup”事件。见valueUpdate in the docs

<input data-bind="value: someValue, valueUpdate: 'keyup'" />

无论如何,这可重现地为我解决了它,并且一旦我完成了就不需要任何睡眠。不利的一面是,为了使测试正常工作,您运行的事件超出了生产所需的范围。另一个缺点是,如果您想在值更改时运行一些代码,现在每次按键都会获得一个事件,而不是每次字段更改一个事件,这有时很糟糕。

还有另一种解决方案,就是让 Selenium 自己触发 change 事件,例如:Selenium IE change event not fired。它也不是最理想的,但你能做什么。

您还可以尝试在单击按钮之前将焦点放在按钮上。不知道行不行,没试过。

【讨论】:

    【解决方案3】:

    我在使用 JavaScriptExecutor 向文本字段发送键时遇到了同样的问题。

    在 IE 中使用以下代码(相同的代码适用于 chrome):

    (JavascriptExecutor) driver.executeScript("arguments[0].value = '" + value + "';", element);
    

    将代码更新为简单的“sendKeys()”方法后,它解决了我的问题:

    element.sendKeys("some text");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多