web-dev-qa-db-fra.com

Comment sélectionner une option dans la liste déroulante, sélectionnez

Je peux cliquer sur le sélecteur, mais ma question est de savoir comment sélectionner l'une des options dans la liste déroulante.

  await page.click('#telCountryInput > option:nth-child(4)')

Cliquez sur l'option à l'aide du sélecteur CSS ne fonctionne pas.

Par exemple, sélectionnez un code de pays dans une liste comme ci-dessous,

enter image description here

28
Lorem Ipsum Dolor

Puppeteer v0.13.0 a la méthode page.select () , qui fait exactement cela. Vous devez juste lui donner la valeur à sélectionner. Donc, en supposant que vous avez un <option value="my-value"> Dans votre <select>:

await page.select('#telCountryInput', 'my-value')

41
zaboco

Pour la composante déroulante, je pense que nous devrions envisager 2 situations:

  • hTML natif select élément
  • composant écrit par JS, composé d'un bouton et d'une liste d'options, prenez liste déroulante de bootstrap à titre d'exemple

Pour la deuxième situation, je pense que click peut résoudre le problème.

Pour la première situation, je viens de trouver 2 façons de faire cela:

  1. page.select
  2. elementHandle.type (avis mis à jour le 27/04/2018)

page.select est une nouvelle fonctionnalité ajoutée à la v0.12.0.

Par exemple, vous avez un élément select:

<label>Choose One:
    <select name="choose1">
        <option value="val1">Value 1</option>
        <option value="val2">Value 2</option>
        <option value="val3">Value 3</option>
    </select>
</label>

Vous avez deux façons de sélectionner la deuxième option "Valeur 2".

// use page.select
await page.select('select[name="choose1"]', 'val2');

// use elementHandle.type
const selectElem = await page.$('select[name="choose1"]');
await selectElem.type('Value 2');

Normalement elementHandle.type est utilisé pour taper du texte dans la zone de saisie, mais comme il

Met l'accent sur l'élément, puis envoie une touche, une pression/entrée et un événement keyup pour chaque caractère du texte.

select L'élément HTML a un événement input, pour que cette méthode fonctionne.

Et je pense personnellement elementHandle.type est préférable, car il n'est pas nécessaire de connaître l'attribut option value, mais uniquement l'étiquette/le nom que l'homme peut voir.

27/04/2018 Mise à jour

J'ai déjà utilisé elementHandle.type uniquement sur Mac OSX. Récemment, mon collègue a signalé un bug lié à cela. Il utilise Linux/Win. De plus, nous utilisons tous les deux marionnettiste v1.3.0.

Après essais et erreurs, nous avons constaté que cette elementHandle.type peut attribuer la valeur à la <select> élément, mais cela ne déclenchera pas l'événement change de l'élément.
Je ne recommande donc plus d'utiliser elementHandle.type sur <select>.

Enfin, nous avons suivi ce commentaire pour envoyer l'événement de modification manuellement. C'est comme:

// use manually trigger change event
await page.evaluate((optionElem, selectElem) => {
    optionElem.selected = true;
    const event = new Event('change', {bubbles: true});
    selectElem.dispatchEvent(event);
}, optionElem, selectElem);
15
bambooom

Pour les selectboxes natives, ma solution consistait à exécuter quelques JS sur la page elle-même:

await page.evaluate(() => {
  document.querySelector('select option:nth-child(2)').selected = true;
})
7
I.devries

C'est en fait plus simple que ce que je pensais car la liste déroulante N'EST PAS une combinaison de sélections et d'options HTML natives. Par conséquent, je peux utiliser le code ci-dessous pour sélectionner la cible que je veux.

  await page.click('#telCountryInput')
  await page.click('#select2-telCountryInput-results > li:nth-child(4)')
3
Lorem Ipsum Dolor