如何让 webdriver 在使用 css、xpath、tag、link 或元素 id 之间切换
How to get webdriver to switch between using css, xpath, tag, link or element id
目前我所有的步骤定义都只接受元素 ID,以便在网页上执行操作。
driver.findElement(By.id("id"));
但是如果我想传入 css 选择器、标签、link 或 xpath 怎么办?
我不想为所有这些场景重写我所有的步骤定义(或创建多个相同的步骤定义),而不知道哪一个将被传递。
driver.findElement(By.cssSelector("css"));
driver.findElement(By.link("link"));
driver.findElement(By.tagName("tag"));
driver.findElement(By.xpath("xpath"));
有没有我可以使用的 switch 语句,它会确定传递的是哪种定位器,然后继续执行相应的操作?
我不知道我是否理解正确,但是 By
class return 中的每个静态方法都是一个 By
对象。因此,如果你想创建一个与 ID、CSS 选择器、XPath 一起工作的方法......你可以简单地使用 By
作为参数类型。
所以不要像这样将 ID 作为 String
传递...
public void foo(String id) {
// ...
driver.findElement(By.id(id));
// ...
}
……你可以做到……
public void foo(By by) {
// ...
driver.findElement(by);
// ...
}
... 所以 foo
的调用者可以传递它喜欢的任何 By
。
您可以根据不同的定位器字符串创建一个助手class到returnBy
。
// feature file
Secnario Outline: Test user login
Given ...
And user input username: <value> into <element>
And user input password: <value> into <element>
Examples:
| value | element |
| user1 | id:username |
| pwd1 | css:input.pwd |
// helper class to build Locator
public class Locator {
public static By build(locator) {
String[] parts = locator.split(":");
String use = parts[0].trim().lowerCase();
String value = parts[1].trim();
if(use.equals("id")) {
return By.id(value);
}
else if(use.equals("css")){
return By.css(value);
}
.....
}
}
// step definition
Then("^user input username: (.+) into (.+)$",
(String inputValue, String locatoExp) -> {
driver.findElement(Locator.build(locatoExp)).sendKeys(inputValue);
});
您是否正在尝试通过类似于用户 'yong' 发布的示例的步骤定义从特征文件传递元素 ID?
如果是这种情况,我强烈建议重新考虑这种方法。使用 Gherkin 作为常规代码之上的层的全部目的是让不了解技术实现的人可以阅读测试。
我宁愿为每个输入字段使用一个步骤定义,因此如果您需要在多个测试中访问该字段,则不必每次都指定 ID 或 cssSelector。如果 HTML 中字段的 ID 发生变化,则无需更新特征文件,只需更新步骤定义即可。
如果您经常在多个步骤定义中使用相同的元素,请查看页面对象模型模式,其中每页只定义一次元素,以便您可以在多个步骤定义中重复使用它们。
目前我所有的步骤定义都只接受元素 ID,以便在网页上执行操作。
driver.findElement(By.id("id"));
但是如果我想传入 css 选择器、标签、link 或 xpath 怎么办? 我不想为所有这些场景重写我所有的步骤定义(或创建多个相同的步骤定义),而不知道哪一个将被传递。
driver.findElement(By.cssSelector("css"));
driver.findElement(By.link("link"));
driver.findElement(By.tagName("tag"));
driver.findElement(By.xpath("xpath"));
有没有我可以使用的 switch 语句,它会确定传递的是哪种定位器,然后继续执行相应的操作?
我不知道我是否理解正确,但是 By
class return 中的每个静态方法都是一个 By
对象。因此,如果你想创建一个与 ID、CSS 选择器、XPath 一起工作的方法......你可以简单地使用 By
作为参数类型。
所以不要像这样将 ID 作为 String
传递...
public void foo(String id) {
// ...
driver.findElement(By.id(id));
// ...
}
……你可以做到……
public void foo(By by) {
// ...
driver.findElement(by);
// ...
}
... 所以 foo
的调用者可以传递它喜欢的任何 By
。
您可以根据不同的定位器字符串创建一个助手class到returnBy
。
// feature file
Secnario Outline: Test user login
Given ...
And user input username: <value> into <element>
And user input password: <value> into <element>
Examples:
| value | element |
| user1 | id:username |
| pwd1 | css:input.pwd |
// helper class to build Locator
public class Locator {
public static By build(locator) {
String[] parts = locator.split(":");
String use = parts[0].trim().lowerCase();
String value = parts[1].trim();
if(use.equals("id")) {
return By.id(value);
}
else if(use.equals("css")){
return By.css(value);
}
.....
}
}
// step definition
Then("^user input username: (.+) into (.+)$",
(String inputValue, String locatoExp) -> {
driver.findElement(Locator.build(locatoExp)).sendKeys(inputValue);
});
您是否正在尝试通过类似于用户 'yong' 发布的示例的步骤定义从特征文件传递元素 ID?
如果是这种情况,我强烈建议重新考虑这种方法。使用 Gherkin 作为常规代码之上的层的全部目的是让不了解技术实现的人可以阅读测试。
我宁愿为每个输入字段使用一个步骤定义,因此如果您需要在多个测试中访问该字段,则不必每次都指定 ID 或 cssSelector。如果 HTML 中字段的 ID 发生变化,则无需更新特征文件,只需更新步骤定义即可。
如果您经常在多个步骤定义中使用相同的元素,请查看页面对象模型模式,其中每页只定义一次元素,以便您可以在多个步骤定义中重复使用它们。