0

所以我早些时候让它工作,但我在我的代码中搞砸了一些东西,现在 FluentWait 方法似乎没有正确调用。如果我使用quickRunset to 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();
  }

}

4

1 回答 1

0

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

  1. 不要使用“调试模式”减慢测试速度。如果要调试测试,请使用断点并单步执行代码以查看它是如何工作的。

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

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

  4. 除非您尝试测试 UI(我假设您不为 youtube 工作),否则您可以使用页面顶部的 Trending 链接导航到 Trending 页面。它将节省您的时间和点击次数。如果你不测试它,就不要测试它……尽可能快地到达你要去的地方。你不希望你的测试因为你没有尝试测试的 UI 而失败,你总是希望你的测试尽可能快地进行。(注意:您甚至可以直接导航到热门 URL。)

  5. 您不需要这些locateClickableElement()功能。只需单击链接...它应该是一个衬里。如果有错误,那将是显而易见的。您无需打印“出现错误”。打印异常消息后。

  6. 您不需要这些stopTest()功能......只需停止测试。当浏览器关闭时,很明显测试已经完成。

重写后的代码如下。它很好,很简单(而且很短),应该更快。

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();
    }
}

如果您不想更改这一切,您的问题的简单答案是替换FluentWaitWebDriverWait.

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

将被替换为

new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(trendingLinkLocator)).click();
于 2016-12-12T00:14:21.910 回答