Java 使用自定义WebDriver谓词避免额外工作的更好方法
在我的webdriver测试用例中,我必须从一个URL解析出一个数字(如果它不在那个里,则测试失败),但在我被重定向到包含数字的URL时,首先等待。 例如,当我转到“localhost/#createRecord”时,我被重定向到“localhost/#editRecord/some number”Java 使用自定义WebDriver谓词避免额外工作的更好方法,java,selenium-webdriver,Java,Selenium Webdriver,在我的webdriver测试用例中,我必须从一个URL解析出一个数字(如果它不在那个里,则测试失败),但在我被重定向到包含数字的URL时,首先等待。 例如,当我转到“localhost/#createRecord”时,我被重定向到“localhost/#editRecord/some number” wait.until(ExpectedConditions.urlMatches("#editRecord/([0-9]*)$")); String url = driver.get
wait.until(ExpectedConditions.urlMatches("#editRecord/([0-9]*)$"));
String url = driver.getCurrentUrl();
Pattern p = Pattern.compile("#editRecord/([0-9]*)$");
Matcher m = p.matcher(url);
int newStudentId=0;
if (m.find()) {
newStudentId = Integer.parseInt(m.group(1));
System.out.println(m.group(1)); // The matched substring
} else fail("There is no ID number in #editRecord page");
在这种情况下,实际上在wait.until(…)之后会发生额外的匹配工作
通过谷歌搜索,我找到了这种代码变体。解析成功后会立即保存解析结果:
Pattern p = Pattern.compile("#editRecord/([0-9]*)$");
final int[] newStudentId = new int[1]; //declared like this because otherwise we won't be able to assign value to it from lambda expression
try {
wait.until((WebDriver driver) -> {
String url = driver.getCurrentUrl();
Matcher m = p.matcher(url);
if (m.find()) {
newStudentId[0] = Integer.parseInt(m.group(1));
return true;
} else return false;
});
} catch (org.openqa.selenium.TimeoutException e) {
fail("There is no ID number in #editRecord page or we haven't been redirected to #editRecord page");
}
System.out.println(newStudentId[0]);
两个版本都可以工作,但我不确定哪一个版本在可读性(我以前没有使用过lambdas,也不完全理解它)和可靠性方面更好。另外,在第二个选项中捕获超时异常会覆盖比第一个选项更多的失败情况如果您经常等待URL更改,您可以编写自己的方法并多次使用它:
public void waitForUrlChange(final WebDriver driver, final String previousUrl, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
wait.until((WebDriver d) -> !d.getCurrentUrl().equals(previousUrl));
}
或等待URL更改为给定URL:
public void waitForUrlToEqual(final WebDriver driver, final String urlToEqual, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
wait.until((WebDriver d) -> d.getCurrentUrl().equals(urlToEqual));
}
或等待URL与模式匹配:
public void waitForUrlToMatch(final WebDriver driver, final String patternToMatch, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
final Pattern pattern = Pattern.compile(patternToMatch);
wait.until((WebDriver d) -> {
Matcher matcher = pattern.matcher(d.getCurrentUrl());
return matcher.find();
});
}
在这些方法中,->
之后的部分每500毫秒调用一次,直到可以将其计算为true
。如果在waitTime
内不为true,则抛出TimeoutException
您的第一个解决方案
相反:
- 您可以使用
两次。您应该声明一个“#editRecord/([0-9]*)$”
变量并重新使用它字符串
优点:
- 异常处理。但是,只需使用try-catch块对
调用进行排序,就可以将其添加到第一个解决方案中wait.until
- 您必须声明一个
变量final
int newStudentId = 0;
String urlPattern = "#editRecord/([0-9]*)$";
String failMessage = "There is no ID number in #editRecord page";
try {
wait.until(ExpectedConditions.urlMatches(urlPattern));
String url = driver.getCurrentUrl();
Pattern p = Pattern.compile(urlPattern);
Matcher m = p.matcher(url);
if (m.find()) {
newStudentId = Integer.parseInt(m.group(1));
System.out.println(newStudentId);
} else {
throw new IndexOutOfBoundsException(failMessage);
}
} catch (org.openqa.selenium.TimeoutException | IndexOutOfBoundsException e) {
fail(failMessage);
}
此外,它看起来很清晰,还有一个词:感谢您对lambdas的澄清。。。它让我思考 如果您经常等待URL更改,您可以编写自己的方法并多次使用:
public void waitForUrlChange(final WebDriver driver, final String previousUrl, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
wait.until((WebDriver d) -> !d.getCurrentUrl().equals(previousUrl));
}
或等待URL更改为给定URL:
public void waitForUrlToEqual(final WebDriver driver, final String urlToEqual, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
wait.until((WebDriver d) -> d.getCurrentUrl().equals(urlToEqual));
}
或等待URL与模式匹配:
public void waitForUrlToMatch(final WebDriver driver, final String patternToMatch, final int waitTime) {
WebDriverWait wait = new WebDriverWait(driver, waitTime);
final Pattern pattern = Pattern.compile(patternToMatch);
wait.until((WebDriver d) -> {
Matcher matcher = pattern.matcher(d.getCurrentUrl());
return matcher.find();
});
}
在这些方法中,->
之后的部分每500毫秒调用一次,直到可以将其计算为true
。如果在waitTime
内不为true,则抛出TimeoutException
您的第一个解决方案
相反:
- 您可以使用
两次。您应该声明一个“#editRecord/([0-9]*)$”
变量并重新使用它字符串
优点:
- 异常处理。但是,只需使用try-catch块对
调用进行排序,就可以将其添加到第一个解决方案中wait.until
- 您必须声明一个
变量final
int newStudentId = 0;
String urlPattern = "#editRecord/([0-9]*)$";
String failMessage = "There is no ID number in #editRecord page";
try {
wait.until(ExpectedConditions.urlMatches(urlPattern));
String url = driver.getCurrentUrl();
Pattern p = Pattern.compile(urlPattern);
Matcher m = p.matcher(url);
if (m.find()) {
newStudentId = Integer.parseInt(m.group(1));
System.out.println(newStudentId);
} else {
throw new IndexOutOfBoundsException(failMessage);
}
} catch (org.openqa.selenium.TimeoutException | IndexOutOfBoundsException e) {
fail(failMessage);
}
此外,它看起来很清晰,还有一个词:感谢您对lambdas的澄清。。。它让我思考 为什么要为
newStudentId
使用数组?如果不这样做,会出现什么错误?@GrzegorzGórkiewicz代码段中有一条注释,解释了这一点。当然,我看到了,但仍然不明白。为什么要将其声明为最终值?将其声明为数组是一种变通方法,因此我仍然可以在数组中指定int。是关于final声明的一种解释,为什么要为newStudentId
使用数组?如果不这样做,会出现什么错误?@GrzegorzGórkiewicz代码段中有一条注释,解释了这一点。当然,我看到了,但仍然不明白。为什么要将其声明为最终值?将其声明为数组是一种变通方法,因此我仍然可以在数组中指定int。这是对最终声明的一种解释