3

When angularjs throws an error, it's caught in a try/catch and then an exception handler logs it as console.error. As a result, testcafe does not make a test fail whenever this happens, but we would like this to be considered a failing test. We tried to follow a suggestion in this thread and wrote this code:

fixture `Getting Started`
    .page `http://localhost:${port}/`;

const handleErrors = ClientFunction(() => {
    console.error = msg => {throw new Error(msg)};
});


test('Test', async t => {
    await handleErrors();
    //visit page with error, go somewhere else, return to page
    await t
        .expect(Selector('body').innerText).contains('hello world')

});

A controller calls $scope.undefined() so it will always throw an error in angular code, but the test still passes. We put console.error = msg => {throw new Error(msg)}; directly in our index.html, and saw that the error printed out like this: Uncaught Error: Error: Error: Error: TypeError: $scope.undefined is not a function.

If we add window.undefined(); directly into our index.html, TestCafe does consider this an error and fails the test. The error message looks like this: Uncaught TypeError: window.undefined is not a function.

Also, if we put console.error = msg => {throw new Error(msg)}; in the index.html, the test will fail when there's an angularjs error. So it seems like the handleErrors isn't working as expected or advertised in that thread.

We've done a bunch of tests like this and have now come to the conclusion that angular saves a reference to console, so when I re-assign it in this handleErrors, it's not affecting the console that angular uses. How can I make errors in angular code fail testcafe tests?

For what it's worth, we're using angular 1.2.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356

1 Answers1

2

We put this in our test and that caused console errors to fail:

fixture `Getting Started`
    .page `http://localhost:${port}/`
    .beforeEach(async t => await failOnJsErrors());

const failOnJsErrors = ClientFunction(() => {
    angular.element(document.body).injector().invoke(function($log) {
        $log.error = function(message) {
            throw new Error(message)
        };
    });
});

There's probably a different solution if you're > angularjs 1.2

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356