J'ai effectué une recherche sur Google et sur le site SO et j'obtiens des réponses pour Java mais ne semble pas en obtenir pour node.js
J'ai une application Web qui prend du temps à charger. Je voudrais programme Selenium pour attendre que la page est chargée et ensuite effectuer certaines actions.
Mon code actuel est le suivant
//dependencies
var webdriver = require('Selenium-webdriver'),
util = require('util'),
_ = require('underscore');
var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
var branchName = _.isUndefined(process.argv[3]) ? 'branch' : process.argv[3],
hostName = _.isUndefined(process.argv[2]) ? 'localhost' : process.argv[2],
appTmpl = 'http://%s/%s',
username = 'xxxx',
password = 'xxxx';
var appUrl = util.format(appTmpl, hostName, branchName);
driver.get(appUrl);
driver.findElement(webdriver.By.name("username")).sendKeys(username);
driver.findElement(webdriver.By.name("password")).sendKeys(password);
driver.findElement(webdriver.By.name("login_button")).click();
driver.quit();
L'erreur que je reçois est:
C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:1643
throw error;
^
NoSuchElementError: no such element
(Session info: chrome=37.0.2062.103)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.1 SP1 x86_64)
at new bot.Error (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\atoms\error.js:109:18)
at Object.bot.response.checkResponse (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\atoms\response.js:106:9)
at C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\webdriver.js:277:20
at C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\goog\base.js:1243:15
at webdriver.promise.ControlFlow.runInNewFrame_ (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:1539:20)
at notify (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:362:12)
at notifyAll (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:331:7)
at resolve (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:309:7)
at fulfill (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:429:5)
at C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\promise.js:1406:10
==== async task ====
WebDriver.findElement(By.name("username"))
at webdriver.WebDriver.schedule (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\webdriver.js:268:15)
at webdriver.WebDriver.findElement (C:\Work\study\Selenium\node_modules\Selenium-webdriver\lib\webdriver\webdriver.js:711:17)
at Object.<anonymous> (C:\Work\study\Selenium\test.js:15:8)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
Je suis tombé sur une réponse à ma question
Donc, pour attendre qu'un élément apparaisse, nous devons:
driver.wait(function () {
return driver.isElementPresent(webdriver.By.name("username"));
}, timeout);
Vous pouvez enregistrer un auditeur sur webdriver.wait
en utilisant then()
return driver.wait(until.elementLocated(By.name('username')), 5 * 1000).then(el => {
return el.sendKeys(username);
});
Vous n'avez pas besoin d'une fonction personnalisée, vous pouvez simplement faire ceci:
let el = await driver.findElement(By.id(`import-file-acqId:${acqId}`));
await driver.wait(until.elementIsVisible(el),100);
await el.sendKeys(file);
Voir les docs ici:
https://seleniumhq.github.io/Selenium/docs/api/javascript/module/Selenium-webdriver/lib/until.html
Essayez quelque chose comme ça:
function isItThere(driver, element){
driver.findElement(webdriver.By.id(element)).then(function(webElement) {
console.log(element + ' exists');
}, function(err) {
if (err.state && err.state === 'no such element') {
console.log(element + ' not found');
} else {
webdriver.promise.rejected(err);
}
});
}
Je l'ai adapté légèrement en fonction de ce que j'ai trouvé ici: Vérifier si l'élément existe - Selenium/javascript/node-js et cela a fonctionné avec charme.
C'est la seule chose qui fonctionne pour moi:
const element = By.id('element');
driver.wait(until.elementLocated(element));
const whatElement = driver.findElement(element);
driver.wait(until.elementIsVisible(whatElement), 5000).click();
J'utilise habituellement de cette façon:
var el = driver.wait(until.elementLocated(By.name('username')));
el.click();
Écriture fonction asynchrone pour éviter ce problème
(async function() {
let url = args[0];
await driver.get(url);
driver.quit();
})();
J'ai proposé cette approche car elle maintient la syntaxe chainable de promesse pour que je puisse écrire ceci: await waitFind(By.id('abc')).click()
const waitFind = (locator) => {
return driver.findElement(async () => {
await driver.wait(until.elementLocated(locator));
return driver.findElement(locator);
});
}