Búsqueda de sitios web

javascript - Limpiando la traza de pila de Protractor


La Pregunta:

¿Es posible limpiar el rastro de la pila y dejar solo los marcos relevantes, eliminando todo lo específico de Protractor, WebDriverJS y Jasmine?

La Historia:

Vamos a ejecutar esta prueba de ejemplo:

describe("SO test", function () {
    beforeEach(function () {
        browser.get("https://angularjs.org");
    });

    it("should throw a meaningful error", function () {
        element(by.id("not_found")).click();
    });
});

Fallarías con la siguiente traza de pila:

SO test should throw a meaningful error
  - Failed: No element found using locator: By.id("not_found")
      at new bot.Error (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/atoms/error.js:108:18)
      at /usr/local/lib/node_modules/protractor/lib/element.js:676:15
      at [object Object].promise.Promise.goog.defineClass.invokeCallback_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:1337:14)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_.execute_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2776:14)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2758:21)
      at goog.async.run.processWorkQueue (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/async/run.js:124:15)
      at process._tickCallback (node.js:377:9)
  Error
      at [object Object].ElementArrayFinder.applyAction_ (/usr/local/lib/node_modules/protractor/lib/element.js:382:21)
      at [object Object].ElementArrayFinder.(anonymous function) [as click] (/usr/local/lib/node_modules/protractor/lib/element.js:78:17)
      at [object Object].ElementFinder.(anonymous function) [as click] (/usr/local/lib/node_modules/protractor/lib/element.js:711:7)
      at Object.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:9:37)
      at /usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:96:23
      at [object Object].promise.Promise.goog.defineClass.constructor (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:1056:7)
      at new wrappedCtr (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/base.js:2468:26)
      at controlFlowExecute (/usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:82:18)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_.execute_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2776:14)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2758:21)
  From: Task: Run it("should throw a meaningful error") in control flow
      at Object.<anonymous> (/usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:81:14)
      at /usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:18:5
      at [object Object].promise.Promise.goog.defineClass.invokeCallback_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:1337:14)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_.execute_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2776:14)
      at [object Object].promise.ControlFlow.goog.defineClass.goog.defineClass.abort_.error.executeNext_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/../webdriver/promise.js:2758:21)
      at goog.async.run.processWorkQueue (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/async/run.js:124:15)
  From asynchronous test: 
  Error
      at Suite.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:8:5)
      at Object.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:3:1)
      at Module._compile (module.js:425:26)
      at Object.Module._extensions..js (module.js:432:10)
      at Module.load (module.js:356:32)

Como puedes ver, no es fácil encontrar en qué línea del test ocurrió realmente el error. Está oculto en algún lugar dentro del rastro de pila cubierto por los marcos de pila de Protractor, WebDriverJS y Jasmine. Esto hace que sea difícil depurar y desarrollar pruebas de extremo a extremo.

Resultado deseado:

SO test should throw a meaningful error
  - Failed: No element found using locator: By.id("not_found")
      at Object.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:9:37)
  From asynchronous test: 
  Error
      at Suite.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:8:5)
      at Object.<anonymous> (/Users/user/job/project/test/e2e/specs/test.spec.js:3:1)
      at Module._compile (module.js:425:26)
      at Object.Module._extensions..js (module.js:432:10)
      at Module.load (module.js:356:32)
      at Function.Module._load (module.js:311:12)

Usando protractor 3.0.0 y jasmine2.

En el mundo de mocha, existe un paquete relevante mocha-clean que filtra todo lo que proviene del interior de node_modules y del propio mocha, dejando un rastro de pila limpio que es fácil de leer.

Respuesta #1

Resulta que, si utilizas cualquier reportero personalizado, es posible que introduzcan un nuevo comportamiento en el control de la salida de una traza de pila. Protractor en sí mismo oculta prácticamente todo, por lo que no verás ninguna entrada de registro de node_modules o Jasmine.

Al usar jasmine-spec-reporter, que proporciona una opción para controlar un seguimiento de pila, podría ser el caso de que hayas configurado algún modo detallado en las opciones. En la documentación de Protractor, por alguna razón, se sugiere usar el modo all, que básicamente muestra toda la traza de la pila.

    onPrepare: function () {
    jasmine.getEnv().addReporter(new SpecReporter({
      spec: {
        displayStacktrace: true
      }
    }));

Si simplemente cambias la opción displayStacktrace de all a none, deberías obtener resultados limpios sin ningún rastro de pila. También existen las opciones summary y specs. Puede que no notes la diferencia entre ellas en tu ejemplo, pero si agregas algunas especificaciones más en tu suite, entonces podrás ver la diferencia:

  1. specs - si una especificación falla en el proceso de ejecución de pruebas, verás un seguimiento de la pila inmediatamente después de un mensaje de fallo de especificación
  2. resumen - si la especificación falla en el proceso de ejecución de las pruebas, no verás un rastreo de pila inmediatamente después de un mensaje de fallo de especificación, pero obtendrás una lista de todos los rastreos de pila de las especificaciones fallidas al final de todas las pruebas
  3. all - combina specs y summary - si una especificación falla durante la ejecución de las pruebas, verás un rastreo de pila para ella inmediatamente después del mensaje de falla de la especificación y obtendrás una lista de todos los rastreos de pila de las especificaciones fallidas al final de todas las pruebas
  4. none - los rastros de pila no se mostrarán en ningún lugar

Respuesta #2

La API de jasmine-spec-reporter ha cambiado.

El nuevo ejemplo ilustra una opción simple para desactivar los rastros de pila:

let SpecReporter = require('jasmine-spec-reporter').SpecReporter;

exports.config = {
    framework: 'jasmine',
    // Your config here...

  jasmineNodeOpts: {
    print: function () {}
  },

    onPrepare: function () {
        jasmine.getEnv().addReporter(
            new SpecReporter({
                spec: {
                     displayStacktrace: true
                }
            })
        );
    }
}