给定一个网络元素,单击它会导致页面重新加载吗?

given a webelement, does clicking it cause a page reload?

我在做什么

我一直在制作一个实用方法来帮助我在 Selenium 中找到并正确等待 Webelements。到目前为止它进展顺利,我有办法尝试各种不同的定位器,等到找到网络元素,然后等到网络元素 displayed/enabled 都有超时和类似的好东西。

那有什么问题吗?

问题是我有时需要在页面重新加载后查找 Webelements。我已经阅读了 'staleness' 问题的可用解决方案并且我知道如何解决它(使用我刚刚找到并单击的旧网络元素我会等到它过时再搜索)BUT 我不想手动检查给定的网络元素是否会导致页面重新加载。我已经尝试查看 Webelement 和预期条件 class 以查看是否有任何方法在给定的 webelement 导致页面重新加载时 returns 为真。我已经尝试在这里和 google 上搜索它,但没有得到任何有用的信息。我想知道是否有可能有这样的东西:

Boolean causesPageReload = webElement.causesPageReload;

使用一些名为 causesPageReload 的虚构方法来确定网络元素在被单击、提交等时是否会导致页面重新加载。我知道一些 webelements 只是导致 javascript 到页面上的 运行 而其他人重新加载页面但是如果我可以通过编程确定它是否重新加载页面我可以说:

if (causesPageReload){
    wait.until(ExpectedConditions.stalenessOf("insert old webelement here"));
}

并解决问题。底层 HTML、java 脚本中是否有任何东西或者可能已经内置的东西可以提供此信息?当然,我可以自己手动完成这些步骤,看看哪些被测 Web 元素实际上会导致页面刷新,但这可能会发生变化,容易出现人为错误并且也很耗时。

可能的替代方案?

或者,我可以在 10 秒的超时时间内进行过时检查,如果它重新加载页面,那很好,但如果没有,它允许 java 脚本或其他任何东西在 10 秒内完成它在做什么。 (我也有点想知道我是否需要等待非页面重新加载 webelement 的点击,但由于 java 脚本,这似乎更难,并且需要一个不同的问题)我不知道我是否需要等待,如果页面不会重新加载。即使我知道在非重新加载情况下我确实需要等待,我也不知道该怎么做。我当前的等待只是等待 webelement 被发现、显示和启用,所以如果点击它会导致一些重要的事情(我需要等待)但不会改变这些事情,我需要其他东西但这需要另一个问题更深入。

Tl:博士

我只需要知道我是否可以找出哪些网络元素导致页面以编程方式重新加载,如果我不能,那么是否需要等待非重新加载的(无需深入了解第二种情况只是告诉我如何问这个作为第二个问题)?

更新

我已经尝试过多线程处理,到目前为止,我已经得到了一些东西,可以(及时地)决定在 DOM 中单击更改时给定元素是否发生变化。这涵盖了大多数页面重新加载的情况,但可能会导致误报,因为我很确定还有其他不涉及页面重新加载的元素引用过时的情况。我认为问题的根本原因是没有 data/flag/hook 可以抓住来真正说明。我想更好的钩子会带来更好的解决方案,但我不知道那个钩子是什么。从好的方面来说,我 learn/become 熟悉很多多线程,这很好,因为它是我一直薄弱的领域。我将尝试研究答案中提到的 java 脚本看看我是否不能将其与我的多线程方法结合起来。一旦我有了一个好的钩子,我需要改变的就是对 WebDriverwait 等待对象的 ExpectedConditions 调用。

更新 2

我找到了这个网站: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded

其中详细说明了“load”和“DOMcontentloaded”事件。 java脚本中的两件事在页面为 loaded/reloaded 时触发。我已经创建了一个带有 ExpectedConditions 的线程应用程序,如下所示:

WebDriverWait wait = new WebDriverWait(driver,timeoutSeconds);
        try{
            wait.until(ExpectedConditions.stalenessOf(webElement));
        }
        catch (TimeoutException e){  
        }

因此我很确定我可以修改 wait.until 行以使用 Java 到 Java 脚本来检查超时触发的 java 脚本事件界面。为了同时使用这两种语言,我被引出了这个问题:

How can I use JavaScript in Java?

为了获得有关其基本工作原理的知识。我将尝试使用 Nashorn 或其他一些接口来实现它,具体取决于什么是最好的。

这可能意味着什么

虽然这不能为我们确定给定的网络元素是否会在实际“尝试”它之前导致页面重新加载,但它确实通过“尝试”该网络元素来确定它。而且,因为我使用了 main 之外的线程,所以我对“不,它没有重新加载页面”的检查实际上只是超时条件,可以根据需要进行配置。我认为如果不实际尝试就无法确定 Webelement 是否会导致页面重新加载,但至少我们可以尝试一下,确定它是否在超时期限内重新加载,然后我们就会知道我们已经等待了足够长的时间如果我们至少知道我们正在寻找的下一个元素存在于新页面上,则在搜索相同或下一个元素时不会得到任何陈旧的引用异常(假设一旦我们执行该方法来尝试定位它,它就会等待用于显示和选择所述元素,但我已经做到了)。这也允许我们通过“尝试”来确定给定的网络元素是否已从页面中删除,因为如果我们将 java 脚本页面加载调用与我已经拥有的陈旧引用检查相结合,那么我们可以使用“the JS 加载事件没有触发(页面静态)但抛出了陈旧引用异常(DOM 元素已更改)”作为检查“此元素显着 deleted/changed 但页面未重新加载”,这是相当有用的信息。此外,因为这些元素现在可以分为三类:

  1. 没有被删除,可以再次参考
  2. 已删除但页面静态
  3. 已删除但页面更改

我们可以预先存储结果(只要定位器保持不变)我们可以更容易地知道在单击网络元素后是否必须等待。我们甚至可以走得更远,如果我们知道我们有第二种情况,我们可以重试定位该元素并在我们单击它时查看它的定位器是否发生变化,因为我认为可以抛出陈旧引用异常而无需更改所有定位器。这有多大用处?我不确定,但我认为它非常有用,但我不认为我是第一个 try/find 解决此问题的人。当我成功实施和测试时,我会 post 一个答案,但这需要一段时间,因为我需要学习一些基本的 Java 脚本,然后如何将它与我的 java.

您可以使用

WaitElement(pBy, pWait);

end 如果你需要如果元素是可见的继续你可以添加 is_displayed()

最后不工作你使用 java 等待 :

Thread.sleep(second)

TimeUnit.SECONDS.sleep(second);

无法以编程方式查明点击是否会导致重新加载。

您需要单独的每个案例,为此您可以创建具有重载(或不重载)的主要 click() 方法,并在每个案例中调用适当的方法

public void clickOnElement(WebElement element, boolean waitForStaleness) {
    element.click();
    if (waitForStaleness) {
        wait.until(ExpectedConditions.stalenessOf(element));
    }
}

public void clickOnElement(WebElement element) {
    clickOnElement(element, false);
}