Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

getCurrentUrl() should wait for Angular before executing #92

Closed
juliemr opened this issue Sep 13, 2013 · 36 comments
Closed

getCurrentUrl() should wait for Angular before executing #92

juliemr opened this issue Sep 13, 2013 · 36 comments
Assignees

Comments

@juliemr
Copy link
Member

juliemr commented Sep 13, 2013

The expectation should be that the page settles down before getCurrentUrl() executes.

Temporary fix - instead of doing ptor.getCurrentUrl().then... do

ptor.waitForAngular();
ptor.getCurrentUrl();
@ghost ghost assigned juliemr Sep 13, 2013
This was referenced Sep 13, 2013
@ranjanbhambroo
Copy link

@juliemr I tried the temporary fix its timing out.

@Douwe92
Copy link

Douwe92 commented Sep 16, 2013

same here

@Douwe92
Copy link

Douwe92 commented Sep 16, 2013

I used the ptor.sleep(5000); to let the page load before it trys and get the current url. It works for me now.

@ranjanbhambroo
Copy link

@Douwe92 I tried your suggestion... Didnt work for me

@Douwe92
Copy link

Douwe92 commented Sep 17, 2013

Can you show your code? @rj051286

@ranjanbhambroo
Copy link

@Douwe92
var util = require('util');
describe('Login', function() {
var ptor;
beforeEach(function() {
ptor = protractor.getInstance();
ptor.get('#/login');
},30000);

it('allows user to log in', function() {
    ptor.findElement(protractor.By.input('login')).sendKeys('username');
    ptor.findElement(protractor.By.input('password')).sendKeys('password');
    ptor.findElement(protractor.By.css('input.login-form-container-button')).click(); 
});  
it('check for the url', function() {
    ptor.sleep(10000);
    var expectedUrl = ptor.baseUrl + '/#/missioncontrol';     
    expect(ptor.getCurrentUrl()).toBe(expectedUrl);    
}, 30000);  

});

@stickel
Copy link

stickel commented Sep 17, 2013

@rj051286 What is it timing out on? One thing I noticed is there's no expectation on the first test. Try combining the two it statements into one test and see if that fixes your timeout issue.

var util = require('util');
describe('Login', function() {
    var ptor;
    beforeEach(function() {
        ptor = protractor.getInstance();
        ptor.get('#/login');
    },30000);

    it('allows user to log in', function() {
        var expectedUrl = ptor.baseUrl + '/#/missioncontrol';
        ptor.findElement(protractor.By.input('login')).sendKeys('username');
        ptor.findElement(protractor.By.input('password')).sendKeys('password');
        ptor.findElement(protractor.By.css('input.login-form-container-button')).click(); 
        ptor.sleep(10000);
        expect(ptor.getCurrentUrl()).toBe(expectedUrl);    
    }, 30000);  
});

@apankov1
Copy link

@stickel, thank you. I was having similar issue #57 and changed my code similar to yours and everything is working now.

@stickel
Copy link

stickel commented Sep 17, 2013

@apankov1 Glad it helped! Hopefully it works for the issue @rj051286 is having.

@ranjanbhambroo
Copy link

@stickel Got this error now

ScriptTimeoutError: Timed out waiting for async script result after 1ms
Command duration or timeout: 12 milliseconds
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.4', java.version: '1.6.0_51'
Session ID: 09c833e0-1e91-454e-98e4-b0e9094359e9
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=firefox, rotatable=false, locationContextEnabled=true, version=23.0.1, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, applicationCacheEnabled=true, takesScreenshot=true}]
Stacktrace:
ScriptTimeoutError: Timed out waiting for async script result after 1ms
Command duration or timeout: 12 milliseconds
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.4', java.version: '1.6.0_51'
Session ID: 09c833e0-1e91-454e-98e4-b0e9094359e9
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=firefox, rotatable=false, locationContextEnabled=true, version=23.0.1, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, applicationCacheEnabled=true, takesScreenshot=true}]
at new bot.Error (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/atoms/error.js:109:18)
at Object.bot.response.checkResponse (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/atoms/response.js:106:9)
at /Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:275:20
at /Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/base.js:1178:15
at webdriver.promise.ControlFlow.runInNewFrame_ (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1438:20)
at notify (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:328:12)
at notifyAll (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:297:7)
at fulfill (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:402:7)
at /Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1305:10
at /Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/goog/base.js:1178:15
==== async task ====
WebDriver.executeScript()
at webdriver.WebDriver.schedule (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:266:15)
at webdriver.WebDriver.executeAsyncScript (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/webdriver.js:506:15)
at Protractor.waitForAngular (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/lib/protractor.js:375:22)
at Protractor.findElement (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/lib/protractor.js:478:8)
at null. (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/tests/test/scenarios/login1.js:11:14)
at /Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/jasminewd/index.js:54:12
at webdriver.promise.ControlFlow.runInNewFrame_ (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1438:20)
at webdriver.promise.ControlFlow.runEventLoop_ (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1303:8)
at wrapper as _onTimeout
==== async task ====
at null. (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/jasminewd/index.js:53:12)
at null. (/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/minijasminenode/lib/async-callback.js:45:37)
at Timer.listOnTimeout as ontimeout

@apankov1
Copy link

@stickel one more question if I may.

I moved Sign In part to beforeEach part and it is failing again. I don't think it's a good idea to put all checks under one it neither to login each time.

Now my code looks like this:

var util = require('util');

describe('SignIn Page', function() {
    var ptor;
    beforeEach(function() {
        ptor = protractor.getInstance();
        ptor.get('#/login/');
        ptor.findElement(protractor.By.css('input[name=email]')).sendKeys("login");
        ptor.findElement(protractor.By.css('input[name=password]')).sendKeys("password");
        ptor.findElement(protractor.By.css('button.green.large')).click();
        ptor.waitForAngular();
    }, 30000);


    it ('Check URL after Sign In', function(){
        var expectedURL = ptor.baseUrl + 'home';
        ptor.sleep(10000);
        expect(ptor.getCurrentUrl()).toBe(expectedURL);
    }, 30000);

});

And it is failing. If I move code back to it ('Check URL after Sign In', function(){ it will start working correct.

What do you think will be the best way to do it? I want to structure my code so that Iog in in beforeEach and then write different test.

Thanks

@stickel
Copy link

stickel commented Sep 17, 2013

@apankov1 How is it failing? What's the error? One thing to try (I haven't tested this) would be putting ptor.waitForAngular() inside the it block instead of the beforeEach block.

Why do you want to log in before each test? After the first login the app will remember the state it was in after each test. For example, if you first test the log in form (and it's successful), the next test will happen on the logged in state (/home in your case). If you really want to log in before each test, you may have to log out after each test because all tests will be run in the same session.

@apankov1
Copy link

@stickel I'm getting:

   Message:
     timeout: timed out after 30000 msec waiting for spec to complete
   Stacktrace:
     undefined

I probably misunderstanding use of beforeEach. I though that before each it code in beforeEach section will be used and it will open login page which means I after each time login page gets opened I need to log in to execute the test inside the app, that's actually the reason I wanted to move log in in before. I even created a separate login function which I'm calling in before each. Am I doing it wrong?

Thank you.

@ranjanbhambroo
Copy link

@stickel I am able to login. It works fine without any timeout.
I have a logout link on the page defined as Logout

The code i am using to make a click on the link is below:
var util = require('util');
describe('Login', function() {
var ptor;
beforeEach(function() {
ptor = protractor.getInstance();
ptor.get('#/login');
},30000);

it('allows user to log in', function() {
    var expectedUrl = ptor.baseUrl + '#/missioncontrol';
    ptor.findElement(protractor.By.input('login')).sendKeys('ranjan');
    ptor.findElement(protractor.By.input('password')).sendKeys('Password1');
    ptor.findElement(protractor.By.css('input.login-form-container-button')).click(); 
    ptor.sleep(10000);
    expect(ptor.getCurrentUrl()).toBe(expectedUrl);     
    ptor.findElement(protractor.By.linkText('Logout')).click();
}, 30000);  

});

The error i am getting is:

ScriptTimeoutError: Timed out waiting for async script result after 1ms
Command duration or timeout: 10 milliseconds
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.4', java.version: '1.6.0_51'
Session ID: 677238de-fe54-8d4c-a9d3-8ea10920e4d2
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=firefox, rotatable=false, locationContextEnabled=true, version=23.0.1, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, applicationCacheEnabled=true, takesScreenshot=true}]

Can you help me understand why this might be occurring?
Thanks

@stickel
Copy link

stickel commented Sep 17, 2013

@apankov1 It sounds like you have it right. beforeEach is called before each it block. After each it block finishes the app will do whatever is in beforeEach prior to running the next test (in your case, load #/login, put in a user/pass, click the button).

In my app I have logging in as one it test and go on from there. I only use beforeEach to set up variables and find elements I'll be reusing in different tests.

@stickel
Copy link

stickel commented Sep 17, 2013

@rj051286 You're trying to end a test after clicking a logout button; there's no expectation. I'd suggest moving ptor.findElement(protractor.By.linkText('Logout')).click() to another test (it).

@ranjanbhambroo
Copy link

@stickel So i will have to move the login credentials in the beforeEach correct? this is what i have now, Still timing out

var util = require('util');
describe('Login', function() {
var ptor;
beforeEach(function() {
ptor = protractor.getInstance();
ptor.get('#/login');
ptor.findElement(protractor.By.input('login')).sendKeys('ranjan');
ptor.findElement(protractor.By.input('password')).sendKeys('Password1');
ptor.findElement(protractor.By.css('input.login-form-container-button')).click();
},30000);

it('allows user to log in', function() {
    var expectedUrl = ptor.baseUrl + '#/missioncontrol';    
    ptor.sleep(10000);
    expect(ptor.getCurrentUrl()).toBe(expectedUrl);     
}, 30000); 
it('allows user to logout', function() {
    var expectedUrl = ptor.baseUrl + '#/login';
    ptor.findElement(protractor.By.linkText('Logout')).click();
    ptor.sleep(10000);
    expect(ptor.getCurrentUrl()).toBe(expectedUrl);            
}, 30000);   

});

@stickel
Copy link

stickel commented Sep 18, 2013

@rj051286 You don't have to move the login credentials into the beforeEach. Honestly, I'd probably do this in my tests:

var util = require('util');
describe('Login', function() {
    var ptor;
    beforeEach(function() {
        ptor = protractor.getInstance();
    });

    it('allows user to log in', function() {
        var expectedUrl = ptor.baseUrl + '#/missioncontrol';
        // We're going to log into the app
        ptor.get('#/login');
        ptor.findElement(protractor.By.input('login')).sendKeys('ranjan');
        ptor.findElement(protractor.By.input('password')).sendKeys('Password1');
        ptor.findElement(protractor.By.css('input.login-form-container-button')).click();
        ptor.sleep(10000);
        // Successful login means we should be on the 'missioncontrol' page
        expect(ptor.getCurrentUrl()).toBe(expectedUrl);     
    }, 30000); 

    it('allows user to logout', function() {
        var expectedUrl = ptor.baseUrl + '#/login';
        // Because we logged in successfully in the last test
        // the Logout button should be on the page, let's click it
        ptor.findElement(protractor.By.linkText('Logout')).click();
        ptor.sleep(10000);
        // we logged out and should be on the login page again
        expect(ptor.getCurrentUrl()).toBe(expectedUrl);     
    }, 30000);
});

@ranjanbhambroo
Copy link

@stickel I got this error

Login
allows user to log in
allows user to logout

Failures:

  1. Login allows user to logout
    Message:
    timeout: timed out after 30000 msec waiting for spec to complete
    Stacktrace:
    undefined

Finished in 47.721 seconds
2 tests, 2 assertions, 1 failure

Shutting down selenium standalone server

/Users/ranjanbhambroo/Documents/protractor_voloforce_tests/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1542
throw error;
^
ScriptTimeoutError: Timed out waiting for async script result after 99952ms
Command duration or timeout: 88.63 seconds
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.4', java.version: '1.6.0_51'
Session ID: 9fa124ef-5f78-1740-9fce-f5baf3c266b9

@apankov1
Copy link

@stickel i have another question/issue, which is most likely has nothing to do with bug but I don't want to create a separate topic because it looks very similar. I'm getting timeout issue when I'm trying to get text and check if it's correct.

here is my code:


var util = require('util');

var loginAsExistingUser;
var firstName = 'Andrew';
var lastName = 'Auto1'

loginAsExistingUser = function (ptor) {
    ptor.findElement(protractor.By.css('input[name=email]')).sendKeys("login email");
    ptor.findElement(protractor.By.css('input[name=password]')).sendKeys("login password");
    ptor.findElement(protractor.By.css('button.green.large')).click();
};

describe('Portal SignIn Page', function() {
    var ptor;

    beforeEach(function() {
        ptor = protractor.getInstance();
        ptor.get('#/login/');
    }, 20000);


    it ('Check URL after Sign In', function(){
        ptor.waitForAngular();

        var expectedURL = ptor.baseUrl + 'home';

        loginAsExistingUser(ptor);
        ptor.sleep(10000);

        expect(ptor.getCurrentUrl()).toBe(expectedURL);

    }, 20000);

    it ('Checking username', function(){
        loginAsExistingUser(ptor);
        ptor.sleep(10000);
        expect(ptor.findElement(protractor.By.css('div.menu')).getText()).
            toEqual(firstName + lastName);
    }, 20000);

}); 

I'm getting:

Failures:

  1) Portal SignIn Page Checking username
   Message:
     timeout: timed out after 20000 msec waiting for spec to complete
   Stacktrace:
     undefined

User's name is shown in the menu. I'm assuming that in case if selector was wrong it would show error:

   Message:
     NoSuchElementError: no such element

Please let me know if I should open a separate ticket with this question (just don't want to pollute issue tracker).

Thank you for you help and responses.

@stickel
Copy link

stickel commented Sep 18, 2013

@rj051286 I'm not sure why the test is timing out now. It could be a slow server response. If you increase the timeout does it still fail the same way? @juliemr might have better insight into this specific issue.

@apankov1 Try removing loginAsExistingUser and ptor.sleep() from the second test ('Checking username'). The test runner is already logged in and doesn't need to be logged in a second time. @juliemr also mentioned in another issue that expect can't handle + so you might have to do the concatenation somewhere else. For example,

var name = firstName + lastName;
expect(...).toEqual(name);

@apankov1
Copy link

@stickel thanks a lot for your help. I've changed my code as you suggested but I still get timeout.

I'm trying to debug my code with this ugly stuff:

    it ('Checking username', function(){
        var name1;
        name1 = ptor.findElement(protractor.By.css('div.login-menu-button')).getText().
            then(console.log("Trying to assign a variable " + name1));


        //console.log(ptor.findElement(protractor.By.css('div.login-menu-button')).getText());

        //var name = (firstName + lastName);
        //expect(ptor.findElement(protractor.By.css('div.login-menu-button')).getText()).
            //toEqual(name);
    }, 20000);

When I do this I get following
Trying to assign a variable undefined. Why my variable gets undefined? Is it because of wrong selector or my code is wrong itself?

Thanks

@stickel
Copy link

stickel commented Sep 18, 2013

@apankov1 In my tests I usually keep the ptor calls out of expectations. See if that helps.

it('Checking username', function() {
    var name = firstName + lastName;
    ptor.findElement(protractor.By.css('div.login-menu-button')).getText().
        then(function(username) {
            expect(username).toEqual(name);
        });
}, 20000);

@apankov1
Copy link

@stickel, i've changed my code to match yours


    it ('Checking username', function(){
       var name = (firstName + lastName);
       ptor.findElement(protractor.By.className('login-menu-button')).getText().
           then(function(username) {
               expect(username).toEqual(name);
           });
    }, 30000);

but I still get an error:

Failures:

  1) Portal SignIn Page Checking username
   Message:
     timeout: timed out after 30000 msec waiting for spec to complete
   Stacktrace:
     undefined

Finished in 54.401 seconds
3 tests, 3 assertions, 1 failure

So weird.

@stickel
Copy link

stickel commented Sep 18, 2013

@apankov1 Small thing, you've got protractor.By.className('login-menu-button') where I had protractor.By.css('.login-menu-button'). Is that a typo in the question or code?

@apankov1
Copy link

@stickel I'm trying both By.className and By.css. With . and without. Non of these work.

@juliemr
Copy link
Member Author

juliemr commented Sep 19, 2013

Re: timeouts

  • can you confirm that there are no polling $http or $timeout calls on your page? These will cause Protractor timeouts.
  • if that's not an issue, can you try changing a couple timeouts to see what the issue is? Right after ptor.getInstance(), add ptor.driver.manage().timeouts().setScriptTimeout(2000). This will set the timeout for the script that waits for Angular to be 2 seconds. Then, can you let me know what error you're getting?

@apankov1
Copy link

Hey @juliemr, we do have $timeout call on our page. Does that mean that we won't be able to use protractor for our project? It's pretty sad. We some core functionality relaying on it. Is there any workaround for it?

I also did what you suggested in and got following error:

Failures:

  1) Portal SignIn Page Checking username
   Message:
     ScriptTimeoutError: asynchronous script timeout: result was not received in 2 seconds
  (Session info: chrome=29.0.1547.76)
  (Driver info: chromedriver=2.0,platform=Mac OS X 10.8.5 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 2.06 seconds

@apankov1
Copy link

@juliemr, I went through opened discussions and found that this issues is being discussed here #49. I will keep an eye on this ticket. I have a question thought about at what point ptor.ignoreSynchronization = true; should be defined? I'm trying to put it in beforeEach function and in it itself but still get a timeout.

@brianmriley
Copy link

For what it's worth, I'm using AngJS + RequireJS and the following E2E worked for me via a Grunt task.

Couple of things to note:

  • If I moved the protractor singleton call to anywhere sans the very first line to execute, no dice.
  • If tried using ptor.waitForAngular(); then I'd receive the error ` UnknownError: javascript error: Cannot call method 'get' of undefined.
  • We're manually bootstrapping the app due to RJS so we need to wait a bit...
  • Selenium SA Server 2.35
describe("AppScenario basic startup tests", function()
{
    // NOTE: this must be done first
    var ptor = protractor.getInstance();

    //-----------------------------------------------------------------------
    // Setup/Teardown  Methods
    //-----------------------------------------------------------------------

    /**
     * Setup the base url.
     */
    beforeEach(function()
    {
        ptor.driver.get(ptor.baseUrl);
    });

    //-----------------------------------------------------------------------
    // Tests Suite
    //-----------------------------------------------------------------------

    /**
     * Ensure that the application defaults to the login view when no other url hash is provided
     */
    it("should automatically redirect to /login when location hash/fragment is empty", function()
    {
        // we make protractor sleep for 5 seconds since we need to wait for the app to bootstrap manually
        // this is not ideal, but will suffice for now
        // consider using ptor.waitForAngular();
        ptor.sleep(5000);
//      ptor.waitForAngular(); // this throws: UnknownError: javascript error: Cannot call method 'get' of undefined

        ptor.getCurrentUrl().
            then(function(url) {
                expect(url).toEqual(ptor.baseUrl+"#/login");
            });
    });
});

@ranjanbhambroo
Copy link

@stickel I have tried increasing the time out but i am still getting the timeout errors...

@brianmriley
Copy link

Is this done for the dev in the framework behind the scenes or is there something the dev needs to add to the test manually to enforce this?

@juliemr
Copy link
Member Author

juliemr commented Sep 24, 2013

Hi,

I think this issue has turned into a couple different issues. Log-in issues may have been addressed here: https://github.com/angular/protractor/blob/master/docs/faq.md

If there are lingering other problems, please open a new issue with a descriptive subject for them!

@carolineBda
Copy link

Hello,

Concerning the getCurrentUrl(), I'm on 0.10 and I still I have an inconsistent behaviour when I'm doing:
expect(ptor.getCurrentUrl()).toBe(ptor.baseUrl + '/myUrl');

ptor.getCurrentUrl() is either malformed, or the previous url I was on, or right.

Is this fix for you or should I reopen that bug?

@eduardomartines
Copy link

reopen, please!

@juliemr
Copy link
Member Author

juliemr commented Jun 16, 2014

@eduardomartines if you are having an issue, please include exactly what is failing and open a new bug. This issue is too out of date to be reopened.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants