angular / protractor

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

If protractor runs tests synchronously, why do we need to use waitForAngular()? #909

Closed SowmyaCVBS closed 10 years ago

SowmyaCVBS commented 10 years ago

I am a newbie in this. As far as I understand, protractor runs the tests synchronously. I have a scenario where I do a click event and expect for a particular text at many places in my test cases. Seldom, I see the expect fails and hence the test cases fail. Do I need to put waitForAngular() at all places to be on a safer side or is there any simpler way to get the lines executed in sequence i.e only after the DOM completely loads?

manevpe commented 10 years ago

Hi,

Protractor actually runs asynchronously, but it takes care to synchronize the test steps with your application, so that they will be executed properly, and the right time, only when the application is ready and has processed the previous step. All the actions (mouse clicks, keyboard typing, etc.) and all the checks / expectations actually return promises, that will be executed some time in the future. At the start of your tests, all of your test scripts are parsed and a chain of promises is created. After that, they begin to execute one after another - protractor takes care for that. It also takes care to synchronize your test steps (actions, expectations, etc.) with angular in your application under test. So after each step (promise), it automatically calls waitForAngular - no need to do that yourself. This way, you can write the steps in a synchronous matter, but they will be executed asynchronously, at the right time. However, this is not entirely true - protractor is a wrapper over webdriverjs - so all protractor methods are automatically synced, but you are also able to call webdriver methods directly and they will not be synced. You can check which are the protractor and which are the webdriverjs methods available in the documentation here - https://github.com/angular/protractor/blob/master/docs/api.md

Hope, I was able to explain this in a more understandable way.

juliemr commented 10 years ago

@manevpe thanks for the great explanation. Closing this as an answered question.

SowmyaCVBS commented 10 years ago

Thank you. That quick reminder about promises helps a ton!

PriyaSr commented 10 years ago

Hi, I am very new to protractor. As far as I have seen protractor is really interesting. But where i struck is that i have created user defined functions outside the spec and called those functions inside the spec. And what my question is that only my first function is getting called and rest of the functions are not getting called. All the console.log, for loop inside the function is getting printed in the first if the function is not even called. Thus i want to know the sequence of execution of protractor and where to call the user defined function?

Thanks in advance!!

flegall commented 10 years ago

Hi,

I'm just wondering why haven't you decided to wrap all webdriverJS calls to automatically call waitForAngular() before calling the inner webdriverJs method.

Perhaps it's not feasible or has unwanted side effects. I'm curious.

juliemr commented 10 years ago

@flegall we pretty much do that. Not every single call is wrapped, but anything that has a chance to throw off synchronization.

anandalex commented 9 years ago

@juliemr

I tried following ways

  1. passing number of arguments via command array and executing in shell.write method

    var command = [java -jar xxx.jar, xxxuser, xxxpass];

    return shell.promise.then(function (shell) { return { output: output.promise, error: error.promise,

           sendMultipleCommand: function (command) {
             for (var i = 0; i < command.length; i++) {
              console.log(command[i] + '\n');
              shell.write(command[i] + '\n');
             }
           }
         };
       });
  2. executing commands with space

    var command = java -jar xxx.jar xxxuser xxxpass;

It is not executing as expected, browser and protractor are stuck.

By manual (the same way need to execute via script)

java -jar xxx.jar enter username: xxxuser enter password: xxxpass

Problem seems jar file take some time to execute, but all other commands are executed before the execution of Jar file

Thanks in advance, help me to solve this issue

gauravAuto commented 8 years ago

Can I execute protractor scripts from java file? If yes, please update how.

sjelin commented 8 years ago

You can execute arbitrary shell commands from java, so just do protractor conf.js

keithdtyler commented 8 years ago

I have run into quite a lot of cases where I could not simply do

// close a modal dialog, which causes an ajax view update
modal.closeButton.click();
// expect the ajax view to be updated
expect(element(by.id('viewbox').getText()).toEqual('updated value');

This fails: "Expected 'previous value' to equal 'updated value'." Protractor simply isn't waiting for the actions initiated by the click() to finish before firing the expect().

The solution:

modal.closeButton.click().then(function(){
    expect(element(by.id('viewbox').getText()).toContain('updated value');
});

My tests are now chock full of lines that look like

}).then(function(){
    return x.y.z()
}).then(function(){
    return a.b.c()
}).then(function(){
    return expect(a.b).toBe(q)

....