最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Check if an element exists with Selenium, JavaScript, and Node.js - Stack Overflow

programmeradmin9浏览0评论

I'm trying to check if an element exists before I can execute this line:

driver.findElement(webdriver.By.id('test'));

This throws an error "no such element" if the id test doesn't exist in the document, even in a try-block. I've found answers for Java, where you can check if the size is 0, but in Node.js this throws an error before I can check the size:

throw error; ^ NoSuchElementError: no such element

I'm trying to check if an element exists before I can execute this line:

driver.findElement(webdriver.By.id('test'));

This throws an error "no such element" if the id test doesn't exist in the document, even in a try-block. I've found answers for Java, where you can check if the size is 0, but in Node.js this throws an error before I can check the size:

throw error; ^ NoSuchElementError: no such element

Share Improve this question edited Nov 19, 2022 at 1:26 Peter Mortensen 31.6k22 gold badges109 silver badges133 bronze badges asked Nov 22, 2013 at 15:45 F. RakesF. Rakes 1,5373 gold badges17 silver badges25 bronze badges 7
  • Can't you just use this : if(webdriver.By.id('test')){ driver.findElement(webdriver.By.id('test')); }. – JeffreyZ Commented Nov 22, 2013 at 15:48
  • findElements() and size() – epascarello Commented Nov 22, 2013 at 15:48
  • @user2389688 webdriver.by.id("anything") seems to always result in true. – F. Rakes Commented Nov 22, 2013 at 16:07
  • @epascarello TypeError: Object [object Object] has no method 'size' – F. Rakes Commented Nov 22, 2013 at 16:07
  • ah, size() would be the Java version. Maybe swap size with .length and see if that works. I only played with the node version a little. Would something like this work driver.findElements(By.id('XXX')).then(function(elements) { var count = elements.length; }); – epascarello Commented Nov 22, 2013 at 16:17
 |  Show 2 more comments

8 Answers 8

Reset to default 32

You can leverage the optional error handler argument of then().

driver.findElement(webdriver.By.id('test')).then(function(webElement) {
        console.log('Element exists');
    }, function(err) {
        if (err.state && err.state === 'no such element') {
            console.log('Element not found');
        } else {
            webdriver.promise.rejected(err);
        }
    });

I couldn't find it explicitly stated in the documentation, but determined this from the function definition in webdriver/promise.js in the selenium-webdriver module source:

  /**
   * Registers a callback on this Deferred.
   * @param {Function=} opt_callback The callback.
   * @param {Function=} opt_errback The errback.
   * @return {!webdriver.promise.Promise} A new promise representing the result
   *     of the callback.
   * @see webdriver.promise.Promise#then
   */
  function then(opt_callback, opt_errback) { 

Just use the isElementPresent(locatorOrElement) method. Here's a link to the code:

http://selenium.googlecode.com/git/docs/api/javascript/source/lib/webdriver/webdriver.js.src.html#l777

Aaron Silverman's answer did not work as expected (err.state was undefined and a NoSuchElementError was always thrown)—though the concept of using the optional callbacks still works.

Since I was getting the same error as the OP is referencing, I believe NoSuchElementError should be referenced when determining if the targeted element exists or not. As its name implies, it is the error that is thrown when an element does not exist. So the condition in the errorCallback should be:

err instanceof webdriver.error.NoSuchElementError

So the complete code block would be as follows (I also am using async/await for those taking advantage of that syntax):

var existed = await driver.findElement(webdriver.By.id('test')).then(function() {
    return true; // It existed
}, function(err) {
    if (err instanceof webdriver.error.NoSuchElementError) {
        return false; // It was not found
    } else {
        webdriver.promise.rejected(err);
    }
});
// Handle value of existed appropriately here

Aaron Silverman's answer did not work for me fully, though some parts of it were helpful. Arthur Weborg's answer worked for me, though some parts caused issues.

My typical use case for "checking if element exists" is when I want to click the element, only if it exists, since if it doesn't exist, it crashes the program due to the error. All I want is for the application to note that it doesn't exist, and move on. So what I do is:

await driver.findElement(By.id("test")).then(found => {
  driver.findElement(By.id("test")).click()
}, error => {
  if (error instanceof webdriver.error.NoSuchElementError) {
    console.log('Element not found.');
  }
});

Just a simple console log, and it moves on with the rest of the program like I wanted.

Here the summary for newbies like me ;-)

As described here:

For consistency with the other Selenium language bindings, WebDriver#isElementPresent() and WebElement#isElementPresent() have been deprecated. These methods will be removed in v3.0. Use the findElements command to test for the presence of an element:

  driver.findElements(By.css('.foo')).then(found => !!found.length);

There are 2 possible cases for this answer:

  1. Case 1: Using promises
  2. Case 2: Using async / await

Case 1 using promises, then() and the error callback is already well explained in the accepted answer.

In Case 2, if you're in an async function (and therefore likely to be using await statements), then you have the pleasure of avoiding all the nasty chaining of then()'s and callbacks.

发布评论

评论列表(0)

  1. 暂无评论