Ad

How To Loop Through Webdriverjs Elements Until Element Has Text Value

- 1 answer

I am trying to work out how looping in WebDriverJs works with promises.

Say you had the following html:

  <div id="textelements">
    <span onclick="spanClicked('Rock')">Rock</span>
    <span onclick="spanClicked('Paper')">Paper</span>
    <span onclick="spanClicked('Scissors')">Scissors</span>
  </div>

Using WebDriverJs I wanted to find the span with text 'Scissors' and click it.

The easiest thing would be to make sure the source html had appropriate identifiers, but say that couldn't be changed, what would the WebDriverJs code look like given the html above.

I have tried the following:

function clickElementWithText(driver, textValue) {
    driver.findElements(webdriver.By.css('#textelements span')).then(function(spans) {
        for (var i = 0; i < spans.length; i++) {
            var matched = spans[i].getText().then(function(text) {
                console.log('Text value is: ' + text);
                return text === textValue;
            });
            console.log(matched);
            if (matched === true) {
                console.log('clicking!');
                spans[i].click();
                return;
            }
        }
    });
}

var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
driver.get('http://webdriverjsdemo.github.io/');
clickElementWithText(driver, 'Scissors');

The issue is that matched doesn't equal true when being evaluated even though it should have been set to true.

Any ideas what is happening?

Ad

Answer

How about we simplify it by using some functional programming, filter() function:

var spans = driver.findElements(webdriver.By.css('#textelements span'));
webdriver.promise.filter(spans, function(span) {
    return span.getText().then(function(text) {
        console.log('Text value is: ' + text);
        return text === textValue;
    });
}).then(function (filteredSpans) {
    filteredSpans[0].click();
});

Or, a "less cool" solution, but a more straightforward, approach would be to use By.xpath:

var span = driver.findElement(webdriver.By.xpath('//*[@id = "textelements"]//span[. = "' + textValue + '"]'));
span.click();

Or, we may also check the onclick attribute value with By.css:

var span = driver.findElement(webdriver.By.css('#textelements span[onclick*="' + textValue + '"]'));
span.click();
Ad
source: stackoverflow.com
Ad