selenium没有点击链接,而在javascript上,链接被点击完美无缺

时间:2015-04-29 07:19:01

标签: javascript jquery selenium selenium-webdriver automation

我使用selenium webdriver来点击链接,但它会抛出NoSuchElementException。我正在使用xpath,当我在Inspect Element选项卡中的浏览器中执行搜索时找到所需的链接,当我在浏览器中执行以下javascript时 - 控制台,链接被优雅地点击,

Javascript代码:

var element = window.top.document.evaluate("//a[@id='clients']/i[@class='icon-chevron-down']" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;if (element != null) { element.click();  } else { alert('Not Found'); }

但不确定为什么selenium会抛出以下异常,我在点击之前尝试过各种明确的等待。

org.openqa.selenium.NoSuchElementException: no such element
  (Session info: chrome=42.0.2311.135)
  (Driver info: chromedriver=2.9.248307,platform=Mac OS X 10.9.5 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.05 seconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: 'unknown', revision: 'unknown', time: 'unknown'
System info: host: 'VDO105.local', ip: '172.16.0.70', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9.5', java.version: '1.7.0_75'
Session ID: b9f85e7103119d4c7b7ff265d02187ca
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={userDataDir=/var/folders/1v/pyj3pk396pb0z71_tlqcppgh0000gn/T/.org.chromium.Chromium.TePZ9p}, rotatable=false, locationContextEnabled=true, version=42.0.2311.135, takesHeapSnapshot=true, cssSelectorsEnabled=true, databaseEnabled=false, handlesAlerts=true, browserConnectionEnabled=false, webStorageEnabled=true, nativeEvents=true, applicationCacheEnabled=false, takesScreenshot=true}]

以下是链接的HTML代码:

<a ng-show="sideBar.length" class="dropdown-toggle toggle-active" id="clients" href="javascript:void(0);">
<i class="icon-group"></i>
<span class="menu-lv-1 ng-binding">Clients</span>
<i class="icon-chevron-down"></i>
</a>

1 个答案:

答案 0 :(得分:0)

当您的页面由javascripts填充时,通常会发生这种情况。当一个新页面出现后,selenium会在完成加载后收到。如果之后发生了变化,硒就不会有这些变化。

听起来这是你的问题。

为此我创建了特殊功能而不是selenium提供的功能。该类包含WebDriver实例。

public void click(final By by){
  act(by, 3, new Callable<Boolean>() {
     public Boolean call() {
       wait.until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOfElementLocated(by)));
       driver.findElement(by).click();
       logger.info("Button "+stripBy(by) + " clicked");
       return Boolean.TRUE; // FOUND IT
     }
  });}

function act是一个特殊的函数,用于重试元素上的speficyfied操作。

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);
        wait.until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOfElementLocated(by)));
        wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(by)));
        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));}