Page Objects are similar to Custom Commands; except they are collections of custom commands that are associated with a specific UI component. This works extremely well with modern component based design, such as in React.
module.exports = {
url: 'http://localhost:3000/login',
commands: [{
login: function(email, password) {
return this
.clearValue('input[name="emailAddress"]')
.clearValue('input[name="password"]')
.setValue('input[name="emailAddress"]', email)
.setValue('input[name="password"]', password)
.verify.elementPresent('#loginButton')
.click("#loginButton");
},
clear: function() {
return this
.waitForElementVisible('@emailInput')
.clearValue('@emailInput')
.clearValue('@passInput')
.waitForElementVisible('@loginButton')
.click('@loginButton')
},
checkElementsRendered: function(){
return this
.verify.elementPresent("#loginPage")
.verify.elementPresent('input[name="emailAddress"]')
.verify.elementPresent('input[name="password"]')
},
pause: function(time, client) {
client.pause(time);
return this;
},
saveScreenshot: function(path, client){
client.saveScreenshot(path);
return this;
}
}],
elements: {
emailInput: {
selector: 'input[name=email]'
},
passInput: {
selector: 'input[name=password]'
},
loginButton: {
selector: 'button[type=submit]'
}
}
};
The only caveat with using the PageObject pattern in testing components, is that the implementation breaks the method chaining flow that the native Nightwatch verify.elementPresent
provides. Instead, you'll need to assign the page object to a variable, and instantiate a new method chain for each page. A reasonable price to pay for a consistent and reliable pattern for testing code reuse.
module.exports = {
tags: ['accounts', 'passwords', 'users', 'entry'],
'User can sign up.': function (client) {
const signupPage = client.page.signupPage();
const indexPage = client.page.indexPage();
client.page.signupPage()
.navigate()
.checkElementsRendered()
.signup('Alice', 'Doe', '[email protected]', 'alicedoe')
.pause(1500, client);
indexPage.expect.element('#indexPage').to.be.present;
indexPage.expect.element('#authenticatedUsername').text.to.contain('Alice Doe');
},
}