Управление расписанием

Для работы с Puppeteer требуется Node.js версии 12 и выше. Установка производится через npm:

npm install puppeteer

По умолчанию Puppeteer поставляется с встроенным Chromium, что обеспечивает предсказуемое окружение для тестирования. Для экономии места можно использовать пакет puppeteer-core и подключать браузер отдельно.

const puppeteer = require(&

Создание экземпляра браузера осуществляется через асинхронную функцию:

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Параметр headless: true запускает браузер в фоновом режиме, что ускоряет выполнение тестов и уменьшает потребление ресурсов.


Навигация и ожидания

Управление расписанием в тестах часто требует корректного ожидания элементов и загрузки страниц. Puppeteer поддерживает несколько стратегий ожидания:

  • page.waitForSelector(selector, options) — ожидание появления элемента в DOM.
  • page.waitForXPath(xpath, options) — ожидание элемента по XPath.
  • page.waitForNavigation(options) — ожидание завершения навигации.
  • page.waitForTimeout(milliseconds) — явная пауза.

Пример использования ожидания элемента перед кликом:

await page.waitForSelector('#schedule-button', { visible: true });
await page.click('#schedule-button');

Здесь ключевой момент — использование { visible: true }, чтобы убедиться, что элемент доступен для взаимодействия, а не просто присутствует в DOM.


Взаимодействие с формами и элементами расписания

Работа с расписанием подразумевает взаимодействие с формами добавления событий, выбора даты и времени. Puppeteer предоставляет методы для ввода данных:

  • page.type(selector, text, options) — ввод текста.
  • page.select(selector, value) — выбор значения из <select>.
  • page.click(selector) — клик по элементу.
  • page.evaluate(fn, …args) — выполнение произвольного JavaScript на странице.

Пример добавления нового события в календарь:

await page.click('#add-event-button');
await page.type('#event-title', 'Встреча с командой');
await page.type('#event-date', '2026-01-15');
await page.select('#event-time', '10:00');
await page.click('#save-event');

Использование page.evaluate позволяет выполнять сложные манипуляции с DOM, например, динамическое выделение ячеек календаря или изменение атрибутов:

await page.evaluate(() => {
  const cells = document.querySelectorAll('.calendar-cell');
  cells.forEach(cell => {
    if (cell.dataset.date === '2026-01-15') {
      cell.classList.add('highlighted');
    }
  });
});

Работа с динамическим контентом

Расписания часто подгружаются асинхронно через API. Puppeteer позволяет управлять ожиданиями и проверкой состояния элементов после AJAX-запросов.

Пример ожидания полной загрузки событий:

await page.waitForFunction(() => {
  const events = document.querySelectorAll('.event-item');
  return events.length > 0;
});

Метод waitForFunction выполняет проверку на странице до тех пор, пока переданное условие не станет истинным, что удобно для динамических списков событий.


Снимки экрана и отладка

Для проверки визуального состояния расписания можно использовать скриншоты:

await page.screenshot({ path: 'schedule.png', fullPage: true });

Скриншоты полезны при регрессионном тестировании, позволяя фиксировать изменения в отображении календаря и событий.

Для пошаговой отладки можно использовать режим headless: false и slowMo:

const browser = await puppeteer.launch({ headless: false, slowMo: 50 });

slowMo замедляет выполнение операций, что позволяет наблюдать процесс взаимодействия с расписанием в реальном времени.


Автоматизация повторяющихся событий

Puppeteer позволяет организовать управление расписанием через циклы и массивы данных, что удобно для массового добавления событий:

const events = [
  { title: 'Встреча с командой', date: '2026-01-15', time: '10:00' },
  { title: 'Совещание с клиентом', date: '2026-01-16', time: '14:00' },
];

for (const event of events) {
  await page.click('#add-event-button');
  await page.type('#event-title', event.title);
  await page.type('#event-date', event.date);
  await page.select('#event-time', event.time);
  await page.click('#save-event');
  await page.waitForSelector('.event-item', { visible: true });
}

Такой подход позволяет создавать масштабируемые тесты расписания с различными данными без дублирования кода.


Слежение за событиями браузера

Для сложного расписания важно отслеживать сетевые запросы и события страницы. Puppeteer предоставляет возможность перехвата запросов и ответа:

await page.setRequestInterception(true);

page.on('request', request => {
  if (request.url().includes('/api/events')) {
    console.log('Запрос к API событий:', request.url());
  }
  request.continue();
});

Это позволяет проверять, что загрузка расписания происходит корректно, и отлавливать ошибки при сетевых запросах.


Использование фреймов и вкладок

Если расписание загружается в iframe или отдельной вкладке, Puppeteer предоставляет методы для работы с ними:

const frames = page.frames();
const scheduleFrame = frames.find(f => f.name() === 'schedule-frame');
await scheduleFrame.click('#add-event-button');

Для работы с новой вкладкой:

const [newPage] = await Promise.all([
  browser.waitForTarget(t => t.url().includes('schedule')).then(t => t.page()),
  page.click('#open-schedule-tab')
]);

Тайминги и асинхронность

Все действия в Puppeteer являются асинхронными. Корректное управление расписанием требует внимательного использования await для последовательных действий:

await page.goto('https://calendar.example.com');
await page.waitForSelector('.event-item');
await page.click('#next-week');
await page.waitForSelector('.event-item');

Игнорирование await может привести к тому, что элементы еще не загрузились, а код попытается с ними взаимодействовать, вызывая ошибки тестирования.


Эти подходы обеспечивают полное управление расписанием в браузере через Puppeteer, позволяя создавать автоматизированные тесты, проверять визуальное состояние событий и работать с динамическим контентом.