angular / protractor

E2E test framework for Angular apps
http://www.protractortest.org
MIT License
8.75k stars 2.31k forks source link

Testing hybrid Angular 1+2 app always fail #2944

Closed sebhorin closed 8 years ago

sebhorin commented 8 years ago

Protractor works well on Angular 1 but after upgrading my app to an hybrid Angular 1+2 I get this error:

Failed: Error while waiting for Protractor to sync with the page: "[ng:test] no injector found for element argument to getTestability http://errors.angularjs.org/1.4.9/ng/test"

It seems a common error when you don't have a ng-app tag <div ng-app=myAppManager"> in your Angular 1 app and can be easily fixed with rootElement : 'html' in your protractor config file but it doesn't seem to change anything on hybrid app.

I tried rootElement : 'html' or even useAllAngular2AppRoots: true.

I heavily suspect the problem comes from the asynchronous loading of the hybrid angular (from the upgrade doc):

One notable difference between angular.bootstrap and upgradeAdapter.bootstrap is that the latter works asynchronously. This means that we cannot assume that the application has been instantiated immediately after the bootstrap call returns.

my config file:

exports.config = {
    framework: 'jasmine2',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['protractor.js'],
    jasmineNodeOpts: {
        showColors: true,
        defaultTimeoutInterval: 50000,
    },
    allScriptsTimeout: 50000,//seb
    capabilities: {
        'browserName': 'chrome',
        'chromeOptions': {
            'prefs': {
                'profile.managed_default_content_settings.notifications':2
            }
        }
    },
    rootElement : 'html',
    // useAllAngular2AppRoots: true,
    jasmineNodeOpts: {
        realtimeFailure: true
    },
    onPrepare: function() {
      var failFast = require('jasmine-fail-fast');
      jasmine.getEnv().addReporter(failFast.init());
    }
}
NickTomlin commented 8 years ago

I'm unfamiliar with hybrid angular, could you provide a small reproducible example that we can use to investigate?

sebhorin commented 8 years ago

Sure! This is a simple hybrid app, do you need anything else?: http://plnkr.co/edit/P4H8eUQvQeTZRJHi3g10?p=preview

A hybrid app is actually an Angular 1 app that can read angular 2 components. There is no big change from Angular 1 app expect the app bootstrapping:

import {UpgradeAdapter} from 'angular2/upgrade';
/* . . . */
const upgradeAdapter = new UpgradeAdapter();
upgradeAdapter.bootstrap(document.body, ['heroApp'], {strictDi: true});

instead of having <body ng-app="heroApp" > or angular.bootstrap(document.body, ['heroApp'], {strictDi: true});.

The hybrid bootstraping is asynch, I guess it's the problem..

heathkit commented 8 years ago

Unfortunately, this is a known issue. We plan on adding support for hybrid apps soon, though.

sjelin commented 8 years ago

Fixed with https://github.com/angular/angular/pull/7603

If you need a work around now you can use the version of upgrade.js from that PR, but I'd recommend waiting for real support. Angular releases pretty often

bringking commented 8 years ago

@sjelin I am still running into issues with this on NG2 RC1. @sebhorin did this resolve your issue?

sebhorin commented 8 years ago

@bringking I havn't set it up yet ..

Pixcell commented 8 years ago

Hello everyone,

I ran in a similar issue, I'm trying to run a testing scenario:

Starting from an angular 1.5 app, I am redirected to an angular 2 app. I can't get the config file to work properly. if I use :

useAllAngular2AppRoots: true

My tests on the angular1 app fails with:

    Failed: Cannot assign to read only property 'stack' of Error while waiting for Protractor to sync with the page: "window.getAllAngularTestabilities is not a function"

and if I don't, my test on the ng2 app fails with:

Failed: Error while waiting for Protractor to sync with the page: "Could not find testability for element."

I need to keep all tests with the same protractor conf, because I cannot predict the url I'll be redirected to (It is a signed url generated by a server when I click on a button in the angular 1.5 app)

Do you guys have any idea how I could get this working ?

Thank you in advance,

juliemr commented 8 years ago

See https://github.com/angular/angular/issues/9407

sjelin commented 8 years ago

https://github.com/angular/angular/pull/10084 should fix this problem

juliemr commented 8 years ago

All the little pieces needing to be fixed for this are now done - see our example against a hybrid app here: https://github.com/angular/protractor/blob/master/spec/hybrid/async_spec.js#L3

Note that this will only work with a recent version of Angular2 and with zone.js 0.6.25 or higher.