The Question:
Is it possible to clean up the stack trace and leave only relevant frames eliminating everything Protractor
, WebDriverJS
and Jasmine
specific?
The Story:
Let's execute this example test:
describe("SO test", function () {
beforeEach(function () {
browser.get("https://angularjs.org");
});
it("should throw a meaningful error", function () {
element(by.id("not_found")).click();
});
});
It would fail with a following stacktrace:
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)
As you can see, it's not easy to find on which line in the test the error actually happened. It's hidden somewhere inside the stack trace covered by Protractor
, WebDriverJS
and Jasmine
stack frames. This makes it difficult to debug and develop end-to-end tests.
Desired output:
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)
Using protractor
3.0.0 and jasmine2
.
In mocha
world, there is a relevant mocha-clean
package that filters out everything coming from inside node_modules
and mocha
itself leaving a clean stack trace that is easy to read.