Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng:test no injector found for element argument to getTestability

There other question on SO with same problem, but the solutions didnt worked for me. Here my spec.js

describe('Protractor Demo App', function() {
  it('should have a title', function() {
    browser.driver.get('http://rent-front-static.s3-website-us-east-1.amazonaws.com/');

    expect(browser.getTitle()).toEqual('How It Works');
  });
});

And here my conf.js

exports.config = {
  framework: 'jasmine',
  rootElement: 'body',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['spec.js']
}

So when i try to run my test im getting the error

  Message:
    Failed: Error while waiting for Protractor to sync with the page: "[ng:test] no injector found for element argument to getTestability\nhttp://errors.angularjs.org/1.5.0/ng/test"
  Stack:
    Error: Failed: Error while waiting for Protractor to sync with the page: "[ng:test] no injector found for element argument to getTestability\nhttp://errors.angularjs.org/1.5.0/ng/test"
        at C:\Users\ShapeR\PycharmProjects\ratest\node_modules\jasminewd2\index.js:101:16
        at Promise.invokeCallback_ (C:\Users\ShapeR\PycharmProjects\ratest\node_modules\selenium-webdriver\lib\promise.js:1329:14)
        at TaskQueue.execute_ (C:\Users\ShapeR\PycharmProjects\ratest\node_modules\selenium-webdriver\lib\promise.js:2790:14)
        at TaskQueue.executeNext_ (C:\Users\ShapeR\PycharmProjects\ratest\node_modules\selenium-webdriver\lib\promise.js:2773:21)

1 spec, 1 failure

I have a manual bootstrapping for body element and set the rootElement to body in config, but it didnt help. I even tried to remove manual boostraping and just add ng-app='rentapplicationApp' to body element, but it changes nothing, still same error.

So what is wrong?

like image 874
Aldarund Avatar asked May 26 '16 23:05

Aldarund


2 Answers

The core value of Protractor is that it manages the angular loading for you, including sync, so you are very right in not wanting to use: browser.ignoreSynchronization = true.

The error message you are getting is that protractor is unable to locate angular in order to sync. This is because of a combination of two issues:

  • The page isn't ready, angular isn't loaded
  • It is unable to locate the ng-app, even once the page is loaded

Firstly, from Protractor setup page.

If your page does manual bootstrap Protractor will not be able to load your page using browser.get. Instead, use the base webdriver instance - browser.driver.get. This means that Protractor does not know when your page is fully loaded, and you may need to add a wait statement to make sure your tests avoid race conditions.

Solution 1

Add a wait statement.

Solution 2

If you don't have a good reason for manually bootstrapping, or don't want to wait:

  • Stop manually bootstrapping the app
  • Use browser.get over browser.driver.get
like image 164
Luke Exton Avatar answered Nov 08 '22 16:11

Luke Exton


[ng:test] no injector found for element argument to getTestability

I suspect there is something wrong with the application itself, the way it is bootstrapped, since Protractor actually finds the root element (you can explicitly set the rootElement: "body.root" inside your config as well), but fails to setup the injector for the root element.

I'd try to figure out what is happening it step by step - first, try running the protractor test against a non-built application started directly from the source to ensure that this is not the webpack's or other part's of the build fault.

Then, I'd try upgrading to the latest 1.x Angular and Protractor (3.3.0 is the most recent version).


The most simple workaround at the moment would be to turn the sync between Protractor and Angular off, by using browser.ignoreSynchronization = true:

describe("Strange Protractor/Angular problem", function () {
    beforeEach(function () {
        browser.ignoreSynchronization = true;
        browser.get("https://dl.dropboxusercontent.com/u/597502/vxcv/index.html");

        var elm = $(".navbar-brand");
        browser.wait(EC.presenceOf(elm), 5000);
    });

    it("should have an expected title", function () {
        expect($(".navbar-brand").getText()).toEqual('RENT APPLICATION');
    });
});

Of course, there are downsides to this approach - you would have to use browser.wait calls here and there to tackle the timing issue. The test flow would not be as natural and simple as it would be when sync is on.

like image 30
alecxe Avatar answered Nov 08 '22 18:11

alecxe