webdriverio: [๐ Bug]: isExisting calls findElements (multiple), a potentially expensive op
WebdriverIO Version
latest
Node.js Version
14
Mode
WDIO Testrunner
Which capabilities are you using?
{
platformName: "iOS"
}
What happened?
Like the title says, under the hood, webdriverIO calls findElements (multiple) when using isExisting and waitForExist.
https://github.com/webdriverio/webdriverio/blob/f1313735cd3441dc172d3955479575854e64a306/packages/webdriverio/src/commands/element/isExisting.ts#L58
Only findElement (single) calls should be needed to assert whether or not the element / selector exists.
This becomes a problem because findElements calls can be quite expensive.
An example would be large scrollable lists on iOS apps, they can take 30+ seconds.
What is your expected behavior?
No call to findElements should be made on isExisting as it is not needed and in fact can needlessly hang the command.
How to reproduce the bug.
Context:
Iโm testing a mobile app with Appium, testing a scrollable list.
Scrollable lists on iOS always possess all the list items, unlike Android which loads the list items into view as you scroll/swipe up and down. Therefore finding multiple elements on iOS can lead to a time consuming operation for large lists. In the same situation however, single findElement call is cheap and fast. Assume a findElements call takes 30+ seconds to resolve and we are trying to purposely avoid it
The flow goes something like this:
- Wait for the (scrollable) list container
- Then wait for the list items to load within the scrollable list
- Irrelevant, do whatever else, expectation, whatever
This translates to some code resembling this:
get list() {
return $('id=list');
}
get items() {
return $$('id=list-item');
}
waitForItems = (title) => {
// We previously already waited for the list container
// We want to wait for the list items to load within the scrollable list
// Assume they appear instantly
// Option 1, takes 30+ seconds because of findElements call
browser.waitUntil(() => this.items.length);
// Option 2, takes 30+ seconds because of findElements call
browser.waitUntil(() => $('id=list-item').isExisting());
// Option 3, takes 30+ seconds because of findElements call
$('id=list-item').waitForExist();
// Workaround to save time
// Option 4, findElements not called, findElement called, 2 seconds
browser.waitUntil(() => !!$('id=list-item').elementId);
}
Relevant log output
No relevant logs.
Code of Conduct
- I agree to follow this projectโs Code of Conduct
Is there an existing issue for this?
- I have searched the existing issues
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 17 (16 by maintainers)
Commits related to this issue
- fix(#7580): update code with the suggested solution — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): simplify implementation — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): address feedback — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): fix error TS2339 — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add type — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add missing await — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add tests — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add missing space — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): update return — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): update code with the suggested solution — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): simplify implementation — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): address feedback — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): fix error TS2339 — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add type — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add missing await — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add tests — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): add missing space — committed to tmjpedro/webdriverio by deleted user 3 years ago
- fix(#7580): update return — committed to tmjpedro/webdriverio by deleted user 3 years ago
It seems potentially a little confusing to hide some magic in there, but if thatโs your suggestion, then Iโm happy to work with it. FWIW, Iโm using WDIO to help build Appium drivers for lots of platforms beyond mobile, and it seems like having the flexibility to use this new behaviour for any platform might be good. I can also imagine myself wanting this for Selenium if I need more fine-grained control over things.