Usar require con rutas relativas


Tenemos un conjunto bastante grande de pruebas de extremo a extremo en el Transportador. Estamos siguiendo el patrón de Objeto de Página que nos ayuda a mantener nuestras pruebas limpias y modulares. También tenemos un conjunto de funciones auxiliares que nos ayudan a seguir el principio SECO .

El Problema:

Una sola especificación puede requerir varios objetos de página y módulos auxiliares. Por ejemplo:

"use strict";

var helpers = require("./../../helpers/helpers.js");
var localStoragePage = require("./../../helpers/localStorage.js");
var sessionStoragePage = require("./../../helpers/sessionStorage.js");

var loginPage = require("./../../po/login.po.js");
var headerPage = require("./../../po/header.po.js");
var queuePage = require("./../../po/queue.po.js");

describe("Login functionality", function () {

    beforeEach(function () {
        browser.get("/#login");

        localStoragePage.clear();
    });

    // ...

});

Puede ver que tenemos ese recorrido de directorio en cada instrucción require: ./../... Esto es porque tenemos un directorio specs donde mantenemos las especificaciones y múltiples directorios dentro agrupados por funcionalidad de la aplicación bajo prueba.

La Pregunta:

¿Cuál es la forma canónica de abordar el problema de la trayectoria relativa en el Transportador?

En otras palabras, nos gustaría evitar atravesar el árbol, subir a importar módulos. Sería mucho más limpio bajar del directorio de la aplicación base en su lugar.


Tentativas y pensamientos:

Hay un gran artículo sobre cómo abordar este problema: Mejores rutas locales require() para el nodo.js , pero no estoy seguro de cuál de las opciones es una recomendada cuando se desarrollan pruebas con Protractor.

También hemos tratado de utilizar require.main para construir la ruta, pero apunta al directorio node_modules/protractor en lugar de nuestro directorio de aplicaciones.

Author: Louis, 2015-07-18

4 answers

Tuve el mismo problema y terminé con la siguiente solución. En mi archivo de configuración Protractor tengo una variable que almacena una ruta a una carpeta base de mis pruebas e2e. Además, Protractor config proporciona el onPrepare callback, donde puede usar una variable llamada global para crear variables globales para sus pruebas. Las define como propiedades de esa variable global y las usa de la misma manera que usa globals browser o element en las pruebas. Lo he utilizado para crear global personalizado requerir funciones para cargar diferentes tipos de entidades:

// __dirname retuns a path of this particular config file
// assuming that protractor.conf.js is in the root of the project
var basePath = __dirname + '/test/e2e/';
// /path/to/project/test/e2e/

exports.config = {

    onPrepare: function () {

        // "relativePath" - path, relative to "basePath" variable

        // If your entity files have suffixes - you can also keep them here
        // not to mention them in test files every time

        global.requirePO = function (relativePath) {
            return require(basePath + 'po/' + relativePath + '.po.js');
        };

        global.requireHelper = function (relativePath) {
            return require(basePath + 'helpers/' + relativePath + '.js');
        };

    }

};

Y luego puede usar estos métodos de utilidad global en sus archivos de prueba de inmediato:

"use strict";    

var localStorageHelper = requireHelper('localStorage');
// /path/to/project/test/e2e/helpers/localStorage.js 

var loginPage = requirePO('login');
// /path/to/project/test/e2e/po/login.po.js

var productShowPage = requirePO('product/show');
// /path/to/project/test/e2e/po/product/show.po.js


describe("Login functionality", function () {

    beforeEach(function () {
        browser.get("/#login");

        localStorageHelper.clear();
    });

    // ...

});
 24
Author: Michael Radionov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-20 09:44:32

Hemos estado enfrentando el mismo problema y decidimos convertir todos los objetos de página y archivos de ayuda en paquetes de nodos. Exigirlos en las pruebas es ahora tan fácil como var Header = require('header-po'). Otro beneficio de convertir a paquetes es que puede usar el control de versiones adecuado.

Aquí hay un simple ejemplo:

./page-objects / header-po / index.js

//page-objects/header-po/index.js

'use strict';

var Header = function () {
    this.goHome = function () {
        $('#logo a').click();
    };
  };

module.exports = Header;

./page-objects / header-po / package.json

{
    "name": "header-po",
    "version": "0.1.1",
    "description": "Header page object",
    "main": "index.js",
    "dependencies": {}
}

./paquete.json

{
    "name": "e2e-test-framework",
    "version": "0.1.0",
    "description": "Test framework",
    "dependencies": {
        "jasmine": "^2.1.1",
        "header-po": "./page-objects/header-po/",
    }
}

./tests / header-test.js

'use strict';

var Header = require('header-po');

var header = new Header();

describe('Header Test', function () {
    it('clicking logo in header bar should open homepage', function () {
        browser.get(browser.baseUrl + '/testpage');
        header.goHome();
        expect(browser.getCurrentUrl()).toBe(browser.baseUrl);
    });
});
 17
Author: finspin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-25 15:54:26

He tenido el mismo problema. Hizo una solución similar a la de Michael Radionov, pero no estableciendo una función global, sino estableciendo una propiedad a protractor en sí.

Transportador.conf.js

onPrepare: function() {
  protractor.basePath = __dirname;
}

Test-e2e.js

require(protractor.basePath+'/helpers.js');

describe('test', function() {
   .......
});
 10
Author: allenhwkim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-21 04:40:02

Creo que el método que usamos donde trabajo podría ser una buena solución para usted. He publicado un breve ejemplo de cómo manejamos todo. Es bastante bueno b / c usted puede llamar a las funciones de objeto de página en cualquier archivo de especificaciones y no es necesario utilizar require en la especificación.

Llama a un módulo de nodo desde otro módulo sin usar require() everywhere

 2
Author: BarretV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:39