Selenium Web驱动程序-循环内等待(Java)

我已经看到许多等待Selenium Web驱动程序(特别是Java)的方法(such as this one)。但是,在此处应用这些方法似乎无效。

我试图通过遍历哈希表中的值来测试用户查询结果。我在下面的代码中尝试了两种方法:等待document.readyState和加载由类选择的项目。但是,似乎列表是全部创建的,没有留出时间完成元素刷新。

package newproject;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;

import org.openqa.selenium.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
//import org.openqa.selenium.chrome.ChromeDriver;

public class MyClass {
  public static void main(String[] args) {
  System.setProperty("webdriver.gecko.driver","/Users/niunani/Selenium/geckodriver");
  WebDriver driver = new FirefoxDriver();
  driver.manage().timeouts().implicitlyWait(15,TimeUnit.SECONDS);

  String baseUrl = "https://www.zillow.com/san-diego-ca-92109/";

  //get price button and click
  WebElement priceButton = driver.findElement(By.id("price"));
  priceText = priceButton.getText();
  System.out.println(priceText);
  //priceButton.click();

  Map<String,List<String>> priceTestCases = new HashMap<String,List<String>>();

  List<String> threeHundThouSet = new ArrayList<String>();
  threeHundThouSet.add("400000");
  threeHundThouSet.add("500000");
  threeHundThouSet.add("600000");
  threeHundThouSet.add("700000");
  threeHundThouSet.add("800000");
  threeHundThouSet.add("900000");
  threeHundThouSet.add("1000000");

  List<String> fourHundThouSet = new ArrayList<String>();
  fourHundThouSet.add("500000");
  fourHundThouSet.add("600000");
  fourHundThouSet.add("700000");
  fourHundThouSet.add("800000");
  fourHundThouSet.add("900000");
  fourHundThouSet.add("1000000");

  List<String> fiveHundThouSet = new ArrayList<String>();
  fiveHundThouSet.add("600000");
  fiveHundThouSet.add("700000");
  fiveHundThouSet.add("800000");
  fiveHundThouSet.add("900000");
  fiveHundThouSet.add("1000000");

  priceTestCases.put("300000",threeHundThouSet);
  priceTestCases.put("400000",fourHundThouSet);
  priceTestCases.put("500000",fiveHundThouSet);

  WebElement priceExposedMin = driver.findElement(By.id("price-exposed-min"));

  WebElement priceExposedMax = driver.findElement(By.id("price-exposed-max"));

  WebElement priceDoneButton = driver.findElement(By.xpath("/html/body/div[1]/div[6]/div/div[1]/div[1]/div[2]/div[2]/div/div/div/button"));

  priceButton.click();
  for (Map.Entry<String,List<String>> entry : priceTestCases.entryset()) {
      String key = entry.getKey();
      List<String> values = entry.getvalue();
      System.out.println("Key = " + key);
      System.out.println("Values = " + values + "n");
      //priceExposedMin.clear();
      for (int i=0;i<20;i++) {
          priceExposedMin.sendKeys(Keys.BACK_SPACE);
      }
      priceExposedMin.sendKeys(key);
      for (String maxPrice : values) {
          System.out.println(maxPrice);
          //priceExposedMax.clear();
          //wait.until(ExpectedConditions.elementToBeclickable(By.xpath("//*[@id=\"price-exposed-max\"]"))).clear();
          for (int i=0;i<20;i++) {
              priceExposedMax.sendKeys(Keys.BACK_SPACE);
          }
          priceExposedMax.sendKeys(maxPrice);
          priceDoneButton.click();

          //ONE WAY: wait for document.readyState
          new WebDriverWait(driver,30).until(
                  webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));

          //SECOND WAY: Wait for 30 sec until AJAX search load the content
          //new WebDriverWait(driver,30).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.classname("list-card-price")));

          Integer countWrong = 0;
          List<WebElement> returnPrices = driver.findElements(By.classname("list-card-price"));
          System.out.println(returnPrices);
          for (WebElement priceElement : returnPrices) {
              String priceString = priceElement.getText();
              priceString = priceString.replace("Est. $","");
              priceString = priceString.replace("$","");
              priceString = priceString.replace(",","");
              Integer price = Integer.parseInt(priceString);
              if (price > Integer.parseInt(maxPrice)) {
                  countWrong++;
                  System.out.println("Over price : " + Integer.toString(price));
              }
              System.out.println("This price : " + Integer.toString(price));

          }
          System.out.println("Incorrect query result: " + Integer.toString(countWrong)) ;
          priceButton.click();
      }
  }

  }
}

有时我会出现以下错误,实际上可能是元素更新时出现的错误。我正在寻找一种可以解决此问题的解决方案:

Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: The element reference of <div class="list-card-price"> is stale; either the element is no longer attached to the DOM,it is not in the current frame context,or the document has been refreshed
For documentation on this error,please visit: https://www.seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '3.141.59',revision: 'e82be7d358',time: '2018-11-14T08:25:48'
System info: host: 'Nhus-MacBook-Pro.local',ip: 'fe80:0:0:0:27:7d6f:961a:384a%en0',os.name: 'Mac OS X',os.arch: 'x86_64',os.version: '10.14',java.version: '1.8.0_221'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities {acceptInsecureCerts: true,browserName: firefox,browserVersion: 70.0.1,javascriptEnabled: true,moz:accessibilityChecks: false,moz:buildID: 20191030021342,moz:geckodriverVersion: 0.26.0,moz:headless: false,moz:processID: 9634,moz:profile: /var/folders/8c/whfw1mpd5tq...,moz:shutdownTimeout: 60000,moz:useNonSpecCompliantPointerOrigin: false,moz:webdriverClick: true,pageLoadStrategy: normal,platform: MAC,platformName: MAC,platformVersion: 18.0.0,rotatable: false,setWindowRect: true,strictFileInteractability: false,timeouts: {implicit: 0,pageLoad: 300000,script: 30000},unhandledPromptBehavior: dismiss and notify}
Session ID: b93bceb8-123a-b546-8743-5c402cd8b341
    at sun.reflect.NativeConstructoraccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructoraccessorImpl.newInstance(NativeConstructoraccessorImpl.java:62)
    at sun.reflect.DelegatingConstructoraccessorImpl.newInstance(DelegatingConstructoraccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
    at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:326)
    at org.openqa.selenium.support.ui.ExpectedConditions$8.apply(ExpectedConditions.java:233)
    at org.openqa.selenium.support.ui.ExpectedConditions$8.apply(ExpectedConditions.java:228)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:249)
    at newproject.MyClass.main(MyClass.java:110)

我当前的解决方法很丑陋,可能会使测试花费的时间太长:

package newproject;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;

import org.openqa.selenium.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
//import org.openqa.selenium.chrome.ChromeDriver;

public class MyClass {
  public static void main(String[] args) {
  System.setProperty("webdriver.gecko.driver",TimeUnit.SECONDS);

  String baseUrl = "https://www.zillow.com/san-diego-ca-92109/";
  String tagName = "";
  String titleText = "";
  String priceText = "";

  //search title
  driver.get(baseUrl);
  WebElement searchTitle = driver.findElement(By.classname("search-title"));
  tagName = searchTitle.getTagName();
  System.out.println(tagName);
  titleText = searchTitle.getText();
  System.out.println(titleText);

  //get price button and click
  WebElement priceButton = driver.findElement(By.id("price"));
  priceText = priceButton.getText();
  System.out.println(priceText);
  //priceButton.click();

  Map<String,fiveHundThouSet);

  WebElement priceExposedMin = driver.findElement(By.id("price-exposed-min"));
  //priceExposedMin.clear();
  //priceExposedMin.sendKeys("300000");

  WebElement priceExposedMax = driver.findElement(By.id("price-exposed-max"));
  //WebElement priceExposedMax = wait.until(
//        ExpectedConditions.visibilityOfElementLocated(By.id("price-exposed-max")));
  //WebElement priceExposedMax = new WebDriverWait(driver,10).until(ExpectedConditions.visibilityOfElementLocated(driver.findElement(By.id("price-exposed-max"))));
  //priceExposedMax.clear();
  //priceExposedMax.sendKeys("500000");

  WebElement priceDoneButton = driver.findElement(By.xpath("/html/body/div[1]/div[6]/div/div[1]/div[1]/div[2]/div[2]/div/div/div/button"));

  priceButton.click();
  for (Map.Entry<String,List<String>> entry : priceTestCases.entryset()) {
      String key = entry.getKey();
      List<String> values = entry.getvalue();
      System.out.println("Key = " + key);
      System.out.println("Values = " + values + "n");
      //priceExposedMin.clear();
      for (int i=0;i<20;i++) {
          priceExposedMin.sendKeys(Keys.BACK_SPACE);
      }
      priceExposedMin.sendKeys(key);
      for (String maxPrice : values) {
          System.out.println(maxPrice);
          //priceExposedMax.clear();
          //wait.until(ExpectedConditions.elementToBeclickable(By.xpath("//*[@id=\"price-exposed-max\"]"))).clear();
          for (int i=0;i<20;i++) {
              priceExposedMax.sendKeys(Keys.BACK_SPACE);
          }
          priceExposedMax.sendKeys(maxPrice);
          priceDoneButton.click();

          //wait for document.readyState
          //new WebDriverWait(driver,30).until(
            //      webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));

          //Wait for 30 sec until AJAX search load the content
          new WebDriverWait(driver,30).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.classname("list-card-price")));
          //new WebDriverWait(driver,30).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("ul > li.closed")));

          int timeToWait = 10; //second
          try {
              for (int i=0; i<timeToWait ; i++) {
                  Thread.sleep(2000);
              }
          } catch (InterruptedException ie)
          {
              Thread.currentThread().interrupt();
          }

          Integer countWrong = 0;

          boolean result = false;
          int attempts = 0;
          while (attempts < 2) {
              try {
                  List<WebElement> returnPrices = driver.findElements(By.classname("list-card-price"));
                  System.out.println(returnPrices);
                  for (WebElement priceElement : returnPrices) {
                      String priceString = priceElement.getText();
                      priceString = priceString.replace("Est. $","");
                      priceString = priceString.replace("$","");
                      priceString = priceString.replace(","");
                      Integer price = Integer.parseInt(priceString);
                      if (price > Integer.parseInt(maxPrice)) {
                          countWrong++;
                          System.out.println("Over price : " + Integer.toString(price));
                      }
                      System.out.println("This price : " + Integer.toString(price));

                  }
                  System.out.println("Incorrect query result: " + Integer.toString(countWrong)) ;
                  priceButton.click();
                  result = true;
                  break;
              } catch(StaleElementReferenceException e) {
              }
              attempts++;
          }

      }
  }

  //driver.close();
  //system.exit(0);
  }
}
zhtang0526 回答:Selenium Web驱动程序-循环内等待(Java)

如果您使用可重用代码编写代码,则将更易于理解且不难看。尝试使用小型可重用对象,然后将它们组合以测试功能

本文链接:https://www.f2er.com/3140795.html

大家都在问