AngularJS Protractor “App Already Bootstrapped” error

When attempting to run an End-to-End test in Protractor for a AngularJS web app with a non-angular login page I received the following error message:

UnknownError: Error Message => '[ng:btstrpd] App Already Bootstrapped with this Element '<html lang="en" data-ng-app=

The test took the same structure as below (NOTE: this is not the real test):

describe('Test a page', function() {
    var ptor;
 
    beforeEach(function() {
        ptor = protractor.getInstance();
 
        browser.driver.get(ptor.baseUrl + '/login');
 
        browser.driver.findElement(by.id('user_email')).sendKeys('test@example.com');
        browser.driver.findElement(by.id('user_password')).sendKeys('passpass');
 
        browser.driver.findElement(by.id('login')).click();
 
        browser.driver.wait(function() {
            return browser.driver.getCurrentUrl().then(function(url) {
                return (/\/#\/$/.test(url));
            });
        });
 
        browser.get('#/');
    });
 
    it('Should list some item on this page', function() {
        browser.get('#/page2');
 
        browser.findElements(by.css('.my-item')).then(function(results) {
            expect(results.length).toBeGreaterThan(0);
        });
 
    });
});

The Angular docs suggests the error is caused when bootstrapping the application in both the HTML and in the JS: http://docs.angularjs.org/error/ng:btstrpd. However I was not doing this.

I had added the line browser.get('#/'); to resolve an issue where Protractor was reporting:

Angular could not be found on the page

This appeared to be caused by Protractor not detecting Angular on a page it had been redirected too (i.e. from the non-angular login page to the Angular app page) so I added in the get() call to explicitly load an Angular page in, this however caused the double bootstrap issue.

It turned out this was due to having two browser.get() in one test run (in the beforeEach() and the it()). Replacing the one in the beforeEach() with the following solved the problem:

browser.driver.get('about:blank');

This clears the currently loaded page, so on the next get() call it starts again and doesn’t think the Angular app has already been bootstrapped. I couldn’t see a better way to do this in the docs, however let me know if you do know of a nicer way to solve this problem.