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

Gracias!

luis.thur@

leandro.romero@

ba-testing@

Training NightwatchJS

By Leandro Romero

Training NightwatchJS

  • 248