4

Rookie question. I am using webdriver.io to write Appium end to end tests.

I am using these commands to check the presence of an element:

  • $(selector)
  • browser.waitForVisible(selector, timeout, waitForAppearOrDisappear);
  • browser.element('selector')

They all block my tests if the element is not found.

How can I check whether an element exists in a particular moment without blocking the test execution?

I cannot find anything in the (concise) documentation.

PS. This should do the trick browser.findElement(By.css('[data-qa="some-id"]')); but it's not a wdio command. (findElement and By are not recognized)


npm dependencies:

"appium": "^1.10.0",
"appium-doctor": "^1.6.0",
"wdio-appium-service": "^0.2.3",
"wdio-jasmine-framework": "^0.3.8",
"wdio-spec-reporter": "^0.1.5",
"webdriverio": "^4.14.1",
Gabe
  • 5,997
  • 5
  • 46
  • 92
  • 1
    I don't use this language but typically you do a findElement**s** (plural) and then check to see if the collection is empty. If it's not, then you know the element exists and can proceed. If it is empty, you can handle that error case or branch of the logic flow. See [$$](https://webdriver.io/docs/api/browser/$$.html). – JeffC May 09 '19 at 17:31
  • Thanks for your reply. I was using $$ so far but it stopped working for some reason.. :( – Gabe May 09 '19 at 17:47
  • 1
    Somehow I doubt that $$ just stopped working. My guess is you've changed the code in some way or the page has changed and the locator has failed, etc. I would make sure you have the current version of all of the libraries that you are using and try again. – JeffC May 09 '19 at 18:03
  • does this work? https://webdriver.io/docs/api/element/isExisting.html – gazzo May 10 '19 at 07:50
  • Is this a `wdio-v4`, or `wdio-v5` question? There are different recommended ways to tackle the task at hand, based on WebdriverIO version. Also some of the methods you mentioned have seen a separation of concern in the latest version. – iamdanchiv May 14 '19 at 09:09
  • @iamdanchiv added my dependencies, thanks – Gabe May 15 '19 at 04:41
  • Any status on this @GaSacchi? – iamdanchiv Jul 13 '19 at 05:56
  • $$ resumed working as expected.. – Gabe Jul 16 '19 at 05:56

2 Answers2

3

Use findElements instead - https://webdriver.io/docs/api/element/$$.html:

$$(selector)

This should return you an empty array if the element can't be found, it should not cause a failure though.

Ardesco
  • 7,281
  • 26
  • 49
0

Well, the simples way would be to abuse the fact that querying the Selenium server (using $ / element) is a non-breaking operation.

Suppose you have to query 2 elements, one has rendered inside the DOM, the other didn't (or the element doesn't exist altogether).

let thisLoaded = $('span.coreSpriteFacebookIconInverted');
let thisDidnt = $('span.coreSpriteInstagramIconInverted');

The two variables would have the following contents:

thisDidnt = { 
  sessionId: '7056961e1950b5c54827a51c137cca96',
  value: { ELEMENT: '0.8611270215748772-1',
           'element-6066-11e4-a52e-4f735466cecf': '0.8611270215748772-1' },
  selector: 'span.coreSpriteFacebookIconInverted',
  _status: 0 
}

thisDidnt = { 
  type: 'NoSuchElement',
  message: 'An element could not be located on the page using the given search parameters.',
  state: 'failure',
  sessionId: '7056961e1950b5c54827a51c137cca96',
  value: null,
  selector: 'span.coreSpriteInstagramIconInverted' 
}

Thus, you can now proceed to do your checks ...

if (thisLoaded.value) {
  // > if element loaded <
} else { 
  // > if element didn't load <
}

I'll add more when I get home ...

iamdanchiv
  • 4,052
  • 4
  • 37
  • 42
  • 1
    Does it depend on timeout settings? I hope you got home well though... – hypers Aug 09 '22 at 09:21
  • 1
    @hypers, only if you configure it ```exports.config = { waitforTimeout: 5000 }``` in your config file, or override explicitly per call, more details in Timeouts section of DOCs. Sadly, I never made it home again... Thanks for the chuckle! :)) Bless ya! – iamdanchiv Aug 11 '22 at 19:51