Getting error: Error while waiting for Protractor to sync with the page: {}
Asked Answered
P

5

9

My e2e.conf.coffee file is:

exports.config =
  baseUrl: 'http://localhost:9001'
  specs: [
    'e2e/**/*.coffee'
  ]

  framework: 'jasmine'

I have my node project running and listening on port 9001.

My test is:

describe 'Happy Path', ->
  it 'should show the login page', ->
    console.log browser

    expect(browser.getLocationAbsUrl()).toMatch("/view1");
  it 'should fail to login', ->
    setTimeout ->
      console.log "FAIL!"
    , 1200

And the error that I get is:

Failures:

  1) Happy Path should show the login page
   Message:
     Error: Error while waiting for Protractor to sync with the page: {}
   Stacktrace:
     Error: Error while waiting for Protractor to sync with the page: {}
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
==== async task ====
WebDriver.executeScript()
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
==== async task ====
Asynchronous test function: it("should show the login page")
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>==== async task ====

What am I doing wrong??

Preemie answered 13/5, 2014 at 14:51 Comment(6)
this question was asked a couple of times on stackoverflow. just copy and paste it into google-search ...Goodhen
I did- the answers gave me no guidancePreemie
depends a little on your project setup. if your login page is angular you'll need to waitForAngular if not, there are exceptions (i would have to google them again, just glanced it as i read it ... not much time right now, will look back tomorrow) good luck!Goodhen
So how do I use waitForAngular?Preemie
var ptor = protractor.getInstance(); ptor.waitForAngular(); still in hurry, wont have much time this weekend. hope i could help a bit, will look backGoodhen
nothin yet.. any more input?Preemie
F
33

The (very) short version: use browser.driver.get instead of browser.get.

The longer version: Protractor is basically a wrapper around Selenium and its Javascript WebDriver code. Protractor adds code to wait for Angular to "settle down" (i.e., finish going through its $digest loops) before proceeding with your test code. However, if your page doesn't have Angular on it, then Protractor will wait "forever" (actually just until it times out) waiting for Angular to settle.

The browser object that Protractor exposes to your test is an instance of Protractor (i.e., if you see old answers on Stack Overflow with var ptor = protractor.getInstance(); ptor.doSomething(), then you can replace ptor with browser in those old answers). Protractor also exposes the wrapped Selenium WebDriver API as browser.driver. So if you call browser.get, you're using Protractor (and it will wait for Angular to settle down), but if you call browser.driver.get, you're using Selenium (which does not know about Angular).

Most of the time, you'll be testing Angular pages, so you'll want to use browser.get to get the benefits of Protractor. But if your login page doesn't use Angular at all, then you should be using browser.driver.get instead of browser.get in the tests that test your login page. Do note that you'll also need to use the Selenium API rather than the Protractor API in the rest of the test: for example, if you have an HTML input element with id="username" somewhere in your page, you'll want to access it with browser.driver.findElement(by.id('username')) instead of element(by.model('username')).

For more examples, see this example from the Protractor test suite (or try this link if the previous one ever goes away). See also the Protractor docs which state:

Protractor will fail when it cannot find the Angular library on a page. If your test needs to interact with a non-angular page, access the webdriver instance directly with browser.driver.

Example code: In your login test above, you would want to do something like:

describe 'Logging in', ->
  it 'should show the login page', ->
    browser.driver.get "http://my.site/login.html"
    // Wait for a specific element to appear before moving on
    browser.driver.wait ->
      browser.driver.isElementPresent(by.id("username"))
    , 1200
    expect(browser.driver.getCurrentUrl()).toMatch("/login.html");
  it 'should login', ->
    // We're still on the login page after running the previous test
    browser.driver.findElement(by.id("username")).sendKeys("some_username")
    browser.driver.findElement(by.id("password")).sendKeys("some_password")
    browser.driver.findElement(by.xpath('//input[@type="submit"]')).click()

(A note of caution: I haven't done much CoffeeScript, and it's entirely possible I made a CoffeeScript syntax error in the code above. You may want to check its syntax before blindly copying and pasting it. I am, however, confident in the logic, because that's copied and pasted almost verbatim from my Javascript code that tests a non-Angular login page.)

Filamentary answered 27/5, 2014 at 5:36 Comment(6)
That didn't do it for me... you can see my code at: gist.github.com/shamoons/2970175f3c815ff7f9caPreemie
@Preemie - I see your code, but what error are you getting? Is it still the "Error while waiting for Protractor to sync" one? Because from what I understand (and from what I've done myself), by using browser.driver you should not be seeing the "waiting for Protractor to sync" error any longer. One more thing to try: before the test that's timing out waiting to sync, add browser.ignoreSynchronization = true; and see if that makes a difference.Filamentary
See ng-learn.org/2014/02/… for one person's approach, which used browser.ignoreSynchronization = true extensively.Filamentary
Note that I have not used ignoreSynchronization at all (sticking with browser.driver worked for me), so if there are tangled weeds down that path, I don't know about them. One thing I suspect is that you might have to set it back to false before running tests that do rely on Angular; the article I linked above ended up sticking a browser.ignoreSynchronization = (true/false) statement in front of every test, using onPrepare and beforeEach to make it slightly easier.Filamentary
Brilliant answer @Filamentary thank you for the detailed background on Protractor / Selenium.. will certainly help others with problems unrelated to this question.. like me! CheersAustinaustina
as explained above , replacing browser.get with browser.driver.get and using selenium API thereafter instead of protractor api did work for meExpertise
S
8

If you need to be using browser.get and are getting this error, the issue is most likely to be the rootElement property in protractor config file.

By default Protractor assumes that the ng-app declaration sits on the BODY-element. However, in our case, it could be declared somewhere else in the DOM. So we have to assign the selector of that element to the rootElement property:

// rootElement: 'body', // default, but does not work in my case
rootElement: '.my-app', // or whatever selector the ng-app element has

Corresponding HTML:

<div ng-app="myApp" class="my-app">

I copied the answer from http://www.tomgreuter.nl/tech/2014/03/timing-errors-with-angular-protractor-testing/

Spruik answered 29/9, 2014 at 2:12 Comment(1)
It's important to note that this is the answer if you're getting this error on a page that does have Angular on it. If, as it appears to be the case for this question, you're using Protractor for pages without Angular as well, the accepted answer is the one you need.Gilgamesh
C
3

I got this error, too, but in my case my tests were working and this error occured after expanding them.

Turns out that this error may occur, if you try to call getText() in your describe block instead of your testcases. My Set-Up was like following:

describe('Test Edit Functionality', function() {
    var testEntry = $$('.list-entry').first(),
        testEntryOldName = testEntry.getText();

   it('Should keep old name if edit is aborted', [...]);
});

That caused the Error Error while waiting for Protractor to sync with the page: {}.

I fixed it by moving the assigment into a beforeEach-block

describe('Test Delete Functionality', function() {
    var testEntry = $$('.list-entry').first(),
        testEntryOldName;

   beforeEach(function() {
        testEntryOldName = testEntry.getText();
   });
});

Or, may be better, assign it in the specific testcases you need this value (if you dont need it in all).

Chappell answered 25/3, 2015 at 9:9 Comment(0)
F
1

Not sure where I picked up the pieces that put this answer at this point, but this is what works for me:

  1. Add class='ng-app' to the element that contains your app.
<div ng-app="myApp" ng-controller="myController" class="ng-app"></div>
  1. Add rootElement to your protractor.conf.
exports.config = {
  specs: ['your-spec.js'],
  rootElement: ".ng-app"
};
  1. Use browser.driver.get not browser.get.
describe('foobar element', function() {
  it('should be "baz" after view is initialized', function() {
  browser.driver.get('http://localhost/view');

    var inputBox = $('input[name=foobar]');
    expect(inputBox.getAttribute('value')).toEqual("baz");
  });
});
Flotow answered 6/4, 2015 at 19:12 Comment(0)
P
0

I got this issue a couple of days back on my CT. My tests were running fine until 3 days back, but then this protractor sync error showed up and just won't go away with any of the solutions/hacks provided here and at https://github.com/angular/protractor/issues/2643.

I checked that this issue only occurred in Firefox headless and worked fine with Chrome headless. Upgrading from Firefox v69 to the latest(v72 currently) fixed the issue. I do not know why the issue started manifesting itself and how it got fixed with the upgrade, but for what it is worth I thought this information might come in handy for someone else.

Paige answered 23/1, 2020 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.