简体   繁体   English

如何在 pupeteer 中的异步 function page.evalue 中单击和 select 元素

[英]How to click and select element within async function page.evalue in pupeteer

Trying to iterate over invalid fields and entering/selecting values on the page.尝试遍历无效字段并在页面上输入/选择值。

const enterTextFields = async (page) => {
  const txtQuestText = await page.evaluate(() =>
    Array.from(
      document.querySelectorAll('div[aria-invalid="true"]'),
      async (element) => {
        const span = element.querySelector(
          'label span[data-test-form-element-label-title="true"]'
        );
        const ques = span.textContent.trim();
        const ans = await window.getAns(ques);
        if (ans) {
          const txtField = element.querySelector('div input[type="text"]');
          if (txtField) {
            txtField.type(ans);
          }
          const dropdownField = element.querySelector(
            "div select[data-test-fb-dropdown-select]"
          );
          if (dropdownField) {
            dropdownField.select(ans);
          }
        }
        return ques + " : " + ans;
      }
    )
  );
  console.log("txtQuestText : ", txtQuestText);
}

On the execution of the above page.evaluate , neither text nor dropdown field is getting filled even though there are ans available for the ques .在执行上述page.evaluate时,即使有可用于quesans ,文本和下拉字段都不会被填充。

In txtQuestText getting:txtQuestText得到:

(2) [{…}, {…}]
0: {}
1: {}
length: 2
[[Prototype]]: Array(0)
[[Prototype]]: Object

If I remove async from async (element) => { , await window.getAns(ques) call and if block then I can see the list of correct Ques strings in txtQuestText .如果我从async (element) => {中删除async ,则await window.getAns(ques)调用和if block然后我可以在txtQuestText中看到正确的Ques字符串列表。

Cannot remove async due to await window.getAns(ques) .由于await window.getAns(ques)而无法删除async

Not sure what is going wrong and or how to use it.不知道出了什么问题以及如何使用它。 Please Help!请帮忙!

I can't run your code, but the problem appears to be returning an array from evaluate rather than a single promise object.我无法运行您的代码,但问题似乎是从evaluate返回一个数组,而不是单个 promise object。 Puppeteer isn't smart enough to realize this is an array of promises, so it doesn't resolve them. Puppeteer 不够聪明,无法意识到这是一系列承诺,因此它无法解决它们。 The promises degrade into empty objects once they pass through the serialization/deserialization process.一旦通过序列化/反序列化过程,promise 就会退化为空对象。

Here's a reproducible example:这是一个可重现的示例:

const puppeteer = require("puppeteer"); // ^18.0.4

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const html = "<html><body><p>test</p><p>test2</p></body></html>";
  await page.setContent(html);

  const result = await page.evaluate(() =>
    Array.from(
      document.querySelectorAll("p"),
      async el => el.textContent // pretend we need to await in this func
    )
  );

  console.log(result); // => [ {}, {} ]
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;

The fix is to return a single promise rather than an array of promises:修复方法是返回单个 promise 而不是一组承诺:

const puppeteer = require("puppeteer"); // ^18.0.4

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const html = "<html><body><p>test</p><p>test2</p></body></html>";
  await page.setContent(html);

  const result = await page.evaluate(() =>
    Promise.all(Array.from(
      document.querySelectorAll("p"),
      async el => el.textContent
    ))
  );

  console.log(result); // => [ 'test', 'test2' ]
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM