Браузерная автоматизация прошла три поколения. Каждое устраняло узкое место предыдущего и одновременно переносило новое ограничение в другую часть системы. Понимать нерешённые проблемы каждого поколения полезнее, чем запоминать названия инструментов.
Браузерная автоматизация существует уже больше двадцати лет и за это время прошла три основных этапа. Интересно, что каждое поколение решает свой класс задач, а после решения прежнего ограничения узкое место просто перемещается в другую часть системы.

Первое поколение: на уровне операционной системы делать вид, что мышью управляет человек
Самая ранняя автоматизация фактически работала не внутри браузера, а на уровне операционной системы. Скрипт двигал мышь и нажимал клавиши, а браузер лишь пассивно принимал этот ввод.
Преимущество заключалось в универсальности: скрипт мог взаимодействовать со всем, что отображалось на экране — веб-страницей, клиентским приложением или старой настольной программой, — и браузеру не требовалось предоставлять никакого интерфейса. Цена была столь же очевидной. Скрипт ориентировался на координаты экрана, поэтому изменение разрешения, системного масштабирования или положения окна могло привести к клику не туда. Он также не знал, завершилась ли загрузка страницы, и вынужден был полагаться на фиксированные задержки. Ещё сложнее было с параллельностью: у одной машины одна мышь и одна клавиатура, поэтому для десяти сред требовалось десять машин.
Главная нерешённая проблема этого поколения была проста: оно не видело страницу.
Второе поколение: обойти экран и обращаться к браузеру напрямую
Появление WebDriver перевело автоматизацию с уровня пикселей на уровень элементов: вместо позиции 800-го пикселя на экране искался конкретный элемент страницы. Один и тот же код мог управлять разными браузерами и быть написан на разных языках, что также стало одной из причин превращения WebDriver в стандарт для тестирования.
Позднее решения на основе протоколов отладки браузера значительно развили этот подход. Puppeteer и Playwright напрямую взаимодействуют с движком браузера и получают внутреннее состояние страницы: автоматически ждут готовности элементов, перехватывают и изменяют запросы, подключаются к уже открытой сессии браузера, работают в headless-режиме и запускают несколько контекстов параллельно. Большая часть возможностей, которые сегодня считаются привычными, оформилась именно на этом этапе.
Это решило проблемы управления и стабильности, но оставило два других вопроса. Во-первых, скрипты по-прежнему жёстко задавались людьми. Если структура страницы менялась или селектор переставал работать, приходилось править код, а стоимость сопровождения росла вместе с масштабом проекта. Во-вторых, оставалась более фундаментальная проблема: подход определяет, как выполнять действия, но не то, как выглядит их источник. Прямое управление через протокол делает действия точнее, однако смена способа связи сама по себе не убирает следы автоматизации. Даже очень стабильный скрипт всё равно может выглядеть как скрипт.
Третье поколение: человеку больше не нужно описывать каждый шаг, и проблема снова смещается
В третьем поколении меняется не способ управления, а способ принятия решений. В первых двух человек должен был явно прописывать каждый шаг: на какую кнопку нажать, какое поле заполнить и в какой последовательности. В поколении, управляемом моделью, задаётся цель, модель сама планирует путь и может найти новую точку входа после изменения интерфейса.
Из-за этого прежние мелкие сложности — как написать селектор или сколько ждать — постепенно теряют критичность. Но почти сразу появляются новые проблемы.
Ключевой момент: сама модель не обращается к веб-странице. Страницу по-прежнему открывает браузер, он же загружает ресурсы и поддерживает состояние входа. Поэтому, когда задача начинает выполняться нестабильно, причина часто не в ошибочном решении модели, а в среде выполнения под ней: несколько задач используют один браузер и загрязняют друг другу cookies и кэш; характеристики fingerprint слишком похожи, поэтому платформа воспринимает задачи как исходящие с одной машины; учётные записи используются между задачами, и один сбой затрагивает сразу несколько; среды нужно временно создавать и освобождать после использования, но единого планирования нет. Модель решает, как выполнить задачу, а вопрос, где её выполнять, становится новым узким местом.
Дополнительный слой в архитектуре
Если посмотреть на три поколения вместе, различие не сводится к тому, какое из них современнее. Каждое должно подхватить то, что не решила предыдущая стадия. В первых двух поколениях среда почти не была проблемой, потому что автоматизация работала в браузере на собственной машине. На этапе Agent задачи становятся массовыми, параллельными и автономными, поэтому средой нужно управлять явно: каждая задача запускается в изолированной среде, fingerprint и сессии не смешиваются; состояние входа сохраняется между задачами, чтобы не авторизоваться каждый раз; IP, часовой пояс и язык согласуются как единый набор; среды создаются и освобождаются по требованию как вычислительные ресурсы.
PurpleMark работает именно на этом уровне, превращая браузерные среды в управляемые ресурсы, чтобы Agent мог сосредоточиться на логике задачи.
Так становится проще определить подход. Корпоративные тестовые стеки и существующие наборы скриптов могут оставаться на прежнем пути; сложные веб-приложения, которым нужен контроль на уровне запросов, относятся к протокольному поколению; а для задач, которые планируются моделью и должны долго работать стабильно, технологии первых двух поколений по-прежнему применимы, но слой среды нужно решать отдельно. Если сценарий требует, чтобы действия выглядели так, будто их выполняет реальный пользователь, сам по себе фреймворк автоматизации не может обеспечить это независимо от поколения.
Помимо технического пути есть ещё одна граница: автоматизация должна соблюдать правила целевой платформы и местное законодательство. Техническая реализуемость не означает автоматической приемлемости для бизнеса.


