3

使用Pagefactory时我直接声明WebElement如下。

@AndroidFindBy(accessibility = "androidLocator")
@iOSFindBy(accessibility = "iosLocator")
private MobileElement element;

但是,有没有办法处理StaleElementReference异常,因为我在这里没有使用任何 By 对象。我能想到的所有解决方案都要求我使用定位器作为 By 的对象。

我想在父类中为所有处理StaleElementReferenceException. 但问题是我只能将引用作为 aWebElement而不是作为 By 对象传递,这超出了重新初始化WebElement.

我可以找到以下解决方案:

FluentWait<MobileDriver<MobileElement>> wait = new FluentWait<MobileDriver<MobileElement>>(driver)
                        .withTimeout(20, TimeUnit.SECONDS).pollingEvery(500, TimeUnit.MILLISECONDS)
                        .ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class);
                wait.until(new Function<WebDriver, MobileElement>() {
                    @Override
                    public MobileElement apply(WebDriver driver) {
                        element.get
                        MobileElement element = driver.findElement(by);
                        return element;
                    }
                });

但同样的问题也出现在这里。我需要将引用作为By对象传递,就像PageFactory我有引用一样WebElemrnt

4

4 回答 4

1

无论是 Appium 还是普通的 Selenium,我对陈旧元素的解决方案始终是确保我正在使用一个新实例化的页面对象。

如果您要跨测试方法共享页面对象,或者如果有可能改变页面状态的东西,重新初始化页面对象不会有什么坏处。

但是,您没有显示您的页面对象初始化代码。您的页面初始化是什么样的?

于 2018-10-22T17:21:11.407 回答
1

您可以使用refreshed ExpectedCondition等待元素在 DOM 中重绘

(new WebDriverWait(driver, 30)).until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOf(element)));
于 2018-10-21T04:49:43.283 回答
0

您可以使用 try catch 块,在 try 中您可以使用正常的 selenium 方法等待并单击。然后在 catch 中,您可以使用 JavascriptExecutor 单击元素。

private WebDriverWait webDriverWait;

public WebElement waitForElement(WebDriver driver, WebElement element) {
    try {
        webDriverWait = new WebDriverWait(driver, 10);
        webDriverWait.until(ExpectedConditions.elementToBeClickable(element));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return element;
}

public void click(WebDriver driver, WebElement element) {
    try {
        waitForElement(driver, element).click();
    } catch (Exception ex) {
        ex.printStackTrace();
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("arguments[0].click();", element);
    }
}

我希望这能解决你的问题。谢谢。

于 2018-10-21T06:14:53.107 回答
0

您可以将命令放在 try...catch 块中,如果您捕获 StaleElementReference 异常,则使用driver.navigate.refresh()刷新页面并再次执行相同的操作。

如果您的元素将在一段时间后自动刷新,那么您也可以在这种情况下使用 ExpectedConditions。

wait.until(ExpectedConditions.refreshed(ExpectedConditions.stalenessOf(element)));

于 2018-10-21T04:59:10.553 回答