【问题标题】:Selenium - unable to find element- during second time硒 - 第二次找不到元素
【发布时间】:2015-04-29 02:32:41
【问题描述】:

我正在尝试寻找这样的元素 -

Select servTypeDA = new Select (driver.findElement(By.xpath("//select[@id='ServicesType']")));
servTypeDA.selectByVisibleText(servTypeData);

当我加载此页面时,这是第一次完美运行。 我正在尝试做一个工作流,所以当这个页面在几个步骤后加载时,对于同一行它会抛出错误 -

org.openqa.selenium.NoSuchElementException: 无法定位元素

但我能够在屏幕上看到该元素,并且它可见但仍无法通过代码访问。 我试图添加等待时间,仍然抛出错误。 为什么第二次无法访问相同的元素?

【问题讨论】:

    标签: selenium xpath selenium-webdriver nosuchelementexception


    【解决方案1】:

    webdriver 无法在 DOM 中找到元素时抛出NoSuchElement。造成这种情况的主要原因可能是您过早地搜索该元素。我建议使用一些显式等待并定期检查元素。

    By byXpath = By.xpath("//select[@id='ServicesType']");
    WebElement element  = new WebDriverWait(driver,10).until(ExpectedConditions.visibilityOfElementLocated(byXpath));
    Select servTypeDA = new Select(element); 
    servTypeDA.selectByVisibleText(servTypeData);
    

    【讨论】:

      【解决方案2】:

      或者你可以设置implicitlyWait,默认为0。 通过设置这个,Webdriver 将在抛出 NoSuchElementException 之前等待给定的时间

      driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
      

      这将节省您几乎在每个元素之前添加 webdriverWait 的工作。

      【讨论】:

        【解决方案3】:

        webdriver 的工作方式是每个页面加载它都会复制页面。所以显示的内容不一定是 webdriver 实例中加载的内容。例如,如果您通过 JavaScript 更改网页,webdriver 将不会察觉。

        这些通常是原因

        NoSuchElementException

        StaleElementReferenceException

        我发现解决这个问题的唯一方法是捕获异常并重试。我必须为每种类型的动作创建一个新函数。我将向您展示我的“selectByVisibleText”示例

        public void selectByLabel(final By by, final String label){
        act(by, 3, new Callable<Boolean>() {
          public Boolean call() {
            logger.trace("Trying to select label: "+label+" in select box "+stripBy(by) );
        
            Boolean found = Boolean.FALSE;
            int attempts = 0;
        
            wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(by)));
        
            Select select = new Select(driver.findElement(by));
            select.selectByVisibleText(label);   
        
            if(isLabelSelected(by,label)){
              found = Boolean.TRUE; // FOUND IT
              logger.info("Selected value "+label+" in select box "+stripBy(by));
            }
        
            return found;
          }
        });
        

        }

        它会重试几次。

        我所有的特殊操作实现都使用一个函数来捕获异常

        private void act(By by, int tryLimit, boolean mode, Callable<Boolean> method){
        logger.trace( "Looking for element: " + stripBy(by) );
        driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
        boolean unfound = true;
        int tries = 0;
        while ( unfound && tries < tryLimit ) {
          tries += 1;
          try {
        
            WebDriverWait wait = new WebDriverWait(driver, 500);
            unfound = !method.call(); // FOUND IT, this is negated since it feel more intuitive if the call method returns true for success
          } catch ( StaleElementReferenceException ser ) {
            logger.error( "ERROR: Stale element exception. " + stripBy(by) );
            unfound = true;
          } catch ( NoSuchElementException nse ) {
            logger.error( "ERROR: No such element exception. " + stripBy(by)+"\nError: "+nse );
            unfound = true;
          } catch ( Exception e ) {
            logger.error( e.getMessage() );
          }
        }
        
        driver.manage().timeouts().implicitlyWait( Constants.DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );
        
        if(unfound)
          Assert.assertTrue(false,"Failed to locate element by locator " + stripBy(by));
        

        }

        【讨论】:

          猜你喜欢
          • 2021-08-17
          • 2020-08-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多