Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування

6 хв. читання

Що таке Puppeteer?

Puppeteer — це бібліотека Node, яка пропонує високорівневий API для контролю Chrome чи Chromium за допомогою протоколу DevTools. Puppeteer стандартно працює у headless-режимі, однак бібліотеку можна налаштувати для запуску в повноцінному (non-headless) Chrome чи Chromium. — github.com/puppeteer/puppeteer

Puppeteer автоматизує рутинну роботу, яку ви час від часу виконуєте у браузері. З цією бібліотекою можна контролювати будь-що у браузері: від простої навігації до аудиту вебсайту з Lighthouse.

Перш ніж перейдемо до практики, розглянемо такий приклад скрипту Puppeteer:

Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування
Імпорт флеш-карток з аудіо в Memrise за допомогою Puppeteer

Автор посібника проходить курс голландської мови, де доводиться працювати з безліччю слів та діалогів. Створення флеш-карток та імпорт великої кількості слів та звуків — не надто легка та цікава робота. Однак погляньте, як швидко з цим справляється автоматизований скрипт. До того ж він уникає помилок, які може зробити людина.

Написати скрипт для Puppeteer не складно, головне — пам'ятати про деякі основні правила.

Правило №1

Всі методи в Puppeteer асинхронні, тож не забувайте використовувати await.

Правило №2

У скрипті вам зазвичай доведеться змушувати Puppeteer очікувати на щось: запит, відповідь з бекенду, елемент тощо.

Правило №3

Пишіть скрипт послідовно. Уявіть, що вам потрібен скрипт, який щось гуглитиме. Як ви це зробите?

  1. Ви відкриєте нову вкладку.
  2. Перейдете на Google.com.
  3. Клікнете на пошукову стрічку.
  4. Введете щось.
  5. Клікнете на кнопку пошуку.

Puppeteer підтримує декілька API для сторінки, клавіатури, мишки. Описану послідовність дій можна легко емулювати за допомогою бібліотеки.

Правило №4

Ви не можете клікати на невидимий елемент. Уявіть меню з декількома пунктами. Спершу вам треба відкрити список, а потім вже обрати необхідний пункт.

Правило №5

Для деяких сторінок запрограмовано певні події (наприклад події jQuery). Якщо вам потрібно, аби такий код виконався, доведеться зробити це за допомогою JS.

Правило №6

Якщо ви не знайомі з селекторами в CSS, надолужте це.

Правило №7

Коли ви переходите на сторінку на зразок example.com/users/, не забувайте про / в кінці.

Ми поговорили про базові теоретичні правила, тепер застосуймо їх на практиці.

Розігрів

Тепер виконайте такі команди у терміналі:

mkdir hello_puppeteer
cd hello_puppeteer
yarn init
yarn add puppeteer

Остання команда триватиме певний час, тому що встановлюється Puppeteer та всі потрібні залежності (на зразок Chromium).

Створіть новий js-файл та назвіть його google.js, а потім додайте туди цей код:

const puppeteer = require("puppeteer");
(async () => {
  // запускаємо браузер
  const browser = await puppeteer.launch({
    headless: false,
    // devtools: false,
    // args: ["--start-maximized"]
  });
// створюємо нову вкладку
  const page = await browser.newPage();
})();
  • Метод puppeteer.laucnh запускає новий екземпляр браузера Chromium. Якщо ви поглянете на код, то помітите там прапор headless: false. Так ми побачимо, що відбувається під капотом.
  • Метод browser.newPage створює нову вкладку в браузері.
  • Автор огорнув блок коду в асинхронну функцію, адже всі методи Puppeteer асинхронні.

Спробуйте запустити скрипт командою node google.js — в терміналі ви побачите такий результат:

Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування

Далі нам потрібно перейти на Google.com. Для цього додамо після const page = ... цей код:

// переходимо на google.com
await page.goto('https://web.archive.org/web/20230322034327/https://google.com');
Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування
Результат скрипту

Тепер ми маємо ввести пошуковий запит на Google.com. Спершу треба дослідити пошукову стрічку за допомогою Web Developer Tools (клік правою кнопкою на пошукову стрічку, виберіть опцію «Дослідити елемент»).

Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування
Досліджуємо елемент за допомогою Web Developer Tools

Спочатку необхідно знайти статичний CSS-селектор, аби працювати з ним у Puppeteer. Стрічка вводу має декілька атрибутів, але ми звернемо увагу на ці:

  • class: на жаль, він динамічний, і ми не можемо покладатися на нього.
  • name: значення цього атрибута унікальне для цілої сторінки. Тому обираємо саме його.

Спробуйте знайти елемент за CSS-селектором безпосередньо в інструментах розробника, на вкладці з консоллю. Елементи можна протестувати за допомогою document.querySelector, document.querySelectorAll.

Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування

Ми обрали CSS-селектор input[name=q] — і він працює чудово. Саме час ввести запит для пошуку.

	await page.focus('input[name=q]');
/* або ви можете: спершу знайти елемент, а потім зробити на ньому фокус
  
  const searchInput = await page.$('input[name=q]');
  await searchInput.focus();
*/

Для API сторінки символ $ працює подібно до documnet.querySelector, а $$ — подібно до document.querySelectorAll.

Аби Puppeeter міг ввести щось в поле вводу, необхідно зробити на ньому фокус. Для цього існує два API. Обидва дають однаковий результат, однак застосовуються в різних ситуаціях.

В поле вводу можна легко щось ввести, використовуючи keyboard API.

await page.keyboard.type('Puppeteer');
Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування
Демонстрація вводу

Далі нас цікавить, як отримати результати пошуку. Зазвичай користувачі тиснуть на Enter або клікають на кнопку Google Search. Аби відтворити такий функціонал, ми можемо:

// натиснути клавішу Enter на клавіатурі
 await page.keyboard.press("Enter");
// або спершу сфокусувати кнопку пошуку, а потім клікнути на неї 
// const searchButton = await page.$('input[name=btnK]');
// await searchButton.click();
Puppeteer, або як я перестав хвилюватись і полюбив автоматизоване тестування

Ми ознайомилися з базовим функціоналом, однак на цьому можливості Puppeteer не закінчуються.

Попросіть Puppeteer почекати на щось

Розглянемо такі сценарії:

  • Ajax-запит надсилається після кліку на кнопку.

Приклад завантаження файлу для file-input:

const fileInput= await page.$('input[type=file]');
const uploadButton = await page.$('#upload-btn');
await fileInput.uploadFile("d:/image.jpg");
await uploadButton.click();
// тепер почекаємо на результат статусу завантаження 
await page.waitForResponse('https://web.archive.org/web/20230322034327/https://example.com/services/upload/');
// знайдемо динамічно згенероване посилання після ajax завантаження
const fileUrlElement = await page.$('a.file-url');
  • Заждемо декілька секунд.
await page.waitFor(1000); // у мілісекундах
  • Очікуємо на навігацію сторінки.
await page.waitForNavigation();
  • Почекаємо, поки певний CSS-селектор буде показаний на сторінці.
await page.waitForSelector('css selector');

Виконання скриптів у браузері

Іноді трапляється, що після завантаження файлу методом uploadFile сторінка не виконує Ajax-завантаження. В такому разі потрібно застосувати jQuery-код, який виконає цю роботу.

const input = await page.$('input[type=file]');
await input.uploadFile(fileToUpload);
await page.evaluate(
 element => $(element).trigger("custom_event"),
 input
);

У прикладі вище $(element).trigger("...") — це JS-код, який виконається в браузері (а не в скрипті Puppeteer).

Більше можливостей

У першому прикладі ми використали прапор headless: false, аби побачити, як все відбувається під капотом. Зазвичай краще використовувати headless-режим, адже так скрипти та браузер запускаються фоново і ви не відволікаєтесь на вкладки та вікна.

Але як побачити результат, запустивши скрипт у режимі headless? Як щодо скріншотів?

await page.screenShot({path: 'my-result.png', fullPage: true})

На початку матеріалу автор продемонстрував роботу власного скрипту з імпорту карток. Повний його код можна знайти за посиланням.

Більше прикладів

Якщо ви хочете дізнатись більше про можливості Puppeteer, зверніть увагу на цей репозиторій. Інші бібліотеки також покладаються на Puppeteer, наприклад генератор ресурсів для PWA.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація