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.)
waitForAngular
? – Preemie