如何使用 Selenium Java WebDriver 测试轮询 javascript ajax 调用
How to test a polling javascript ajax call with Selenium Java WebDriver
我有一个包含 Java 脚本代码的页面,该脚本代码每秒轮询一个 API 并用响应替换 HTML 页面中的元素。我想使用 Selenium WebDriver 测试这个页面。我在我的 Junit 测试中设置了 WebDriver,但我不知道如何处理轮询 Java 脚本。
RemoteWebDriver driver = chrome.getWebDriver();
driver.get("http://localhost:8080");
Java脚本代码配置一个计时器来调用 getMessage()
是这样设置的。
<body>
<h1 id="message"> Loading ... </h1>
</body>
<script>
function getMessage()
{
$.ajax({
url : '/message',
type: 'GET',
success: function(data){
$('#message').text(data.message);
},
error: function (data) {
$('#message').text("Error Response");
}
});
}
$(document).ready(function() {
window.setInterval(getMessage, 1000);
});
</script>
我想测试 H1 消息值每秒更改为大约 30 秒,因此我希望在测试的 30 秒内看到 25 次更改 运行。我如何使用 Selenium WebDriver 做到这一点?
下面是每两秒打印一次消息的一种怪异方式
我们可以编写自己的函数并将该函数传递给 FluentWait 的 Until 方法。它将每 2 秒调用一次此方法,超时设置为 30 秒。我们正在使用计数器 Once count > 10 。它应该从 until 出来。可能需要根据您的需要进行一些重构。
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>()
{
int count = 1;
public Boolean apply(WebDriver arg0) {
count++;
WebElement element = arg0.findElement(By.id("message"));
String text= element.getText();
System.out.println("Message " + text); // your logic
if(count > 10))
{
return true;
}
return false;
}
}
示例使用。假设驱动程序路径等设置正确
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080");
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(Duration.ofSeconds(2));
wait.withTimeout(Duration.ofSeconds(30));
wait.ignoring(NoSuchElementException.class);
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>()
{
int count = 1;
public Boolean apply(WebDriver arg0) {
count++;
WebElement element = arg0.findElement(By.id("message"));
String text= element.getText();
System.out.println("Message " + text); // your logic
if(count > 10))
{
System.out.println(count + "++++++++++++++++++");
return true;
}
return false;
}
};
wait.until(function);// You can handle timeout exception using try-catch as per your
//use case
}
这是另一种方法:
private boolean testElementFor1SecChange(SearchContext searchContext, By locator, Duration testDuration){
String baseElementText = searchContext.findElement(locator).getText();
for(int i = 0; i < testDuration.get(ChronoUnit.SECONDS); i++){
try {
Thread.sleep(1000);
String nextElementText = searchContext.findElement(locator).getText();
if(baseElementText == null || baseElementText.equals(nextElementText)){
return false;
}
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
return true;
}
所以测试看起来像:
@Test
public void testChanges(){
driver.get("http://localhost:8080");
Assert.assertTrue(
testElementFor1SecChange(driver, By.id("message"), Duration.ofSeconds(30))
);
}
我有一个包含 Java 脚本代码的页面,该脚本代码每秒轮询一个 API 并用响应替换 HTML 页面中的元素。我想使用 Selenium WebDriver 测试这个页面。我在我的 Junit 测试中设置了 WebDriver,但我不知道如何处理轮询 Java 脚本。
RemoteWebDriver driver = chrome.getWebDriver();
driver.get("http://localhost:8080");
Java脚本代码配置一个计时器来调用 getMessage()
是这样设置的。
<body>
<h1 id="message"> Loading ... </h1>
</body>
<script>
function getMessage()
{
$.ajax({
url : '/message',
type: 'GET',
success: function(data){
$('#message').text(data.message);
},
error: function (data) {
$('#message').text("Error Response");
}
});
}
$(document).ready(function() {
window.setInterval(getMessage, 1000);
});
</script>
我想测试 H1 消息值每秒更改为大约 30 秒,因此我希望在测试的 30 秒内看到 25 次更改 运行。我如何使用 Selenium WebDriver 做到这一点?
下面是每两秒打印一次消息的一种怪异方式
我们可以编写自己的函数并将该函数传递给 FluentWait 的 Until 方法。它将每 2 秒调用一次此方法,超时设置为 30 秒。我们正在使用计数器 Once count > 10 。它应该从 until 出来。可能需要根据您的需要进行一些重构。
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>()
{
int count = 1;
public Boolean apply(WebDriver arg0) {
count++;
WebElement element = arg0.findElement(By.id("message"));
String text= element.getText();
System.out.println("Message " + text); // your logic
if(count > 10))
{
return true;
}
return false;
}
}
示例使用。假设驱动程序路径等设置正确
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080");
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(Duration.ofSeconds(2));
wait.withTimeout(Duration.ofSeconds(30));
wait.ignoring(NoSuchElementException.class);
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>()
{
int count = 1;
public Boolean apply(WebDriver arg0) {
count++;
WebElement element = arg0.findElement(By.id("message"));
String text= element.getText();
System.out.println("Message " + text); // your logic
if(count > 10))
{
System.out.println(count + "++++++++++++++++++");
return true;
}
return false;
}
};
wait.until(function);// You can handle timeout exception using try-catch as per your
//use case
}
这是另一种方法:
private boolean testElementFor1SecChange(SearchContext searchContext, By locator, Duration testDuration){
String baseElementText = searchContext.findElement(locator).getText();
for(int i = 0; i < testDuration.get(ChronoUnit.SECONDS); i++){
try {
Thread.sleep(1000);
String nextElementText = searchContext.findElement(locator).getText();
if(baseElementText == null || baseElementText.equals(nextElementText)){
return false;
}
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
return true;
}
所以测试看起来像:
@Test
public void testChanges(){
driver.get("http://localhost:8080");
Assert.assertTrue(
testElementFor1SecChange(driver, By.id("message"), Duration.ofSeconds(30))
);
}