SlideShare une entreprise Scribd logo
1  sur  76
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Automated Web Testing using JavaScript
Automated Web Testing using JavaScriptAutomated Web Testing using JavaScript
Automated Web Testing using JavaScriptSimon Guest
 
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 2015Codemotion
 
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 laterMek Srunyu Stittri
 
Front-end Automated Testing
Front-end Automated TestingFront-end Automated Testing
Front-end Automated TestingRuben Teijeiro
 
Real World Selenium Testing
Real World Selenium TestingReal World Selenium Testing
Real World Selenium TestingMary Jo Sminkey
 
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 JSMichael Haberman
 
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 sideMek Srunyu Stittri
 
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)Faichi Solutions
 
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.jsMek Srunyu Stittri
 
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)Cogapp
 
Building testable chrome extensions
Building testable chrome extensionsBuilding testable chrome extensions
Building testable chrome extensionsSeth McLaughlin
 
Automated Smoke Tests with Protractor
Automated Smoke Tests with ProtractorAutomated Smoke Tests with Protractor
Automated Smoke Tests with Protractor🌱 Dale Spoonemore
 
AngularJS and Protractor
AngularJS and ProtractorAngularJS and Protractor
AngularJS and ProtractorFilipe Falcão
 
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
 
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 BeyondAlan Richardson
 
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 ProtractorCubet Techno Labs
 
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 JourneyOren Farhi
 
Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Efficient JavaScript Unit Testing, May 2012
Efficient JavaScript Unit Testing, May 2012Hazem Saleh
 
Angular UI Testing with Protractor
Angular UI Testing with ProtractorAngular UI Testing with Protractor
Angular UI Testing with ProtractorAndrew Eisenberg
 

Tendances (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
 

En vedette

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)Deutsche Post
 
Automation Testing using Selenium
Automation Testing using SeleniumAutomation Testing using Selenium
Automation Testing using SeleniumNaresh Chintalcheru
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907NodejsFoundation
 
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 TwitterGary Vaynerchuk
 
113. ¿Cualquiera puede ser un tester?
113. ¿Cualquiera puede ser un tester?113. ¿Cualquiera puede ser un tester?
113. ¿Cualquiera puede ser un tester?GeneXus
 
Severity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеSeverity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеDeutsche Post
 
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 TISoftware Guru
 
Usando Netbeans para desarrollos en PHP
Usando Netbeans para desarrollos en PHPUsando Netbeans para desarrollos en PHP
Usando Netbeans para desarrollos en PHPDKR Visión SRL
 
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 Optimizely
 
Desarrollo para Android con Groovy
Desarrollo para Android con GroovyDesarrollo para Android con Groovy
Desarrollo para Android con GroovySoftware Guru
 

En vedette (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
 

Similaire à Join the darkside: Selenium testing with Nightwatch.js

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.jsVladimir Roudakov
 
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 BBQMichelangelo van Dam
 
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 2013Michelangelo van Dam
 
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 ServicesRob Tweed
 
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 AppsMike Subelsky
 
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)Yevgeniy Brikman
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unitsitecrafting
 
Automated javascript unit testing
Automated javascript unit testingAutomated javascript unit testing
Automated javascript unit testingryan_chambers
 
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 2013Michelangelo van Dam
 
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...Rob Tweed
 
Workshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsWorkshop: Building Vaadin add-ons
Workshop: Building Vaadin add-onsSami Ekblad
 
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 mirageKrzysztof Bialek
 
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 2013Michelangelo van Dam
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress DevelopmentAdam Tomat
 
Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]JavaScript Meetup HCMC
 
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 ApplicationRob Tweed
 
Micro app-framework - NodeLive Boston
Micro app-framework - NodeLive BostonMicro app-framework - NodeLive Boston
Micro app-framework - NodeLive BostonMichael Dawson
 

Similaire à 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
 

Plus de Seth McLaughlin

Chapter 2: What's your type?
Chapter 2: What's your type?Chapter 2: What's your type?
Chapter 2: What's your type?Seth McLaughlin
 
Chapter 1: Communicating with Your Computer
Chapter 1: Communicating with Your ComputerChapter 1: Communicating with Your Computer
Chapter 1: Communicating with Your ComputerSeth McLaughlin
 
JavaScript State of Mind
JavaScript State of MindJavaScript State of Mind
JavaScript State of MindSeth McLaughlin
 
Get Moving! (with HTML5 canvas)
Get Moving! (with HTML5 canvas)Get Moving! (with HTML5 canvas)
Get Moving! (with HTML5 canvas)Seth McLaughlin
 
Introduction to Venus.js
Introduction to Venus.jsIntroduction to Venus.js
Introduction to Venus.jsSeth McLaughlin
 

Plus de 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
 

Dernier

Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
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 GoalsJhone kinadey
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 

Dernier (20)

Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
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
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
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
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

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