Кукловод: дождитесь звонка Ajax после загрузки страницы - PullRequest
0 голосов
/ 30 мая 2020

РЕШЕНИЕ:

Согласно предложению @pguardiario, следующее перехватывает вызов Ajax и ожидает его завершения:

  await page.waitForResponse('http://localhost:58080/', {timeout: 2000})
    .catch(() => {console.log('[puppeteer] Error')});

У меня есть страница, которая выполняет вызов Ajax после загрузки страницы, и мне нужно, чтобы кукольник дождался завершения этого вызова. В кукловод: дождитесь вызова ajax после навигации принятый ответ использует await page.waitForSelector(cssSelector);, что не работает в моем текущем случае, поскольку успех вызова Ajax не добавляет никаких новых элементов в страница. Вот минимальный рабочий пример с некоторыми комментариями относительно того, что делает фактическая страница:

index.html:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" charset="utf-8"></script>
  </head>
  <body>
  </body>
  <script charset="utf-8">
    $(document).ready(function() {
      // render data previously stored in localStorage
      console.log('Fetching page');
      // in reality it is fetching a JSON API endpoint, but for the purposes of this example, use /
      $.get("/")
      .fail(function () {
        // add an error element to the page
        console.log('Error');
      })
      .done(function () {
        // empty the table containing the data and rerender
        console.log('Success');
      })
      .always(function () {
        // puppeteer can now continue and check for error
        console.log('Done fetching page');
      });
    });
  </script>
</html>

test.js:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', consoleObj => console.log(consoleObj.text()));
  await page.goto('http://localhost:58080');
  // What to do to wait for the completion of the ajax call done after
  // document is ready?
  console.log('[puppeteer] Sleeping');
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log('[puppeteer] Closing');
  await browser.close();
});

serve.js:

const http = require('http');
const fs = require('fs');

http.createServer(function (request, response) {
    fs.readFile('index.html', function(error, content) {
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.end(content, 'utf-8');
    });
}).listen(58080, 'localhost');

В одном терминале:

node serve.js

В другом:

node test.js

Вывод:

[puppeteer] Sleeping
Fetching page
Success
Done fetching page
[puppeteer] Closing

Хочу кукловода для ожидания точки, в которой будет напечатана страница «Готовая загрузка», без заданного тайм-аута. Я контролирую исходный код самой страницы, поэтому принимаются любые идеи, даже те, которые требуют изменений на целевом сервере. Например, если я добавлю скрытый элемент DOM после завершения вызова Ajax, я могу использовать await page.waitForSelector(cssSelector);. Интересно, есть ли способ лучше.

1 Ответ

0 голосов
/ 30 мая 2020

Я считаю, что у кукольника есть событие загрузки, к которому вы можете подключиться.

Примерно так:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', consoleObj => console.log(consoleObj.text()));
  page.on('load', await () => { //set listener before you go to the page.
     // Now do something...
  });
  await page.goto('http://localhost:58080');
  // What to do to wait for the completion of the ajax call done after
  // document is ready?
  console.log('[puppeteer] Sleeping');
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log('[puppeteer] Closing');
  await browser.close();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...