【发布时间】:2012-09-27 10:25:14
【问题描述】:
我有一个页面,它有一个带有一个输入字段和一个提交按钮的小表单。 提交按钮是 AJAX! 当我单击它时,它会将输入值提交给服务器,服务器要么验证它是否可接受并加载新页面,要么发现问题并添加反馈错误标签。
我编写了以下 selenium 代码来测试此功能:
WebDriverWait waiter = new WebDriverWait(driver, 20);
WebElement inputField = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("inputField")));
inputField.sendKeys("Test input");
WebElement submitInput = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("submitInput")));
submitInput.click();
WebElement feedback = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("feedback")));
Assert.assertTrue("Feedback not was not empty, but was: " + feedback.getText(), feedback.getText().isEmpty());
问题是submitInput.click() 完成并立即返回,如果新页面是通过事件加载的:the selenium docs,因此通过“反馈”进行检索的调用工作正常,我可以通过调试看到它正确地获取了元素,但是当我调用feedback.getText() 时我得到了StaleElementException,因为页面已经在后台刷新了。
如果没有:我怎样才能通过测试:
- 添加 Thread.sleep()。
- 添加
StaleElementException捕获以重新获取元素。
注意:上述测试在输入无效时有效,因为页面没有刷新,但在输入有效时无效。
任何帮助将不胜感激。
编辑:请注意,在元素出现之前轮询页面不是问题,而是检测submitInput.click() 是否加载新页面或向现有标签添加文本时存在问题。
编辑 2:为了说明问题,我编译了一个时间记录的贯穿测试和服务器日志:
16:34:48,589 - TEST - Navigating to page.
16:34:48,605 - SERVER - Page request started.
16:34:48,631 - SERVER - Page request ended.
16:34:49,050 - TEST - Typing test input.
16:34:49,456 - TEST - Clicking button.
16:34:49,519 - SERVER - Received click event.
16:34:49,529 - SERVER - Responding with redirect.
16:34:49,556 - TEST - Finding feedback by id.
16:34:49,560 - SERVER - Page request started.
16:34:49,581 - SERVER - Page request ended.
16:34:49,775 - TEST - Test threw exception.
您可以看到服务器在测试发送后仅半秒多一点就收到了点击事件。它立即响应(在这种情况下)重定向命令。由于单击是 AJAX 事件,测试同时有continued in the background as per the docs,这导致(如您所见)测试在服务器收到新页面请求之前 0.004 秒检索反馈。当 feedback.getText() 被解析并发送到 ChromeDriver 时,服务器已经响应了一个新页面,因此该函数返回过时异常。
真正的关键是我可以使用Thread.sleep(1000) 解决这个问题,但这远非理想;首先是因为在某些情况下,服务器解析 AJAX 并返回结果的时间可能超过半秒,这使得测试具有不确定性,其次因为这些时间很快就会堆积起来并浪费时间,通常是不必要的,当只有一个需要几毫秒。
【问题讨论】:
标签: java selenium junit selenium-chromedriver