![ZAPP](zapp_logo.png)

## О проекте

**ZAPP** - это фреймворк для UI-тестирования на основе BDD.

Возможности:

* Запуск тестов на основе сценариев, описанных в синтаксисе gherkin, то есть практически русским языком, описывающим действия со стороны пользователя.
* Отображение результатов выполнения тестов в JIRA с привязкой к версиям проекта или к пользовательским историям.

## Установка

### Установка в виде python-приложения

Требования:
* Установлен VSCode (можно использовать любую другую IDE)
* Установлен Python версии >=3.10.0,<3.13.0
* Создано и активировано виртуальное окружение (venv):
    1. `python -m venv ./.venv`
    2. `source ./.venv/bin/activate` (для *nix, MacOS); `.\.venv\Scripts\activate` (для Win)
    3. `pip install tzdata` (для Win)
* Установлен poetry (`pip3 install poetry`)

Шаги:
* Склонировать проект (`git clone <...>`)
* Настроить виртуальное окружение и установить необходимые зависимости (в корне проекта ввести: `poetry install`)

### Запуск

#### Запуск в vscode

Стартовой точкой является: `run.py`. Для VSCode можно использовать `.vscode/launch.json`.

#### Запуск через терминал:

1. Обязательным параметром является `config`: `python3 run.py --config=<...>` (предварительно перейти в подпапку zapp: `cd zapp`).
2. Предварительно необходимо перейти в подпапку zapp: `cd zapp`
3. Ввести команду `python run.py --config=zapp-demo.config.json`, можете создать и изменять свой конфиг

#### Запуск средствами IDE от JetBrains
1. Открываем `Run/Debug Configurations` -> `Edit configurations` -> `Script` и ставим путь до `/zapp/zapp/run.py`
2. Открываем `Run/Debug Configurations` -> `Edit configurations` -> `Script parameters` и прописываем `--config=ваш.конфиг.json`
3. `Working directory` ставим: `\zapp\zapp`

Перед первым запуском рекомендуется создать в корне файл конфига **zapp.config.json**, который будет считываться по умолчанию:

```
{
  "PROJECT": "JIRA",
  "TEST_STAND": "https://example.com",
  "ENV": "STAGE",
  "DEBUG": "True",
  "SMARTWAIT_DELAY": "7",
  "tags": "@demo",
  "SCREENSHOT_DIR": "_screenshots"
}
```

* PROJECT - Имя тестируемого проекта в Jira
* TEST_STAND - основная страница проекта (используется в шаге Я перешел на главную страницу)
* ENV - тип тестируемой среды (QA, STAGE, PROD)
* DEBUG - режим вывода более подробных логов (вляет на уровень логирования. При False log_level = INFO)
* SMARTWAIT_DELAY - время максимального ожидания появления элемента или наступления события
* tags - тег(теги) по которым будут запускаться тесты (является параметром behave, аналогичным образом можно задавать параметры командной строки behave по умолчанию через конфиг)
* SCREENSHOT_DIR - директория сохранения скриншотов относительно корня установки для использования в скриншот-тестировании

Запись
`"tags": ["@first_page,@second_page" ,"@base","~@wip"],`
Эквивалентна параметрам командной строки
`--tags=@first_page,@second_page --tags=@base --tags=~@wip`
(запустить все тесты, содержащие хотя бы один из тегов first_page/second_page и при этом содержащие тег base и не содержащие тег wip)

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

Рекомендуется именовать их в верхнем регистре и через подчеркивания (правила именований переменных окружения).
Например:

```
"MY_TEST_VAR": "my test string 1"
```

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

```
python run.py --TEST_STAND=new.example.com --BROWSER=firefox
```

Также zapp умеет работать с разными наборами параметров. Указывая параметр командной строки
--config можно выбирать файл (относительно корня установки), который будет использоваться для загрузки параметров:

```
python run.py --config=other_dir/zapp-second.config.json
python run.py --config=zapp-second.config.json --ENV=STAGE --BROWSER=firefox
```

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

## Состав файлов

Примеры файлов, необходимых для реализации тестов находятся в папке features
* <имя>.feature - файлы сценариев тестов. Содержат background секцию, выполняемую перед каждым сценарием и один или несколько тестовых сценариев. Расположены в папке features.
* <имя>_locators.py - файлы со списком локаторов элементов. В момент запуска доступны элементы из всех файлов локаторов одновременно, независимо от названия фичи или файла локаторов. Расположены в папке features/steps (постфикс и расположение файлов с локаторами можно переопределить через переменные `LOCATORS_DIR` и `LOCATORS_FILE_POSTFIX`)
* <имя>_steps.py - вспомогательные файлы с дополнительными шагами, расширяющими библиотеку шагов. Для правильной работы требуется добавить два импорта:

```
from zapp.features.steps.steps_library import *
from behave import *
```

## Рекомендации

* Для реализации крупных декларативных шагов рекомендуется использовать context.execute_steps (см. zapp_demo_steps.py)
* Для каждой фичи лучше создавать новый файл с локаторами, именуя его по образцу <project>_<featurename>_locators
* 1 фича = 1 файл .feature

## Алгоритм скриншот-тестирования

1. В начале сценария создаём объект run_info с данными прогона скриншот-тестирования
1. Во время сценария пишем в объект run_info данные о проверенных элементах. Также на сервер сохраняются сделанные скриншоты и JSON с данными прогона.
1. В конце сценария показываем результаты и сгенерированную ссылку, по которой можно посмотреть результаты прогона в web-интерфейсе. Результаты на сайте берутся из сохранённого в процессе прогона JSON, поэтому они доступны сразу же.

### Алгоритм проверки элемента при скриншот-тестировании

* Есть три типа изображений, которые сохраняются: эталон, текущий вариант (если есть отличия) и изображение с подстветкой отличий (если есть).
* Эталон сохраняется в глобальной папке по идентификатору элемента.
* Текущий вариант и отличия сохраняются в папке прогона.
* Элемент уникально идентифицируется по совокупности следующих составляющих:
  * Имя локатора элемента (уникально в пределах всего проекта)
  * Имя браузера, используемого при прогоне (так как отображение элементов может незначительно отличаться в разных
    браузерах)
  * Ширина и высота окна браузера (чтобы можно было проверять одни и те же элементы на разных разрешениях)
* Прогон уникально идентифицируется по времени начала и случайному хешу.
* При первой проверке элемента, скриншот будет сохранён как эталон, а элемент получит статус "новый" в отчёте.
* При повторной проверке и отсутствии отличий, новые скриншоты не будут сохранены, а элемент получит статус "одинаковый"
  .
* При повторной проверке и наличии отличий от эталона, будет сохранён новый скриншот, скриншот с подсветкой отличий, а
  элемент получит статус "отличается".
* При нахождении отличающихся элементов прогон продолжается дальше и в конце завершается с ошибкой и сообщением о
  количестве отличающихся элементов.

## Интеграция с Zephyr Server (API v1)

Список параметров:

* USE_ZEPHYR -- вкл/выкл синхронизация (по умолчанию: False).
* JIRA_HOST -- адрес развернутой Jira c плагином Zephyr (по умолчанию: <https://sberworks.ru/jira>).
* JIRA_USER -- имя пользователя для авторизации в Jira по логину и паролю (по умолчанию: None).
* JIRA_PASSWORD -- пароль пользователя для авторизации в Jira по логину и паролю (по умолчанию: None).
* JIRA_TOKEN -- токен для авторизации в Jira (по умолчанию: None). Используется в первую очередь: даже при наличии
  JIRA_USER и JIRA_PASSWORD.
* ZEPHYR_TEST_RUN -- ключ Test Cycle (по умолчанию: None).
  * "" -- пустой, не будет привязки тестов к Test Cycle
  * "new" -- будет создан новый.
  * Все другие значения будут восприниматься как ключ уже существующего Test Cycle
* ZEPHYR_TEST_CASE_SEARCH_TYPE -- тип поиска ТК в Zephyr: CUSTOM_FIELD или KEY.
  * При CUSTOM_FIELD (значение по умолчанию) будет создан новый ТК при отсутствии подходящего ТК по комбинации
    CUSTOM_FIELD (`ZEPHYR_TEST_CASE_CUSTOM_FIELD_NAME`) и его значения из аннотации.
  * При KEY происходит поиск уже существующих ТК по значению в аннотации `allure.link.tms`; новый не создается -- будет
    выброшена ошибка при ненахождении.
* ZEPHYR_TEST_CASE_FOLDER -- задает директорию для сохранения всех ТК при обновлении (по умолчанию: None, т. е.
  директория не изменяется).
* ZEPHYR_TEST_CASE_CUSTOM_FIELD_NAME -- название Custom Field в Test Case, по которому будет происходить поиск (по
  умолчанию: ZephyrLabel).
* ZEPHYR_TEST_CASE_RELEASE_UPDATE -- вкл/выкл создания новой версии ТК при несовпадении указанного
  релиза (`ZEPHYR_RELEASE_VERSION`) с уже заданным в предыдущей версии (по умолчанию: False).
* ZEPHYR_RELEASE_CHECK_TYPE -- тип проверки версии релиза у ТК: CUSTOM_FIELD или LABEL.
  * При CUSTOM_FIELD (значение по умолчанию) берется значение из заданного (`ZEPHYR_RELEASE_CUSTOM_FIELD_NAME`) поля и
    сравнивается с переданным (`ZEPHYR_RELEASE_VERSION`).
  * При LABEL проверка версии будет осуществляться по меткам Test Case.
* ZEPHYR_RELEASE_CUSTOM_FIELD_NAME -- название Custom Field в Test Case для проставления версии релиза (по умолчанию:
  Релиз).
* ZEPHYR_RELEASE_VERSION -- версия релиза для обновления ТК при необходимости (по умолчанию: None).
* ZEPHYR_RELEASE_REGEX -- регулярное выражение для поиска версии релиза в метках ТК (по умолчанию: `([0-9.]*)`).

## Стратегия запуска браузера

Существует три варианта запуска:

1. Один экземпляр на весь тестовый прогон. (Поведение по умолчанию.)
2. На каждую фичу создается свой экземпляр браузера.
3. На каждый сценарий создается свой экземпляр браузера.

Поведение определяется настройкой `BROWSER_LIFECYCLE`, которая может принимать значения:
`ONE_INSTANCE`, `EACH_FEATURE` и `EACH_SCENARIO`.
