J'aimerais savoir si je peux dire au marionnettiste d'attendre qu'un élément soit affiché.
const inputValidate = await page.$('input[value=validate]');
await inputValidate.click()
//I want to do something like that
waitElemenentVisble('.btnNext ')
const btnNext = await page.$('.btnNext');
await btnNext.click();
Y at-il un moyen que je peux accomplir cela?
Je pense que vous pouvez utiliser la fonction page.waitForSelector(selector[, options])
à cette fin.
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => {
const page = await browser.newPage();
page
.waitForSelector('#myId')
.then(() => console.log('got it');
browser.close();
});
Remarque, la réponse ci-dessus est incorrecte!
Parce qu'il répond pour un élément si existe ou se trouve but NOT
visible ou affiché
La bonne solution consiste à vérifier la taille ou la visibilité d'un élément à l'aide de page.waitFor()
ou page.waitForFunction()
, voir l'explication ci-dessous.
// wait until present on the DOM
// await page.waitForSelector( css_selector );
// wait until "display"-ed
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').clientHeight != 0");
// or wait until "visibility" not hidden
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').style.visibility != 'hidden'");
const btnNext = await page.$('.btnNext');
await btnNext.click();
L'élément qui existe sur le DOM de la page n'est pas toujours visible si possède la propriété CSS display:none
Ou visibility:hidden
, Raison pour laquelle utiliser page.waitForSelector(selector)
n'est pas une bonne idée. extrait ci-dessous.
function isExist(selector) {
let el = document.querySelector(selector);
let exist = el.length != 0 ? 'Exist!' : 'Not Exist!';
console.log(selector + ' is ' + exist)
}
function isVisible(selector) {
let el = document.querySelector(selector).clientHeight;
let visible = el != 0 ? 'Visible, ' + el : 'Not Visible, ' + el;
console.log(selector + ' is ' + visible + 'px')
}
isExist('#idA');
isVisible('#idA');
console.log('=============================')
isExist('#idB')
isVisible('#idB')
.bd {border: solid 2px blue;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bd">
<div id="idA" style="display:none">#idA, hidden element</div>
</div>
<br>
<div class="bd">
<div id="idB">#idB, visible element</div>
</div>
sur l'extrait de code au-dessus de la fonction isExist()
simule
page.waitForSelector('#myId');
et nous pouvons voir en exécutant isExist()
pour les deux éléments #idA
un #idB
est de retour existe.
Mais lors de l'exécution de isVisible()
, le #idA
N'est ni visible ni masqué.
Et voici d'autres objets pour vérifier si un élément est affiché ou en utilisant la propriété CSS display
.
scrollWidth
scrollHeight
offsetTop
offsetWidth
offsetHeight
offsetLeft
clientWidth
clientHeight
pour le style visibility
cocher non hidden
.
note: Je ne suis pas bon en Javascript ou en anglais, n'hésitez pas à améliorer cette réponse.
Si vous voulez vous assurer que l'élément est réellement visible, vous devez utiliser
page.waitForSelector('#myId', {visible: true})
Sinon, vous recherchez uniquement l'élément dans le DOM et ne recherchez pas la visibilité.
Vous pouvez utiliser page.waitFor()
, page.waitForSelector()
ou page.waitForXPath()
attendre pour un élément sur un page :
// Selectors
const css_selector = '.btnNext';
const xpath_selector = '//*[contains(concat(" ", normalize-space(@class), " "), " btnNext ")]';
// Wait for CSS Selector
await page.waitFor( css_selector );
await page.waitForSelector( css_selector );
// Wait for XPath Selector
await page.waitFor( xpath_selector );
await page.waitForXPath( xpath_selector );
Remarque: En référence à un frame , vous pouvez également utiliser
frame.waitFor()
=,frame.waitForSelector()
, ouframe.waitForXPath()
.
Réponse mise à jour avec quelques optimisations:
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto('https://www.somedomain.com', {waitUntil: 'networkidle2'});
await page.click('input[value=validate]');
await page.waitForSelector('#myId');
await page.click('.btnNext');
console.log('got it');
browser.close();
})();