I am writing Webdriver automation for a web app. I have a test that looks like this:
it('has five items', async function(done) { try { await driver.wait(until.elementLocated(By.className('item-class')),5000); const items = await driver.findElements(By.className('item-class')); expect(items.length).toBe(5); done(); } catch(err) { console.log(err) } }
This test will pass about 2/3 of the time, but will sometimes fail with:
Expected 0 to be 5.
I would think that there should be no way to get this response, since the first line is supposed to make it wait until some of these items exist. I could understand a result of “Expected 1 to equal 5.”, in the case that one item was added to the page, and the rest of the test completed before they were all there, but reaching the expect() call with 0 items on the page does not make sense to me.
The questions, then, are:
1) What am I missing / not understanding, such that this result is in fact possible?
2) Is there a different construct / method I should be using to make it wait until the expected items are on the page?
Advertisement
Answer
I checked the source code and elementLocatedBy
uses findElements
, see here. And findElements
can return an empty array of elements after the timeout and hence 0
is expected (learnt something new today).
You can write something custom or use some ready-made method from here that doesn’t use findElements
driver.wait(async function() { const items = await driver.findElements(By.className('item-class')) return items.length > 0; }, 5000);