We have a website that is built 100% from Angular and I was asked to use Protractor to write an end to end testing. Now encountered a problem that if I do not use waitForAngular(false)
and browser.sleep(3000)
then my test fails even I used the ExpectedCondition
.
So here is my Scenario:
In the login page, I can find all elements, send keys to the input box and login. But after login, it fails. It cannot find any element, click any element at all.
My Code looks like this.
describe("/profile", () => {
let page: Profile;
beforeAll(async () => {
page = await login(Profile, user, login);
await browser.wait(ExpectedConditions.presenceOf(page.element));
await navigate(path.profile)
})
afterAll(async () => {
logout();
})
it("should have navigate to the page", async () => {
expect(await browser.getCurrentUrl()).toContain("/profile");
});
it("should have correct page markup", async () => {
// this test fails without waitForAngular(false)
// or browser.sleep(3000) in the navigation or OnPrepare in the config
expect(await page.headerTitle.isDisplayed()).toBe(true);
expect(await page.headerTitle.getText()).toContain("Profile")
})
})
What am I doing wrong?
First of all, browser.wait()
takes three parameters - function condition, timeout, message on failure. Only last one is optional. You forgot to specify timeout time in milliseconds, likely it causes your problem
Second, waitForAngular
takes optional string as a description. Idk why you pass false
to it
P.S. I think you misunderstand major concepts about how to handle waiting in protractor
browser.sleep(ms)
- is explicit wait, stops execution for number of ms specified as a parameter
browser.wait()
- waits until the function passed to it returns true, or for the number of ms passed as a parameter. It's not an explicit wait. Also, its not going to wait indefinitely. You pass timeout time as argument, or it takes jasmineNodeOpts.defaultTimeoutInterval
from your protractor.conf.js or default 30 seconds
Your browser.sleep(ms)
causing performance issue of your tests. Avoid it in your tests
browser.waitForAngular()
- very useful, it waits until your angular app completes all tasks behind scene, but it's included in each actions by default. So no usually no affects if you use 2,3 or 4 times. IMPORTANT, some apps are poorly built and always load something in a background, so your tests are either slow or unresponsive at all. This is why I always run tests with browser.waitForAngularEnabled(false)
, but it's super difficult to handle wait. As an advantage you get fast and reliable tests. And don't pass false
to waitForAngular
, it has no effect.
With that said, forget about browser.sleep()
instead learn how to use browser.wait
if you're using browser.sleep(3000)
you make your tests stop for 3 sec, but what if your next element is ready to be interacted with in 500ms?? so just say wait until element is present(visible(intractable(or whatever you want))), but no longer than 3 sec, and you end up having faster tests
Hope that answers your question