angular / protractor

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

Page won't resync after using browser.pause() to interact with browser manually #2513

Closed bleurose closed 9 years ago

bleurose commented 9 years ago

I am trying to test an enrollment page which has a built-in "recaptcha" box to prevent "bots" from registering (I can't disable this behavior for testing - that would be ideal but I can't and in any case, I think the approach I am taking should work).

A simplified (non-PageObject) version of my code (-spec file) is as follows:

describe("enroll user page", function() {
  it("should enroll a user", function() {
    browser.get("http://myurl.com/enroll");
    element(by.model("contact.firstName")).sendKeys("first");
    element(by.model("contact.lastName")).sendKeys("last");
    element(by.model("contact.companyName")).sendKeys("company001");
    element(by.model("contact.phoneNbr")).sendKeys("8318313333");
    element(by.model("contact.companyWebUrl")).sendKeys("www.test.com");
    element(by.model("contact.email")).sendKeys("testemail+9999@gmail.com");
    element(by.model("contact.password")).sendKeys("pswd:pswd");
    element(by.model("contact.passwordConfirm")).sendKeys("pswd:pswd");
    browser.pause();
    element(by.css("form[name='addContactForm'] button.my-submit")).click();
  });
});

When I run this (including --troubleshoot), I get the following output up to the browse.pause() statement:

/Users/jonrosen/Documents/repo/gyft/gyft-b2b-webapp/test
: protractor --troubleshoot --specs=e2e/enrollment-spec.js 
DEBUG - Running with --troubleshoot
DEBUG - Protractor version: 2.1.0
DEBUG - Your base url for tests is undefined
Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
DEBUG - WebDriver session successfully started with capabilities { caps_: 
   { applicationCacheEnabled: false,
     rotatable: false,
     mobileEmulationEnabled: false,
     chrome: { userDataDir: '/var/folders/sy/cwsgb52d68sczbjsptkz4cmc0000gn/T/.org.chromium.Chromium.kG0x0Q' },
     takesHeapSnapshot: true,
     databaseEnabled: false,
     handlesAlerts: true,
     version: '45.0.2454.93',
     platform: 'MAC',
     browserConnectionEnabled: false,
     nativeEvents: true,
     acceptSslCerts: true,
     'webdriver.remote.sessionid': '9f4096f0-b43f-46f9-ba78-fd9fbad860a5',
     locationContextEnabled: true,
     webStorageEnabled: true,
     browserName: 'chrome',
     takesScreenshot: true,
     javascriptEnabled: true,
     cssSelectorsEnabled: true } }
Starting WebDriver debugger in a child process. Pause is still beta, please report issues at github.com/angular/protractor

------- WebDriver Debugger -------
Starting debugger agent.
Debugger listening on port 5858
 ready

press c to continue to the next webdriver command
press d to continue to the next debugger statement
type "repl" to enter interactive mode
type "exit" to break out of interactive mode
press ^C to exit

-- Next command: executeScript
ControlFlow::1
| Frame::73
| | (pending) Task::72<Asynchronous test function: it()>
| | | Task: Asynchronous test function: it()
| | | Frame::81
| | | | Frame::1525
| | | | | Frame::384
| | | | | | (pending) Task::1539<empty debugger hook>
| | | | | | | Task: empty debugger hook
| | | | | | |     at Array.forEach (native)
| | | | | | | (active) Frame::1545
| | | | | | | | Frame::1547
| | | | Task::396<Protractor.waitForAngular()>
| | | | | Task: Protractor.waitForAngular()
| | | | |     at [object Object].<anonymous> (/Users/jonrosen/Documents/repo/gyft/gyft-b2b-webapp/test/e2e/enrollment-spec.js:14:69)
wd-debug>

At this point, I go to the browser and directly enter the recaptcha validation that is required. According to the documentation on pause(), I should be able to now continue with the application. But when I do that, it hangs and ultimately says that it has timed out trying to synchronize the page. This happens no matter how I exit the debug mode: I can use Ctl-C or I can just use "c" to go to the next statement as is shown below:

wd-debug> c
-- Next command: executeAsyncScript
ControlFlow::1
| Frame::73
| | (pending) Task::72<Asynchronous test function: it()>
| | | Task: Asynchronous test function: it()
| | | Frame::81
| | | | (pending) Task::396<Protractor.waitForAngular()>
| | | | | Task: Protractor.waitForAngular()
| | | | |     at [object Object].<anonymous> (/Users/jonrosen/Documents/repo/gyft/gyft-b2b-webapp/test/e2e/enrollment-spec.js:14:69)
| | | | | (active) Frame::1559
| | | | | | Frame::1561
wd-debug> c
enroll user page
  should enroll a user - fail

Failures:

  1) enroll user page should enroll a user
   Message:
     Timed out waiting for Protractor to synchronize with the page after 11 seconds. Please see https://github.com/angular/protractor/blob/master/docs/faq.md
   Stacktrace:
     undefined

Finished in 39.83 seconds
1 test, 1 assertion, 1 failure

-- Next command: quit
ControlFlow::1
| Frame::1575
| | Frame::1574
| | | (pending) Task::1584<WebDriver.quit()>
| | | | Task: WebDriver.quit()
| | | |     at Array.forEach (native)
| | | | (active) Frame::1596
| | | | | Frame::1598
| | Frame::1595
| | | Frame::1580
wd-debug>

I think this may be a bug in pause(). Thank you for looking at this.

hhaamm commented 9 years ago

@bleurose

Have you tried putting the pause in its own it() function?

Like:

describe("enroll user page", function() {
  it("should enroll a user", function() {
    browser.get("http://myurl.com/enroll");
    element(by.model("contact.firstName")).sendKeys("first");
    element(by.model("contact.lastName")).sendKeys("last");
    element(by.model("contact.companyName")).sendKeys("company001");
    element(by.model("contact.phoneNbr")).sendKeys("8318313333");
    element(by.model("contact.companyWebUrl")).sendKeys("www.test.com");
    element(by.model("contact.email")).sendKeys("testemail+9999@gmail.com");
    element(by.model("contact.password")).sendKeys("pswd:pswd");
    element(by.model("contact.passwordConfirm")).sendKeys("pswd:pswd");
  });
  it("pauses", function() {
    browser.pause();
  });
  it("Submit", function() {
    element(by.css("form[name='addContactForm'] button.my-submit")).click();
  });
});
bleurose commented 9 years ago

tI tried that and the first TWO "it" tests passed but the third timed out with the same error as before. So that means that control is returning from the browser.pause() (it "passes") but the attempt to find the element form in the next step is failing because of the sync problem.

I assume that either I need to do something more to "resync" test with the page but I don't know what that would be. Is there some kind of resync method that is part of browser or protractor objects that could make this happen?

Thanks!

juliemr commented 9 years ago

This error message means that Angular has some pending request on your page, such as a $http request or $timeout. Is there any way that the captcha request is creating that?

To get around this, you can turn off waiting temporarily:

browser.ignoreSynchronizaton = true;
element(by.css("form[name='addContactForm'] button.my-submit")).click();
browser.ignoreSynchronizaton = false;

Closing as I believe this is a specific support question, not a generic issue. Thanks!