Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免硒中毒的最佳方法是什么?_Java_Selenium Webdriver_Selenium Grid_Nosuchelementexception - Fatal编程技术网

Java 避免硒中毒的最佳方法是什么?

Java 避免硒中毒的最佳方法是什么?,java,selenium-webdriver,selenium-grid,nosuchelementexception,Java,Selenium Webdriver,Selenium Grid,Nosuchelementexception,我使用Java在SeleniumWebDriver中编写了几个测试用例,并在网格(集线器和多个节点)上执行它们。我注意到有几个测试用例由于NoTouchElementException而失败。什么是避免NoTouchElementException并确保元素始终被找到的最佳和可靠的方法?您永远无法确定元素是否会被找到,实际上这是功能测试的目的-告诉您页面上是否有任何更改。但有一件事绝对有帮助,那就是添加对元素的等待,这些元素通常会导致NoTouchElementExceptionlike Web

我使用Java在SeleniumWebDriver中编写了几个测试用例,并在网格(集线器和多个节点)上执行它们。我注意到有几个测试用例由于
NoTouchElementException
而失败。什么是避免NoTouchElementException并确保元素始终被找到的最佳和可靠的方法?

您永远无法确定元素是否会被找到,实际上这是功能测试的目的-告诉您页面上是否有任何更改。但有一件事绝对有帮助,那就是添加对元素的等待,这些元素通常会导致
NoTouchElementException
like

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
WebDriverWait wait=new-WebDriverWait(webDriver,timeoutingseconds);
等待.直到(预期条件.元素的可视性(通过.id));

您也可以使用
FluentWait

每个
FluentWait
实例定义等待条件的最长时间,以及检查条件的频率

此外,用户可以将等待配置为在等待时忽略特定类型的异常,例如当搜索页面上的元素时,
NoSuchElementExceptions

// Waiting 30 seconds for an element to be present on the page, checking
   // for its presence once every 5 seconds.
   Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

   WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.id("foo"));
     }
   });
//等待30秒,让元素出现在页面上,检查
//每5秒检查一次。
等待等待=新建FluentWait(驱动程序)
.带超时(30秒)
.每(5秒)轮询一次
.忽略(NoSuchElementException.class);
WebElement foo=wait.until(新函数(){
公共WebElement应用(WebDriver){
返回驱动程序findElement(By.id(“foo”);
}
});

我完全同意上面提到的彼得·门西克(Petr Mensik)。这件事你永远不能说元素是否存在。 你应该清楚地理解为什么会发生这种情况。根据我的经验,我应该说这是由于以下原因造成的:

  • 1) 页面仍在呈现中,您已经完成了 元素搜索并获取无元素异常
  • 2) 第二个原因是AJAX尚未返回,而您已经返回了 获取
    NoTouchElementException
  • 3) 第三点最明显:元素实际上不在页面上 无论何时
因此,使用一个函数调用处理所有这三种情况的最健壮的IMHO方法是使用Amith003建议的
fluentWait

因此,代码如下所示:

让ur元素具有定位器:

String elLocXpath= "..blablabla";
WebElement myButton= fluentWait(By.xpath(elLocXpath));
myButton.click();

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

                .pollingEvery(5, TimeUnit.SECONDS)

        .ignoring(org.openqa.selenium.NoSuchElementException.class);
        WebElement foo = wait.until(
                new Function<WebDriver, WebElement>() {
                    public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                    }
                }
        );
        return  foo;
    };
这也很有用

因此,如果您想避免
NoElement
异常,那么要总结所有提到的内容,只需正确处理它,因为没有人能够确保页面上存在元素

// Waiting 30 seconds for an element to be present on the page, checking
   // for its presence once every 5 seconds.
   Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

   WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.id("foo"));
     }
   });
希望你现在更清楚。关于

WebDriverWait wait=new WebDriverWait(webDriver,timeoutines);
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
wait.until(ExpectedConditions.elementtobelickable(By.id));
元素可选择等待元素的启用可见

公共WebElement fluientWaitforElement(WebElement元素、int-timoutSec、int-pollingSec){
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {

    FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
    .pollingEvery(pollingSec, TimeUnit.SECONDS)
    .ignoring(NoSuchElementException.class, TimeoutException.class);

    for (int i = 0; i < 2; i++) {
        try {
            //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']")));
            fWait.until(ExpectedConditions.visibilityOf(element));
            fWait.until(ExpectedConditions.elementToBeClickable(element));
        } 
        catch (Exception e) {

            System.out.println("Element Not found trying again - " + element.toString().substring(70));
            e.printStackTrace();
        }
    }

    return element;
}
FluentWait fWait=新的FluentWait(驱动程序)。带超时(timoutSec,TimeUnit.SECONDS) .pollingEvery(pollingSec,时间单位为秒) .忽略(NoSuchElementException.class、TimeoutException.class); 对于(int i=0;i<2;i++){ 试一试{ //fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(“/*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data original--title='我们正在处理数以万亿计的数据事件,完成此洞察可能需要15分钟以上。'); 等待至(元素的预期条件可见度); 等待至(预期条件。元素可禁用(元素)); } 捕获(例外e){ System.out.println(“再次尝试时未找到元素-”+Element.toString().substring(70)); e、 printStackTrace(); } } 返回元素; }
我通常在主函数中使用这一行

public static void main(String[] args) throws ParseException {
    driver= new ChromeDriver();
    driver.manage().window().maximize();
    **driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);**

希望这有帮助。

我们可以应用以下代码来删除此异常情况

  • 通过应用WebDriverWait,webdriver对象将等待元素的特定时间(以秒为单位)以获取其可见性

          WebDriverWait wait = new WebDriverWait(driver, 10);       
           wait.until(ExpectedConditions.visibilityOf(link));
    
  • 我们可以通过泛型方法中的try-catch块来处理NoTouchElementException

     public boolean isElementPresent(By by) {
     boolean isPresent = true;
     try {
     driver.findElement(by);
     } catch (NoSuchElementException e) {
      isPresent = false;
     }
    return isPresent
    }
    

  • 有时可以等待所需项目的下载

    driver.get("https://zzzzzzzzz.market/items/mirage_prime_set")
    
    WebDriverWait(driver, 20)
           .until(
            EC.visibility_of_element_located(
              (By.XPATH, ('//div[@class="orders-row__element order__price sell_color"]')
            )))
    
    有时,您需要执行一些操作,以便UI框架加载数据。例如滚动页面

    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    
    然后得到必要的数据

    responsetext=driver.page_source
    
    from lxml import html
    parsed_body = html.fromstring(responsetext)
    
    obj1 = parsed_body.xpath('.//div[@class="orders-row__element order__price sell_color"]/span[1]')
    print(len(obj1))
    

    当定位器(即id/xpath/css选择器)无法在网页上找到web元素时,会发生NoTouchElementException

    原因可能是:

  • 不正确的定位器

  • Web元素在网页上不可用

    为了避免这种异常,我们可以使用Fluent Wait。此等待允许我们定义最大超时、轮询频率,并定义要忽略的异常

  • 请在下面找到Fluent wait的示例用法:

    .withTimeout(50, TimeUnit.SECONDS)
    .pollingevery(3, TimeUnit.SECONDS)
    .ignoring(NoSuchElementException.class);
    

    这当然是有帮助的。我们可以有一个通用的等待条件,这样我们就不需要检查要使用哪个ExpectedConditions条件了吗?还可以访问
    Webdriver API提供的
    隐式
    等待,但这只是设置了一个任意的“不做”周期,与
    睡眠
    非常相似,为了可靠性和速度,鼓励使用
    显式等待
    。这实际上是我在所有代码示例中看到的最干净、最简单的代码。谢谢这当然是有帮助的。但是我们可以有一个通用的应用方法。。。i、 例如,它等待页面完全加载,然后找到元素,如果找不到元素,则刷新页面,直到fluentwait超时。你可以尝试将“显式等待由try-and-catch包围”与fluent-wait结合起来..尝试{“使用显式等待”}catch(除