Nightwatchjs: how to check if element exists without creating an error/failure/exception

本小妞迷上赌 提交于 2019-11-30 11:07:25

You can achieve this by using the Selenium protocol "element" and a callback function to check the result status to determine if the element was found. For example:

browser.element('css selector', '#advanced-search', function(result){
    if(result.status != -1){
        //Element exists, do something
    } else{
        //Element does not exist, do something else
    }
});
dwoodwardgb

You seem to be on the right track with isVisible. From the nightwatch documentation, we see that in the callback you can check the result.value property to see whether or not the element was visible, i.e:

browser.isVisible('#advanced-search', results => {
  if (results.value) { /* is visible */ }
  else { /* is not visible */ }
});

Alternatively, you could use the approach suggested by Saifur. Call the selenium api's .elements command and then check the result array's length:

browser.elements('css selector', '#advanced-search', results => {
  if (results.value.length > 0) { /* element exists */ }
  else { /* element does not exist */ }
});

This in fact could be wrapped into a custom command:

// isPresent.js
module.exports.command = function (selector, callback) {
  return this.elements('css selector', selector, results => {
    if (results.status !== 0) { // some error occurred, handle accordingly
    }

    callback(results.value.length > 0);
  });
};

then in normal code you could call it like this:

browser.isPresent('#advanced-search', advancedSearchPresent => {
  // make decisions here
}

If you are going to be making additional api calls in the callback, it may be wise to wrap it all in a .perform call:

browser.perform((_, done) => {
  browser.isPresent('#advanced-search', advancedSearchPresent => {

    // ...do more stuff...

    done();
  });
});

As to why the .perform is necessary, this might be helpful.

The syntax could be little off. Not very familiar with NightWatchJS. However the concept remains same.

//I would not wait for a element that should not exist
//rather I would find the list of the element and see if the count is greater than 0
//and if so, we know the element exists
browser.findElements(webdriver.By.css('#advanced-search')).then(function(elements){
    if(elements.length> 0){
        console.log(elements.length);
    }
});

See some more example here

My team uses a single function to authenticate with a few different signin forms, and we utilize a custom command called ifElementExists to accomplish the branching logic for understanding which form we're on. We also use this on a few other pages that don't have a better method for determining current state.

import { CustomCommandShorthand } from './customCommands';
import { isFunction } from 'lodash';

exports.command = function ifElementExists(this: CustomCommandShorthand, selector: string, ifTrue: Function, ifFalse?: Function) {
    this.perform(() => {
        if (!isFunction(ifTrue)) {
            throw new Error(`The second argument must be callable. You passed a ${typeof ifTrue} instead of a function.`);
        }

        this.element('css selector', selector, function ifElementExistsCallback({ status }) {
            if (status !== -1) {
                return ifTrue();
            }

            if (isFunction(ifFalse)) {
                ifFalse();
            }
        });
    })
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!