Simplify mobile test architecture and stabilize data setup
This commit is contained in:
+1
-8
@@ -1,11 +1,4 @@
|
|||||||
DB_URL=jdbc:postgresql://<host>:<port>/<db>
|
DB_URL=jdbc:postgresql://<host>:<port>/<db>
|
||||||
DB_USER=<db_user>
|
DB_USER=<db_user>
|
||||||
DB_PASSWORD=<db_password>
|
DB_PASSWORD=<db_password>
|
||||||
|
MOBILE_HOST=127.0.0.1
|
||||||
WISHLISTS_USERNAME=<login_1>
|
|
||||||
WISHLISTS_PASSWORD=<password_1>
|
|
||||||
GIFTS_USERNAME=<login_2>
|
|
||||||
GIFTS_PASSWORD=<password_2>
|
|
||||||
RESERVATION_USERNAME=<login_3>
|
|
||||||
RESERVATION_PASSWORD=<password_3>
|
|
||||||
RESERVATION_OWNER=<login_owner>
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
DB_URL=jdbc:postgresql://sql.otus.kartushin.su:5432/wishlist
|
||||||
|
DB_USER=<prod_db_user>
|
||||||
|
DB_PASSWORD=<prod_db_password>
|
||||||
|
MOBILE_HOST=127.0.0.1
|
||||||
@@ -59,13 +59,7 @@ PowerShell:
|
|||||||
$env:DB_URL="jdbc:postgresql://<host>:<port>/<db>"
|
$env:DB_URL="jdbc:postgresql://<host>:<port>/<db>"
|
||||||
$env:DB_USER="<db_user>"
|
$env:DB_USER="<db_user>"
|
||||||
$env:DB_PASSWORD="<db_password>"
|
$env:DB_PASSWORD="<db_password>"
|
||||||
$env:WISHLISTS_USERNAME="<login_1>"
|
$env:MOBILE_HOST="127.0.0.1"
|
||||||
$env:WISHLISTS_PASSWORD="<password_1>"
|
|
||||||
$env:GIFTS_USERNAME="<login_2>"
|
|
||||||
$env:GIFTS_PASSWORD="<password_2>"
|
|
||||||
$env:RESERVATION_USERNAME="<login_3>"
|
|
||||||
$env:RESERVATION_PASSWORD="<password_3>"
|
|
||||||
$env:RESERVATION_OWNER="<login_owner>"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
bash:
|
bash:
|
||||||
@@ -73,30 +67,22 @@ bash:
|
|||||||
export DB_URL="jdbc:postgresql://<host>:<port>/<db>"
|
export DB_URL="jdbc:postgresql://<host>:<port>/<db>"
|
||||||
export DB_USER="<db_user>"
|
export DB_USER="<db_user>"
|
||||||
export DB_PASSWORD="<db_password>"
|
export DB_PASSWORD="<db_password>"
|
||||||
export WISHLISTS_USERNAME="<login_1>"
|
export MOBILE_HOST="127.0.0.1"
|
||||||
export WISHLISTS_PASSWORD="<password_1>"
|
|
||||||
export GIFTS_USERNAME="<login_2>"
|
|
||||||
export GIFTS_PASSWORD="<password_2>"
|
|
||||||
export RESERVATION_USERNAME="<login_3>"
|
|
||||||
export RESERVATION_PASSWORD="<password_3>"
|
|
||||||
export RESERVATION_OWNER="<login_owner>"
|
|
||||||
```
|
```
|
||||||
Оба варианта эквивалентны: тесты используют переменные окружения процесса.
|
Оба варианта эквивалентны: тесты используют переменные окружения процесса.
|
||||||
|
|
||||||
|
Тестовые пользователи зафиксированы в коде (`TestAccount`):
|
||||||
|
- `user1us` — тест списков желаний;
|
||||||
|
- `user2us` — тест подарков;
|
||||||
|
- `user3us` — пользователь, который резервирует подарок;
|
||||||
|
- `user4us` — пользователь-владелец списка в тесте резервирования.
|
||||||
|
|
||||||
|
Для production-подобного запуска используйте шаблон `.env.production.example` и не коммитьте реальные значения в репозиторий.
|
||||||
|
|
||||||
Тесты запускаются параллельно по классам (2 потока) и распределяются по эмуляторам через очередь.
|
Тесты запускаются параллельно по классам (2 потока) и распределяются по эмуляторам через очередь.
|
||||||
4. Запустить тесты:
|
4. Запустить тесты:
|
||||||
```bash
|
```bash
|
||||||
mvn test
|
mvn test
|
||||||
```
|
```
|
||||||
|
|
||||||
Примечание: если нужен запуск только на одном эмуляторе, можно поднять только `wiremock` и `android-emulator-1`, а перед `mvn test` задать:
|
Примечание: эмуляторы зафиксированы в enum `TestEmulator` (порты `4723` и `4725`), в конфигурации задается только хост (`MOBILE_HOST`).
|
||||||
|
|
||||||
PowerShell:
|
|
||||||
```powershell
|
|
||||||
$env:MOBILE_EMULATORS="android-emulator-1|http://127.0.0.1:4723|Android Emulator"
|
|
||||||
```
|
|
||||||
bash:
|
|
||||||
```bash
|
|
||||||
export MOBILE_EMULATORS="android-emulator-1|http://127.0.0.1:4723|Android Emulator"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
package ru.otus.mobile.config;
|
package ru.otus.mobile.config;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class MobileConfig {
|
public final class MobileConfig {
|
||||||
private final String appPackage;
|
private final String appPackage;
|
||||||
private final String appUrl;
|
private final String appUrl;
|
||||||
private final String reservationOwnerUsername;
|
private final String appiumHost;
|
||||||
private final List<Emulator> emulators;
|
private final List<Emulator> emulators;
|
||||||
|
|
||||||
public MobileConfig(
|
public MobileConfig(
|
||||||
String appPackage,
|
String appPackage,
|
||||||
String appUrl,
|
String appUrl,
|
||||||
String reservationOwnerUsername,
|
String appiumHost,
|
||||||
List<Emulator> emulators
|
List<Emulator> emulators
|
||||||
) {
|
) {
|
||||||
this.appPackage = appPackage;
|
this.appPackage = appPackage;
|
||||||
this.appUrl = appUrl;
|
this.appUrl = appUrl;
|
||||||
this.reservationOwnerUsername = reservationOwnerUsername;
|
this.appiumHost = appiumHost;
|
||||||
this.emulators = List.copyOf(emulators);
|
this.emulators = List.copyOf(emulators);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,33 +28,13 @@ public final class MobileConfig {
|
|||||||
return appUrl;
|
return appUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String reservationOwnerUsername() {
|
public String appiumHost() {
|
||||||
return reservationOwnerUsername;
|
return appiumHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Emulator> emulators() {
|
public List<Emulator> emulators() {
|
||||||
return emulators;
|
return emulators;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Emulator(String id, String appiumUrl, String deviceName, String appUrl) {
|
public record Emulator(String id, String appiumUrl, String deviceName, String appUrl) { }
|
||||||
public static List<Emulator> parse(String rawValue, String defaultAppUrl) {
|
|
||||||
List<Emulator> emulators = new ArrayList<>();
|
|
||||||
for (String entry : rawValue.split(",")) {
|
|
||||||
String trimmed = entry.trim();
|
|
||||||
if (trimmed.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String[] parts = trimmed.split("\\|");
|
|
||||||
String id = parts.length > 0 ? parts[0].trim() : "emulator-1";
|
|
||||||
String appiumUrl = parts.length > 1 ? parts[1].trim() : "http://127.0.0.1:4723";
|
|
||||||
String deviceName = parts.length > 2 ? parts[2].trim() : "Android Emulator";
|
|
||||||
String emulatorAppUrl = parts.length > 3 ? parts[3].trim() : defaultAppUrl;
|
|
||||||
emulators.add(new Emulator(id, appiumUrl, deviceName, emulatorAppUrl));
|
|
||||||
}
|
|
||||||
if (emulators.isEmpty()) {
|
|
||||||
emulators.add(new Emulator("emulator-1", "http://127.0.0.1:4723", "Android Emulator", defaultAppUrl));
|
|
||||||
}
|
|
||||||
return emulators;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +1,34 @@
|
|||||||
package ru.otus.mobile.config;
|
package ru.otus.mobile.config;
|
||||||
|
|
||||||
|
import ru.otus.mobile.db.DbClient;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public enum TestAccount {
|
public enum TestAccount {
|
||||||
WISHLISTS("WISHLISTS", "user1us", "user1us", """
|
WISHLISTS("user1us", "user1us", DbClient::clearWishlistsByUsername),
|
||||||
WITH target_user AS (
|
GIFTS("user2us", "user2us", DbClient::clearGiftsByUsername),
|
||||||
SELECT id FROM users WHERE username = ?
|
RESERVATION("user3us", "user3us", DbClient::doNothing),
|
||||||
),
|
RESERVATION_OWNER("user4us", "user4us", DbClient::clearReservationByUsername);
|
||||||
delete_gifts AS (
|
|
||||||
DELETE FROM gifts
|
|
||||||
WHERE wish_id IN (SELECT id FROM wishlists WHERE user_id IN (SELECT id FROM target_user))
|
|
||||||
),
|
|
||||||
delete_wishlists AS (
|
|
||||||
DELETE FROM wishlists WHERE user_id IN (SELECT id FROM target_user)
|
|
||||||
)
|
|
||||||
SELECT 1;
|
|
||||||
"""),
|
|
||||||
GIFTS("GIFTS", "user2us", "user2us", """
|
|
||||||
WITH target_user AS (
|
|
||||||
SELECT id FROM users WHERE username = ?
|
|
||||||
),
|
|
||||||
delete_gifts AS (
|
|
||||||
DELETE FROM gifts
|
|
||||||
WHERE wish_id IN (SELECT id FROM wishlists WHERE user_id IN (SELECT id FROM target_user))
|
|
||||||
),
|
|
||||||
delete_wishlists AS (
|
|
||||||
DELETE FROM wishlists WHERE user_id IN (SELECT id FROM target_user)
|
|
||||||
)
|
|
||||||
SELECT 1;
|
|
||||||
"""),
|
|
||||||
RESERVATION("RESERVATION", "user3us", "user3us", """
|
|
||||||
WITH owner_user AS (
|
|
||||||
SELECT id FROM users WHERE username = ?
|
|
||||||
),
|
|
||||||
target_user AS (
|
|
||||||
SELECT id FROM users WHERE username = ?
|
|
||||||
),
|
|
||||||
delete_owner_gifts AS (
|
|
||||||
DELETE FROM gifts
|
|
||||||
WHERE wish_id IN (SELECT id FROM wishlists WHERE user_id IN (SELECT id FROM owner_user))
|
|
||||||
),
|
|
||||||
delete_owner_wishlists AS (
|
|
||||||
DELETE FROM wishlists WHERE user_id IN (SELECT id FROM owner_user)
|
|
||||||
),
|
|
||||||
delete_target_gifts AS (
|
|
||||||
DELETE FROM gifts
|
|
||||||
WHERE wish_id IN (SELECT id FROM wishlists WHERE user_id IN (SELECT id FROM target_user))
|
|
||||||
),
|
|
||||||
delete_target_wishlists AS (
|
|
||||||
DELETE FROM wishlists WHERE user_id IN (SELECT id FROM target_user)
|
|
||||||
),
|
|
||||||
owner_wishlist AS (
|
|
||||||
INSERT INTO wishlists (id, title, description, user_id)
|
|
||||||
SELECT gen_random_uuid(), 'Owner Wishlist', 'Prepared for reservation test', id
|
|
||||||
FROM owner_user
|
|
||||||
RETURNING id
|
|
||||||
)
|
|
||||||
INSERT INTO gifts (id, name, description, price, is_reserved, store_url, image_url, wish_id)
|
|
||||||
SELECT gen_random_uuid(), 'Owner Gift', 'Prepared for reservation test', 100, false, NULL, NULL, id
|
|
||||||
FROM owner_wishlist;
|
|
||||||
""");
|
|
||||||
|
|
||||||
private final String envPrefix;
|
private final String username;
|
||||||
private final String defaultUsername;
|
private final String password;
|
||||||
private final String defaultPassword;
|
private final BiConsumer<DbClient, String> dataPreparation;
|
||||||
private final String resetSql;
|
|
||||||
|
|
||||||
TestAccount(String envPrefix, String defaultUsername, String defaultPassword, String resetSql) {
|
TestAccount(String username, String password, BiConsumer<DbClient, String> dataPreparation) {
|
||||||
this.envPrefix = envPrefix;
|
this.username = username;
|
||||||
this.defaultUsername = defaultUsername;
|
this.password = password;
|
||||||
this.defaultPassword = defaultPassword;
|
this.dataPreparation = dataPreparation;
|
||||||
this.resetSql = resetSql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String username() {
|
public String username() {
|
||||||
return resolve(envPrefix + "_USERNAME", defaultUsername);
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String password() {
|
public String password() {
|
||||||
return resolve(envPrefix + "_PASSWORD", defaultPassword);
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String resetSql() {
|
public BiConsumer<DbClient, String> dataPreparation() {
|
||||||
return resetSql;
|
return dataPreparation;
|
||||||
}
|
|
||||||
|
|
||||||
private String resolve(String envKey, String defaultValue) {
|
|
||||||
String value = System.getenv(envKey);
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package ru.otus.mobile.config;
|
||||||
|
|
||||||
|
public enum TestEmulator {
|
||||||
|
EMULATOR_1("android-emulator-1", 4723, "Android Emulator"),
|
||||||
|
EMULATOR_2("android-emulator-2", 4725, "Android Emulator");
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final int appiumPort;
|
||||||
|
private final String deviceName;
|
||||||
|
|
||||||
|
TestEmulator(String id, int appiumPort, String deviceName) {
|
||||||
|
this.id = id;
|
||||||
|
this.appiumPort = appiumPort;
|
||||||
|
this.deviceName = deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MobileConfig.Emulator toEmulator(String appiumHost, String appUrl) {
|
||||||
|
return new MobileConfig.Emulator(
|
||||||
|
id,
|
||||||
|
"http://" + appiumHost + ":" + appiumPort,
|
||||||
|
deviceName,
|
||||||
|
appUrl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package ru.otus.mobile.db;
|
package ru.otus.mobile.db;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import ru.otus.mobile.config.MobileConfig;
|
|
||||||
import ru.otus.mobile.config.TestAccount;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
@@ -11,37 +9,56 @@ import java.sql.SQLException;
|
|||||||
|
|
||||||
public final class DbClient {
|
public final class DbClient {
|
||||||
private final DbConfig config;
|
private final DbConfig config;
|
||||||
private final MobileConfig mobileConfig;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DbClient(DbConfig config, MobileConfig mobileConfig) {
|
public DbClient(DbConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.mobileConfig = mobileConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetData(TestAccount account) {
|
public void clearWishlistsByUsername(String username) {
|
||||||
try (Connection connection = DriverManager.getConnection(config.url(), config.user(), config.password());
|
executeUpdate("""
|
||||||
PreparedStatement statement = connection.prepareStatement(account.resetSql())) {
|
DELETE FROM wishlists
|
||||||
if (account == TestAccount.RESERVATION) {
|
WHERE user_id IN (SELECT id FROM users WHERE username = ?)
|
||||||
statement.setString(1, mobileConfig.reservationOwnerUsername());
|
""", username, "clear wishlists");
|
||||||
statement.setString(2, account.username());
|
|
||||||
} else {
|
|
||||||
statement.setString(1, account.username());
|
|
||||||
}
|
|
||||||
statement.execute();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new IllegalStateException("Failed to prepare test data for account " + account.name(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareReservationData(String ownerUsername, String reservationUsername) {
|
public void clearGiftsByUsername(String username) {
|
||||||
try (Connection connection = DriverManager.getConnection(config.url(), config.user(), config.password());
|
executeUpdate("""
|
||||||
PreparedStatement statement = connection.prepareStatement(TestAccount.RESERVATION.resetSql())) {
|
DELETE FROM gifts
|
||||||
statement.setString(1, ownerUsername);
|
WHERE wish_id IN (
|
||||||
statement.setString(2, reservationUsername);
|
SELECT w.id
|
||||||
statement.execute();
|
FROM wishlists w
|
||||||
|
JOIN users u ON u.id = w.user_id
|
||||||
|
WHERE u.username = ?
|
||||||
|
)
|
||||||
|
""", username, "clear gifts");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearReservationByUsername(String username) {
|
||||||
|
executeUpdate("""
|
||||||
|
UPDATE gifts
|
||||||
|
SET is_reserved = false
|
||||||
|
WHERE wish_id IN (
|
||||||
|
SELECT w.id
|
||||||
|
FROM wishlists w
|
||||||
|
JOIN users u ON u.id = w.user_id
|
||||||
|
WHERE u.username = ?
|
||||||
|
)
|
||||||
|
""", username, "reset reservation status");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doNothing(String username) {
|
||||||
|
// no-op preparation for accounts that do not require DB setup
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeUpdate(String sql, String username, String operation) {
|
||||||
|
try (Connection connection = DriverManager.getConnection(config.url(), config.user(), config.password())) {
|
||||||
|
try (PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||||
|
statement.setString(1, username);
|
||||||
|
statement.executeUpdate();
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new IllegalStateException("Failed to prepare reservation data for owner " + ownerUsername, e);
|
throw new IllegalStateException("Failed to " + operation + " for username " + username, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
package ru.otus.mobile.driver;
|
|
||||||
|
|
||||||
import com.codeborne.selenide.WebDriverRunner;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import io.appium.java_client.android.AndroidDriver;
|
|
||||||
import ru.otus.mobile.config.TestContext;
|
|
||||||
|
|
||||||
public final class MobileSession {
|
|
||||||
private final TestContext context;
|
|
||||||
private final Injector injector;
|
|
||||||
private final EmulatorQueue emulatorQueue;
|
|
||||||
private final LogcatCollector logcatCollector;
|
|
||||||
|
|
||||||
public MobileSession(
|
|
||||||
TestContext context,
|
|
||||||
Injector injector,
|
|
||||||
EmulatorQueue emulatorQueue,
|
|
||||||
LogcatCollector logcatCollector
|
|
||||||
) {
|
|
||||||
this.context = context;
|
|
||||||
this.injector = injector;
|
|
||||||
this.emulatorQueue = emulatorQueue;
|
|
||||||
this.logcatCollector = logcatCollector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void activate() {
|
|
||||||
WebDriverRunner.setWebDriver(context.driver());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void injectMembers(Object target) {
|
|
||||||
injector.injectMembers(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
logcatCollector.save(context);
|
|
||||||
AndroidDriver driver = context.driver();
|
|
||||||
try {
|
|
||||||
if (driver != null) {
|
|
||||||
driver.quit();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
WebDriverRunner.closeWebDriver();
|
|
||||||
emulatorQueue.release(context.emulator());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package ru.otus.mobile.driver;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import io.appium.java_client.android.AndroidDriver;
|
|
||||||
import ru.otus.mobile.config.MobileConfig;
|
|
||||||
import ru.otus.mobile.config.TestAccount;
|
|
||||||
import ru.otus.mobile.config.TestContext;
|
|
||||||
import ru.otus.mobile.guice.SessionModule;
|
|
||||||
|
|
||||||
public final class MobileSessionFactory {
|
|
||||||
private final Injector rootInjector;
|
|
||||||
private final EmulatorQueue emulatorQueue;
|
|
||||||
private final MobileDriverFactory driverFactory;
|
|
||||||
private final LogcatCollector logcatCollector;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public MobileSessionFactory(
|
|
||||||
Injector rootInjector,
|
|
||||||
EmulatorQueue emulatorQueue,
|
|
||||||
MobileDriverFactory driverFactory,
|
|
||||||
LogcatCollector logcatCollector
|
|
||||||
) {
|
|
||||||
this.rootInjector = rootInjector;
|
|
||||||
this.emulatorQueue = emulatorQueue;
|
|
||||||
this.driverFactory = driverFactory;
|
|
||||||
this.logcatCollector = logcatCollector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MobileSession create(TestAccount account, String testName) {
|
|
||||||
MobileConfig.Emulator emulator = emulatorQueue.acquire();
|
|
||||||
AndroidDriver driver = driverFactory.create(emulator);
|
|
||||||
TestContext context = new TestContext(account, emulator, driver, testName);
|
|
||||||
Injector childInjector = rootInjector.createChildInjector(new SessionModule(context));
|
|
||||||
return new MobileSession(context, childInjector, emulatorQueue, logcatCollector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +1,71 @@
|
|||||||
package ru.otus.mobile.extensions;
|
package ru.otus.mobile.extensions;
|
||||||
|
|
||||||
|
import com.codeborne.selenide.WebDriverRunner;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import io.appium.java_client.android.AndroidDriver;
|
||||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.junit.jupiter.api.extension.ParameterContext;
|
||||||
|
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||||
|
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||||
|
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||||
import ru.otus.mobile.annotations.MobileUser;
|
import ru.otus.mobile.annotations.MobileUser;
|
||||||
|
import ru.otus.mobile.config.MobileConfig;
|
||||||
import ru.otus.mobile.config.TestAccount;
|
import ru.otus.mobile.config.TestAccount;
|
||||||
import ru.otus.mobile.db.DbClient;
|
import ru.otus.mobile.config.TestContext;
|
||||||
import ru.otus.mobile.driver.MobileSession;
|
import ru.otus.mobile.driver.EmulatorQueue;
|
||||||
import ru.otus.mobile.driver.MobileSessionFactory;
|
import ru.otus.mobile.driver.LogcatCollector;
|
||||||
|
import ru.otus.mobile.driver.MobileDriverFactory;
|
||||||
import ru.otus.mobile.guice.CoreModule;
|
import ru.otus.mobile.guice.CoreModule;
|
||||||
import ru.otus.mobile.page.LoginPage;
|
|
||||||
|
|
||||||
public final class MobileExtension implements
|
public final class MobileExtension implements
|
||||||
BeforeEachCallback,
|
TestInstancePostProcessor,
|
||||||
|
ParameterResolver,
|
||||||
|
AfterTestExecutionCallback,
|
||||||
AfterEachCallback {
|
AfterEachCallback {
|
||||||
private static final ExtensionContext.Namespace NAMESPACE =
|
private static final ExtensionContext.Namespace NAMESPACE =
|
||||||
ExtensionContext.Namespace.create(MobileExtension.class);
|
ExtensionContext.Namespace.create(MobileExtension.class);
|
||||||
private static final String SESSION_KEY = "mobile.session";
|
private static final String SESSION_KEY = "mobile.session";
|
||||||
|
private static final Injector INJECTOR = Guice.createInjector(new CoreModule());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeEach(ExtensionContext context) {
|
public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
|
||||||
Injector injector = rootInjector(context);
|
INJECTOR.injectMembers(testInstance);
|
||||||
TestAccount account = resolveAccount(context);
|
}
|
||||||
injector.getInstance(DbClient.class).resetData(account);
|
|
||||||
|
|
||||||
MobileSessionFactory sessionFactory = injector.getInstance(MobileSessionFactory.class);
|
@Override
|
||||||
MobileSession session = sessionFactory.create(account, context.getDisplayName());
|
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||||
session.activate();
|
throws ParameterResolutionException {
|
||||||
session.injectMembers(context.getRequiredTestInstance());
|
return TestContext.class.equals(parameterContext.getParameter().getType());
|
||||||
context.getStore(NAMESPACE).put(SESSION_KEY, session);
|
}
|
||||||
injector.getInstance(LoginPage.class).login(account);
|
|
||||||
|
@Override
|
||||||
|
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext context)
|
||||||
|
throws ParameterResolutionException {
|
||||||
|
TestAccount account = resolveAccount(context);
|
||||||
|
TestContext testContext = createContext(account, context.getDisplayName());
|
||||||
|
context.getStore(NAMESPACE).put(SESSION_KEY, testContext);
|
||||||
|
return testContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTestExecution(ExtensionContext context) {
|
||||||
|
TestContext testContext = context.getStore(NAMESPACE).get(SESSION_KEY, TestContext.class);
|
||||||
|
if (testContext != null) {
|
||||||
|
INJECTOR.getInstance(LogcatCollector.class).save(testContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterEach(ExtensionContext context) {
|
public void afterEach(ExtensionContext context) {
|
||||||
MobileSession session = context.getStore(NAMESPACE).remove(SESSION_KEY, MobileSession.class);
|
TestContext testContext = context.getStore(NAMESPACE).remove(SESSION_KEY, TestContext.class);
|
||||||
if (session != null) {
|
if (testContext != null) {
|
||||||
session.close();
|
closeContext(testContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Injector rootInjector(ExtensionContext context) {
|
|
||||||
return context.getRoot()
|
|
||||||
.getStore(NAMESPACE)
|
|
||||||
.getOrComputeIfAbsent("root.injector", key -> Guice.createInjector(new CoreModule()), Injector.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TestAccount resolveAccount(ExtensionContext context) {
|
private TestAccount resolveAccount(ExtensionContext context) {
|
||||||
MobileUser annotation = context.getRequiredTestClass().getAnnotation(MobileUser.class);
|
MobileUser annotation = context.getRequiredTestClass().getAnnotation(MobileUser.class);
|
||||||
if (annotation == null) {
|
if (annotation == null) {
|
||||||
@@ -55,4 +73,30 @@ public final class MobileExtension implements
|
|||||||
}
|
}
|
||||||
return annotation.value();
|
return annotation.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TestContext createContext(TestAccount account, String testName) {
|
||||||
|
EmulatorQueue queue = INJECTOR.getInstance(EmulatorQueue.class);
|
||||||
|
MobileConfig.Emulator emulator = queue.acquire();
|
||||||
|
try {
|
||||||
|
AndroidDriver driver = INJECTOR.getInstance(MobileDriverFactory.class).create(emulator);
|
||||||
|
WebDriverRunner.setWebDriver(driver);
|
||||||
|
return new TestContext(account, emulator, driver, testName);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
queue.release(emulator);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeContext(TestContext context) {
|
||||||
|
AndroidDriver driver = context.driver();
|
||||||
|
EmulatorQueue queue = INJECTOR.getInstance(EmulatorQueue.class);
|
||||||
|
try {
|
||||||
|
if (driver != null) {
|
||||||
|
driver.quit();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
WebDriverRunner.closeWebDriver();
|
||||||
|
queue.release(context.emulator());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import com.google.inject.Provides;
|
|||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import ru.otus.mobile.config.MobileConfig;
|
import ru.otus.mobile.config.MobileConfig;
|
||||||
import ru.otus.mobile.config.ProjectPaths;
|
import ru.otus.mobile.config.ProjectPaths;
|
||||||
|
import ru.otus.mobile.config.TestEmulator;
|
||||||
import ru.otus.mobile.db.DbConfig;
|
import ru.otus.mobile.db.DbConfig;
|
||||||
import ru.otus.mobile.driver.EmulatorQueue;
|
import ru.otus.mobile.driver.EmulatorQueue;
|
||||||
import ru.otus.mobile.driver.LogcatCollector;
|
import ru.otus.mobile.driver.LogcatCollector;
|
||||||
import ru.otus.mobile.driver.MobileDriverFactory;
|
import ru.otus.mobile.driver.MobileDriverFactory;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class CoreModule extends AbstractModule {
|
public final class CoreModule extends AbstractModule {
|
||||||
@@ -22,15 +24,11 @@ public final class CoreModule extends AbstractModule {
|
|||||||
MobileConfig mobileConfig() {
|
MobileConfig mobileConfig() {
|
||||||
String appPackage = value("app.package", "APP_PACKAGE", "ru.otus.wishlist");
|
String appPackage = value("app.package", "APP_PACKAGE", "ru.otus.wishlist");
|
||||||
String appUrl = value("app.url", "APP_URL", "http://wiremock:8080/wishlist.apk");
|
String appUrl = value("app.url", "APP_URL", "http://wiremock:8080/wishlist.apk");
|
||||||
String reservationOwner = value("reservation.owner", "RESERVATION_OWNER", "user4us");
|
String appiumHost = value("mobile.host", "MOBILE_HOST", "127.0.0.1");
|
||||||
String rawEmulators = value(
|
List<MobileConfig.Emulator> emulators = Arrays.stream(TestEmulator.values())
|
||||||
"mobile.emulators",
|
.map(emulator -> emulator.toEmulator(appiumHost, appUrl))
|
||||||
"MOBILE_EMULATORS",
|
.toList();
|
||||||
"android-emulator-1|http://127.0.0.1:4723|Android Emulator,"
|
return new MobileConfig(appPackage, appUrl, appiumHost, emulators);
|
||||||
+ "android-emulator-2|http://127.0.0.1:4725|Android Emulator"
|
|
||||||
);
|
|
||||||
List<MobileConfig.Emulator> emulators = MobileConfig.Emulator.parse(rawEmulators, appUrl);
|
|
||||||
return new MobileConfig(appPackage, appUrl, reservationOwner, emulators);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
package ru.otus.mobile.guice;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import io.appium.java_client.android.AndroidDriver;
|
|
||||||
import ru.otus.mobile.config.TestAccount;
|
|
||||||
import ru.otus.mobile.config.TestContext;
|
|
||||||
|
|
||||||
public final class SessionModule extends AbstractModule {
|
|
||||||
private final TestContext testContext;
|
|
||||||
|
|
||||||
public SessionModule(TestContext testContext) {
|
|
||||||
this.testContext = testContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
bind(TestContext.class).toInstance(testContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
TestAccount testAccount() {
|
|
||||||
return testContext.account();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
AndroidDriver androidDriver() {
|
|
||||||
return testContext.driver();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,6 +20,15 @@ public final class UsersPage extends AbsBasePage {
|
|||||||
byId("users_content").shouldBe(Condition.visible);
|
byId("users_content").shouldBe(Condition.visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void filterByUsername(String username) {
|
||||||
|
openFilter();
|
||||||
|
SelenideElement input = filterInput().shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
input.clear();
|
||||||
|
input.setValue(username);
|
||||||
|
applyFilter();
|
||||||
|
byTextContains(username).shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
}
|
||||||
|
|
||||||
public void openUser(String username) {
|
public void openUser(String username) {
|
||||||
String appPackage = config().appPackage();
|
String appPackage = config().appPackage();
|
||||||
String xpath = "//android.widget.TextView[@resource-id='" + appPackage + ":id/username'"
|
String xpath = "//android.widget.TextView[@resource-id='" + appPackage + ":id/username'"
|
||||||
@@ -33,18 +42,6 @@ public final class UsersPage extends AbsBasePage {
|
|||||||
byTextContains(username).shouldBe(Condition.visible, Duration.ofSeconds(15));
|
byTextContains(username).shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String firstVisibleUsernameExcluding(String excludedUsername) {
|
|
||||||
var usernames = allById("username")
|
|
||||||
.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15));
|
|
||||||
for (SelenideElement usernameElement : usernames) {
|
|
||||||
String username = usernameElement.getText().trim();
|
|
||||||
if (!username.isEmpty() && !username.equals(excludedUsername)) {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("No visible username found excluding '" + excludedUsername + "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openFirstWishlist() {
|
public void openFirstWishlist() {
|
||||||
allById("wishlist_item")
|
allById("wishlist_item")
|
||||||
.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15))
|
.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15))
|
||||||
@@ -76,4 +73,85 @@ public final class UsersPage extends AbsBasePage {
|
|||||||
public void toggleReservation() {
|
public void toggleReservation() {
|
||||||
tap("reserved");
|
tap("reserved");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openFilter() {
|
||||||
|
if (byId("users_filter").exists()) {
|
||||||
|
tap("users_filter");
|
||||||
|
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byId("filter_button").exists()) {
|
||||||
|
tap("filter_button");
|
||||||
|
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byId("action_filter").exists()) {
|
||||||
|
tap("action_filter");
|
||||||
|
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SelenideElement button = byUiAutomator("new UiSelector().descriptionContains(\"Фильтр\")");
|
||||||
|
if (button.exists()) {
|
||||||
|
button.click();
|
||||||
|
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button = byUiAutomator("new UiSelector().descriptionContains(\"Filter\")");
|
||||||
|
if (button.exists()) {
|
||||||
|
button.click();
|
||||||
|
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Filter button was not found on Users screen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SelenideElement filterInput() {
|
||||||
|
if (byId("filter_input").exists()) {
|
||||||
|
return byId("filter_input");
|
||||||
|
}
|
||||||
|
if (byId("username_filter_input").exists()) {
|
||||||
|
return byId("username_filter_input");
|
||||||
|
}
|
||||||
|
if (byId("users_filter_input").exists()) {
|
||||||
|
return byId("users_filter_input");
|
||||||
|
}
|
||||||
|
if (byId("username_input").exists()) {
|
||||||
|
return byId("username_input");
|
||||||
|
}
|
||||||
|
if (byId("search_src_text").exists()) {
|
||||||
|
return byId("search_src_text");
|
||||||
|
}
|
||||||
|
if (byId("query_text").exists()) {
|
||||||
|
return byId("query_text");
|
||||||
|
}
|
||||||
|
String appPackage = config().appPackage();
|
||||||
|
SelenideElement editText = byXpath(
|
||||||
|
"//android.view.ViewGroup[@resource-id='" + appPackage + ":id/users_filter_bottom_sheet']"
|
||||||
|
+ "//android.widget.EditText"
|
||||||
|
);
|
||||||
|
if (editText.exists()) {
|
||||||
|
return editText;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Filter input was not found on Users screen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyFilter() {
|
||||||
|
if (byId("apply_button").exists()) {
|
||||||
|
tap("apply_button");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byId("apply").exists()) {
|
||||||
|
tap("apply");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byText("ПРИМЕНИТЬ").exists()) {
|
||||||
|
byText("ПРИМЕНИТЬ").click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (byText("APPLY").exists()) {
|
||||||
|
byText("APPLY").click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Apply filter button was not found on Users filter screen.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package ru.otus.mobile.page;
|
package ru.otus.mobile.page;
|
||||||
|
|
||||||
import com.codeborne.selenide.Condition;
|
import com.codeborne.selenide.Condition;
|
||||||
|
import com.codeborne.selenide.CollectionCondition;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import ru.otus.mobile.component.BottomNavigationComponent;
|
import ru.otus.mobile.component.BottomNavigationComponent;
|
||||||
import ru.otus.mobile.component.WishlistFormComponent;
|
import ru.otus.mobile.component.WishlistFormComponent;
|
||||||
import ru.otus.mobile.config.MobileConfig;
|
import ru.otus.mobile.config.MobileConfig;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
public final class WishlistsPage extends AbsBasePage {
|
public final class WishlistsPage extends AbsBasePage {
|
||||||
private final WishlistFormComponent form;
|
private final WishlistFormComponent form;
|
||||||
|
|
||||||
@@ -39,6 +42,14 @@ public final class WishlistsPage extends AbsBasePage {
|
|||||||
scrollToText(name).click();
|
scrollToText(name).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openFirstWishlist() {
|
||||||
|
allById("wishlist_item")
|
||||||
|
.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15))
|
||||||
|
.first()
|
||||||
|
.shouldBe(Condition.visible, Duration.ofSeconds(15))
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureWishlistsList() {
|
private void ensureWishlistsList() {
|
||||||
if (exists("wishlist_item") || exists("wishlists")) {
|
if (exists("wishlist_item") || exists("wishlists")) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import ru.otus.mobile.annotations.MobileUser;
|
import ru.otus.mobile.annotations.MobileUser;
|
||||||
import ru.otus.mobile.config.TestAccount;
|
import ru.otus.mobile.config.TestAccount;
|
||||||
|
import ru.otus.mobile.config.TestContext;
|
||||||
|
import ru.otus.mobile.db.DbClient;
|
||||||
import ru.otus.mobile.extensions.MobileExtension;
|
import ru.otus.mobile.extensions.MobileExtension;
|
||||||
import ru.otus.mobile.page.GiftsPage;
|
import ru.otus.mobile.page.GiftsPage;
|
||||||
|
import ru.otus.mobile.page.LoginPage;
|
||||||
import ru.otus.mobile.page.WishlistsPage;
|
import ru.otus.mobile.page.WishlistsPage;
|
||||||
import ru.otus.mobile.util.TestData;
|
import ru.otus.mobile.util.TestData;
|
||||||
|
|
||||||
@@ -23,16 +26,23 @@ public class GiftsTest {
|
|||||||
@Inject
|
@Inject
|
||||||
private TestData testData;
|
private TestData testData;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DbClient dbClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private LoginPage loginPage;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Создание и редактирование подарка")
|
@DisplayName("Создание и редактирование подарка")
|
||||||
void createAndEditGift() {
|
void createAndEditGift(TestContext context) {
|
||||||
String wishlistName = testData.uniqueName("Wishlist");
|
context.account().dataPreparation().accept(dbClient, context.account().username());
|
||||||
|
loginPage.login(context.account());
|
||||||
|
|
||||||
String name = testData.uniqueName("Gift");
|
String name = testData.uniqueName("Gift");
|
||||||
String updated = name + " updated";
|
String updated = name + " updated";
|
||||||
|
|
||||||
wishlistsPage.open();
|
wishlistsPage.open();
|
||||||
wishlistsPage.createWishlist(wishlistName);
|
wishlistsPage.openFirstWishlist();
|
||||||
wishlistsPage.openWishlist(wishlistName);
|
|
||||||
giftsPage.createGift(name);
|
giftsPage.createGift(name);
|
||||||
giftsPage.shouldSeeGift(name);
|
giftsPage.shouldSeeGift(name);
|
||||||
giftsPage.editGift(name, updated);
|
giftsPage.editGift(name, updated);
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import ru.otus.mobile.annotations.MobileUser;
|
import ru.otus.mobile.annotations.MobileUser;
|
||||||
import ru.otus.mobile.config.TestAccount;
|
import ru.otus.mobile.config.TestAccount;
|
||||||
|
import ru.otus.mobile.config.TestContext;
|
||||||
import ru.otus.mobile.db.DbClient;
|
import ru.otus.mobile.db.DbClient;
|
||||||
import ru.otus.mobile.extensions.MobileExtension;
|
import ru.otus.mobile.extensions.MobileExtension;
|
||||||
|
import ru.otus.mobile.page.LoginPage;
|
||||||
import ru.otus.mobile.page.UsersPage;
|
import ru.otus.mobile.page.UsersPage;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
@@ -15,25 +17,26 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
|||||||
@ExtendWith(MobileExtension.class)
|
@ExtendWith(MobileExtension.class)
|
||||||
@MobileUser(TestAccount.RESERVATION)
|
@MobileUser(TestAccount.RESERVATION)
|
||||||
public class ReservationTest {
|
public class ReservationTest {
|
||||||
private static final String OWNER_WISHLIST_NAME = "Owner Wishlist";
|
|
||||||
private static final String OWNER_GIFT_NAME = "Owner Gift";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UsersPage usersPage;
|
private UsersPage usersPage;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DbClient dbClient;
|
private DbClient dbClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private LoginPage loginPage;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Изменение статуса резервирования подарка другого пользователя")
|
@DisplayName("Изменение статуса резервирования подарка другого пользователя")
|
||||||
void changeReservationStatus() {
|
void changeReservationStatus(TestContext context) {
|
||||||
|
TestAccount.RESERVATION_OWNER.dataPreparation().accept(dbClient, TestAccount.RESERVATION_OWNER.username());
|
||||||
|
loginPage.login(context.account());
|
||||||
|
|
||||||
usersPage.open();
|
usersPage.open();
|
||||||
String reservationOwner = usersPage.firstVisibleUsernameExcluding(TestAccount.RESERVATION.username());
|
usersPage.filterByUsername(TestAccount.RESERVATION_OWNER.username());
|
||||||
dbClient.prepareReservationData(reservationOwner, TestAccount.RESERVATION.username());
|
usersPage.openUser(TestAccount.RESERVATION_OWNER.username());
|
||||||
usersPage.open();
|
usersPage.openFirstWishlist();
|
||||||
usersPage.openUser(reservationOwner);
|
usersPage.openFirstGift();
|
||||||
usersPage.openWishlist(OWNER_WISHLIST_NAME);
|
|
||||||
usersPage.openGift(OWNER_GIFT_NAME);
|
|
||||||
boolean before = usersPage.isReserved();
|
boolean before = usersPage.isReserved();
|
||||||
usersPage.toggleReservation();
|
usersPage.toggleReservation();
|
||||||
assertNotEquals(before, usersPage.isReserved(), "Reservation status was not changed");
|
assertNotEquals(before, usersPage.isReserved(), "Reservation status was not changed");
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import ru.otus.mobile.annotations.MobileUser;
|
import ru.otus.mobile.annotations.MobileUser;
|
||||||
import ru.otus.mobile.config.TestAccount;
|
import ru.otus.mobile.config.TestAccount;
|
||||||
|
import ru.otus.mobile.config.TestContext;
|
||||||
|
import ru.otus.mobile.db.DbClient;
|
||||||
import ru.otus.mobile.extensions.MobileExtension;
|
import ru.otus.mobile.extensions.MobileExtension;
|
||||||
|
import ru.otus.mobile.page.LoginPage;
|
||||||
import ru.otus.mobile.page.WishlistsPage;
|
import ru.otus.mobile.page.WishlistsPage;
|
||||||
import ru.otus.mobile.util.TestData;
|
import ru.otus.mobile.util.TestData;
|
||||||
|
|
||||||
@@ -19,9 +22,18 @@ public class WishlistsTest {
|
|||||||
@Inject
|
@Inject
|
||||||
private TestData testData;
|
private TestData testData;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DbClient dbClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private LoginPage loginPage;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Создание и редактирование списка желаний")
|
@DisplayName("Создание и редактирование списка желаний")
|
||||||
void createAndEditWishlist() {
|
void createAndEditWishlist(TestContext context) {
|
||||||
|
context.account().dataPreparation().accept(dbClient, context.account().username());
|
||||||
|
loginPage.login(context.account());
|
||||||
|
|
||||||
String name = testData.uniqueName("Wishlist");
|
String name = testData.uniqueName("Wishlist");
|
||||||
String updated = name + " updated";
|
String updated = name + " updated";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user