История и эволюция Protractor

К началу 2010-х годов экосистема JavaScript активно смещалась в сторону одностраничных приложений. AngularJS (Angular 1.x), представленный Google в 2010 году, стал одним из ключевых фреймворков этого периода. Он предложил принципиально иной подход к построению UI: двустороннее связывание данных, директивы, dependency injection и управление состоянием через $scope.

Классические инструменты end-to-end тестирования, такие как Selenium WebDriver, изначально не учитывали особенностей Angular-приложений. Основная проблема заключалась в асинхронной природе Angular: обновление DOM происходило не сразу после действий пользователя, а после завершения digest-цикла и обработки $http, $timeout, $interval и промисов. Selenium требовал ручного управления ожиданиями, что приводило к нестабильным тестам и избыточному коду.

Возникновение Protractor

Protractor был создан командой Angular в Google как специализированная надстройка над Selenium WebDriver, ориентированная на тестирование AngularJS-приложений. Первый публичный релиз появился примерно в 2013 году.

Ключевая идея Protractor заключалась в глубокой интеграции с Angular:

  • автоматическое ожидание завершения digest-цикла;
  • понимание Angular-специфичных конструкций;
  • сокращение необходимости ручных wait и sleep.

Protractor изначально разрабатывался как инструмент end-to-end тестирования, а не unit или integration тестов.

Архитектурные особенности ранних версий

Protractor строился поверх нескольких ключевых компонентов:

  • Selenium WebDriverJS — JavaScript-реализация WebDriver;
  • Node.js как среда выполнения;
  • Control Flow (webdriver.promise.Manager) для управления асинхронностью;
  • Jasmine как тестовый фреймворк по умолчанию.

Одной из важных архитектурных особенностей стало внедрение Angular-хуков. Protractor внедрял специальный скрипт в страницу, позволяя:

  • отслеживать активные $http запросы;
  • определять состояние $rootScope;
  • понимать, когда Angular стабилизировался.

Это дало возможность реализовать автоматическое ожидание, которое стало визитной карточкой Protractor.

Специфичные локаторы Angular

Важным этапом эволюции Protractor стало появление Angular-локаторов, недоступных в чистом Selenium:

  • by.model
  • by.binding
  • by.repeater
  • by.exactBinding
  • by.options

Эти локаторы работали напрямую с внутренними структурами AngularJS, а не только с DOM. Это позволяло писать более устойчивые и выразительные тесты, тесно связанные с логикой приложения.

Пример концепции:

  • тест оперировал моделью и биндингами;
  • изменения в разметке меньше влияли на тесты;
  • улучшалась читаемость тестового кода.

Расширение поддержки браузеров и окружений

На ранних этапах Protractor активно использовался преимущественно с Chrome и Firefox. По мере развития:

  • улучшалась поддержка различных версий WebDriver;
  • добавлялась интеграция с Selenium Grid;
  • расширялись возможности параллельного запуска тестов;
  • улучшалась работа в CI/CD окружениях.

Protractor быстро стал стандартом де-факто для e2e-тестирования AngularJS-приложений.

Переход Angular к новой архитектуре

С выходом Angular 2 (2016 год) экосистема столкнулась с серьёзными изменениями:

  • отказ от $scope и digest-цикла;
  • переход на Zone.js;
  • использование TypeScript;
  • модульная архитектура.

Protractor адаптировался к этим изменениям. Хотя Angular 2+ кардинально отличался от AngularJS, инструмент продолжил использоваться как основной e2e-фреймворк.

Ключевые изменения в Protractor в этот период:

  • переход от AngularJS-хуков к Zone.js-based ожиданиям;
  • улучшенная поддержка TypeScript;
  • расширенная конфигурация для non-Angular приложений;
  • возможность отключать Angular-синхронизацию (browser.waitForAngularEnabled(false)).

Отказ от Control Flow и переход к async/await

Одним из самых значимых этапов эволюции Protractor стал отказ от Selenium Control Flow.

Изначально Protractor маскировал асинхронность, позволяя писать код в синхронном стиле:

element(by.id('login')).sendKeys('admin');
element(by.id('submit')).click();

Под капотом все действия ставились в очередь Control Flow. Однако этот подход:

  • усложнял отладку;
  • конфликтовал с современным JavaScript;
  • стал несовместим с развитием WebDriverJS.

Начиная с версий Protractor 5+ и особенно в 6–7 версиях:

  • Control Flow был признан устаревшим;
  • внедрена обязательная поддержка async/await;
  • тесты стали ближе к стандартному JavaScript.

Это сблизило Protractor с остальной экосистемой Node.js, но потребовало миграции существующих проектов.

Снижение роли Protractor в экосистеме

К концу 2010-х годов рынок e2e-тестирования начал смещаться:

  • Cypress предложил иной подход без Selenium;
  • Playwright и Puppeteer обеспечили более низкоуровневый контроль браузера;
  • Angular-команда сделала акцент на универсальные инструменты.

Основные проблемы Protractor на этом этапе:

  • сильная зависимость от Selenium;
  • сложная конфигурация;
  • медленный запуск тестов;
  • устаревшая архитектура по сравнению с конкурентами.

Объявление о завершении поддержки

В 2021 году команда Angular официально объявила о прекращении активной поддержки Protractor. Репозиторий был переведён в режим maintenance, а затем архивирован.

Причины решения:

  • уменьшение числа пользователей;
  • рост альтернативных инструментов;
  • фокус Angular на core-разработке, а не тестовых фреймворках;
  • отсутствие уникальных преимуществ в новых версиях Angular.

При этом Protractor продолжает использоваться в существующих проектах, особенно в legacy-системах на AngularJS и ранних версиях Angular.

Историческое значение Protractor

Protractor сыграл ключевую роль в развитии frontend-тестирования:

  • сформировал подход к Angular-aware e2e тестам;
  • популяризировал автоматические ожидания;
  • повлиял на дизайн современных инструментов;
  • показал важность интеграции тестового фреймворка с фреймворком приложения.

Многие идеи Protractor — такие как синхронизация с состоянием приложения и высокоуровневые локаторы — стали стандартом для последующих поколений инструментов тестирования.