使用selenium-webdriver(api docs here),您如何等待元素可见?
我有以下功能,一组自制的测试帮助器,第一个工作但第二个工作失败(例如,即使它存在,它也会超时并且元素可见 - 如已确认通过第一个有效的功能 - 并且可见 - 由所有可以想象的测试和页面html / css / js的检查确认。
他们是:
/**
* Wait for an element to exist
*
* @param {object} locator
* @param {int} timeout (ms)
*
* @return {Promise<element>}
*/
// !! THIS WORKS OK
exports.waitForElement = function (locator, timeout) {
var waitTimeout = timeout || DEFAULT_TIMEOUT;
return this.wait(until.elementLocated(locator), waitTimeout)
.then(() => {
return this.findElement(locator);
});
};
/**
* Wait for an element to exist and then wait for it to be visible
*
* IMPORTANT: this is probable what you want to use instead of
* waitForVisibleElement most of the time.
*
* @param {hash} locator
* @param {number} timeout
*
* @return {Promise<element>}
*/
// !! THIS FAILS TO WORK AS EXPECTED
exports.waitForVisibleElement = function (locator, timeout) {
var waitTimeout = timeout || DEFAULT_TIMEOUT;
return this.waitForElement(locator, waitTimeout)
.then(el => {
console.log('--- element found:', el);
return this.wait(until.elementIsVisible(el), waitTimeout)
.then(() => {
console.log('--- element visible!');
// this is to make sure we are returning the same kind of
// promise as waitForElement
return this.findElement(locator);
});
});
};
...我在多个环境中进行了测试,因此waitForVisibleElement
内部的代码没有其他原因导致问题,但我似乎找不到任何原因导致其无效工作!
作为澄清,在this
方法monkeypatches给定的webdriver对象后,该代码的new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build()
最终成为webdriver实例(augment
的结果...)可能是一个有问题的设计模式,但这里没有我的问题的原因:)
UPDATE:显然这只发生在XPath定位器上,例如{ xpath: '//*[contains(text(), "first name")]' }
...而不是它现在更有意义了。此外,它与Firefox相同,所以它不是一个奇怪的chrome-webdriver thingy ...
答案 0 :(得分:3)
很可能是承诺问题。 试试这个:
exports.waitForElement = function (locator, timeout) {
var timeout = timeout || DEFAULT_TIMEOUT;
return this.wait(until.elementLocated(locator), timeout);
};
exports.waitForVisibleElement = function (locator, timeout) {
var timeout = timeout || DEFAULT_TIMEOUT;
var element = this.wait(until.elementLocated(locator), timeout);
return this.wait(new until.WebElementCondition('for element to be visible ' + locator, function() {
return element.isDisplayed().then(v => v ? element : null);
}), timeout);
};
用法:
driver.get("...");
driver.waitForElement(By.id("..."), 2000).getText().then(function(text){
console.log(text);
});
driver.waitForVisibleElement(By.id("..."), 2000).getText().then(function(text){
console.log(text);
});