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

问题描述 投票:0回答:1

我已经看到许多等待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", "/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/";
  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, 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"));
  //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);
  }
}
java selenium firefox
1个回答
0
投票

如果您使用可重用代码编写代码,那么它将更容易理解并且看起来并不难看。尝试使用小的可重用对象,然后结合使用它们来测试功能

© www.soinside.com 2019 - 2024. All rights reserved.