SlideShare ist ein Scribd-Unternehmen logo
1 von 76
Downloaden Sie, um offline zu lesen
Join The Darkside 
Selenium testing with Nightwatch.js 
presented by seth mclaughlin on 10.21.14
Nightwatch.js 
learn more: www.nightwatchjs.org
1. Project Overview 
2. Features 
3. Getting Started
"End to End" testing 
1. Navigate to Login page 
2. Locate username form field, type in seth 
3. Locate password form field, type in html5dev 
4. Locate submit form button and click it 
5. Wait for form submission to complete 
6. Verify that title of page is now equal to Welcome!
Selenium 
HTTP 
Test Runner WebDriver Web Browser 
JAVA JAR 
Test Script
Selenium 
HTTP 
Test Runner WebDriver Web Browser 
JAVA JAR 
Test Script
Selenium 
HTTP 
Node.js module 
Test Script 
Test Runner WebDriver Web Browser 
Node.js application JAVA JAR
Selenium 
WebDriver 
Selenium 
WebDriver 
Web 
HTTP 
Test Runner Browser 
JAVA JAR 
Test Script 
Selenium 
Grid 
Selenium 
WebDriver 
Web 
Browser 
JAVA JAR 
Selenium 
WebDriver 
Web 
Browser 
JAVA JAR 
Web 
Browser 
JAVA JAR
Features 
★ Good documentation 
★ Use CSS or XPATH selectors 
★ Test runner can execute sequentially or in parallel 
★ Test filtering by file name pattern, folders and tags 
★ SauceLabs + BrowserStack support 
★ Built in JUnit XML reporting 
★ Extension model for custom commands
created by 
Andrei Rusu 
@beatfactor 
learn more: www.linkedin.com/in/beatfactor
~9,000 
downloads per month 
~2,200 
stars on github 
~150 
forks on github 
~83% 
code coverage 
learn more: www.npmjs.org/package/nightwatch
contributors 
27 
1 
1 
46 
164 
primary contributor (Andrei) 
pending pull requests (from 8/14/14) 
open issues 
closed issues 
learn more: github.com/beatfactor/nightwatch
Sample test: Login flow 
1. Navigate to Login page 
2. Locate username form field, type in seth 
3. Locate password form field, type in html5dev 
4. Locate submit form button and click it 
5. Wait for form submission to complete 
6. Verify that title of page is now equal to Welcome!
├── Nightwatch.js 
└── tests 
└── login.js
├── Nightwatch.js 
└── tests 
└── login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client.url('http://localhost:8000'); 
client.assert.title('Awesome App'); 
client.setValue('input[name=username]', 'seth'); 
client.setValue('input[name=password]', 'html5dev'); 
client.click('input[type=submit]'); 
client.assert.title('Welcome!'); 
client.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client.url('http://localhost:8000'); 
client.assert.title('Awesome App'); 
client.setValue('input[name=username]', 'seth'); 
client.setValue('input[name=password]', 'html5dev'); 
client.click('input[type=submit]'); 
client.assert.title('Welcome!'); 
console.log('all done!'); // wrong! 
client.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client.url('http://localhost:8000'); 
client.assert.title('Awesome App'); 
client.setValue('input[name=username]', 'seth'); 
client.setValue('input[name=password]', 'html5dev'); 
client.click('input[type=submit]'); 
client.assert.title('Welcome!'); 
client.perform(function (client, done) { 
console.log('all done!'); // right! 
}); 
client.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client.url('http://localhost:8000'); 
client.assert.title('Awesome App'); 
client.setValue('input[name=username]', 'seth'); 
client.setValue('input[name=password]', 'html5dev'); 
client.click('input[type=submit]'); 
client.assert.title('Welcome!'); 
client.perform(function (client, done) { 
foo.doSomethingAsync().then(done); 
}); 
client.end(); 
} 
}; 
login.js
├── Nightwatch.js 
└── tests 
└── login.js
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
Nightwatch.js
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
Nightwatch.js
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
Nightwatch.js
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
Nightwatch.js
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
Nightwatch.js
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
path: './results/screenshots' 
}, 
desiredCapabilities: { 
browserName: 'firefox', 
javascriptEnabled: true, 
acceptSslCerts: true 
} 
} 
} 
}; 
Nightwatch.js
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
path: './results/screenshots' 
}, 
desiredCapabilities: { 
browserName: 'firefox', 
javascriptEnabled: true, 
acceptSslCerts: true 
} 
} 
} 
}; 
Nightwatch.js
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
path: './results/screenshots' 
}, 
desiredCapabilities: { 
browserName: 'firefox', 
javascriptEnabled: true, 
acceptSslCerts: true 
} 
} 
} 
}; 
Nightwatch.js
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
path: './results/screenshots' 
}, 
desiredCapabilities: { 
browserName: 'firefox', 
javascriptEnabled: true, 
acceptSslCerts: true 
} 
} 
} 
}; 
Nightwatch.js
> nightwatch -c ./Nightwatch.js --env default
[Login] Test Suite 
================== 
Running: Fill out form and login 
✔ Testing if the page title equals "Awesome App". 
✔ Testing if the page title equals "Welcome!". 
OK. 2 total assertions passed. (2.233s)
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
Y U HARDCODE 
VALUES ???
Data Driven Tests
├── Nightwatch.js 
├── data 
│ ├── dev.js 
│ └── staging.js 
└── tests 
└── login.js
module.exports = { 
username: 'seth', 
password: 'html5dev', 
urls: { 
login: 'http://localhost:8000' 
} 
}; 
data/dev.js
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
screenshots: { 
enabled: true, 
path: './results/screenshots' 
}, 
desiredCapabilities: { 
browserName: 'firefox', 
javascriptEnabled: true, 
acceptSslCerts: true 
}, 
globals: require('./data/dev') 
} 
} 
Nightwatch.js
module.exports = { 
'Fill out form and login': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password) 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password) 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password) 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form and login': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password) 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
} 
}; 
login.js
module.exports = { 
'Fill out form': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password); 
}, 
'Submit form': function (client) { 
var data = client.globals; 
client 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
}, 
}; 
login.js
module.exports = { 
'Fill out form': function (client) { 
var data = client.globals; 
client 
.url(data.urls.login) 
.assert.title('Awesome App') 
.setValue('input[name=username]', data.username) 
.setValue('input[name=password]', data.password); 
}, 
'Submit form': function (client) { 
console.log('previous step is done executing'); 
var data = client.globals; 
client 
.click('input[type=submit]') 
.assert.title('Welcome!') 
.end(); 
}, 
}; 
login.js
[Login] Test Suite 
=================== 
Running: Fill out form 
✔ Testing if the page title equals "Awesome App". 
OK. 1 assertions passed. (1.567s) 
Running: Submit form 
✔ Testing if the page title equals "Welcome!". 
OK. 1 assertions passed. (204ms)
Terminology 
Login Test suite 
Fill out form Test 
Submit form Test
Assert vs. Verify 
assert.title('Awesome App') If false, log failure 
and stop running current 
test suite 
verify.title('Awesome App') If false, log failure 
and continue running 
current test suite
Debugging tips 
pause() Pause test execution, leaving 
browser window open. 
client 
.url('http://localhost:8000') 
.assert.title('Awesome App') 
.setValue('input[name=username]', 'seth') 
.setValue('input[name=password]', 'html5dev') 
.pause() 
.click('input[type=submit]')
Debugging tips 
debugger; Insert breakpoint (in node.js code) 
> node debug `which nightwatch` 
-c ./Nightwatch.js --env default 
Commands: run (r), cont (c), next (n), step (s), out (o), backtrace (bt), 
setBreakpoint (sb), clearBreakpoint (cb), watch, unwatch, watchers, 
repl, restart, kill, list, scripts, breakOnException, breakpoints, version 
learn more: nodejs.org/api/debugger.html
Commands 
clearValue 
click 
deleteCookie 
deleteCookies 
end 
getAttribute 
getCookie 
getCookies 
getCssProperty 
getElementSize 
getLocation 
learn more: nightwatchjs.org/api 
getLocationInView 
getTagName 
getText 
getTitle 
getValue 
init 
injectScript 
isVisible 
maximizeWindow 
moveToElement 
pause 
resizeWindow 
saveScreenshot 
setCookie 
setValue 
submitForm 
switchWindow 
urlHash 
waitForElementNotPresent 
waitForElementNotVisible 
waitForElementPresent 
waitForElementVisible
Assertions 
attributeEquals 
containsText 
cssClassPresent 
cssClassNotPresent 
cssProperty 
elementPresent 
elementNotPresent 
learn more: nightwatchjs.org/api 
hidden 
title 
urlContains 
value 
valueContains 
visible
Using custom commands and assertions 
module.exports = { 
'Load Netflix.com': function (client) { 
client 
.url('http://www.netflix.com') 
.tagCount('a', function (result) { 
console.log( 
'NOTE: there are %s anchor elements on the pagen', 
result.value 
); 
}) 
.assert.tagCountGreaterThan('a', 100) 
.end(); 
} 
}; 
learn more: nightwatchjs.org/guide#custom-commands
Using custom commands and assertions 
module.exports = { 
'Load Netflix.com': function (client) { 
client 
.url('http://www.netflix.com') 
.tagCount('a', function (result) { 
console.log( 
'NOTE: there are %s anchor elements on the pagen', 
result.value 
); 
}) 
.assert.tagCountGreaterThan('a', 100) 
.end(); 
} 
}; 
learn more: nightwatchjs.org/guide#custom-commands
Using custom commands and assertions 
module.exports = { 
'Load Netflix.com': function (client) { 
client 
.url('http://www.netflix.com') 
.tagCount('a', function (result) { 
console.log( 
'NOTE: there are %s anchor elements on the pagen', 
result.value 
); 
}) 
.assert.tagCountGreaterThan('a', 100) 
.end(); 
} 
}; 
learn more: nightwatchjs.org/guide#custom-commands
Extending Nightwatch: custom commands 
// command to return the number of elements in a page 
// which are of a certain tag name 
exports.command = function (tagName, callback) { 
callback = callback || function () {}; 
this.execute(function (tagName) { 
return document.getElementsByTagName(tagName).length; 
}, [tagName], function (result) { 
callback.call(this, result); 
}); 
return this; // allows the command to be chained. 
}; 
learn more: nightwatchjs.org/guide#custom-commands
Extending Nightwatch: custom assertions 
var util = require('util'); 
exports.assertion = function(tagName, minCount, msg) { 
var defaultMessage = 'Testing if there are more than %s <%s> elements on the page'; 
var errorMessage = 'Error executing command'; 
// Set default message 
this.message = msg || util.format(defaultMessage, minCount, tagName); 
// The expected text 
this.expected = function () { 
return 'to find at least ' + (minCount+1) + ' ' + tagName + ' elements on page'; 
}; 
// returning true means assertion passed 
// returning false means assertion failed 
this.pass = function(value) { 
return (value > minCount); 
}; 
// returning true means element could not be found 
this.failure = function (result) { 
var failed = (result === false || (result && result.status === -1)); 
if (failed) { 
this.message = msg || errorMessage; 
} 
return failed; 
}; 
learn more: nightwatchjs.org/guide#custom-assertions 
// passed result of calling this.command() 
this.value = function (result) { 
return result.value;
module.exports = { 
src_folders: ['./tests'], 
output_folder: './results', 
custom_commands_path: './commands', 
custom_assertions_path: './assertions', 
selenium: { 
start_process: true, 
server_path: './selenium-server-standalone-2.38.0.jar', 
log_path: './results', 
host: '127.0.0.1', 
port: 4444 
}, 
test_settings: { 
default: { 
selenium_host: '127.0.0.1', 
selenium_port: 4444, 
Nightwatch.js
more to explore 
before and after test hooks! 
take screenshots! 
use sauce labs to run tests! 
use tags to organize test suites! 
learn more: www.nightwatchjs.org 
create custom commands! 
create custom assertions! 
contribute to nightwatch! 
...and more
Get started 
prerequisite: node.js 
1. Use npm to install nightwatch 
2. Download selenium-server-standalone.jar 
3. Create Nightwatch config file 
4. Create some tests
Closing thoughts 
Nightwatch.js is best selenium testing framework 
available to JavaScript developers 
Good community, actively supported 
Easy to get started, check it out
Resources 
documentation 
http://nightwatchjs.org/guide & http://nightwatchjs.org/api 
sample code 
https://github.com/sethmcl/join-the-dark-side 
nightwatch generator (quick start) 
https://github.com/sethmcl/generator-selenium-nightwatch 
nightwatch page object model 
https://github.com/beatfactor/nightwatch/issues/242

Weitere ähnliche Inhalte

Was ist angesagt?

Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015 Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015
Joe Ferguson
 

Was ist angesagt? (20)

Automated Web Testing using JavaScript
Automated Web Testing using JavaScriptAutomated Web Testing using JavaScript
Automated Web Testing using JavaScript
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
 
Fullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year laterFullstack End-to-end test automation with Node.js, one year later
Fullstack End-to-end test automation with Node.js, one year later
 
Front-end Automated Testing
Front-end Automated TestingFront-end Automated Testing
Front-end Automated Testing
 
Real World Selenium Testing
Real World Selenium TestingReal World Selenium Testing
Real World Selenium Testing
 
Unit-testing and E2E testing in JS
Unit-testing and E2E testing in JSUnit-testing and E2E testing in JS
Unit-testing and E2E testing in JS
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java side
 
Automate testing with behat, selenium, phantom js and nightwatch.js (5)
Automate testing with behat, selenium, phantom js and nightwatch.js (5)Automate testing with behat, selenium, phantom js and nightwatch.js (5)
Automate testing with behat, selenium, phantom js and nightwatch.js (5)
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
 
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
 
Building testable chrome extensions
Building testable chrome extensionsBuilding testable chrome extensions
Building testable chrome extensions
 
Automated Smoke Tests with Protractor
Automated Smoke Tests with ProtractorAutomated Smoke Tests with Protractor
Automated Smoke Tests with Protractor
 
AngularJS and Protractor
AngularJS and ProtractorAngularJS and Protractor
AngularJS and Protractor
 
Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015 Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015
 
Automation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and BeyondAutomation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and Beyond
 
An Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using ProtractorAn Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using Protractor
 
UI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected JourneyUI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected Journey
 
Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012
 
Angular UI Testing with Protractor
Angular UI Testing with ProtractorAngular UI Testing with Protractor
Angular UI Testing with Protractor
 

Andere mochten auch

Andere mochten auch (16)

Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)
 
Automation Testing using Selenium
Automation Testing using SeleniumAutomation Testing using Selenium
Automation Testing using Selenium
 
Selenium ppt
Selenium pptSelenium ppt
Selenium ppt
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907
 
Technical report writing
Technical report writingTechnical report writing
Technical report writing
 
The Number One Mistake Everybody Makes on Twitter
The Number One Mistake Everybody Makes on TwitterThe Number One Mistake Everybody Makes on Twitter
The Number One Mistake Everybody Makes on Twitter
 
113. ¿Cualquiera puede ser un tester?
113. ¿Cualquiera puede ser un tester?113. ¿Cualquiera puede ser un tester?
113. ¿Cualquiera puede ser un tester?
 
Severity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеSeverity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятное
 
Selenium Primer
Selenium PrimerSelenium Primer
Selenium Primer
 
La Importancia de las Certificaciones en TI
La Importancia de las Certificaciones en TILa Importancia de las Certificaciones en TI
La Importancia de las Certificaciones en TI
 
Capacitacitación Tester - QA 4
Capacitacitación Tester - QA 4Capacitacitación Tester - QA 4
Capacitacitación Tester - QA 4
 
Agile webinar pack (2)
Agile webinar pack (2)Agile webinar pack (2)
Agile webinar pack (2)
 
Usando Netbeans para desarrollos en PHP
Usando Netbeans para desarrollos en PHPUsando Netbeans para desarrollos en PHP
Usando Netbeans para desarrollos en PHP
 
Using chrome developer tools for QA'ing Optimizely
Using chrome developer tools for QA'ing Optimizely Using chrome developer tools for QA'ing Optimizely
Using chrome developer tools for QA'ing Optimizely
 
Desarrollo para Android con Groovy
Desarrollo para Android con GroovyDesarrollo para Android con Groovy
Desarrollo para Android con Groovy
 
Webdriver.io
Webdriver.io Webdriver.io
Webdriver.io
 

Ähnlich wie Join the darkside: Selenium testing with Nightwatch.js

Automated javascript unit testing
Automated javascript unit testingAutomated javascript unit testing
Automated javascript unit testing
ryan_chambers
 

Ähnlich wie Join the darkside: Selenium testing with Nightwatch.js (20)

DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.jsDrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
 
Webauthn Tutorial
Webauthn TutorialWebauthn Tutorial
Webauthn Tutorial
 
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQUA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesEWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
 
Automated javascript unit testing
Automated javascript unit testingAutomated javascript unit testing
Automated javascript unit testing
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-ons
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
Rapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirageRapid prototyping and easy testing with ember cli mirage
Rapid prototyping and easy testing with ember cli mirage
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
 
Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]
 
EWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5a: First Steps in Building a QEWD ApplicationEWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
 
Micro app-framework - NodeLive Boston
Micro app-framework - NodeLive BostonMicro app-framework - NodeLive Boston
Micro app-framework - NodeLive Boston
 
Micro app-framework
Micro app-frameworkMicro app-framework
Micro app-framework
 

Mehr von Seth McLaughlin (7)

Chapter 2: What's your type?
Chapter 2: What's your type?Chapter 2: What's your type?
Chapter 2: What's your type?
 
Chapter 1: Communicating with Your Computer
Chapter 1: Communicating with Your ComputerChapter 1: Communicating with Your Computer
Chapter 1: Communicating with Your Computer
 
Are we there yet?
Are we there yet?Are we there yet?
Are we there yet?
 
JavaScript State of Mind
JavaScript State of MindJavaScript State of Mind
JavaScript State of Mind
 
Get Moving! (with HTML5 canvas)
Get Moving! (with HTML5 canvas)Get Moving! (with HTML5 canvas)
Get Moving! (with HTML5 canvas)
 
Hello, Canvas.
Hello, Canvas.Hello, Canvas.
Hello, Canvas.
 
Introduction to Venus.js
Introduction to Venus.jsIntroduction to Venus.js
Introduction to Venus.js
 

Kürzlich hochgeladen

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Kürzlich hochgeladen (20)

%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 

Join the darkside: Selenium testing with Nightwatch.js

  • 1. Join The Darkside Selenium testing with Nightwatch.js presented by seth mclaughlin on 10.21.14
  • 2.
  • 3.
  • 4.
  • 5. Nightwatch.js learn more: www.nightwatchjs.org
  • 6. 1. Project Overview 2. Features 3. Getting Started
  • 7. "End to End" testing 1. Navigate to Login page 2. Locate username form field, type in seth 3. Locate password form field, type in html5dev 4. Locate submit form button and click it 5. Wait for form submission to complete 6. Verify that title of page is now equal to Welcome!
  • 8. Selenium HTTP Test Runner WebDriver Web Browser JAVA JAR Test Script
  • 9. Selenium HTTP Test Runner WebDriver Web Browser JAVA JAR Test Script
  • 10. Selenium HTTP Node.js module Test Script Test Runner WebDriver Web Browser Node.js application JAVA JAR
  • 11. Selenium WebDriver Selenium WebDriver Web HTTP Test Runner Browser JAVA JAR Test Script Selenium Grid Selenium WebDriver Web Browser JAVA JAR Selenium WebDriver Web Browser JAVA JAR Web Browser JAVA JAR
  • 12. Features ★ Good documentation ★ Use CSS or XPATH selectors ★ Test runner can execute sequentially or in parallel ★ Test filtering by file name pattern, folders and tags ★ SauceLabs + BrowserStack support ★ Built in JUnit XML reporting ★ Extension model for custom commands
  • 13. created by Andrei Rusu @beatfactor learn more: www.linkedin.com/in/beatfactor
  • 14. ~9,000 downloads per month ~2,200 stars on github ~150 forks on github ~83% code coverage learn more: www.npmjs.org/package/nightwatch
  • 15. contributors 27 1 1 46 164 primary contributor (Andrei) pending pull requests (from 8/14/14) open issues closed issues learn more: github.com/beatfactor/nightwatch
  • 16.
  • 17. Sample test: Login flow 1. Navigate to Login page 2. Locate username form field, type in seth 3. Locate password form field, type in html5dev 4. Locate submit form button and click it 5. Wait for form submission to complete 6. Verify that title of page is now equal to Welcome!
  • 18. ├── Nightwatch.js └── tests └── login.js
  • 19. ├── Nightwatch.js └── tests └── login.js
  • 20. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 21. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 22. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 23. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 24. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 25. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 26. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 27. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 28. module.exports = { 'Fill out form and login': function (client) { client.url('http://localhost:8000'); client.assert.title('Awesome App'); client.setValue('input[name=username]', 'seth'); client.setValue('input[name=password]', 'html5dev'); client.click('input[type=submit]'); client.assert.title('Welcome!'); client.end(); } }; login.js
  • 29. module.exports = { 'Fill out form and login': function (client) { client.url('http://localhost:8000'); client.assert.title('Awesome App'); client.setValue('input[name=username]', 'seth'); client.setValue('input[name=password]', 'html5dev'); client.click('input[type=submit]'); client.assert.title('Welcome!'); console.log('all done!'); // wrong! client.end(); } }; login.js
  • 30. module.exports = { 'Fill out form and login': function (client) { client.url('http://localhost:8000'); client.assert.title('Awesome App'); client.setValue('input[name=username]', 'seth'); client.setValue('input[name=password]', 'html5dev'); client.click('input[type=submit]'); client.assert.title('Welcome!'); client.perform(function (client, done) { console.log('all done!'); // right! }); client.end(); } }; login.js
  • 31. module.exports = { 'Fill out form and login': function (client) { client.url('http://localhost:8000'); client.assert.title('Awesome App'); client.setValue('input[name=username]', 'seth'); client.setValue('input[name=password]', 'html5dev'); client.click('input[type=submit]'); client.assert.title('Welcome!'); client.perform(function (client, done) { foo.doSomethingAsync().then(done); }); client.end(); } }; login.js
  • 32. ├── Nightwatch.js └── tests └── login.js
  • 33. module.exports = { src_folders: ['./tests'], output_folder: './results', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, Nightwatch.js
  • 34. module.exports = { src_folders: ['./tests'], output_folder: './results', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, Nightwatch.js
  • 35. module.exports = { src_folders: ['./tests'], output_folder: './results', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, Nightwatch.js
  • 36. module.exports = { src_folders: ['./tests'], output_folder: './results', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, Nightwatch.js
  • 37. module.exports = { src_folders: ['./tests'], output_folder: './results', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, Nightwatch.js
  • 38. port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, path: './results/screenshots' }, desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } }; Nightwatch.js
  • 39. port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, path: './results/screenshots' }, desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } }; Nightwatch.js
  • 40. port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, path: './results/screenshots' }, desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } }; Nightwatch.js
  • 41. port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, path: './results/screenshots' }, desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true } } } }; Nightwatch.js
  • 42. > nightwatch -c ./Nightwatch.js --env default
  • 43. [Login] Test Suite ================== Running: Fill out form and login ✔ Testing if the page title equals "Awesome App". ✔ Testing if the page title equals "Welcome!". OK. 2 total assertions passed. (2.233s)
  • 44. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 45. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 46. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 47. module.exports = { 'Fill out form and login': function (client) { client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 48. Y U HARDCODE VALUES ???
  • 50. ├── Nightwatch.js ├── data │ ├── dev.js │ └── staging.js └── tests └── login.js
  • 51. module.exports = { username: 'seth', password: 'html5dev', urls: { login: 'http://localhost:8000' } }; data/dev.js
  • 52. test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, screenshots: { enabled: true, path: './results/screenshots' }, desiredCapabilities: { browserName: 'firefox', javascriptEnabled: true, acceptSslCerts: true }, globals: require('./data/dev') } } Nightwatch.js
  • 53. module.exports = { 'Fill out form and login': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password) .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 54. module.exports = { 'Fill out form and login': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password) .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 55. module.exports = { 'Fill out form and login': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password) .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 56. module.exports = { 'Fill out form and login': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password) .click('input[type=submit]') .assert.title('Welcome!') .end(); } }; login.js
  • 57. module.exports = { 'Fill out form': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password); }, 'Submit form': function (client) { var data = client.globals; client .click('input[type=submit]') .assert.title('Welcome!') .end(); }, }; login.js
  • 58. module.exports = { 'Fill out form': function (client) { var data = client.globals; client .url(data.urls.login) .assert.title('Awesome App') .setValue('input[name=username]', data.username) .setValue('input[name=password]', data.password); }, 'Submit form': function (client) { console.log('previous step is done executing'); var data = client.globals; client .click('input[type=submit]') .assert.title('Welcome!') .end(); }, }; login.js
  • 59. [Login] Test Suite =================== Running: Fill out form ✔ Testing if the page title equals "Awesome App". OK. 1 assertions passed. (1.567s) Running: Submit form ✔ Testing if the page title equals "Welcome!". OK. 1 assertions passed. (204ms)
  • 60. Terminology Login Test suite Fill out form Test Submit form Test
  • 61. Assert vs. Verify assert.title('Awesome App') If false, log failure and stop running current test suite verify.title('Awesome App') If false, log failure and continue running current test suite
  • 62. Debugging tips pause() Pause test execution, leaving browser window open. client .url('http://localhost:8000') .assert.title('Awesome App') .setValue('input[name=username]', 'seth') .setValue('input[name=password]', 'html5dev') .pause() .click('input[type=submit]')
  • 63. Debugging tips debugger; Insert breakpoint (in node.js code) > node debug `which nightwatch` -c ./Nightwatch.js --env default Commands: run (r), cont (c), next (n), step (s), out (o), backtrace (bt), setBreakpoint (sb), clearBreakpoint (cb), watch, unwatch, watchers, repl, restart, kill, list, scripts, breakOnException, breakpoints, version learn more: nodejs.org/api/debugger.html
  • 64. Commands clearValue click deleteCookie deleteCookies end getAttribute getCookie getCookies getCssProperty getElementSize getLocation learn more: nightwatchjs.org/api getLocationInView getTagName getText getTitle getValue init injectScript isVisible maximizeWindow moveToElement pause resizeWindow saveScreenshot setCookie setValue submitForm switchWindow urlHash waitForElementNotPresent waitForElementNotVisible waitForElementPresent waitForElementVisible
  • 65. Assertions attributeEquals containsText cssClassPresent cssClassNotPresent cssProperty elementPresent elementNotPresent learn more: nightwatchjs.org/api hidden title urlContains value valueContains visible
  • 66. Using custom commands and assertions module.exports = { 'Load Netflix.com': function (client) { client .url('http://www.netflix.com') .tagCount('a', function (result) { console.log( 'NOTE: there are %s anchor elements on the pagen', result.value ); }) .assert.tagCountGreaterThan('a', 100) .end(); } }; learn more: nightwatchjs.org/guide#custom-commands
  • 67. Using custom commands and assertions module.exports = { 'Load Netflix.com': function (client) { client .url('http://www.netflix.com') .tagCount('a', function (result) { console.log( 'NOTE: there are %s anchor elements on the pagen', result.value ); }) .assert.tagCountGreaterThan('a', 100) .end(); } }; learn more: nightwatchjs.org/guide#custom-commands
  • 68. Using custom commands and assertions module.exports = { 'Load Netflix.com': function (client) { client .url('http://www.netflix.com') .tagCount('a', function (result) { console.log( 'NOTE: there are %s anchor elements on the pagen', result.value ); }) .assert.tagCountGreaterThan('a', 100) .end(); } }; learn more: nightwatchjs.org/guide#custom-commands
  • 69. Extending Nightwatch: custom commands // command to return the number of elements in a page // which are of a certain tag name exports.command = function (tagName, callback) { callback = callback || function () {}; this.execute(function (tagName) { return document.getElementsByTagName(tagName).length; }, [tagName], function (result) { callback.call(this, result); }); return this; // allows the command to be chained. }; learn more: nightwatchjs.org/guide#custom-commands
  • 70. Extending Nightwatch: custom assertions var util = require('util'); exports.assertion = function(tagName, minCount, msg) { var defaultMessage = 'Testing if there are more than %s <%s> elements on the page'; var errorMessage = 'Error executing command'; // Set default message this.message = msg || util.format(defaultMessage, minCount, tagName); // The expected text this.expected = function () { return 'to find at least ' + (minCount+1) + ' ' + tagName + ' elements on page'; }; // returning true means assertion passed // returning false means assertion failed this.pass = function(value) { return (value > minCount); }; // returning true means element could not be found this.failure = function (result) { var failed = (result === false || (result && result.status === -1)); if (failed) { this.message = msg || errorMessage; } return failed; }; learn more: nightwatchjs.org/guide#custom-assertions // passed result of calling this.command() this.value = function (result) { return result.value;
  • 71. module.exports = { src_folders: ['./tests'], output_folder: './results', custom_commands_path: './commands', custom_assertions_path: './assertions', selenium: { start_process: true, server_path: './selenium-server-standalone-2.38.0.jar', log_path: './results', host: '127.0.0.1', port: 4444 }, test_settings: { default: { selenium_host: '127.0.0.1', selenium_port: 4444, Nightwatch.js
  • 72. more to explore before and after test hooks! take screenshots! use sauce labs to run tests! use tags to organize test suites! learn more: www.nightwatchjs.org create custom commands! create custom assertions! contribute to nightwatch! ...and more
  • 73. Get started prerequisite: node.js 1. Use npm to install nightwatch 2. Download selenium-server-standalone.jar 3. Create Nightwatch config file 4. Create some tests
  • 74.
  • 75. Closing thoughts Nightwatch.js is best selenium testing framework available to JavaScript developers Good community, actively supported Easy to get started, check it out
  • 76. Resources documentation http://nightwatchjs.org/guide & http://nightwatchjs.org/api sample code https://github.com/sethmcl/join-the-dark-side nightwatch generator (quick start) https://github.com/sethmcl/generator-selenium-nightwatch nightwatch page object model https://github.com/beatfactor/nightwatch/issues/242