我正在尝试弄清楚WebDriverJs中的循环如何与Promise一起工作。

假设您有以下html:

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


我想使用WebDriverJs查找带有文本“ Scissors”的跨度,然后单击它。

最简单的方法是确保源html具有适当的标识符,但是要说不能更改,鉴于上面的html,WebDriverJs代码看起来像什么。

我尝试了以下方法:

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');


问题是即使被匹配时,匹配项也不应该等于true,即使它应该设置为true。

有什么想法吗?

最佳答案

我们如何通过使用一些功能性编程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();
});


或者,一种“不太酷”的解决方案,但更直接的方法是使用By.xpath

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


或者,我们也可以使用onclick检查By.css属性值:

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

07-28 07:10