loading...

webdriverIO tips: get text from a list of items

intricatecloud profile image Danny Perez Originally published at intricatecloud.io ・2 min read

There's a few ways to go about getting text from a list of elements, but there's been a few gotchas when working with a dynamic webapp where elements are added/removed from the DOM (like react and angular).

The easiest way should be to:

// get some of the headers on wikipedia.org
> browser.getText("#mp-topbanner > ul > li")
[ 'Arts',
  'Biography',
  'Geography',
  'History',
  'Mathematics',
  'Science',
  'Society',
  'Technology',
  'All portals' ]

One exception that I seem to get intermittently with browser.getText(selector) (and also with waitForVisible) is the damn Invalid Argument error. Here's an example of the issue

> browser.url('http://webdriver.io')
> browser.getText('nav > ul > li')
[ 'I/O',
  'Home',
  'Developer Guide',
  'API',
  'Contribute',
  '',
  'API Version',
  '' ]
> browser.getText('nav > ul > li')
/Users/dperez/Documents/projects/tchdp/wdio-tips/node_modules/wdio-sync/build/index.js:357
            throw e;
            ^

Error: java.net.SocketException: Invalid argument
    at new RuntimeError (node_modules/webdriverio/build/lib/utils/ErrorHandler.js:143:12)
    at Request._callback (node_modules/webdriverio/build/lib/utils/RequestHandler.js:316:39)
    at Request.self.callback (node_modules/webdriverio/node_modules/request/request.js:185:22)
java.net.SocketException: Invalid argument
[chrome desktop #0-0] Error: An unknown server-side error occurred while processing the command.

The first call to getText succeeded, and the second call which ran immediately after ran into an error. I believe the error message is coming from Selenium server, and it sends back a very helpful message about invalid arguments. It tends to happen when your selector returns too many elements. In the above example, the selectors were returning 8/9 elements. I've also seen it crap out even with 3 elements, so there's something else going on there.

Here's a workaround. Query for the elements and loop over them manually. I've found this to be a lot less flaky:

> $$("#mp-topbanner > ul > li").map(function(element){
    return element.getAttribute('innerText')
})
[ 'Arts',
  'Biography',
  'Geography',
  'History',
  'Mathematics',
  'Science',
  'Society',
  'Technology',
  'All portals' ]

recap

Selenium can be flaky, and while webdriverio does a good job at making writing tests a lot easier, it does have to deal with the webdriver API at the end of the day. If you're seeing SocketException: Invalid argument, its best to skip the convenience of getText and loop over your elements.


Last week, I started working on integrating a test suite previously built using Nightwatch, and making it work with webdriverIO. While I love all of webdriverIO’s features like synchronous code when using their test runner and a REPL, there were a few things that I’d like to share which were a little hard to find in the docs or on a quick search.

In case you missed it... Each day this week, I've been posting one thing I've learned while setting up webdriverIO. Check out my previous posts here:

Posted on by:

intricatecloud profile

Danny Perez

@intricatecloud

DevOps Engineer & Engineering Manager at an ed-tech company helping our teams ship software quickly and reliably.

Discussion

markdown guide