FluentWait不能正常工作:Youtube示例

时间:2016-12-11 10:01:17

标签: java selenium-webdriver safaridriver

所以我早些时候工作了但是我在我的代码中弄乱了一些东西,现在FluentWait方法似乎没有正常调用。如果我使用quickRun设置为false运行它,它按预期工作(因为隐含)但当我将其设置为true时它不会因为它不会等待元素正确加载。有谁知道我做错了什么?



package myPackage;

import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import com.google.common.base.Function;

//import com.gargoylesoftware.htmlunit.javascript.host.Console;
//https://www.codeproject.com/articles/143430/test-your-web-application-s-ui-with-junit-and-sele

//this will open a dynamic page example (ie. youtube) trending
public class youtubeTest {

  public boolean quickRun = false; //Disable for debugging otherwise full speed
  private static int defaultDebugDelay = 2; //Time in sec for next test to occur in debug 

  //do no change any of the below
  private String testUrl; //target url destination ie youtube
  private WebDriver driver; //webdriver instance to reference within class
  private int testIndex = 1; //initial index value for console outputting

  public WebElement fluentWait(final By locator) {
    Wait < WebDriver > wait = new FluentWait < WebDriver > (driver)
      .withTimeout(30, TimeUnit.SECONDS)
      .pollingEvery(1, TimeUnit.SECONDS)
      .ignoring(NoSuchElementException.class);

    WebElement foo = wait.until(new Function < WebDriver, WebElement > () {
      public WebElement apply(WebDriver driver) {
        return driver.findElement(locator);
      }
    });

    return foo;
  };

  @
  Before
  public void beforeTest() {
    driver = new SafariDriver();
    System.out.println("Setting up Test...");
    if (quickRun) {
      System.out.println("Test Type: Quick Run (Fastest Mode)");
    } else {
      System.out.println("Test Type: Slow Run (Debug Mode) - Each Test has a " + defaultDebugDelay + " sec call time buffer");
    }
    testUrl = "https://www.youtube.com";
    driver.get(testUrl);
    System.out.println("Setting Driver " + driver + "for url: " + testUrl);

  }

  @
  Test
  public void Test() {
    //insert unit tests within here
    //open yt nav menu
    locateClickableElement("#appbar-guide-button");
    //go to trending
    locateClickableElement("#trending-guide-item");
    //click on 4th Trending video from list
    //locateClickableElement(".expanded-shelf-content-item-wrapper", 3);
    locateClickableElement(".expanded-shelf-content-item-wrapper");


  }

  @
  After
  public void afterTest() throws Exception {
    //wait 10 sec before closing test indefinitely
    System.out.println("Test auto ending in 10 seconds...");
    Thread.sleep(10000);
    stopTest();
  }

  //individual unit tests
  private void locateClickableElement(String ExpectedElement, int child) {
    //format string into something like: "ELEMENT:nth-child(1)"
    String formattedString = ExpectedElement + ":nth-child(" + child + ")";
    System.out.println("Strung: " + formattedString);
    locateClickableElement(formattedString);
  }

  private void locateClickableElement(String ExpectedElement) {
    try {
      System.out.println("Test " + testIndex + ": locateClickableElement(" + ExpectedElement + ")");

      //do absolute delay for visual debugging
      if (!quickRun) Thread.sleep(2000);

      //click on target if found
      fluentWait(By.cssSelector(ExpectedElement)).click();
      System.out.println("Test " + testIndex + ": Successful Click on Element(" + ExpectedElement + ")");

    } catch (Exception e) {
      //whenever error is found output it and end program
      System.out.println("Error Could not locateClickableElement(" + ExpectedElement + ")");
      System.out.println("Exception Handled:" + e.getMessage());
      stopTest("error");
    }
    testIndex++;
  }

  private void stopTest() {
    System.out.println("Test Completed: Reached End.");
    driver.quit();
  }

  private void stopTest(String typeError) {
    System.out.println("Test Completed: With an Error.");
    driver.quit();
  }

}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

我会以不同的方式写这个并提供一些建议。

  1. 使用&#34;调试模式&#34;不要减慢测试速度。如果您想调试测试,请使用断点并逐步执行代码以查看它是如何工作的。

  2. 你在这里不需要FluentWait。使用WebDriverWait的简单ExpectedConditions.elementToBeClickable(locator)可以很好地工作,而且不那么复杂。如果你接受我的修改,你甚至不需要它。

  3. 不要使用String传递定位器,请使用预期的定位器类By。您不必解释它,翻译它等等,它会更快,更灵活。

  4. 除非您尝试测试用户界面(我假设您不为youtube工作),然后您可以使用顶部的趋势图链接导航至趋势页面这页纸。它可以节省您的时间和点击次数。如果您没有对其进行测试,请不要对其进行测试......尽可能快地到达目的地。您不希望您的测试失败,因为您没有尝试测试用户界面,并且您始终希望测试尽可能快。 (注意:您甚至可以直接导航到趋势网址。)

  5. 您不需要locateClickableElement()功能。只需点击链接......它应该是一个班轮。如果出现错误,那将是显而易见的。你不需要打印,&#34;出现了错误。&#34;打印出异常消息后。

  6. 您不需要stopTest()功能......只需停止测试即可。当浏览器关闭时,测试就很明显了。

  7. 重写的代码如下。它既美观又简单(而且简短),应该更快。

    public class youtubeTest
    {
        // do no change any of the below
        private String testUrl = "https://www.youtube.com"; // target url destination ie youtube
        private WebDriver driver; // webdriver instance to reference within class
    
        private By trendingGuideLinkLocator = By.cssSelector("#trending-guide-item");
        private By trendingLinkLocator = By.xpath("//h2[contains(.,'Trending')]");
    
        @Before
        public void beforeTest()
        {
            System.out.println("Setting up Test..."); // if you are going to have this statement, put it at the start of beforeTest()
            driver = new SafariDriver();
            driver.get(testUrl);
            System.out.println("Set Driver " + driver + "for url: " + testUrl);
        }
    
        @Test
        public void Test()
        {
            // insert unit tests within here
            driver.findElement(trendingLinkLocator).click(); // just click the Trending link, it's faster
            driver.findElements(trendingGuideLinkLocator).get(3).click();
        }
    
        @After
        public void afterTest()
        {
            driver.close();
            driver.quit();
        }
    }
    

    如果您不想更改所有这些内容,则问题的简单答案是将FluentWait替换为WebDriverWait

    fluentWait(By.cssSelector(ExpectedElement)).click();
    

    将被

    取代
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(trendingLinkLocator)).click();