Использование Puppeteer для автоматического тестирования пользовательского интерфейса
В эту эпоху передовых технологий написание скриптов для парсинга, тестирования и мониторинга может быть сложной задачей. Вот почему команда Google Chrome предоставила инструмент, который позволяет вам выполнять стандартные действия в браузере Chromium или Chrome программно через JavaScript с помощью простого и удобного API под названием Puppeteer.
В этой статье в блоге вы узнаете о Puppeteer и о том, как его использовать для очистки веб-страницы и записи автоматических тестов пользовательского интерфейса для вашего проекта.
Предпосылки
Для этого урока вам потребуются базовые знания JavaScript и Node.js.
Что такое puppeteer?
Согласно Google, «Puppeteer - это библиотека Node, которая предоставляет высокоуровневый API для управления headless Chrome или Chromium по протоколу DevTools. Его также можно настроить для использования полного headless Chrome или Chromium».
С помощью Puppeteer вы можете очищать веб-сайты, создавать скриншоты и PDF-файлы страниц, действовать как сканеры для SPA и генерировать предварительно обработанный контент, автоматизировать отправку форм, тестировать пользовательский интерфейс, получать доступ к веб-страницам и дополнительной информации с помощью DOM API и, наконец, автоматизировать анализ производительности.
Давайте продемонстрируем, как работает Puppeteer, сканируя портал вакансий, что легко сделать и поможет нам понять парсинг веб-страниц в целом.
Настройка проекта Node
Начните с настройки вашего проекта:
- Установите Node.js 12.12.0 или новее.
- Установить yarn или npm
mkdir JobScrapper
cd JobScrapper
yarn add puppeteer
Обратите внимание, что вы можете использовать puppeteer-core
, если не хотите загружать браузер Chromium, о котором вы можете прочитать здесь.
Создать файл jobScript.js
Добавьте следующие коды в только что созданный файл сценария:
const puppeteer = require("puppeteer");
const jobUrl = process.env.JOB_URL;
let page;
let browser;
let cardArr = [];
class Jobs {
static async init() {
// console.log('Loading Page ...')
browser = await puppeteer.launch();
page = await browser.newPage();
await page.goto(jobUrl, { waitUntil: "networkidle2" });
await page.waitForSelector(".search-card");
}
static async resolve() {
await this.init();
// console.log('Grabbing List of Job URLS ...')
const jobURLs = await page.evaluate(() => {
const cards = document.querySelectorAll(".search-card");
cardArr = Array.from(cards);
const cardLinks = [];
cardArr.map(card => {
const cardTitle = card.querySelector(".card-title-link");
const cardDesc = card.querySelector(".card-description");
const cardCompany = card.querySelector(
'a[data-cy="search-result-company-name"]'
);
const cardDate = card.querySelector(".posted-date");
const { text } = cardTitle;
const { host } = cardTitle;
const { protocol } = cardTitle;
const pathName = cardTitle.pathname;
const query = cardTitle.search;
const titleURL = protocol + "//" + host + pathName + query;
const company = cardCompany.textContent;
cardLinks.push({
jobText: text,
jobURLHost: host,
jobURLPathname: pathName,
jobURLSearchQuery: query,
jobURL: titleURL,
jobDesc: cardDesc.innerHTML,
jobCompany: company,
jobDate: cardDate.textContent
});
});
return cardLinks;
});
return jobURLs;
}
static async getJobs() {
const jobs = await this.resolve();
await browser.close();
// console.log(jobs)
return jobs;
}
}
export default Jobs;
Здесь класс Jobs
имеет три важных метода: Init
, resolve
и getJobs
.
Метод Init
инициализирует экземпляр puppeteer и создает объект browser
, который, в свою очередь, используется для создания новой страницы в браузере с методом newPage()
. Мы вызовем goto()
с URL-адресом, который мы хотим, чтобы наш браузер посетил и указали networkidle2
, что пригодится для страниц, которые выполняют длительный опрос или любую другую активность. После этого дождитесь загрузки определенного HTML-элемента с указанным классом .search-card
в область просмотра.
Второй метод, метод resolve
, вызывает метод Init
, оценивает открытую страницу и запрашивает все HTML-элементы с селектором .search-card
. Он повторяет каждый из них и извлекает конкретную информацию, такую как название должности, дата публикации, компания и описание, а затем помещает их в массив для отображения.
Наконец, метод getJobs
просто вызывает метод resolve
, чтобы получить список всех найденных заданий и вернуть их вызывающей стороне.
Теперь создайте файл server.js
для отображения заданий, введя следующий код:
// Create a simple Express API
const express = require("express");
// Require the Job Scrapper
const Jobs = require("./jobScript");
// Instantiate Express server
const app = express();
const port = 9000;
// Get Jobs from with the Scrapper and return a Job with jobs
app.get("/", async (req, res) => {
const jobs = await Jobs.getJobs();
res.json(jobs);
});
// Listen to port 9000
app.listen(port, () => {});
// PS: If you encounter problem with `Module not found` run:
// npm i puppeteer
// again
Отображение очищенных вакансий
Ниже приведен образец JSON всех успешно очищеных вакансий на основе предоставленного URL-адреса веб-сайта вакансий.
Что такое Puppeteer Recorder?
Теперь, когда мы знаем, что такое Puppeteer и что он умеет, давайте рассмотрим важное использование Puppeteer: автоматическое тестирование.
Используя Puppeteer Recorder, расширение Chrome, мы можем записывать наши действия и действия в браузере, а затем генерировать скрипт Puppeteer для автоматического тестирования.
Вот список полезных действий, которые может выполнять расширение Puppeteer Recorder Chrome:
- Может легко записывать клики на веб-сайте и различные типы событий.
- Может легко отображать выполненные события и текущие выполняющиеся события.
- В нем есть полезные пункты, такие как
waitForNaigation
иsetViewPort
. - Встроенная функция копирования в буфер обмена.
- Имеет разные варианты конфигурации.
- Может запрашивать элементы с атрибутом
data-id
. - Автоматическая генерация скрипта Puppeteer
Сначала установите расширение Chrome для Puppeteer Recorder, нажав Add to Chrome
.
Автоматизированное тестирование пользовательского интерфейса
Автоматизированное тестирование пользовательского интерфейса используется для проверки правильности работы приложения путем навигации по веб-сайтам и использования технологий таким образом, чтобы имитировать работу обычного пользователя. Это помогает выявлять ошибки и неработающие ссылки на веб-сайтах во время веб-разработки до того, как веб-сайт, наконец, станет доступен.
Для этого было разработано множество инструментов, включая Selenium и TestComplete, но мы продемонстрируем, как этого добиться с помощью Puppeteer.
Теперь давайте запишем автоматический тест пользовательского интерфейса.
Прежде чем начать запись, перейдите в настройки и снимите флажки с параметров headless
и waitForNavigation
, чтобы включить плавную запись.
Щелкните значок расширения Puppeteer, затем щелкните Record:
Затем введите в адресную строку http://www.google.com
и щелкните в браузере, чтобы Puppeteer Recorder мог записать несколько событий.
Обязательно следите за статусами wait
и и rec
на панели значков Puppeteer — они дадут вам подсказку, когда перейти к следующему событию или нажать кнопку.
Вы можете нажать Stop, когда вы записали достаточно событий для теста пользовательского интерфейса. Затем скопируйте сгенерированный скрипт Puppeteer и запустите тест, используя сервер Node / Express.
Я записал какое-то событие в сценарии ниже:
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(
"https://www.google.com/search?q=what+is+puppeteer+js&oq=wh&aqs=chrome.0.69i59j69i64j0l3j5l3.7647j0j7&sourceid=chrome&ie=UTF-8"
);
await page.setViewport({ width: 1366, height: 669 });
await page.waitForSelector(
".g:nth-child(3) > .rc:nth-child(1) > .r > a > .LC20lb"
);
await page.click(".g:nth-child(3) > .rc:nth-child(1) > .r > a > .LC20lb");
await page.waitForSelector(
".blog_post-main_content > .blog_post-body > .blog_post_body > p> a:nth-child(3)"
);
await page.click(
".blog_post-main_content > .blog_post-body > .blog_post_body > p > a:nth-child(3)"
);
await browser.close();
})();
Запуск скрипта Puppeteer
Запуск сценария Puppeteer несложен после того, как вы настроили среду тестирования. Используя Node / Express, вы можете просто вставить сгенерированный код и выполнить его:
const express = require("express");
const app = express();
const port = 9000;
app.get("/test", (req, res) => {
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(
"https://www.google.com/search?q=what+is+puppeteer+js&oq=wh&aqs=chrome.0.69i59j69i64j0l3j5l3.7647j0j7&sourceid=chrome&ie=UTF-8"
);
await page.setViewport({ width: 1366, height: 669 });
await page.waitForSelector(
".g:nth-child(3) > .rc:nth-child(1) > .r > a > .LC20lb"
);
await page.click(".g:nth-child(3) > .rc:nth-child(1) > .r > a > .LC20lb");
await page.waitForSelector(
".blog_post-main_content > .blog_post-body > .blog_post_body > p > a:nth-child(3)"
);
await page.click(
".blog_post-main_content > .blog_post-body > .blog_post_body > p > a:nth-child(3)"
);
await browser.close();
})();
});
app.listen(port, () => {});
Теперь все готово! Поздравляю.