PayPal's NemoJS and Applitools Eyes - Visual Testing with Node.js
-
Upload
applitools -
Category
Software
-
view
1.031 -
download
2
Transcript of PayPal's NemoJS and Applitools Eyes - Visual Testing with Node.js
NemoJS'and'Applitools'EyesVisual'Tes*ng'with'node.js
Where%does%Nemo%fit?
A"basic"JavaScript"selenium3webdriver"script:
var webdriver = require('selenium-webdriver'), SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
var server = new SeleniumServer(pathToSeleniumJar, { port: 4444});
server.start();
var driver = new webdriver.Builder(). usingServer(server.address()). withCapabilities(webdriver.Capabilities.firefox()). build();
driver.get('https://www.paypal.com');
The$same$script$using$Nemo
var Nemo = require('nemo');var nemo = Nemo(function () { nemo.driver.get('https://www.paypal.com');});
What%does%Nemo%do?• provides*environment.aware*JSON*configura9on
• provides*plugin'API
• provides*access*to*the*webdriver*API
The$webdriver$API
exposed'as'nemo.driver'and'nemo.wd
Environment*aware*configura1on
• config.json"is"the"defaults"file
• add"overrides"based"on"NODE_ENV
• e.g."NODE_ENV=local"looks"for"local.json
Configura)on*protocols• shortstop(handlers
• env:foo
• path:foo
• argv:foo
• config:foo.bar
config.json
{ "plugins": { "view": { "module": "nemo-view" }, "util": { "module": "path:plugin/util" } }, "driver": { "browser": "chrome" }}
Nemo%code%pa*erns
Using&nemo*viewit('should execute high level functionality using flow modules', function (done) {
//login nemo.driver.get(nemo.data.baseUrl); util.waitForJSReady(nemo); nemo.view.login.emailWaitVisible().sendKeys('[email protected]'); nemo.view.login.password().sendKeys('11111111'); nemo.view.login.button().click();
//add card success nemo.view.card.numberWaitVisible().sendKeys('123456789012'); nemo.view.card.typeOptionText('Misa'); nemo.view.card.button().click(); nemo.view.card.successWait();
//add card fail nemo.view.card.number().clear(); nemo.view.card.number().sendKeys('1001001'); nemo.view.card.typeOptionText('Misa'); nemo.view.card.button().click(); nemo.view.card.failureWait(); ...
DRY$pa'ern$(card$module)var Card = function (nemo) { this.nemo = nemo;};
var _enterForm = function (nemo, number, type) { nemo.view.card.numberWaitVisible().clear(); nemo.view.card.number().sendKeys(number); nemo.view.card.typeOptionText(type); return nemo.view.card.button().click();}Card.prototype.addSuccess = function(number, type) { _enterForm(this.nemo, number, type); return this.nemo.view.card.successWait();};
Card.prototype.addFailure = function(number, type) { _enterForm(this.nemo, number, type); return this.nemo.view.card.failureWait();};
module.exports = Card;
DRY$pa'ern$(navigate$module)var util = require('../util');var Navigate = function (nemo) { this.nemo = nemo;};...Navigate.prototype.logout = function() { this.nemo.view.nav.logoutLink().click(); return this.nemo.view.login.emailWaitVisible();};Navigate.prototype.bank = function() { this.nemo.view.nav.bankLink().click(); return this.nemo.view.bank.numberWaitVisible();};Navigate.prototype.card = function() { this.nemo.view.nav.cardLink().click(); return nemo.view.card.numberWaitVisible();};module.exports = Navigate;
DRY$pa'ern$(spec$usage)it('should execute high level functionality using flow modules', function (done) { navigate.loginFailure('[email protected]', '11111111'); navigate.loginSuccess('[email protected]', '11111111'); card.addSuccess('0123456789012345', 'Misa'); card.addFailure('1001001', 'Misa'); bank.addSuccess('0432787332', '92929'); bank.addFailure('1001001', '92929'); navigate.logout().then(util.doneSuccess(done), util.doneError(done));});
countries.js,(dynamic,data)
module.exports = [ { "locality": "en-US", "url": "http://localhost:8000/responsive/us" }, { "locality": "de-DE", "url": "http://localhost:8000/responsive/de" }];
eyes$spec.js
dd(countries, function () { it('should let me reply to an email for locale {locality}', function (country, done) { //login nemo.driver.get(country.url); nemo.waitForDom(); nemo.view._find('#reply').click(); nemo.view._find('#forward').click(); nemo.view._find('#moveto').click(); nemo.driver.sleep(2000); nemo.view._find('#verify').getText(). then(function (verifyText) { nemo.assert.equal(verifyText, 'replyforwardmoveto'); }). then(function () { done(); }).thenCatch(function (err) { done(err); }); });});
Demo:&Running&our&localized&testVisual'bug'introduced'DE'transla3on
Incorporate*ApplitoolsCatch&the&visual&bug&in&the&future
Basic&configura-on"eyes": { "module": "path:plugin/eyes", "arguments": [ { "sdk": { "setApiKey": "env:applitools_api_key", "setMatchLevel": "Layout" }, "viewport": { "width": 1200, "height": 600 }, "mock": "env:applitools_mock" } ] }
Demo:&Run&one&test&to&applitools
Add#responsive#tes-ngnew$config$for$each$form$factor
phone.json{ "plugins": { "eyes": { "module": "path:plugin/eyes", "arguments": [{ "sdk": { "setBatch": "PHONE", "setMatchLevel": "Layout" }, "viewport": { "width": 620, "height": 400 } }] } }}
tablet.json{ "plugins": { "eyes": { "module": "path:plugin/eyes", "arguments": [{ "sdk": { "setBatch": "PHONE", "setMatchLevel": "Layout" }, "viewport": { "width": 950, "height": 600 } }] } }}
Demo:&Visual&tes.ng&along&two&dimensions
Per$country,$per$form$factor
THANK&YOU
• h#ps://applitools.com/
• h#p://nemo.js.org
• @nemojs_news
• h#ps://github.com/paypal/nemo