Каковы плюсы и минусы Playwright для автоматизации тестирования?

«Каковы плюсы и минусы Playwright для автоматизации тестирования?» — вопрос из категории Фреймворки тестирования, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Плюсы с точки зрения инженера по автоматизации:

  • Кроссплатформенность и поддержка браузеров: Единый API для Chromium, Firefox и WebKit. Это позволяет легко тестировать кросс-браузерную совместимость.
  • Автоматическое ожидание (Auto-waiting): Playwright автоматически ждет, пока элементы станут интерактивными (visible, enabled, stable). Это резко снижает количество sleep и явных ожиданий в коде, делая тесты стабильнее.
  • Высокая скорость и надежность: Прямое взаимодействие с браузером через DevTools Protocol (а не через медленный WebDriver) делает выполнение быстрым и менее подверженным флакy.
  • Мощные возможности для эмуляции: Встроенная поддержка мобильных viewport, геолокации, языков, разрешений (камера, микрофон).
  • Поддержка сетевых запросов: Можно перехватывать и мокать API-запросы, что полезно для изоляции тестов фронтенда.

Минусы и сложности:

  • Кривая обучения и документация: Сообщество и количество готовых решений пока меньше, чем у Selenium. Документация хороша, но иногда не хватает глубоких примеров для сложных кейсов.
  • Отсутствие поддержки legacy-браузеров: Не подходит для тестирования Internet Explorer или старых версий Safari.
  • Отладка: Отладка сложных сценариев может быть менее интуитивной, особенно при работе с несколькими контекстами или страницами.

Пример кода на Python, демонстрирующий auto-waiting и перехват запроса:

import re
from playwright.sync_api import sync_playwright, expect

def test_login_and_api_call():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()

        # Мокаем API-ответ перед навигацией
        page.route(
            re.compile(r".*/api/user/profile"),
            lambda route: route.fulfill(json={"name": "Test User"})
        )

        page.goto("https://example-app.com/login")
        # Auto-waiting: fill и click будут ждать готовности элементов
        page.fill("#username", "test_user")
        page.fill("#password", "password123")
        page.click("button[type='submit']")

        # Assertion с автоматическим ожиданием
        expect(page.locator(".user-profile")).to_have_text("Test User")

        browser.close()