2

Использование selenium-webdriver (api docs here), как вы можете подождать, пока элемент будет виден?Selenium-webdriver JS - как ждать, пока элемент будет виден

У меня есть следующие функции, часть самодельного набора помощников по тестированию, и первый работает, но второй не работает (например, время ожидания и элемент должны быть видимы, даже если они существуют - как подтвержденный первой функцией, которая работает - и видна - как подтверждают все мыслимые тесты и проверки страницы 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 для этого кода заканчивается время экземпляра WebDriver (результат new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build()) после augment метод не monkeypatches данного объекта WebDriver ... возможно сомнительный дизайн шаблона, но не является причиной для моих проблема здесь :)


UPDATE: Видимо, это происходит только для XPath локаторов, как { xpath: '//*[contains(text(), "first name")]' } ... не то, что он делает больше смысла в настоящее время. Кроме того, это то же самое для Firefox, поэтому это не странный хром-webdriver thingy ...

ответ

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); 
}); 
+0

Спасибо! Вы помогли мне лучше структурировать код моего обещания. Но это была не единственная проблема. В конце концов, единственным обходным решением, которое я нашел, было избежать * всех селекторов xpath * и добавить специальный код, который проверяет видимость * внутри браузера * на 'executeScript' для случаев, когда я использовал xpath для ... наверное, лучше всего подумать делать это просто отказаться от всякой надежды и бросить взломать после взлома, пока все не сработает> 90% времени ... ожидая, что selenium/webdriver сделает что-нибудь ожидаемым/предсказуемым образом, бессмысленно ... – NeuronQ

+0

Я рад, что это помогло. Хотя у меня никогда не было проблем с XPath. Не могли бы вы добавить пример или лучше, создать новый вопрос с воспроизводимым примером? –

Смежные вопросы