Java 在对元素执行操作之前,如何等待页面加载器(它根据API调用出现和消失)消失

Java 在对元素执行操作之前,如何等待页面加载器(它根据API调用出现和消失)消失,java,selenium-webdriver,Java,Selenium Webdriver,正如标题所述,我试图在元素上执行一个操作,即sendkeys或click等,但具有ID的加载程序使该操作不一致 我已经尝试了很多不同的方法,现在我正在尝试一种使用线程睡眠的方法,这种方法可以半一致地工作,但仍然会偶尔出现误报,从而导致测试失败 加载程序id=spinner在一个API调用完成向脚本发送一个信号表示可以继续执行后从页面消失,但在下一个调用开始时,加载程序返回,然后在当前3个API调用完成后消失。我想设计一种方法,使这项工作无论实施了多少呼吁 public void Loader()

正如标题所述,我试图在元素上执行一个操作,即sendkeys或click等,但具有ID的加载程序使该操作不一致

我已经尝试了很多不同的方法,现在我正在尝试一种使用线程睡眠的方法,这种方法可以半一致地工作,但仍然会偶尔出现误报,从而导致测试失败

加载程序id=spinner在一个API调用完成向脚本发送一个信号表示可以继续执行后从页面消失,但在下一个调用开始时,加载程序返回,然后在当前3个API调用完成后消失。我想设计一种方法,使这项工作无论实施了多少呼吁

public void Loader()
{    
   WebDriverWait wait=new WebDriverWait(driver,50);
   WebElement CPloader = driver.findElement(By.id("spinner"));
   boolean test = wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner")));         

   if(test==false) {
       wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner")));
       wait.until(ExpectedConditions.invisibilityOf(CPloader));
       threadsleep(2000);
       wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner")));
       wait.until(ExpectedConditions.invisibilityOf(CPloader));
       threadsleep(2000);
       wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner")));
       wait.until(ExpectedConditions.invisibilityOf(CPloader));
   }

}
在测试脚本代码中,我通常会放置loader方法、threadsleep、loader方法,试图让它延迟足够长的时间,但我知道这是不合适的。。。示例如下:

Util.Loader();
Util.threadsleep(2000);
Util.Loader();
//click element or send keys etc
我想象这是一个有着隐形等待的循环,但似乎无法理解

任何指向正确方向的指针都会有很大帮助。

正如您所提到的,具有ID的加载程序正在执行不一致的操作,因此您可以为想要调用click或sendKeys的元素调用方法,而不是为加载程序调用InvisibilityFelementLocated方法,如下所示:

使用CSS选择器并单击:

使用xpath和sendKeys:


我会通过等待加载程序出现然后消失来实现这一点。。。在一个循环中这样做。一旦加载程序停止出现,等待将抛出TimeoutException。用试一试的方式抓住它,然后跳出圈外。您可能需要调整10秒的等待时间,这取决于加载微调器之间通常经过的时间

public static void Loader()
{
    By loader = By.id("spinner");
    WebDriverWait wait = new WebDriverWait(driver, 10);
    while (true)
    {
        try
        {
            wait.until(ExpectedConditions.visibilityOfElementLocated(loader));
            wait.until(ExpectedConditions.invisibilityOfElementLocated(loader));
        }
        catch (Exception e)
        {
            break;
        }
    }
}

如果一个人正在与这个页面交互,他们怎么知道什么时候可以安全地继续?当页面有一个巨大的加载程序和覆盖程序时,他们不会试图点击所有的输入。通常情况下,加载程序/覆盖程序速度很快,但有时会挂断几秒钟或其他时间,这就是我认为threadsleep和重新检查隐身性有帮助的地方,但我仍然得到一些误报。作为对DebanjanB回答的回应,我还应该注意到我有可选择的元素,以及位于所有按钮/发送键目标字段中的元素的可见性。当加载程序消失然后重新出现时,这仍然会被欺骗。我应该提到的是,我在所有按钮/发送键目标字段中都有elementtobelickable和elementvisibilityofelements。这仍然会被加载程序消失然后重新出现的那一刻所欺骗。终于有时间回到这一点上了。这无疑增加了一致性,因此感谢您的帮助。需要注意的一点是,这显著增加了运行时间,我想这只是我不得不接受的一种权衡。花一点时间比失败五次中的一次要好得多。再次感谢。它根本不会增加运行时间。它只等待条件为真,而不是完全等待时间。这就是WebDriverWait相对于Thread.Sleep的好处。
new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(By.xpath("xpath_of_element_to_interact']"))).sendKeys("Test");
public static void Loader()
{
    By loader = By.id("spinner");
    WebDriverWait wait = new WebDriverWait(driver, 10);
    while (true)
    {
        try
        {
            wait.until(ExpectedConditions.visibilityOfElementLocated(loader));
            wait.until(ExpectedConditions.invisibilityOfElementLocated(loader));
        }
        catch (Exception e)
        {
            break;
        }
    }
}