Транспортир - Краткое руководство

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

Что такое транспортир?

Protractor - это фреймворк для сквозного тестирования с открытым исходным кодом для приложений Angular и AngularJS. Он был построен Google на основе WebDriver. Он также служит заменой существующей среды тестирования AngularJS E2E под названием «Angular Scenario Runner».

Он также работает как интегратор решений, объединяющий мощные технологии, такие как NodeJS, Selenium, Jasmine, WebDriver, Cucumber, Mocha и т. Д. Наряду с тестированием приложения AngularJS, он также пишет автоматические регрессионные тесты для обычных веб-приложений. Это позволяет нам тестировать наше приложение, как настоящий пользователь, потому что оно запускает тест в реальном браузере.

Следующая диаграмма даст краткий обзор транспортира -

Обратите внимание, что на приведенной выше диаграмме мы имеем -

  • Protractor - Как обсуждалось ранее, это оболочка над WebDriver JS, специально разработанная для приложений angular.

  • Jasmine- По сути, это среда разработки, управляемая поведением, для тестирования кода JavaScript. Мы можем легко писать тесты с помощью Jasmine.

  • WebDriver JS - Это реализация привязки Node JS для selenium 2.0 / WebDriver.

  • Selenium - Он просто автоматизирует браузер.

Происхождение

Как было сказано ранее, Protractor является заменой существующей среды тестирования AngularJS E2E под названием «Angular Scenario Runner». По сути, происхождение Protractor начинается с конца Scenario Runner. Здесь возникает вопрос: зачем нам создавать транспортир? Чтобы понять это, нам сначала нужно узнать о его предшественнике - Scenario Runner.

Начало транспортира

Джули Ральф, главный участник разработки Protractor, имела следующий опыт работы с Angular Scenario Runner в другом проекте Google. Это еще больше стало мотивацией для создания транспортира, специально для заполнения пробелов -

«Мы попробовали использовать Scenario Runner и обнаружили, что он действительно не может делать то, что нам нужно было протестировать. Нам нужно было протестировать такие вещи, как вход в систему. Ваша страница входа не является страницей Angular, и Scenario Runner не может с этим справиться. И он не мог справиться с такими вещами, как всплывающие окна и несколько окон, навигация по истории браузера и тому подобное ».

Самым большим преимуществом Protractor была зрелость проекта Selenium, и он завершает свои методы, чтобы его можно было легко использовать для проектов Angular. Дизайн Protractor построен таким образом, что он тестирует все слои, такие как веб-интерфейс, серверные службы, уровень сохраняемости и т. Д. Приложения.

Почему транспортир?

Как мы знаем, почти все приложения используют JavaScript для разработки. Задача тестировщиков усложняется, когда размер JavaScript увеличивается и становится сложным для приложений из-за увеличения числа самих приложений. В большинстве случаев становится очень сложно захватить веб-элементы в приложениях AngularJS, использует расширенный синтаксис HTML для выражения компонентов веб-приложений с помощью JUnit или Selenium WebDriver.

Вопрос в том, почему Selenium Web Driver не может найти веб-элементы AngularJS? Причина в том, что приложения AngularJS имеют некоторые расширенные атрибуты HTML, такие как ng-Repeater, ng-controller, ng-model и т. Д., Которые не включены в локаторы Selenium.

Здесь важность Protractor проявляется в том, что Protractor в верхней части Selenium может обрабатывать и контролировать эти расширенные HTML-элементы в веб-приложениях AngularJS. Вот почему мы можем сказать, что большинство фреймворков сосредоточено на проведении модульных тестов для приложений AngularJS, а Protractor использовался для тестирования фактической функциональности приложения.

Работа транспортира

Protractor, среда тестирования, работает вместе с Selenium, чтобы предоставить автоматизированную тестовую инфраструктуру для имитации взаимодействия пользователя с приложением AngularJS, запущенным в браузере или мобильном устройстве.

Работу транспортира можно понять с помощью следующих шагов -

  • Step 1- На первом этапе нам нужно написать тесты. Это можно сделать с помощью жасмина, мокко или огурца.

  • Step 2- Теперь нам нужно запустить тест, который можно сделать с помощью Protractor. Его еще называют тест-раннером.

  • Step 3 - На этом этапе сервер Selenium поможет управлять браузерами.

  • Step 4 - Наконец, API-интерфейсы браузера вызываются с помощью Selenium WebDriver.

Преимущества

Эта среда для сквозного тестирования с открытым исходным кодом предлагает следующие преимущества:

  • Инструмент с открытым исходным кодом, Protractor очень прост в установке и настройке.

  • Хорошо работает с Jasmine framework для создания теста.

  • Поддерживает разработку через тестирование (TDD).

  • Содержит автоматические ожидания, что означает, что нам не нужно явно добавлять ожидания и ожидания в наш тест.

  • Предлагает все преимущества Selenium WebDriver.

  • Поддерживает параллельное тестирование через несколько браузеров.

  • Обеспечивает автоматическую синхронизацию.

  • Имеет отличную скорость тестирования.

Ограничения

Эта среда для сквозного тестирования с открытым исходным кодом обладает следующими ограничениями:

  • Не раскрывает вертикалей в автоматизации браузера, поскольку является оболочкой для WebDriver JS.

  • Знание JavaScript необходимо пользователю, потому что он доступен только для JavaScript.

  • Предоставляет только интерфейсное тестирование, потому что это инструмент тестирования, управляемый пользовательским интерфейсом.

Поскольку знание JavaScript необходимо для работы с Protractor, в этой главе давайте подробно разберемся с концепциями тестирования JavaScript.

Тестирование и автоматизация JavaScript

JavaScript - самый популярный язык сценариев с динамической типизацией и интерпретацией, но наиболее сложной задачей является тестирование кода. Это потому, что, в отличие от других скомпилированных языков, таких как JAVA и C ++, в JavaScript нет шагов компиляции, которые могут помочь тестировщику выявить ошибки. Кроме того, тестирование в браузере занимает очень много времени; следовательно, существует потребность в инструментах, поддерживающих автоматическое тестирование JavaScript.

Концепции автоматизированного тестирования

Написание теста - это всегда хорошая практика, потому что это улучшает код; Проблема с ручным тестированием заключается в том, что оно занимает немного времени и подвержено ошибкам. Процесс ручного тестирования довольно утомителен и для программистов, так как им нужно повторять процесс, писать спецификации тестов, менять код и обновлять браузер несколько раз. Кроме того, ручное тестирование также замедляет процесс разработки.

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

По сути, разработчик может реализовать набор инструментов в CLI (интерпретатор командной строки) или в среде разработки (интегрированная среда разработки). Затем эти тесты будут выполняться непрерывно в отдельном процессе даже без участия разработчика. Автоматическое тестирование JavaScript также не ново, и было разработано множество инструментов, таких как Karma, Protractor, CasperJS и т. Д.

Типы тестирования для JavaScript

Для разных целей могут быть разные тесты. Например, некоторые тесты написаны для проверки поведения функций в программе, а другие - для проверки выполнения модуля или функции. Таким образом, у нас есть следующие два типа тестирования -

Модульное тестирование

Тестирование проводится на самой маленькой тестируемой части программы, называемой модулем. Блок в основном тестируется изолированно, без какой-либо зависимости этого блока от других частей. В случае JavaScript отдельный метод или функция, обладающая определенным поведением, может быть единицей кода, и эти единицы кода должны тестироваться изолированно.

Одним из преимуществ модульного тестирования является то, что тестирование модулей может выполняться в любом порядке, поскольку модули независимы друг от друга. Еще одно преимущество модульного тестирования, которое действительно имеет значение, заключается в том, что он может запускать тест в любое время следующим образом:

  • С самого начала процесса разработки.
  • После завершения разработки любого модуля / функции.
  • После изменения любого модуля / функции.
  • После добавления любой новой функции в существующее приложение.

Для автоматизированного модульного тестирования приложений JavaScript мы можем выбирать из множества инструментов и фреймворков тестирования, таких как Mocha, Jasmine и QUnit.

Сквозное тестирование

Его можно определить как методологию тестирования, используемую для проверки того, нормально ли работает поток приложения от начала до конца (от одного конца до другого) согласно проекту.

Сквозное тестирование также называется функциональным / поточным тестированием. В отличие от модульного тестирования, сквозное тестирование проверяет, как отдельные компоненты работают вместе как приложение. Это основное различие между модульным тестированием и сквозным тестированием.

Например, предположим, что если у нас есть модуль регистрации, в котором пользователь должен предоставить некоторую действительную информацию для завершения регистрации, тогда тестирование E2E для этого конкретного модуля будет выполнять следующие шаги для завершения тестирования:

  • Сначала он загрузит / скомпилирует форму или модуль.
  • Теперь он получит DOM (объектную модель документа) элементов формы.
  • Затем активируйте событие нажатия кнопки отправки, чтобы проверить, работает она или нет.
  • Теперь, для проверки, соберите значение из полей ввода.
  • Затем необходимо проверить поля ввода.
  • В целях тестирования вызовите поддельный API для хранения данных.

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

Теперь возникает вопрос, хотя этот вид E2E или функционального тестирования можно также выполнять вручную, зачем нам для этого нужна автоматизация? Основная причина в том, что автоматизация упростит этот процесс тестирования. Некоторые из доступных инструментов, которые можно легко интегрировать с любым приложением, для этой цели - это Selenium, PhantomJS и Protractor.

Инструменты и фреймворки для тестирования

У нас есть различные инструменты и фреймворки для тестирования Angular. Ниже приведены некоторые из хорошо известных инструментов и фреймворков.

Карма

Карма, созданная Войтой Джиной, является бегуном-тестером. Изначально этот проект назывался Testacular. Это не тестовая среда, а это значит, что она дает нам возможность легко и автоматически запускать модульные тесты JavaScript в реальных браузерах. Karma была создана для AngularJS, потому что до Karma не было инструмента автоматического тестирования для веб-разработчиков JavaScript. С другой стороны, с помощью автоматизации, предоставляемой Karma, разработчики могут запустить простую единственную команду и определить, прошел ли весь набор тестов или нет.

Плюсы использования Кармы

Ниже приведены некоторые преимущества использования Karma по сравнению с ручным процессом.

  • Автоматизирует тесты в нескольких браузерах, а также на разных устройствах.
  • Следит за файлами на предмет ошибок и исправляет их.
  • Предоставляет онлайн-поддержку и документацию.
  • Упрощает интеграцию с сервером непрерывной интеграции.

Минусы использования кармы

Ниже приведены некоторые минусы использования Кармы:

Основным недостатком использования Karma является то, что для его настройки и обслуживания требуется дополнительный инструмент.

Если вы используете средство запуска тестов Karma с Jasmine, то доступно меньше документации для поиска информации о настройке вашего CSS в случае наличия нескольких идентификаторов для одного элемента.

Жасмин

Jasmine, управляемая поведением среда разработки для тестирования кода JavaScript, разработана в Pivotal Labs. До активной разработки фреймворка Jasmine похожий фреймворк модульного тестирования под названием JsUnit также был разработан Pivotal Labs, у которого есть встроенный инструмент запуска тестов. Тесты браузеров можно запускать с помощью тестов Jasmine, включая файл SpecRunner.html или используя его в качестве средства запуска тестов командной строки. Его также можно использовать с кармой или без нее.

Плюсы использования жасмина

Ниже приведены некоторые плюсы использования жасмина:

  • Фреймворк, не зависящий от браузера, платформы и языка.

  • Поддерживает разработку через тестирование (TDD) и разработку на основе поведения.

  • По умолчанию имеет интеграцию с Karma.

  • Легко понять синтаксис.

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

Минусы использования жасмина

Ниже приводится недостаток использования Жасмина -

  • Пользователь должен возвращать тесты по мере их изменения, потому что в Jasmine нет функции просмотра файлов во время выполнения теста.

Мокко

Mocha, написанный для приложений Node.js, представляет собой среду тестирования, но также поддерживает тестирование браузера. Он очень похож на Jasmine, но главное различие между ними в том, что Mocha нужен плагин и библиотека, потому что он не может работать автономно в качестве тестовой среды. С другой стороны, Жасмин автономна. Однако Mocha более гибок в использовании, чем Jasmine.

Плюсы использования Mocha

Ниже приведены некоторые плюсы использования Mocha:

  • Mocha очень легко установить и настроить.
  • Удобная и простая документация.
  • Содержит плагины с несколькими проектами узлов.

Минусы использования мокко

Ниже приведены некоторые минусы использования Mocha:

  • Нужны отдельные модули для утверждений, шпионов и т. Д.
  • Также требуется дополнительная настройка для использования с Karma.

QUnit

QUint, первоначально разработанный Джоном Ресигом в 2008 году как часть jQuery, представляет собой мощный, но простой в использовании набор модульных тестов JavaScript. Его можно использовать для тестирования любого универсального кода JavaScript. Хотя он ориентирован на тестирование JavaScript в браузере, разработчику его очень удобно использовать.

Плюсы использования QUnit

Ниже приведены некоторые преимущества использования QUnit:

  • Простота установки и настройки.
  • Удобная и простая документация.

Минусы использования QUnit

Ниже приводится недостаток использования QUnit -

  • Он был в основном разработан для jQuery и, следовательно, не очень хорош для использования с другими фреймворками.

Селен

Selenium, первоначально разработанный Джейсоном Хаггинсом в 2004 году в качестве внутреннего инструмента в ThoughtWorks, представляет собой инструмент автоматизации тестирования с открытым исходным кодом. Selenium определяет себя как «Selenium автоматизирует браузеры. Это оно!". Автоматизация браузеров означает, что разработчики могут очень легко взаимодействовать с браузерами.

Плюсы использования Selenium

Ниже приведены некоторые преимущества использования Selenium:

  • Содержит большой набор функций.
  • Поддерживает распределенное тестирование.
  • Имеет поддержку SaaS через такие службы, как Sauce Labs.
  • Простота использования, простая документация и доступные ресурсы.

Минусы использования Selenium

Ниже приведены некоторые недостатки использования Selenium:

  • Основным недостатком использования Selenium является то, что он должен выполняться как отдельный процесс.
  • Конфигурация немного обременительна, так как разработчик должен выполнить несколько шагов.

В предыдущих главах мы узнали основы транспортира. В этой главе давайте узнаем, как его установить и настроить.

Предпосылки

Перед установкой Protractor на ваш компьютер необходимо выполнить следующие предварительные требования:

Node.js

Protractor - это модуль Node.js, поэтому очень важным предварительным условием является то, что на нашем компьютере должен быть установлен Node.js. Мы собираемся установить пакет Protractor, используя npm (менеджер пакетов JavaScript), который поставляется с Node.js.

Для установки Node.js перейдите по официальной ссылке - https://nodejs.org/en/download/. После установки Node.js вы можете проверить версию Node.js и npm, написав командуnode --version и npm --version в командной строке, как показано ниже -

Хром

Google Chrome, веб-браузер, созданный Google, будет использоваться для выполнения сквозных тестов в Protractor без необходимости использования сервера Selenium. Вы можете скачать хром, перейдя по ссылке -https://www.google.com/chrome/.

Selenium WebDriver для Chrome

Этот инструмент поставляется с модулем npm Protractor и позволяет нам взаимодействовать с веб-приложениями.

Установка транспортира

После установки Node.js на наш компьютер мы можем установить Protractor с помощью следующей команды -

npm install -g protractor

После успешной установки транспортира мы можем проверить его версию, написав protractor --version в командной строке, как показано ниже -

Установка WebDriver для Chrome

После установки Protractor нам нужно установить Selenium WebDriver для Chrome. Его можно установить с помощью следующей команды -

webdriver-manager update

Приведенная выше команда создаст каталог Selenium, содержащий необходимый драйвер Chrome, используемый в проекте.

Подтверждение установки и конфигурации

Мы можем подтвердить установку и настройку Protractor, немного изменив conf.js, представленный в примере, после установки Protractor. Вы можете найти этот файл conf.js в корневом каталогеnode_modules/Protractor/example.

Для этого сначала создайте новый файл с именем testingconfig.js в том же каталоге, т.е. node_modules/Protractor/example.

Теперь в файле conf.js в параметре объявления исходного файла напишите testconfig.js.

Затем сохраните и закройте все файлы и откройте командную строку. Запустите файл conf.js, как показано на скриншоте ниже.

Конфигурация и установка транспортира успешны, если вы получили результат, как показано ниже -

Приведенный выше вывод показывает, что спецификации нет, потому что мы предоставили пустой файл в параметре объявления исходного файла в файле conf.js. Но из приведенного выше вывода мы видим, что транспортир и WebDriver работают успешно.

Проблемы при установке и настройке

При установке и настройке Protractor и WebDriver мы можем столкнуться со следующими общими проблемами:

Селен установлен неправильно

Это наиболее частая проблема при установке WebDriver. Эта проблема возникает, если вы не обновляете WebDriver. Обратите внимание, что мы должны обновить WebDriver, иначе мы не сможем ссылаться на него при установке Protractor.

Не удалось найти тесты

Другая распространенная проблема заключается в том, что после запуска Protractor он показывает, что не может найти тесты. Для этого мы должны убедиться, что относительные пути, имена файлов или расширения верны. Нам также нужно очень внимательно писать файл conf.js, потому что он начинается с самого файла конфигурации.

Как обсуждалось ранее, Protractor - это комплексная среда тестирования с открытым исходным кодом для приложений Angular и AngularJS. Это программа Node.js. С другой стороны, Selenium - это среда автоматизации браузера, которая включает в себя Selenium Server, API WebDriver и драйверы браузера WebDriver.

Транспортир с селеном

Если мы говорим о соединении Protractor и Selenium, Protractor может работать с сервером Selenium для обеспечения инфраструктуры автоматизированного тестирования. Инфраструктура может имитировать взаимодействие пользователя с приложением angular, запущенным в браузере или на мобильном устройстве. Объединение Protractor и Selenium можно разделить на три раздела, а именно: тест, сервер и браузер, как показано на следующей диаграмме -

Процессы Selenium WebDriver

Как мы видели на приведенной выше диаграмме, тест с использованием Selenium WebDriver включает следующие три процесса:

  • Тестовые скрипты
  • Сервер
  • Браузер

В этом разделе давайте обсудим связь между этими тремя процессами.

Связь между тестовыми сценариями и сервером

Связь между первыми двумя процессами - тестовыми скриптами и сервером зависит от работы Selenium Server. Другими словами, мы можем сказать, что способ работы сервера Selenium придаст форму процессу связи между тестовыми скриптами и сервером.

Сервер Selenium может работать локально на нашей машине как автономный сервер Selenium (selenium-server-standalone.jar) или он может работать удаленно через службу (Sauce Labs). В случае автономного сервера Selenium между Node.js и сервером selenium будет http-соединение.

Связь между сервером и браузером

Как мы знаем, сервер отвечает за пересылку команд в браузер после их интерпретации из тестовых сценариев. Вот почему сервер и браузер также требуют средства связи, и здесь связь осуществляется с помощьюJSON WebDriver Wire Protocol. В браузер добавлен драйвер браузера, который используется для интерпретации команд.

Вышеупомянутое понятие о процессах Selenium WebDriver и их взаимодействии можно понять с помощью следующей диаграммы -

При работе с Protractor самый первый процесс, то есть тестовый скрипт, запускается с использованием Node.js, но перед выполнением каких-либо действий в браузере он отправляет дополнительную команду, чтобы убедиться, что тестируемое приложение стабилизировано.

Настройка Selenium Server

Selenium Server действует как прокси-сервер между нашим тестовым скриптом и драйвером браузера. По сути, он пересылает команду из нашего тестового сценария в WebDriver и возвращает ответы от WebDriver на наш тестовый скрипт. Существуют следующие варианты настройки сервера Selenium, которые включены вconf.js файл тестового скрипта -

Автономный Selenium Server

Если мы хотим запустить сервер на нашей локальной машине, нам нужно установить автономный селен-сервер. Необходимым условием для установки автономного сервера selenium является JDK (Java Development Kit). У нас должен быть установлен JDK на нашем локальном компьютере. Мы можем проверить это, выполнив следующую команду из командной строки -

java -version

Теперь у нас есть возможность установить и запустить Selenium Server вручную или из тестового сценария.

Установка и запуск Selenium server вручную

Для установки и запуска сервера Selenium вручную нам нужно использовать инструмент командной строки WebDriver-Manager, который поставляется с Protractor. Шаги по установке и запуску сервера Selenium следующие:

Step 1- Первый шаг - установка сервера Selenium и ChromeDriver. Это можно сделать с помощью следующей команды -

webdriver-manager update

Step 2- Далее нам нужно запустить сервер. Это можно сделать с помощью следующей команды -

webdriver-manager start

Step 3- Наконец, нам нужно установить seleniumAddress в конфигурационном файле на адрес работающего сервера. Адрес по умолчанию будетhttp://localhost:4444/wd/hub.

Запуск сервера Selenium из тестового скрипта

Для запуска сервера Selenium из тестового сценария нам необходимо установить следующие параметры в нашем файле конфигурации:

  • Location of jar file - Нам нужно указать расположение файла jar для автономного сервера Selenium в файле конфигурации, установив seleniumServerJar.

  • Specifying the port- Нам также необходимо указать порт, который будет использоваться для запуска автономного сервера Selenium. Его можно указать в файле конфигурации, установив seleniumPort. Порт по умолчанию - 4444.

  • Array of command line options- Нам также необходимо установить массив параметров командной строки для передачи на сервер. Его можно указать в файле конфигурации, установив seleniumArgs. Если вам нужен полный список массива команд, то запустите сервер с-help флаг.

Работа с удаленным сервером Selenium

Другой вариант запуска нашего теста - удаленное использование сервера Selenium. Предварительным условием для удаленного использования сервера является наличие учетной записи в службе, в которой размещен сервер. При работе с Protractor у нас есть встроенная поддержка следующих сервисов, на которых размещен сервер:

TestObject

Для использования TestObject в качестве удаленного сервера Selenium нам необходимо установить testobjectUser, имя пользователя нашей учетной записи TestObject и testobjectKey, ключ API нашей учетной записи TestObject.

BrowserStack

Для использования BrowserStack в качестве удаленного сервера Selenium нам необходимо установить browserstackUser, имя пользователя нашей учетной записи BrowserStack и browserstackKey, ключ API нашей учетной записи BrowserStack.

Соус лаборатории

Для использования Sauce Labs в качестве удаленного Selenium Server нам необходимо установить соусаUser, имя пользователя нашей учетной записи Sauce Labs и SauceKey, ключ API нашей учетной записи Sauce Labs.

Кобитон

Для использования Kobiton в качестве удаленного Selenium Server нам необходимо установить kobitonUser, имя пользователя нашей учетной записи Kobiton и kobitonKey, ключ API нашей учетной записи Kobiton.

Прямое подключение к драйверу браузера без использования Selenium Server

Еще один вариант запуска нашего теста - напрямую подключиться к драйверу браузера без использования сервера Selenium. Protractor может тестировать напрямую, без использования Selenium Server, против Chrome и Firefox, установив directConnect: true в файле конфигурации.

Настройка браузера

Перед настройкой и настройкой браузера нам нужно знать, какие браузеры поддерживает Protractor. Ниже приведен список браузеров, поддерживаемых Protractor.

  • ChromeDriver
  • FirefoxDriver
  • SafariDriver
  • IEDriver
  • Appium-iOS/Safari
  • Appium-Android/Chrome
  • Selendroid
  • PhantomJS

Для установки и настройки браузера нам нужно перейти в файл конфигурации Protractor, потому что настройка браузера выполняется в объекте возможностей файла конфигурации.

Настройка Chrome

Для настройки браузера Chrome нам нужно установить объект возможностей следующим образом

capabilities: {
   'browserName': 'chrome'
}

Мы также можем добавить параметры, специфичные для Chrome, которые вложены в chromeOptions, и их полный список можно увидеть на https://sites.google.com/a/chromium.org/chromedriver/capabilities.

Например, если вы хотите добавить FPS-счетчик в правом верхнем углу, это можно сделать в файле конфигурации следующим образом:

capabilities: {
   'browserName': 'chrome',
   'chromeOptions': {
      'args': ['show-fps-counter=true']
   }
},

Настройка Firefox

Для настройки браузера Firefox нам нужно установить объект возможностей следующим образом:

capabilities: {
   'browserName': 'firefox'
}

Мы также можем добавить параметры, специфичные для Firefox, которые вложены в объект moz: firefoxOptions, и его полный список можно увидеть на https://github.com/mozilla/geckodriver#firefox-capabilities.

Например, если вы хотите запустить свой тест в Firefox в безопасном режиме, это можно сделать в файле конфигурации следующим образом:

capabilities: {
   'browserName': 'firefox',
   'moz:firefoxOptions': {
     'args': ['—safe-mode']
   }
},

Настройка другого браузера

Для настройки любого другого браузера, кроме Chrome или Firefox, нам необходимо установить отдельный двоичный файл из https://docs.seleniumhq.org/download/.

Настройка PhantonJS

Фактически, PhantomJS больше не поддерживается из-за проблем с его сбоями. Вместо этого рекомендуется использовать Chrome без головы или Firefox без головы. Их можно настроить следующим образом -

Чтобы настроить Chrome без головы, нам нужно запустить Chrome с флагом –headless следующим образом:

capabilities: {
   'browserName': 'chrome',
   'chromeOptions': {
      'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
   }
},

Для настройки безголового Firefox нам нужно запустить Firefox с –headless флаг следующим образом -

capabilities: {
   'browserName': 'firefox',
   'moz:firefoxOptions': {
      'args': [“--headless”]
   }
},

Настройка нескольких браузеров для тестирования

Мы также можем протестировать против нескольких браузеров. Для этого нам нужно использовать опцию конфигурации multiCapabilities следующим образом:

multiCapabilities: [{
   'browserName': 'chrome'
},{
   'browserName': 'firefox'
}]

Какой фреймворк?

Protractor поддерживает две среды тестирования BDD (разработка, управляемая поведением), Jasmine и Mocha. Обе инфраструктуры основаны на JavaScript и Node.js. Эти платформы обеспечивают синтаксис, отчет и строительные леса, необходимые для написания тестов и управления ими.

Далее мы увидим, как мы можем установить различные фреймворки -

Жасминовая рамка

Это стандартная тестовая среда для Protractor. При установке Protractor вы получите версию Jasmine 2.x. Устанавливать его отдельно не нужно.

Фреймворк из мокко

Mocha - еще одна среда тестирования JavaScript, в основном работающая на Node.js. Для использования Mocha в качестве нашей тестовой среды нам необходимо использовать интерфейс BDD (разработка, управляемая поведением) и утверждения Chai с Chai As Promised. Установка может быть выполнена с помощью следующих команд -

npm install -g mocha
npm install chai
npm install chai-as-promised

Как видите, при установке mocha используется опция -g, потому что мы установили Protractor глобально с помощью опции -g. После его установки нам нужно потребовать и настроить Chai в наших тестовых файлах. Это можно сделать следующим образом -

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;

После этого мы можем использовать Chai As Promised как таковой -

expect(myElement.getText()).to.eventually.equal('some text');

Теперь нам нужно установить для свойства framework значение mocha файла конфигурации, добавив framework: 'mocha'. Такие параметры, как «репортер» и «медленно» для мокко, могут быть добавлены в файл конфигурации следующим образом:

mochaOpts: {
   reporter: "spec", slow: 3000
}

Рамка из огурца

Чтобы использовать Cucumber в качестве нашей тестовой среды, нам нужно интегрировать его с Protractor с опцией framework custom. Установка может быть произведена с помощью следующих команд

npm install -g cucumber
npm install --save-dev protractor-cucumber-framework

Как видите, опция -g используется при установке Cucumber, потому что мы установили Protractor глобально, то есть с опцией -g. Далее нам нужно установить для свойства framework значениеcustom файла конфигурации, добавив framework: 'custom' и frameworkPath: 'Protractor-cucumber-framework' в файл конфигурации с именем cucumberConf.js.

Пример кода, показанный ниже, представляет собой базовый файл cucumberConf.js, который можно использовать для запуска файлов функций огурца с помощью Protractor -

exports.config = {
   seleniumAddress: 'http://localhost:4444/wd/hub',

   baseUrl: 'https://angularjs.org/',

   capabilities: {
      browserName:'Firefox'
   },

   framework: 'custom',

   frameworkPath: require.resolve('protractor-cucumber-framework'),

   specs: [
      './cucumber/*.feature'
   ],

   // cucumber command line options
   cucumberOpts: {
      require: ['./cucumber/*.js'],
      tags: [],
      strict: true,
      format: ["pretty"],
      'dry-run': false,
      compiler: []
   },
   onPrepare: function () {
      browser.manage().window().maximize();
   }
};

В этой главе давайте поймем, как написать первый тест в Protractor.

Файлы, необходимые для транспортира

Транспортиру нужны следующие два файла для запуска -

Спецификация или тестовый файл

Это один из важных файлов для запуска Protractor. В этом файле мы напишем наш тестовый код. Тестовый код написан с использованием синтаксиса нашей тестовой среды.

Например, если мы используем Jasmine framework, то тестовый код будет написан с использованием синтаксиса Jasmine. Этот файл будет содержать все функциональные потоки и утверждения теста.

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

пример

Ниже приведен простой сценарий TestSpecification.js, имеющий тестовый пример для перехода по URL-адресу и проверки заголовка страницы.

//TestSpecification.js
describe('Protractor Demo', function() {
   it('to check the page title', function() {
      browser.ignoreSynchronization = true;
      browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
      browser.driver.getTitle().then(function(pageTitle) {
         expect(pageTitle).toEqual('Free Online Tutorials and Courses');
      });
   });
});

Код Пояснение

Код указанного выше файла спецификации можно объяснить следующим образом:

Браузер

Это глобальная переменная, созданная Protractor для обработки всех команд уровня браузера. По сути, это оболочка для экземпляра WebDriver. browser.get () - это простой метод Selenium, который сообщает Protractor о необходимости загрузки определенной страницы.

  • describe и it- Оба являются синтаксисами тестовой среды Jasmine. В’Describe’ используется, чтобы содержать сквозной поток нашего тестового примера, тогда как ‘it’содержит некоторые тестовые сценарии. У нас может быть несколько‘it’ блоки в нашей тестовой программе.

  • Expect - Это утверждение, в котором мы сравниваем заголовок веб-страницы с некоторыми предопределенными данными.

  • ignoreSynchronization- Это тег браузера, который используется, когда мы пытаемся тестировать неугловые веб-сайты. Предполагается, что Protractor будет работать только с веб-сайтами angular, но если мы хотим работать с веб-сайтами, отличными от angular, то этот тег должен быть установлен на“true”.

Конфигурационный файл

Как следует из названия, в этом файле содержатся объяснения всех параметров конфигурации транспортира. Он в основном сообщает Protractor следующее:

  • Где найти файлы тестов или спецификаций
  • Какой браузер выбрать
  • Какую среду тестирования использовать
  • Где поговорить с Selenium Server

пример

Ниже представлен простой скрипт config.js с тестом

// config.js
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when
   // protractor is called.
   specs: ['TestSpecification.js'],

Код Пояснение

Код вышеуказанного файла конфигурации, имеющий три основных параметра, можно объяснить следующим образом:

Параметр возможностей

Этот параметр используется для указания имени браузера. Это можно увидеть в следующем блоке кода файла conf.js -

exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
},

Как видно выше, имя браузера, данного здесь, - «хром», которое по умолчанию является браузером для Protractor. Мы также можем изменить имя браузера.

Параметр рамки

Этот параметр используется для указания имени платформы тестирования. Это можно увидеть в следующем блоке кода файла config.js -

exports.config = {
   directConnect: true,

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

Здесь мы используем тестовую среду «жасмин».

Параметр объявления исходного файла

Этот параметр используется для указания имени объявления исходного файла. Это можно увидеть в следующем блоке кода файла conf.js -

exports.config = {
   directConnect: true,
   // Spec patterns are relative to the current working 
   directory when protractor is called.
   specs: ['TsetSpecification.js'],

Как видно выше, приведенное здесь имя объявления исходного файла ‘TestSpecification.js’. Это потому, что для этого примера мы создали файл спецификации с именемTestSpecification.js.

Выполнение кода

Поскольку у нас есть базовое представление о необходимых файлах и их коде для запуска Protractor, давайте попробуем запустить пример. Мы можем выполнить следующие шаги, чтобы выполнить этот пример:

  • Step 1 - Сначала откройте командную строку.

  • Step 2 - Далее нам нужно перейти в каталог, в котором мы сохранили наши файлы, а именно config.js и TestSpecification.js.

  • Step 3 - Теперь запустите файл config.js, выполнив команду Protrcator config.js.

Снимок экрана, показанный ниже, объяснит вышеуказанные шаги для выполнения примера -

На снимке экрана видно, что тест пройден.

Теперь предположим, что если мы тестируем веб-сайты, не относящиеся к Angular, и не устанавливаем для тега ignoreSynchronization значение true, то после выполнения кода мы получим ошибку «Angular не может быть найден на странице».

Это можно увидеть на следующем снимке экрана -

Генерация отчетов

До сих пор мы обсуждали необходимые файлы и их код для запуска тестовых примеров. Protractor также может создавать отчет для тестовых случаев. Для этого он поддерживает Жасмин. JunitXMLReporter можно использовать для автоматического создания отчетов о выполнении тестов.

Но перед этим нам нужно установить Jasmine reporter с помощью следующей команды -

npm install -g jasmine-reporters

Как видите, опция -g используется при установке Jasmine Reporters, потому что мы установили Protractor глобально с опцией -g.

После успешной установки jasmine-reporters нам нужно добавить следующий код в наш ранее использованный файл config.js -

onPrepare: function(){ //configure junit xml report

   var jasmineReporters = require('jasmine-reporters');
   jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
      consolidateAll: true,
      filePrefix: 'guitest-xmloutput',
      savePath: 'test/reports'
   }));

Теперь наш новый файл config.js будет следующим:

// An example configuration file.
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when
   // protractor is called.
   specs: ['TestSpecification.js'],
   //framework: "jasmine2", //must set it if you use JUnitXmlReporter
   onPrepare: function(){ //configure junit xml report
      var jasmineReporters = require('jasmine-reporters');
      jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
         consolidateAll: true,
         filePrefix: 'guitest-xmloutput',
         savePath: 'reports'
      }));
   },
};

После запуска вышеуказанного файла конфигурации таким же образом, как мы запускали ранее, он сгенерирует XML-файл, содержащий отчет, в корневом каталоге в reportsпапка. Если тест прошел успешно, отчет будет выглядеть следующим образом -

Но, если тест не прошел, отчет будет выглядеть, как показано ниже -

Транспортир - Ядро APIS

Эта глава позволяет вам понять различные основные API-интерфейсы, которые являются ключевыми для функционирования транспортира.

Важность API-интерфейсов транспортира

Protractor предоставляет нам широкий спектр API-интерфейсов, которые очень важны для выполнения следующих действий для получения текущего состояния веб-сайта:

  • Получение DOM-элементов веб-страницы, которую мы собираемся протестировать.
  • Взаимодействие с элементами DOM.
  • Назначение им действий.
  • Обмен информацией с ними.

Для выполнения вышеуказанных задач очень важно понимать API-интерфейсы Protractor.

Различные API-интерфейсы Protractor

Как мы знаем, Protractor - это оболочка для Selenium-WebDriver, которая является привязкой WebDriver для Node.js. Protractor имеет следующие API -

Браузер

Это оболочка вокруг экземпляра WebDriver, который используется для обработки команд уровня браузера, таких как навигация, информация по всей странице и т. Д. Например, метод browser.get загружает страницу.

Элемент

Он используется для поиска и взаимодействия с элементом DOM на странице, которую мы тестируем. Для этого требуется один параметр для определения местоположения элемента.

Локаторы (автор)

Это набор стратегий поиска элементов. Например, элементы можно найти с помощью селектора CSS, идентификатора или любого другого атрибута, к которому они привязаны с помощью ng-модели.

Далее мы собираемся подробно обсудить эти API и их функции.

API браузера

Как обсуждалось выше, это оболочка вокруг экземпляра WebDriver для обработки команд уровня браузера. Он выполняет различные функции следующим образом -

Функции и их описание

Функции ProtractorBrowser API следующие:

browser.angularAppRoot

Эта функция API браузера устанавливает селектор CSS для элемента, на котором мы собираемся найти Angular. Обычно эта функция находится в 'теле', но в случае нашего ng-app, она находится в подразделе страницы; он также может быть подэлементом.

browser.waitForAngularEnabled

Эта функция API браузера может иметь значение true или false. Как следует из названия, если для этой функции установлено значение false, транспортир не будет ждать Angular$http and $таймаут для выполнения задач перед взаимодействием с браузером. Мы также можем прочитать текущее состояние, не меняя его, вызвав waitForAngularEnabled () без передачи значения.

browser.getProcessedConfig

С помощью этой функции API браузера мы можем получить обработанный объект конфигурации, включая спецификацию и возможности, который в настоящее время выполняется.

browser.forkNewDriverInstance

Как следует из названия, эта функция будет форкнуть еще один экземпляр браузера, который будет использоваться в интерактивных тестах. Его можно запускать с включенным и отключенным потоком управления. Ниже приведен пример для обоих случаев -

Example 1

Бег browser.forkNewDriverInstance() с включенным потоком управления -

var fork = browser.forkNewDriverInstance();
fork.get(‘page1’);

Example 2

Бег browser.forkNewDriverInstance() с отключенным потоком управления -

var fork = await browser.forkNewDriverInstance().ready;
await forked.get(‘page1’);

browser.restart

Как следует из названия, он перезапустит браузер, закрыв экземпляр браузера и создав новый. Он также может работать с включенным и отключенным потоком управления. Ниже приведен пример для обоих случаев -

Example 1 - Бег browser.restart() с включенным потоком управления -

browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);

Example 2 - Бег browser.forkNewDriverInstance() с отключенным потоком управления -

await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);

browser.restartSync

Это похоже на функцию browser.restart (). Единственное отличие состоит в том, что он возвращает новый экземпляр браузера напрямую, а не возвращает обещание, разрешающееся в новый экземпляр браузера. Он может работать только при включенном потоке управления.

Example - Бег browser.restartSync() с включенным потоком управления -

browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);

browser.useAllAngular2AppRoots

Как следует из названия, он совместим только с Angular2. Он будет искать все доступные на странице приложения angular, находя элементы или ожидая стабильности.

browser.waitForAngular

Эта функция API браузера дает указание WebDriver дождаться завершения рендеринга Angular и отсутствия выдачи $http or $вызовы тайм-аута перед продолжением.

browser.findElement

Как следует из названия, эта функция API браузера ожидает завершения рендеринга Angular перед поиском элемента.

browser.isElementPresent

Как следует из названия, эта функция API браузера проверяет, присутствует ли элемент на странице или нет.

browser.addMockModule

Он будет добавлять модуль для загрузки перед Angular каждый раз, когда вызывается метод Protractor.get.

Example

browser.addMockModule('modName', function() {
   angular.module('modName', []).value('foo', 'bar');
});

browser.clearMockModules

в отличие от browser.addMockModule, он очистит список зарегистрированных фиктивных модулей.

browser.removeMockModule

Как следует из названия, он удалит фиктивные модули реестра. Пример: browser.removeMockModule ('modName');

browser.getRegisteredMockModules

В отличие от browser.clearMockModule, он получит список зарегистрированных макетных модулей.

browser.get

Мы можем использовать browser.get () для перехода в браузере по определенному веб-адресу и загрузки фиктивных модулей для этой страницы перед загрузкой Angular.

Example

browser.get(url);
browser.get('http://localhost:3000'); 
// This will navigate to the localhost:3000 and will load mock module if needed

browser.refresh

Как следует из названия, это перезагрузит текущую страницу и загрузит макетные модули перед Angular.

browser.navigate

Как следует из названия, он используется для смешивания методов навигации обратно в объект навигации, чтобы они вызывались, как и раньше. Пример: driver.navigate (). Refresh ().

browser.setLocation

Он используется для перехода на другую страницу с помощью внутристраничной навигации.

Example

browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
   .toBe('url/DEF');

Он перейдет от ABC к странице DEF.

browser.debugger

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

browser.pause

Он используется для отладки тестов WebDriver. Мы можем использоватьbrowser.pause() в нашем тесте для входа в отладчик транспортира из этой точки в потоке управления.

Example

element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();

browser.controlFlowEnabled

Он используется для определения, включен ли поток управления или нет.

Транспортир - основной APIS (ПРОДОЛЖЕНИЕ…)

В этой главе давайте узнаем еще несколько основных API-интерфейсов Protractor.

Elements API

Элемент - одна из глобальных функций, предоставляемых транспортиром. Эта функция принимает локатор и возвращает следующее:

  • ElementFinder, который находит один элемент на основе локатора.
  • ElementArrayFinder, который находит массив элементов на основе локатора.

Оба вышеупомянутых метода цепочки поддерживают, как описано ниже.

Функции связывания ElementArrayFinder и их описания

Следующие функции ElementArrayFinder -

element.all(locator).clone

Как следует из названия, эта функция создаст неглубокую копию массива элементов, то есть ElementArrayFinder.

element.all(locator).all(locator)

Эта функция в основном возвращает новый ElementArrayFinder, который может быть пустым или содержать дочерние элементы. Его можно использовать для выбора нескольких элементов в виде массива следующим образом

Example

element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));
// it will return another ElementFindArray as child element based on child locator.

element.all(locator).filter(filterFn)

Как следует из названия, после применения функции фильтра к каждому элементу в ElementArrayFinder он возвращает новый ElementArrayFinder со всеми элементами, которые передают функцию фильтрации. В основном он имеет два аргумента: первый - ElementFinder, а второй - index. Его также можно использовать в объектах страницы.

Example

View

<ul class = "items">
   <li class = "one">First</li>
   <li class = "two">Second</li>
   <li class = "three">Third</li>
</ul>

Code

element.all(by.css('.items li')).filter(function(elem, index) {
   return elem.getText().then(function(text) {
      return text === 'Third';
   });
}).first().click();

element.all(locator).get(index)

С помощью этого мы можем получить элемент в ElementArrayFinder по индексу. Обратите внимание, что индекс начинается с 0, а отрицательные индексы переносятся.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');

element.all(locator).first()

Как следует из названия, он получит первый элемент для ElementArrayFinder. Он не получит базовый элемент.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');

element.all(locator).last()

Как следует из названия, он получит последний элемент для ElementArrayFinder. Он не получит базовый элемент.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');

element.all(locator).all(selector)

Он используется для поиска массива элементов в родительском элементе, когда вызовы $$ могут быть связаны.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).$$('li');

element.all(locator).count()

Как следует из названия, это будет подсчитывать количество элементов, представленных ElementArrayFinder. Он не получит базовый элемент.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);

element.all(locator).isPresent()

Он сопоставит элементы с искателем. Он может возвращать истину или ложь. Истина, если присутствуют какие-либо элементы, соответствующие поисковому запросу, и Ложь в противном случае.

Example

expect($('.item').isPresent()).toBeTruthy();

element.all(locator).locator

Как следует из названия, он вернет наиболее подходящий локатор.

Example

$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')

element.all(locator).then(thenFunction)

Он получит элементы, представленные ElementArrayFinder.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

element.all(by.css('.items li')).then(function(arr) {
   expect(arr.length).toEqual(3);
});

element.all(locator).each(eachFunction)

Как следует из названия, он будет вызывать функцию ввода для каждого ElementFinder, представленного ElementArrayFinder.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

element.all(by.css('.items li')).each(function(element, index) {
   // It will print First 0, Second 1 and Third 2.
   element.getText().then(function (text) {
      console.log(index, text);
   });
});

element.all(locator).map(mapFunction)

Как следует из названия, он применит функцию карты к каждому элементу в ElementArrayFinder. У него два аргумента. Первым будет ElementFinder, а вторым - индекс.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let items = element.all(by.css('.items li')).map(function(elm, index) {
   return {
      index: index,
      text: elm.getText(),
      class: elm.getAttribute('class')
   };
});
expect(items).toEqual([
   {index: 0, text: 'First', class: 'one'},
   {index: 1, text: 'Second', class: 'two'},
   {index: 2, text: 'Third', class: 'three'}
]);

element.all(locator).reduce(reduceFn)

Как следует из названия, он применит функцию сокращения к аккумулятору и каждому элементу, найденному с помощью локатора. Эта функция уменьшит каждый элемент до одного значения.

Example

View

<ul class = "items">
   <li>First</li>
   <li>Second</li>
   <li>Third</li>
</ul>

Code

let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
   return elem.getText().then(function(text) {
      return acc + text + ' ';
   });
}, '');

expect(value).toEqual('First Second Third ');

element.all(locator).evaluate

Как следует из названия, он будет оценивать ввод независимо от того, находится ли он в области действия текущих базовых элементов или нет.

Example

View

<span class = "foo">{{letiableInScope}}</span>

Code

let value = 
element.all(by.css('.foo')).evaluate('letiableInScope');

element.all(locator).allowAnimations

Как следует из названия, он определит, разрешена ли анимация для текущих базовых элементов или нет.

Example

element(by.css('body')).allowAnimations(false);

Функции связывания ElementFinder и их описания

Функции связывания ElementFinder и их описания -

element(locator).clone

Как следует из названия, эта функция создаст неглубокую копию ElementFinder.

element(locator).getWebElement()

Он вернет WebElement, представленный этим ElementFinder, и будет выдана ошибка WebDriver, если элемент не существует.

Example

View

<div class="parent">
   some text
</div>

Code

// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));

element(locator).all(locator)

Он найдет массив элементов в родительском элементе.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).all(by.tagName('li'));

element(locator).element(locator)

Он найдет элементы внутри родителя.

Example

View

<div class = "parent">
   <div class = "child">
      Child text
      <div>{{person.phone}}</div>
   </div>
</div>

Code

// Calls Chain 2 element.
let child = element(by.css('.parent')).
   element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');

// Calls Chain 3 element.
let triple = element(by.css('.parent')).
   element(by.css('.child')).
   element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');

element(locator).all(selector)

Он найдет массив элементов внутри родителя, когда вызовы $$ могут быть связаны.

Example

View

<div class = "parent">
   <ul>
      <li class = "one">First</li>
      <li class = "two">Second</li>
      <li class = "three">Third</li>
   </ul>
</div>

Code

let items = element(by.css('.parent')).$$('li'));

element(locator).$(locator)

Он найдет элементы в родительском элементе, когда вызовы $ могут быть связаны.

Example

View

<div class = "parent">
   <div class = "child">
      Child text
      <div>{{person.phone}}</div>
  </div>
</div>

Code

// Calls Chain 2 element.
let child = element(by.css('.parent')).
   $('.child')); expect(child.getText()).toBe('Child text\n981-000-568'); // Calls Chain 3 element. let triple = element(by.css('.parent')). $('.child')).
   element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');

element(locator).isPresent()

Он определит, представлен ли элемент на странице или нет.

Example

View

<span>{{person.name}}</span>

Code

expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element

expect(element(by.binding('notPresent')).isPresent()).toBe(false); 
// will check for the non-existence of element

element(locator).isElementPresent()

Аналогично элементу (локатору) .isPresent (). Единственное отличие состоит в том, что он будет проверять, присутствует ли элемент, идентифицированный сублокатором, а не средство поиска текущего элемента.

element.all(locator).evaluate

Как следует из названия, он будет оценивать ввод независимо от того, находится ли он в области текущих базовых элементов или нет.

Example

View

<span id = "foo">{{letiableInScope}}</span>

Code

let value = element(by.id('.foo')).evaluate('letiableInScope');

element(locator).allowAnimations

Как следует из названия, он определит, разрешена ли анимация для текущих базовых элементов или нет.

Example

element(by.css('body')).allowAnimations(false);

element(locator).equals

Как следует из названия, он будет сравнивать элемент на предмет равенства.

Локаторы (по) API

По сути, это набор стратегий поиска элементов, которые предоставляют способы поиска элементов в приложениях Angular по привязке, модели и т. Д.

Functions and their descriptions

Функции ProtractorLocators API следующие:

by.addLocator(locatorName,fuctionOrScript)

Он добавит локатор к этому экземпляру ProtrcatorBy, который в дальнейшем можно будет использовать с element (by.locatorName (args)).

Example

View

<button ng-click = "doAddition()">Go!</button>

Code

// Adding the custom locator.
by.addLocator('buttonTextSimple',
      function(buttonText, opt_parentElement, opt_rootSelector) {

      var using = opt_parentElement || document,
         buttons = using.querySelectorAll('button');

      return Array.prototype.filter.call(buttons, function(button) {
      return button.textContent === buttonText;
   });
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.

by.binding

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

Example

View

<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>

Code

var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');

var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('[email protected]');

by.exactbinding

Как следует из названия, он найдет элемент путем точной привязки.

Example

View

<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>

Code

expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);

by.model(modelName)

Как следует из названия, он найдет элемент по выражению ng-model.

Example

View

<input type = "text" ng-model = "person.name">

Code

var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');

by.buttonText

Как следует из названия, он найдет кнопку по тексту.

Example

View

<button>Save</button>

Code

element(by.buttonText('Save'));

by.partialButtonText

Как следует из названия, он найдет кнопку по частичному тексту.

Example

View

<button>Save my file</button>

Code

element(by.partialButtonText('Save'));

by.repeater

Как следует из названия, он найдет элемент внутри ng-repeat.

Example

View

<div ng-repeat = "cat in pets">
   <span>{{cat.name}}</span>
   <span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
   <span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
   <h4>{{book.name}}</h4>
   <p>{{book.blurb}}</p>
</div>

Code

var secondCat = element(by.repeater('cat in 
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
   row(0).column('cat.name')); // It will return the SPAN for the first cat's name.

by.exactRepeater

Как следует из названия, он найдет элемент с помощью точного повторителя.

Example

View

<li ng-repeat = "person in peopleWithRedHair"></li>
<li ng-repeat = "car in cars | orderBy:year"></li>

Code

expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
   .toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);

by.cssContainingText

Как следует из названия, он найдет элементы, содержащие точную строку, с помощью CSS.

Example

View

<ul>
<li class = "pet">Dog</li>
<li class = "pet">Cat</li>
</ul>

Code

var dog = element(by.cssContainingText('.pet', 'Dog')); 
// It will return the li for the dog, but not for the cat.

by.options(optionsDescriptor)

Как следует из названия, он найдет элемент по выражению ng-options.

Example

View

<select ng-model = "color" ng-options = "c for c in colors">
   <option value = "0" selected = "selected">red</option>
   <option value = "1">green</option>
</select>

Code

var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');

by.deepCSS(selector)

Как следует из названия, он найдет элемент с помощью селектора CSS в теневой DOM.

Example

View

<div>
   <span id = "outerspan">
      <"shadow tree">
         <span id = "span1"></span>
      <"shadow tree">
      <span id = "span2"></span>
   </>
   </>
</div>

Code

var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);

Транспортир - Объекты

В этой главе подробно обсуждаются объекты в Транспортире.

Что такое объекты страницы?

Объект страницы - это шаблон проектирования, который стал популярным для написания тестов e2e для улучшения обслуживания тестов и уменьшения дублирования кода. Его можно определить как объектно-ориентированный класс, служащий интерфейсом для страницы вашего AUT (тестируемого приложения). Но, прежде чем углубляться в объекты страницы, мы должны понять проблемы, связанные с автоматическим тестированием пользовательского интерфейса, и способы их решения.

Проблемы с автоматическим тестированием пользовательского интерфейса

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

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

Очень распространенные проблемы при работе с UI-тестированием - это изменения, происходящие в UI. Например, в большинстве случаев кнопки, текстовые поля и т. Д. Обычно меняются, что создает проблемы для тестирования пользовательского интерфейса.

Отсутствие поддержки DSL (доменного языка)

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

Много повторений / дублирование кода

Следующая распространенная проблема при тестировании пользовательского интерфейса заключается в частом повторении или дублировании кода. Это можно понять с помощью следующих строк кода -

element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));

Жесткое обслуживание

Из-за вышеуказанных проблем техническое обслуживание становится головной болью. Это потому, что мы должны найти все экземпляры, заменить их новым именем, селектором и другим кодом. Нам также нужно потратить много времени, чтобы тесты соответствовали рефакторингу.

Сломанные тесты

Еще одна проблема при тестировании пользовательского интерфейса - это множество сбоев в тестах.

Способы решения проблем

Мы видели некоторые общие проблемы тестирования пользовательского интерфейса. Вот некоторые из способов решения таких проблем:

Обновление ссылок вручную

Самый первый вариант решения вышеуказанных проблем - это обновить ссылки вручную. Проблема с этой опцией заключается в том, что мы должны вручную изменять код, а также наши тесты. Это можно сделать, если у вас есть один или два файла тестов, но что, если у вас есть сотни файлов тестов в проекте?

Использование объектов страницы

Другой вариант решения вышеуказанных проблем - использовать объекты страницы. Объект страницы - это в основном простой JavaScript, который инкапсулирует свойства шаблона Angular. Например, следующий файл спецификации написан без объектов страницы и с ними, чтобы понять разницу:

Without Page Objects

describe('angularjs homepage', function() {
   it('should greet the named user', function() {
      browser.get('http://www.angularjs.org');
      element(by.model('yourName')).sendKeys('Julie');
      var greeting = element(by.binding('yourName'));
      expect(greeting.getText()).toEqual('Hello Julie!');
   });
});

With Page Objects

Для написания кода с объектами страницы первое, что нам нужно сделать, это создать объект страницы. Следовательно, объект страницы для приведенного выше примера может выглядеть так:

var AngularHomepage = function() {
   var nameInput = element(by.model('yourName'));
   var greeting = element(by.binding('yourName'));

   this.get = function() {
      browser.get('http://www.angularjs.org');
   };

   this.setName = function(name) {
      nameInput.sendKeys(name);
   };
   
   this.getGreetingText = function() {
      return greeting.getText();
   };
};
module.exports = new AngularHomepage();

Использование объектов страницы для организации тестов

В приведенном выше примере мы видели использование объектов страницы для решения задач тестирования пользовательского интерфейса. Далее мы собираемся обсудить, как мы можем использовать их для организации тестов. Для этого нам нужно изменить тестовый скрипт, не изменяя функциональность тестового скрипта.

пример

Чтобы понять эту концепцию, мы берем указанный выше файл конфигурации с объектами страницы. Нам нужно изменить тестовый скрипт следующим образом -

var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
   it('should greet the named user', function() {
      angularHomepage.get();

      angularHomepage.setName('Julie');
   
      expect(angularHomepage.getGreetingText()).toEqual
      ('Hello Julie!');
   });
});

Здесь обратите внимание, что путь к объекту страницы будет относиться к вашей спецификации.

В том же примечании мы также можем разделить наш набор тестов на различные наборы тестов. Затем файл конфигурации можно изменить следующим образом

exports.config = {
   // The address of a running selenium server.
   seleniumAddress: 'http://localhost:4444/wd/hub',

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },
   // Spec patterns are relative to the location of the spec file. They may
   // include glob patterns.
   suites: {
      homepage: 'tests/e2e/homepage/**/*Spec.js',
      search: ['tests/e2e/contact_search/**/*Spec.js',
         'tests/e2e/venue_search/**/*Spec.js']
   },

   // Options to be passed to Jasmine-node.
   jasmineNodeOpts: {
      showColors: true, // Use colors in the command line report.
   }
};

Теперь мы можем легко переключаться между запуском того или иного набора тестов. Следующая команда запустит только раздел домашней страницы теста -

protractor protractor.conf.js --suite homepage

Точно так же мы можем запускать определенные наборы тестов с помощью следующей команды:

protractor protractor.conf.js --suite homepage,search

Транспортир - Отладка

Теперь, когда мы ознакомились со всеми концепциями Protractor в предыдущих главах, давайте подробно разберемся с концепциями отладки в этой главе.

Введение

Сквозные (e2e) тесты очень сложно отлаживать, потому что они зависят от всей экосистемы этого приложения. Мы видели, что они зависят от различных действий или, в частности, мы можем сказать, что от предыдущих действий, таких как вход в систему, а иногда они зависят от разрешения. Еще одна трудность при отладке тестов e2e заключается в их зависимости от WebDriver, поскольку он по-разному действует в разных операционных системах и браузерах. Наконец, отладка тестов e2e также генерирует длинные сообщения об ошибках и затрудняет разделение проблем, связанных с браузером, и ошибок процесса тестирования.

Типы неудач

Могут быть разные причины сбоя тестовых наборов, и вот некоторые хорошо известные типы сбоев:

Ошибка WebDriver

Когда команда не может быть завершена, WebDriver выдает ошибку. Например, браузер не может получить указанный адрес или элемент не найден, как ожидалось.

Неожиданный сбой WebDriver

Неожиданный сбой, связанный с браузером и ОС, происходит, когда не удается обновить диспетчер веб-драйверов.

Ошибка транспортира для Angular

Ошибка Protractor для Angular происходит, когда Protractor не нашел Angular в библиотеке, как ожидалось.

Ошибка транспортира Angular2

При таком сбое Protractor завершится ошибкой, если параметр useAllAngular2AppRoots не найден в конфигурации. Это происходит потому, что без этого тестовый процесс будет смотреть на один единственный корневой элемент, ожидая более одного элемента в процессе.

Ошибка транспортира по таймауту

Этот вид сбоя происходит, когда спецификация теста попадает в цикл или длинный пул и не может вернуть данные вовремя.

Неудачное ожидание

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

Почему в транспортире важна отладка?

Предположим, если вы написали тестовые примеры, и они не прошли проверку, очень важно знать, как отлаживать эти тестовые примеры, потому что было бы очень сложно найти точное место, где произошла ошибка. Во время работы с Транспортиром вы будете получать несколько длинных ошибок красным шрифтом в командной строке.

Приостановка и отладка теста

Здесь объясняются способы отладки в Protractor & miuns;

Метод паузы

Использование метода паузы для отладки тестовых примеров в Protractor - один из самых простых способов. Мы можем ввести следующую команду в том месте, где мы хотим приостановить наш тестовый код & miuns;

browser.pause();

Когда выполняющиеся коды попадают в указанную выше команду, на этом этапе выполняющаяся программа приостанавливается. После этого мы можем дать следующие команды в соответствии с нашими предпочтениями:

Тип C для движения вперед

Всякий раз, когда команда исчерпана, мы должны нажать C, чтобы двигаться вперед. Если вы не наберете C, тест не запустит полный код и завершится ошибкой из-за ошибки времени ожидания Jasmine.

Введите REP для входа в интерактивный режим

Преимущество интерактивного режима заключается в том, что мы можем отправлять команды WebDriver нашему браузеру. Если мы хотим войти в интерактивный режим, то набираемrepl.

Нажмите Ctrl-C для выхода и продолжения тестов.

Чтобы выйти из теста из состояния паузы и продолжить тест с того места, где он был остановлен, нам нужно нажать Ctrl-C.

пример

В этом примере у нас есть файл спецификации ниже с именем example_debug.jsтранспортир пытается идентифицировать элемент с помощью локатора by.binding('мммм') но URL (https://angularjs.org/ страница не имеет элемента с указанным локатором.

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      element(by.model('yourName')).sendKeys('Vijay');
         //Element doesn't exist
         var welcomeText = 
         element(by.binding('mmmm')).getText();
         expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Теперь для выполнения вышеуказанного теста нам нужно добавить код browser.pause (), в котором вы хотите приостановить тест, в указанном выше файле спецификации. Это будет выглядеть следующим образом -

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      browser.pause();
      element(by.model('yourName')).sendKeys('Vijay');
      //Element doesn't exist
      var welcomeText = 
      element(by.binding('mmmm')).getText();
      expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Но перед запуском нам нужно также внести некоторые изменения в файл конфигурации. Мы вносим следующие изменения в ранее использованный файл конфигурации с именемexample_configuration.js в предыдущей главе -

// An example configuration file.
exports.config = {
   directConnect: true,

   // Capabilities to be passed to the webdriver instance.
   capabilities: {
      'browserName': 'chrome'
   },

   // Framework to use. Jasmine is recommended.
   framework: 'jasmine',

   // Spec patterns are relative to the current working directory when

   // protractor is called.
   specs: ['example_debug.js'],
      allScriptsTimeout: 999999,
      jasmineNodeOpts: {
      defaultTimeoutInterval: 999999
   },
   onPrepare: function () {
      browser.manage().window().maximize();
      browser.manage().timeouts().implicitlyWait(5000);
   }
};

Теперь выполните следующую команду -

protractor example_configuration.js

Отладчик запустится после указанной выше команды.

Метод отладчика

Использование метода паузы для отладки тестовых примеров в Protractor - это немного продвинутый способ. Мы можем ввести следующую команду в том месте, где мы хотим сломать наш тестовый код:

browser.debugger();

Он использует отладчик узлов для отладки тестового кода. Для запуска указанной выше команды мы должны ввести следующую команду в отдельной командной строке, которая открылась из местоположения тестового проекта:

protractor debug protractor.conf.js

В этом методе нам также нужно ввести C в терминале, чтобы продолжить тестовый код. Но в отличие от метода паузы, в этом методе он набирается только один раз.

пример

В этом примере мы используем тот же файл спецификации с именем bexample_debug.js, использованный выше. Единственная разница в том, что вместоbrowser.pause(), нам нужно использовать browser.debugger()где мы хотим сломать тестовый код. Это будет выглядеть следующим образом -

describe('Suite for protractor debugger',function(){
   it('Failing spec',function(){
      browser.get("http://angularjs.org");
      browser.debugger();
      element(by.model('yourName')).sendKeys('Vijay');
      //Element doesn't exist
      var welcomeText = element(by.binding('mmmm')).getText();
      expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
   });
});

Мы используем тот же файл конфигурации, example_configuration.js, использованный в примере выше.

Теперь запустите тест транспортира со следующей опцией командной строки отладки

protractor debug example_configuration.js

Отладчик запустится после указанной выше команды.

Транспортир - Руководство по стилю для транспортира

В этой главе давайте подробно узнаем о руководстве по стилю для транспортира.

Введение

Руководство по стилю было создано двумя программистами по имени Carmen Popoviciu, фронтенд-инженер ING и Andres Dominguez, инженер-программист в Google. Следовательно, это руководство по стилю также называется Кармен Поповичу и руководство по стилю Google для транспортира.

Это руководство по стилю можно разделить на следующие пять ключевых моментов:

  • Общие правила
  • Структура проекта
  • Стратегии локатора
  • Объекты страницы
  • Наборы тестов

Общие правила

Ниже приведены некоторые общие правила, которые необходимо соблюдать при использовании транспортира для тестирования.

Не проводите сквозное тестирование того, что уже прошло модульное тестирование.

Это самое первое общее правило, данное Кармен и Андресом. Они предложили не проводить тест e2e для кода, который уже прошел модульное тестирование. Основная причина этого в том, что модульные тесты намного быстрее, чем тесты e2e. Другая причина заключается в том, что мы должны избегать дублирования тестов (не выполнять одновременно модульное тестирование и тестирование e2e), чтобы сэкономить наше время.

Используйте только один файл конфигурации

Еще один важный рекомендуемый момент заключается в том, что мы должны использовать только один файл конфигурации. Не создавайте файл конфигурации для каждой тестируемой среды. Вы можете использоватьgrunt-protractor-coverage для настройки различных сред.

Избегайте использования логики в вашем тесте

Мы должны избегать использования операторов IF или циклов FOR в наших тестовых примерах, потому что, если мы это сделаем, тест может пройти, ничего не проверяя, или он может работать очень медленно.

Сделайте тест независимым на уровне файла

Транспортир может запускать тест параллельно, если разрешено совместное использование. Затем эти файлы запускаются в разных браузерах по мере их доступности. Кармен и Андрес рекомендовали сделать тест независимым, по крайней мере, на уровне файлов, потому что порядок, в котором они будут выполняться транспортиром, неясен, и, кроме того, довольно легко запустить тест изолированно.

Структура проекта

Еще одним важным ключевым моментом в руководстве по стилю Protractor является структура вашего проекта. Ниже приведены рекомендации по структуре проекта -

Нащупывание теста e2e в разумной структуре

Кармен и Андрес рекомендовали сгруппировать наши тесты e2e в структуру, которая имеет смысл для структуры вашего проекта. Причина этой рекомендации заключается в том, что поиск файлов стал бы проще, а структура папок стала бы более читаемой. Этот шаг также отделит тесты e2e от модульных тестов. Они рекомендовали избегать следующего вида структуры -

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         home-page.js
         home-spec.js
         profile-page.js
         profile-spec.js
         contacts-page.js
         contacts-spec.js

С другой стороны, они рекомендовали следующую структуру -

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         |-- page-objects
            home-page.js
            profile-page.js
            contacts-page.js
         home-spec.js
         profile-spec.js
         contacts-spec.js

Стратегии поиска

Ниже приведены некоторые стратегии локатора, которые необходимо соблюдать при использовании транспортира для тестирования.

Никогда не используйте XPATH

Это первая стратегия локатора, рекомендованная в руководстве по стилю транспортира. Причина этого в том, что XPath требует значительного обслуживания, потому что разметка очень легко изменяется. Более того, выражения XPath являются самыми медленными и очень сложными для отладки.

Всегда предпочитайте локаторы, специфичные для транспортира, такие как by.model и by.binding.

Специфические для транспортира локаторы, такие как by.model и by.binding, короткие, точные и легко читаемые. С их помощью очень легко написать и наш локатор.

пример

View

<ul class = "red">
   <li>{{color.name}}</li>
   <li>{{color.shade}}</li>
   <li>{{color.code}}</li>
</ul>

<div class = "details">
   <div class = "personal">
      <input ng-model = "person.name">
   </div>
</div>

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

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));

С другой стороны, рекомендуется использовать следующее:

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));

Когда локаторы Protractor недоступны, рекомендуется предпочесть by.id и by.css.

Всегда избегайте локаторов текста для часто меняющегося текста

Мы должны избегать текстовых локаторов, таких как by.linkText, by.buttonText и by.cssContaningText, потому что текст для кнопок, ссылок и меток часто меняется со временем.

Объекты страницы

Как обсуждалось ранее, объекты страницы инкапсулируют информацию об элементах на странице нашего приложения и благодаря этому помогают нам писать более чистые тестовые примеры. Очень полезным преимуществом объектов страницы является то, что их можно повторно использовать в нескольких тестах, и в случае, если шаблон нашего приложения был изменен, нам нужно только обновить объект страницы. Ниже приведены некоторые рекомендации для объектов страницы, которые необходимо соблюдать при использовании транспортира для тестирования.

Для взаимодействия с тестируемой страницей используйте объекты страницы

Рекомендуется использовать объекты страницы для взаимодействия с тестируемой страницей, поскольку они могут инкапсулировать информацию об элементе на тестируемой странице, а также их можно использовать повторно.

Всегда объявляйте одностраничный объект для каждого файла

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

В конце страницы объектного файла всегда используется один модуль.

Рекомендуется, чтобы каждый объект страницы объявлял один класс, чтобы нам нужно было экспортировать только один класс. Например, следует избегать следующего использования объектного файла -

var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;

Но, с другой стороны, рекомендуется использовать следующее -

/** @constructor */
var UserPropertiesPage = function() {};

module.exports = UserPropertiesPage;

Объявите все необходимые модули вверху

Мы должны объявить все необходимые модули в верхней части объекта страницы, потому что это делает зависимости модулей понятными и легко обнаруживаемыми.

Создайте экземпляры всех объектов страницы в начале набора тестов

Рекомендуется создать экземпляры всех объектов страницы в начале набора тестов, поскольку это отделит зависимости от кода теста, а также сделает зависимости доступными для всех спецификаций набора.

Не используйте expect () в объектах страницы

Мы не должны использовать expect () в объектах страницы, т.е. мы не должны делать никаких утверждений в наших объектах страницы, потому что все утверждения должны выполняться в тестовых примерах.

Другая причина заключается в том, что читатель теста должен понимать поведение приложения, читая только тестовые примеры.