Frontend Automation
Testing
Sesión 1
Agenda
- Sesión 1:
- ¿Que es Nightwach?
- Estructura
- Page Object
- Sintaxis
- Buenas Prácticas
- Ejemplo
- Sesión 2:
- Hands On
- Preguntas
¿Qué es Nightwatch?
NightwatchJS

Ventajas
Sintáxis simple
Integracion Continua

Paralelismo nativo

Agrupacion de tests


Multiples browsers

Custom asserts

Custom commands

Estructura
Scaffolding
test
|-- e2e
|-- custom-asserts
|-- custom-commands
|-- groups
|-- desktop
demoSpec.js
|--mobile
|-- pages
DemoPage.js
globals.js
nightwatch.json
package.json
package.json
{
...
"scripts": {
"e2e": "./node_modules/.bin/nightwatch --env desktop"
},
"repository": {
...
},
"dependencies": {
...
"phantomjs": "2.1.1",
"chromedriver": "2.29.*",
"selenium-server": "3.1.0",
"nightwatch": "v0.9.12",
"nwjs-reporter": "0.0.*",
"minimist": "^1.2.0"
}
}
nightwatch.json
{
"src_folders": ["tests/e2e/groups/"],
"output_folder": "tests/e2e/results",
"globals_path": "tests/e2e/globals.js",
"page_objects_path": "tests/e2e/pages/",
"custom_commands_path": "tests/e2e/custom_commands/",
"custom_assertions_path": "tests/e2e/custom_asserts/",
"test_workers": {
"enabled": false,
"workers": 2
},
"selenium": {
"start_process": true,
"host": "127.0.0.1",
"port": 4444,
"server_path": "path/to/selenium-server.jar",
"cli_args": {
"webdriver.chrome.driver": "path/to/chromedriver"
}
},
"test_settings": {
"env_1": {
...
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"env_2": {...},
"env_3": {...},
}
}
Page Object
//DemoPage.js
var demoCommands = {
seachProduct: function(client, query) {
return this .waitForElementPresent('@textBoxSearch', timeout)
.setValue('@textBoxSearch',query)
.sendKeys('@textBoxSearch',client.Keys.ENTER);
}
};
var timeout = 20000;
module.exports = {
url: function () {
var siteId = this.api.globals.site; //Supongamos siteId=mla
return this.api.globals.sites[siteId]; //Trae la url del site mla
},
commands: [demoCommands],
elements: {
mlPage: '[href="//www.mercadolibre.com.ar/"]',
textBoxSearch: '.nav-search-input'
}
};
Sintáxis
module.exports = {
elements: {
textBoxSearch: { //Hacer explícita la locate estrategy
selector: '//[@name="q"]',
locateStrategy: 'xpath'
},
searchBar: { // css selector como default localte strategy
selector: 'input[type=text]'
},
}
Selectores
Funciones
module.exports = { //Todos tienen locate strategy css selector
elements: {
textBoxSearch: 'input[type=text]'
}
}
Commands
//MyPageObject.js
var pageCommands = {
submit: function() {
return this
.waitForElementVisible('@submitButton', 1000)
.click('@submitButton');
}
};
module.exports = {
commands: [pageCommands],
elements: {
searchBar: 'element1',
submitButton: 'element2'
}
};
//myTest.js
module.exports = {
'Test': function (client) {
var page = client.page.MyPageObject();
page
.submit();
...
client.end();
}
};
Funciones
//myTest.js
function searchInMercadoLibre(client, query){
var selector = client.page.SearchPage().getSelector(client);
client
.page.HomePage()
.assert.elementPresent('@mlPage')
.seachProduct(client, query)
client
.page.SearchPage()
.assert.elementPresent(selector)
.assert.containsText(selector, query);
}
module.exports = {
'Should search in mercadolibre an Iphone 7 Plus': function (client) {
searchInMercadoLibre(client, "iPhone 7 Plus")
},
'Should search in mercadolibre Google Pixel': function (client) {
searchInMercadoLibre(client, "Google Pixel")
}
};
Asserts
//myTest.js
module.exports = {
'Test': function (client) {
var page = client.page.MyPageObject();
page
.search('@searchBar', 'nightwatch')
.assert.elementPresent('@boxTitle')
.assert.containsText('@boxTitle', "Has buscado nightwatch")
.assert.hasResults('@rowResults', 15)
client.end();
}
};
Ejemplo
# INSTALL ENVIRONMENT
$ npm run setup
# RUN TESTS
$ npm run test -- --tag demo
$ npm run test -- --tag demo -e xvfb_mobile
$ npm run test -- --tag demo -e xvfb_desktop
$ npm run test -- --tag demo -e xvfb_mobile --test myFirstTest/myFirstSpec.js
Best Practices
// Las Url a las que debemos acceder desde los test deben estar en el archivo globals.js
"mla" : {
'URL': {'description': 'My URL', 'url': 'http://www.mercadolibre.com.ar/'}
}
// Las acciones son propias de la pagina (clicks, setValue, etc)
var demoCommands = {
seachProduct: function(client, query) {
return this .waitForElementPresent('@textBoxSearch', timeout)
.setValue('@textBoxSearch',query);
}
};
// Los tests invocan a las acciones de la pagina y deben contener los asserts
function searchTvLed(client, query){
client
.page.HomePage()
.assert.elementPresent('@mlPage')
.seachProduct(client, query)
}
Preguntas?
Sesión 2
Hands On
Guía
Ingresar a Mercado Libre Argentina


Buscar "Tv led hd"

Elegir la categoria TV 4K

Cambiar el tipo de vista a mosaico

Verificar que estemos en la categoria TV 4K
Elegir el primer producto de la lista

Verificar que el titulo y el precio del producto sea el mismo que el de la pagina de producto

Preguntas?
Links Utiles
* [Sitio oficial](http://nightwatchjs.org/)
* [Repositorio](https://github.com/nightwatchjs/nightwatch)
* [Changelog](https://github.com/nightwatchjs/nightwatch/releases)
* [Developer Guide](http://nightwatchjs.org/guide)
* [StackOverflow](http://stackoverflow.com/questions/tagged/nightwatch.js)
* [Google Group](https://groups.google.com/forum/#!forum/nightwatchjs)
* [Twitter](https://twitter.com/nightwatchjs)
* [Selenium](http://docs.seleniumhq.org/)
* [CssSelectors](https://www.w3schools.com/cssref/css_selectors.asp)
* [RepoMLEjemplo](https://github.com/mercadolibre/fury_credits-frontend)
https://github.com/leandroromero/trainings-nightwatchJS/tree/GuideDemo
Gracias!
luis.thur@
leandro.romero@
ba-testing@
Training NightwatchJS
By Leandro Romero
Training NightwatchJS
- 248