angular / protractor

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

Tests failing when ng-app and ui-view directives are declared on the same div #1147

Closed taromero closed 10 years ago

taromero commented 10 years ago

Protractor gives an uninformative error while testing if np-app and ui-view are declared on the same div.

Error:

Error: Error while waiting for Protractor to sync with the page: {"message":"angular.element(...).injector(...) is undefined","stackTrace":[{"fileName":"http://localhost:3000/","lineNumber":71,"methodName":"anonymous/<"},{"fileName":"http://localhost:3000/","lineNumber":76,"methodName":"anonymous"},{"fileName":"http://localhost:3000/","lineNumber":68,"methodName":"handleEvaluateEvent"}]}

This only happens while testing, the app works fine on the browser when used normally.

If I move the ui-view directive to a nested div inside the ng-app div, my tests work fine.

StackOverflow post

sroe commented 10 years ago

I#m having the same problem. I would like to know if it's ui-router or protractor related, or maybe both?

dctr commented 10 years ago

Just the same without ngRoute and with nested divs

<div ng-app="myApp">
  <div  ng-controller="myController">
    ...
  </div>
</div>
  var myApp = angular.module('myApp', []);

  myApp.controller('myController', [
    '$scope',
    function ($scope) {
      ...
    }
  ]);

Results in

Error: Error while waiting for Protractor to sync with the page: {}
juliemr commented 10 years ago

How does the DOM render when ng-app and ui-view are on the same element? Does it make it so that ng-app is actually outside of Angular's sphere of influence (e.g, you can't get an injector from that element)?

juliemr commented 10 years ago

The problem is that when ng-app and ui-view are declared on the same element, angular.element(<that>).injector() is undefined. However, if they're on different elements, the injector exists for both elements.

This is because of an interaction between ui-router and angular, because the ui-view directive uses transclusion. Using a directive using transclusion on the same element as ng-app results in it not having the correct injector via angular.element().injector(). Here's a simplified example: https://gist.github.com/juliemr/ffccf5bbe5b88a2d3da9

I think that this is all working as intended and the solution is to just not use ng-app and ui-view on the same element. I'm going to go ahead and close this issue, but I'll open up an FYI with ui-router and link here.

dctr commented 10 years ago

The issue also appears then nesting the two directives in subsequent DIVs. For me it only seems to work if ng-app is in the HTML tag.