1

In order to click a button I have to wait for an element to slide into the visible viewport. This works reliably:

await browser.sleep( 1200 );
await btnToggleDeactivateQuestionnaire.click();

However, since I've learned that using "browser.sleep()" is considered bad practice, I want to achieve this using protractor's ExpectedConditions:

let isPresent = EC.presenceOf(btnToggleDeactivateQuestionnaire);
let isVisible = EC.visibilityOf(btnToggleDeactivateQuestionnaire);
let isClickable = EC.elementToBeClickable(btnToggleDeactivateQuestionnaire);
let isPresentAndVisibleAndClickable = EC.and(isPresent, isVisible, isClickable);

await browser.wait(isPresentAndVisibleAndClickable, 4000);
await btnToggleDeactivateQuestionnaire.click();

After waiting 4 seconds, i get the following error:

Failed: Wait timed out after 4019ms
TimeoutError: Wait timed out after 4019ms
    at C:\xxx\lib\promise.js:2201:17
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

After a lot of trial and error I've figured out that using only "EC.presenceOf" will do the trick. However, as soon as I chain it with "EC.visibilityOf" or "EC.elementToBeClickable", or use either alone, the test stops for 4 seconds and fails at that point.

To me, that behaviour doesn't seem to make sense at all. Especially since that element is present since the page loaded, it's just not visible and clickabe yet (as it has to slide into view first).

Is my general understanding of ExpectedConditions, or their behaviour on a non-angular site, wrong? What am I missing here?

Jan and RESTless
  • 199
  • 1
  • 14

1 Answers1

1

My guess would be that this bit doesn't work well within protractor's capabilities?: EC.and(isPresent, isVisible, isClickable);

I'd try something like this instead:

let isPresent = await EC.presenceOf(btnToggleDeactivateQuestionnaire);
let isClickable = await EC.elementToBeClickable(btnToggleDeactivateQuestionnaire);
await btnToggleDeactivateQuestionnaire.click();

Since I don't think you need visibilityOf followed by elementToBeClickable, waiting for its clickability should work fine.
I learned that a web application is not always perfectly made so when you are automating tests, finding the correct element to wait on, is the most challenging part.

Joaquin Casco
  • 704
  • 5
  • 14