dsi*_*ler 1 java selenium xpath selenium-webdriver
我有一个响应式设计,我需要与之交互的很多项目都有2个WebElements.一个用于桌面,一个用于移动,我正在尝试使用PageFactory.以下是我现在要识别并与元素交互的内容.
//this returns 2 webelements, one for desktop and one for mobile
@FindBy(xpath = "//selector-dropdown/p")
private WebElement dropdown;
public void ClickDropdown() throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOf(dropdown)).click();
}
Run Code Online (Sandbox Code Playgroud)
我的印象是ExpectedConditions.visibilityOf(WebElement)会发现第一个元素可见.现在,当我在桌面上打开应用程序时,它会找到该元素(桌面是DOM中的第一个).但是在移动设备上,它等待可见性超时,因为它等待第一个变得可见.
我的另一种方法是使用@FindBy来声明每个元素两次,然后创建一个if语句来决定采用哪个路径.这项额外的工作是否能使其发挥作用?
你的假设"... ExpectedConditions.visibilityOf(WebElement)会发现第一个元素可见." 是错的!您需要将WebElement声明为List,找到所有这些,然后选择一个可见的.以下是我过去成功使用的示例:
@FindBy(xpath = "//input[@ng-model='loginData.username']")
private List<WebElement> txtUsername;
public String getUsername() {
driverWait.until(CustomExpectedConditions.presenceOfAllElements(txtUsername));
for (WebElement oneUsername : txtUsername) {
if (oneUsername.isDisplayed())
return oneUsername.getAttribute("value");
}
return null;
}
public void setUsername(String username) {
driverWait.until(CustomExpectedConditions.presenceOfAllElements(txtUsername));
for (WebElement oneUsername : txtUsername) {
if (oneUsername.isDisplayed()) {
oneUsername.clear();
oneUsername.sendKeys(username);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据其他地方的讨论,这里是CustomExpectedConditions:
public class CustomExpectedConditions {
/**
* Based on {@link ExpectedConditions#presenceOfAllElementsLocatedBy(org.openqa.selenium.By)}.
*
* @param elements
* @return
*/
public static ExpectedCondition<List<WebElement>> presenceOfAllElements(
final List<WebElement> elements) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
// List<WebElement> elements = findElements(locator, driver);
return elements.size() > 0 ? elements : null;
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
将@Andersons 和@SiKing 的答案组合成一个可以在任何地方使用的解决方案,您可以PageObjects在基类中为所有人提供一个方法,您可能已经拥有:
protected WebElement getVisibleElement(List<WebElement> elements)
{
//Need a guard clause here to ensure there are exactly two elements,
//Or make the wait check for all elements more safely. Either way,
//consider changing the method name to be clear about expectations
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(
ExpectedConditions.or(
//This should be done more safely, unless already guarded to expect 2 elements
ExpectedConditions.visibilityOf(elements.get(0))),
ExpectedConditions.visibilityOf(elements.get(1)))
)
);
for (WebElement element : elements) {
if (element.isDisplayed())
{
return element;
}
}
//Throw element not visible exception or something
}
Run Code Online (Sandbox Code Playgroud)
然后在您的 PageObject 中:
@FindBy(xpath = "//selector-dropdown/p")
private List<WebElement> dropdown;
public void ClickDropdown() throws InterruptedException {
getVisibleElement(dropdown)).click();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3999 次 |
| 最近记录: |