You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用WebElement替代By实现PresenceOfAllElementsLocatedBy?及PageFactory元素等待问题

Hey there! Let's break down solutions for your two Selenium scenarios, tailored for PageFactory and explicit wait workflows:

1. Implementing PresenceOfAllElementsLocatedBy with WebElement Instead of By

The built-in ExpectedConditions.presenceOfAllElementsLocatedBy() relies on a By locator, but if you're working with WebElement instances initialized via PageFactory, you can create a custom ExpectedCondition to check for the presence of all elements in a list.

PageFactory uses proxy objects for WebElement, so actual element lookup only happens when you call a method like isDisplayed() — this makes the custom condition feasible:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import java.util.ArrayList;
import java.util.List;

public class CustomExpectedConditions {
    public static ExpectedCondition<List<WebElement>> presenceOfAllWebElements(final List<WebElement> elements) {
        return new ExpectedCondition<>() {
            @Override
            public List<WebElement> apply(WebDriver driver) {
                List<WebElement> presentElements = new ArrayList<>();
                for (WebElement element : elements) {
                    try {
                        // Adjust the check based on your needs (isDisplayed(), isEnabled(), etc.)
                        if (element.isDisplayed()) {
                            presentElements.add(element);
                        }
                    } catch (Exception ignored) {
                        // Ignore exceptions for elements that aren't yet present
                    }
                }
                // Return the list only when all elements are present; else return null to keep waiting
                return presentElements.size() == elements.size() ? presentElements : null;
            }

            @Override
            public String toString() {
                return "presence of all target web elements";
            }
        };
    }
}

Usage with PageFactory:

If your page class has a list of elements initialized via @FindBy:

@FindBy(css = ".product-item")
private List<WebElement> productItems;

// In your wait logic:
new FluentWait<>(driver)
    .withTimeout(10, TimeUnit.SECONDS)
    .pollingEvery(50, TimeUnit.MILLISECONDS)
    .until(CustomExpectedConditions.presenceOfAllWebElements(productItems));
2. Implementing Wait for Element Absence with PageFactory

Your existing FluentWait setup is on the right track — let's refine it to handle both By locators and PageFactory WebElement instances:

Option 1: Wait for element absence using By

This is straightforward with built-in ExpectedConditions:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import java.util.concurrent.TimeUnit;

public void waitForElementToDisappear(By by) {
    try {
        FluentWait<WebDriver> wait = new FluentWait<>(driver)
                .withTimeout(10, TimeUnit.SECONDS)
                .pollingEvery(50, TimeUnit.MILLISECONDS)
                .ignoring(NoSuchElementException.class)
                .ignoring(StaleElementReferenceException.class);

        // Wait until the element is no longer present in the DOM
        wait.until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(by)));
    } catch (TimeoutException e) {
        throw new AssertionError("Element still exists after timeout: " + by);
    }
}

Option 2: Wait for PageFactory WebElement to disappear

For elements initialized via PageFactory, we can check by attempting to interact with the element and catching exceptions that signal absence:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.FluentWait;
import java.util.concurrent.TimeUnit;

public void waitForWebElementToDisappear(final WebElement element) {
    try {
        FluentWait<WebDriver> wait = new FluentWait<>(driver)
                .withTimeout(10, TimeUnit.SECONDS)
                .pollingEvery(50, TimeUnit.MILLISECONDS)
                .ignoring(NoSuchElementException.class)
                .ignoring(StaleElementReferenceException.class);

        wait.until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver driver) {
                try {
                    // If the element is still present, this call will succeed — return false to keep waiting
                    element.isDisplayed();
                    return false;
                } catch (Exception e) {
                    // Exceptions mean the element is gone — return true to end the wait
                    return true;
                }
            }
        });
    } catch (TimeoutException e) {
        throw new AssertionError("WebElement still exists after timeout");
    }
}

Key Notes:

  • If you need to wait for an element to be invisible (not just absent from DOM), use ExpectedConditions.invisibilityOfElementLocated(by) or ExpectedConditions.invisibilityOf(element) — this handles both hidden and absent elements.
  • Avoid ignoring TimeoutException intentionally; letting it bubble up (or wrapping it in an assertion error) helps catch cases where elements don't disappear as expected.

内容的提问来源于stack exchange,提问作者arena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:41:24