# OTUS Homework 7: Mobile (Selenide + Appium)

Автотесты мобильного приложения Wishlist через Selenide + Appium и инфраструктура эмулятора через Docker Compose.

## Что реализовано
- 3 сценария из ТЗ: списки желаний, подарки, резервирование подарка другого пользователя.
- Архитектура: базовый тест + экранные объекты (screens).
- Конфигурируемые capabilities через system properties.
- Подготовка тестовых данных через БД перед каждым тестом.
- Скрипты для сбора Logcat.

## Стек и версии
- Java 21, Maven.
- Selenide: 7.3.1
- Appium Java Client: 9.3.0 (UiAutomator2)
- Selenium: 4.25.0
- JUnit: 5.10.2
- PostgreSQL JDBC: 42.7.10
- apk-parser: 2.6.10
- SLF4J: 2.0.13
- Docker Compose (эмулятор Android + Appium)

## Структура проекта
- `src/test/java/ru/otus/mobile/tests` — тесты.
- `src/test/java/ru/otus/mobile/screens` — экранные объекты.
- `src/test/java/ru/otus/mobile/config` — конфигурация Appium/Android.
- `src/test/java/ru/otus/mobile/driver` — фабрика драйвера.
- `src/test/java/ru/otus/mobile/db` — reset SQL и JDBC-клиент.
- `docker-compose.yml` — эмулятор Android с Appium.
- `scripts/` — утилиты (Logcat).

## Инфраструктура (Docker Compose)
Эмулятор и Appium поднимаются одной командой:
```bash
docker compose up -d
```

Порты:
- Appium: `http://localhost:4723`
- noVNC: `http://localhost:6080`

APK берется из файла `./wishlist-349317-5fd795.apk`, копируется в `./apk/wishlist.apk` и монтируется в контейнер по пути `/apk/wishlist.apk`.
После старта контейнеров APK автоматически устанавливается в эмулятор и приложение стартует.

## Подготовка данных через БД
Для повторяемости тестов перед каждым тестом выполняется SQL‑сброс данных аккаунта.
Данные доступа к БД **не хранятся в репозитории** — нужно передать через env или `-D`.
Аккаунты можно создать заранее (регистрация через приложение) или доверить это автотестам.
Если логин/пароль не переданы через параметры запуска, тест сгенерирует логины, создаст пользователей через reset‑SQL в БД (если их нет), затем выполнит логин. Регистрация через приложение используется как fallback, если вход не удался.

Переменные/свойства:
- `DB_URL` или `-Ddb.url`
- `DB_USER` или `-Ddb.user`
- `DB_PASSWORD` или `-Ddb.password`
- `DB_RESET_SQL` или `-Ddb.reset.sql` — SQL c параметрами `?` (username, email, password_hash, username). Если не задано, используется встроенный reset‑SQL (удаляет wishlists/gifts и создает пользователя при отсутствии).

Пример (PowerShell, значения подставить свои):
```powershell
$env:DB_URL = "jdbc:postgresql://<host>:5432/<db>"
$env:DB_USER = "<user>"
$env:DB_PASSWORD = "<password>"
$env:DB_RESET_SQL = "<one-statement reset sql with ? placeholders>"
```

## Как запускать
### Полный прогон (обязательная последовательность)
1) Поднять инфраструктуру:
```bash
docker compose up -d
```
Убедиться, что Docker Desktop/Engine запущен. Если Appium недоступен, тесты падают быстро с понятной ошибкой.

2) Задать доступ к БД (обязательно, иначе тесты упадут):
```powershell
$env:DB_URL="jdbc:postgresql://sql.otus.kartushin.su:5432/wishlist"
$env:DB_USER="student"
$env:DB_PASSWORD="student"
```

3) Запустить все тесты (логины/пароли можно не задавать):
```bash
mvn test
```

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

Опционально: задать логины/пароли тестовых пользователей (если зарегистрированы вручную):
```bash
mvn "-Dlogin.username.wishlists=<user1>" "-Dlogin.password.wishlists=<pass1>" \
    "-Dlogin.username.gifts=<user2>" "-Dlogin.password.gifts=<pass2>" \
    "-Dlogin.username.reservation=<user3>" "-Dlogin.password.reservation=<pass3>" \
    "-Dreservation.owner=<user4>" \
    test
```

### Один тест
```bash
mvn "-Dtest=ru.otus.mobile.tests.WishlistsTest" test
```

### Запуск через Docker Compose
```bash
mvn -Dappium.url=http://localhost:4723 -Dapp.path=/apk/wishlist.apk -Dapp.package=ru.otus.wishlist -Dapp.activity=ru.otus.wishlist.MainActivity test
```

### Полный пример запуска (Appium + БД)
```bash
mvn -Dappium.url=http://localhost:4723 -Dapp.path=/apk/wishlist.apk -Dapp.package=ru.otus.wishlist -Dapp.activity=ru.otus.wishlist.MainActivity -Ddb.url=jdbc:postgresql://<host>:5432/<db> -Ddb.user=<user> -Ddb.password=<password> test
```

## Параметры запуска
- `-Dappium.url` — URL Appium (default: `http://localhost:4723`)
- `-Dapp.path` — путь до APK (default: `/apk/wishlist.apk`)
- `-Dapp.package` — package приложения (если APK недоступен локально)
- `-Dapp.activity` — main activity (если APK недоступен локально)
- `-Ddevice.name` — имя устройства (default: `Android Emulator`)
- `-Dplatform.version` — версия Android (опционально)
- `-Dudid` — UDID (опционально)
- `-DnoReset` — не сбрасывать состояние (default: `false`)
- `-DnewCommandTimeout` — timeout Appium, сек (default: `120`)
- `-Dlogin.username.<account>` — логин для конкретного теста (например `login.username.wishlists`)
- `-Dlogin.password` — пароль (default: `Admin123`)
- `-Dlogin.password.hash` — bcrypt‑хэш пароля для reset‑SQL (default в коде)

## Сбор Logcat
PowerShell:
```powershell
.\scripts\collect-logcat.ps1
```

Bash:
```bash
./scripts/collect-logcat.sh
```

Логи сохраняются в файл `logcat.txt` в корне проекта.
