Unfortunately, nightwatch does not support promises or general asyncness very well. The blog post here summarises some of the pain points.
Fortunately, it is possible using a combination of browser.elements
and browser.perform
.
var assert = require('assert');
module.exports = {
'foobar': function (browser) {
var isTextFound = false;
browser
.url('http://localhost:3000')
.waitForElementVisible('body', 1000);
browser.elements('css selector', '.myclass', function (res) {
res.value.forEach(function (jsonWebElement) {
var jsonWebElementId = jsonWebElement.ELEMENT;
browser.elementIdText(jsonWebElementId, function (jsonElement) {
var text = jsonElement.value;
if (text.indexOf('text1') !== -1 && text.indexOf('second_text') !== -1) {
isTextFound = true;
}
});
});
});
browser.perform(function () {
assert.ok(isTextFound, 'Text found');
});
browser.end();
}
}
Let's go through some of the key points
require('assert')
This is required because nightwatch asserts only operate on DOM elements and hence you can not assert a boolean. This also means that the assertion will not show up on the report, however if it is false, it will throw an error and this will come up.
browser.perform(function(){...})
This puts the assertion onto the command queue so that the assertion will happen afterwards. If this was not there, the evaluation will happen immediately and the assert will fail.
browser.elements('css selector, '.myclass', function(res){...})
This is using the elements api. Please note that the api under the webdriver protocol section do not return web elements directly but return the Selenium representation of web elements (WebElement JSON objects) and hence we have to use special methods such as elementIdText
to get information out of them.