Align page objects and DI with review comments

This commit is contained in:
2026-04-21 03:03:45 +03:00
parent bcf831ad99
commit 97c58a29e0
23 changed files with 137 additions and 277 deletions
@@ -1,22 +1,12 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import com.google.inject.Inject;
import io.appium.java_client.AppiumBy;
import static com.codeborne.selenide.appium.SelenideAppium.$;
public final class AlertDialogComponent extends BaseMobileComponent { public final class AlertDialogComponent extends BaseMobileComponent {
private final SelenideElement positiveButton; private final SelenideElement positiveButton = byIdInRoot("android:id/button1");
@Inject
public AlertDialogComponent() {
this($(AppiumBy.id("android:id/content")));
}
public AlertDialogComponent(SelenideElement root) { public AlertDialogComponent(SelenideElement root) {
super(root); super(root);
this.positiveButton = byIdInRoot("android:id/button1");
} }
public void acceptIfVisible() { public void acceptIfVisible() {
@@ -1,24 +1,13 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import com.google.inject.Inject;
import io.appium.java_client.AppiumBy;
import static com.codeborne.selenide.appium.SelenideAppium.$;
public final class BottomNavigationComponent extends BaseMobileComponent { public final class BottomNavigationComponent extends BaseMobileComponent {
private final SelenideElement mineMenu; private final SelenideElement mineMenu = byIdInRoot("mine_menu");
private final SelenideElement usersMenu; private final SelenideElement usersMenu = byIdInRoot("users_menu");
@Inject
public BottomNavigationComponent() {
this($(AppiumBy.id(fullIdValue("bottom_navigation"))));
}
public BottomNavigationComponent(SelenideElement root) { public BottomNavigationComponent(SelenideElement root) {
super(root); super(root);
this.mineMenu = byIdInRoot("mine_menu");
this.usersMenu = byIdInRoot("users_menu");
} }
public void openWishlists() { public void openWishlists() {
@@ -1,26 +1,14 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import com.google.inject.Inject;
import io.appium.java_client.AppiumBy;
import static com.codeborne.selenide.appium.SelenideAppium.$;
public final class GiftFormComponent extends BaseMobileComponent { public final class GiftFormComponent extends BaseMobileComponent {
private final SelenideElement nameInput; private final SelenideElement nameInput = byIdInRoot("name_input");
private final SelenideElement priceInput; private final SelenideElement priceInput = byIdInRoot("price_input");
private final SelenideElement saveButton; private final SelenideElement saveButton = byIdInRoot("save_button");
@Inject
public GiftFormComponent() {
this($(AppiumBy.id("android:id/content")));
}
public GiftFormComponent(SelenideElement root) { public GiftFormComponent(SelenideElement root) {
super(root); super(root);
this.nameInput = byIdInRoot("name_input");
this.priceInput = byIdInRoot("price_input");
this.saveButton = byIdInRoot("save_button");
} }
public void save(String name, String price) { public void save(String name, String price) {
@@ -5,13 +5,11 @@ import com.codeborne.selenide.SelenideElement;
import static com.codeborne.selenide.Condition.text; import static com.codeborne.selenide.Condition.text;
public final class GiftItemComponent extends BaseMobileComponent { public final class GiftItemComponent extends BaseMobileComponent {
private final SelenideElement title; private final SelenideElement title = byIdInRoot("title");
private final SelenideElement editButton; private final SelenideElement editButton = byIdInRoot("edit_button");
public GiftItemComponent(SelenideElement root) { public GiftItemComponent(SelenideElement root) {
super(root); super(root);
this.title = byIdInRoot("title");
this.editButton = byIdInRoot("edit_button");
} }
public String titleText() { public String titleText() {
@@ -1,19 +1,21 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.CollectionCondition;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection; import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import io.appium.java_client.AppiumBy;
import java.time.Duration;
public final class GiftsContentComponent extends BaseMobileComponent { public final class GiftsContentComponent extends BaseMobileComponent {
private final ElementsCollection items; private final ElementsCollection items = allByIdInRoot("gift_item");
public GiftsContentComponent(SelenideElement root) { public GiftsContentComponent(SelenideElement root) {
super(root); super(root);
this.items = root.$$(AppiumBy.id(fullIdValue("gift_item")));
} }
public GiftItemComponent get(int index) { public GiftItemComponent get(int index) {
return new GiftItemComponent(items.get(index)); return new GiftItemComponent(items.get(index).shouldBe(Condition.visible, Duration.ofSeconds(15)));
} }
public GiftItemComponent first() { public GiftItemComponent first() {
@@ -21,6 +23,7 @@ public final class GiftsContentComponent extends BaseMobileComponent {
} }
public GiftItemComponent byTitle(String title) { public GiftItemComponent byTitle(String title) {
items.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15));
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
GiftItemComponent item = get(i); GiftItemComponent item = get(i);
if (title.equals(item.titleText())) { if (title.equals(item.titleText())) {
@@ -3,27 +3,13 @@ package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
public final class TopBarComponent extends BaseMobileComponent { public final class TopBarComponent extends BaseMobileComponent {
private final SelenideElement filterButton = byIdInRoot("filter");
public TopBarComponent(SelenideElement root) { public TopBarComponent(SelenideElement root) {
super(root); super(root);
} }
public void openUsersFilter() { public void openUsersFilter() {
if (byId("filter").exists()) { filterButton.click();
byId("filter").click();
return;
}
if (byId("users_filter").exists()) {
byId("users_filter").click();
return;
}
if (byId("filter_button").exists()) {
byId("filter_button").click();
return;
}
if (byId("action_filter").exists()) {
byId("action_filter").click();
return;
}
throw new IllegalStateException("Filter button was not found on Users screen.");
} }
} }
@@ -3,11 +3,10 @@ package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
public final class UserItemComponent extends BaseMobileComponent { public final class UserItemComponent extends BaseMobileComponent {
private final SelenideElement username; private final SelenideElement username = byIdInRoot("username");
public UserItemComponent(SelenideElement root) { public UserItemComponent(SelenideElement root) {
super(root); super(root);
this.username = byIdInRoot("username");
} }
public String usernameText() { public String usernameText() {
@@ -1,19 +1,21 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.CollectionCondition;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection; import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import io.appium.java_client.AppiumBy;
import java.time.Duration;
public final class UsersContentComponent extends BaseMobileComponent { public final class UsersContentComponent extends BaseMobileComponent {
private final ElementsCollection items; private final ElementsCollection items = allByIdInRoot("user_item");
public UsersContentComponent(SelenideElement root) { public UsersContentComponent(SelenideElement root) {
super(root); super(root);
this.items = root.$$(AppiumBy.id(fullIdValue("user_item")));
} }
public UserItemComponent get(int index) { public UserItemComponent get(int index) {
return new UserItemComponent(items.get(index)); return new UserItemComponent(items.get(index).shouldBe(Condition.visible, Duration.ofSeconds(15)));
} }
public UserItemComponent first() { public UserItemComponent first() {
@@ -21,6 +23,7 @@ public final class UsersContentComponent extends BaseMobileComponent {
} }
public UserItemComponent byUsername(String username) { public UserItemComponent byUsername(String username) {
items.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15));
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
UserItemComponent item = get(i); UserItemComponent item = get(i);
if (username.equals(item.usernameText())) { if (username.equals(item.usernameText())) {
@@ -3,36 +3,17 @@ package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
public final class UsersFilterComponent extends BaseMobileComponent { public final class UsersFilterComponent extends BaseMobileComponent {
private final SelenideElement usernameInput = byIdInRoot("username_input");
private final SelenideElement applyButton = byIdInRoot("apply_button");
public UsersFilterComponent(SelenideElement root) { public UsersFilterComponent(SelenideElement root) {
super(root); super(root);
} }
public void applyByUsername(String username) { public void applyByUsername(String username) {
SelenideElement filterInput = filterInput(); usernameInput.click();
SelenideElement applyButton = applyButton(); usernameInput.clear();
filterInput.click(); usernameInput.sendKeys(username);
filterInput.clear();
filterInput.sendKeys(username);
applyButton.click(); applyButton.click();
} }
private SelenideElement filterInput() {
if (byIdInRoot("username_input").exists()) {
return byIdInRoot("username_input");
}
if (byIdInRoot("filter_input").exists()) {
return byIdInRoot("filter_input");
}
if (byIdInRoot("users_filter_input").exists()) {
return byIdInRoot("users_filter_input");
}
return byIdInRoot("username_filter_input");
}
private SelenideElement applyButton() {
if (byIdInRoot("apply_button").exists()) {
return byIdInRoot("apply_button");
}
return byIdInRoot("apply");
}
} }
@@ -1,24 +1,13 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import com.google.inject.Inject;
import io.appium.java_client.AppiumBy;
import static com.codeborne.selenide.appium.SelenideAppium.$;
public final class WishlistFormComponent extends BaseMobileComponent { public final class WishlistFormComponent extends BaseMobileComponent {
private final SelenideElement titleInput; private final SelenideElement titleInput = byIdInRoot("title_input");
private final SelenideElement saveButton; private final SelenideElement saveButton = byIdInRoot("save_button");
@Inject
public WishlistFormComponent() {
this($(AppiumBy.id("android:id/content")));
}
public WishlistFormComponent(SelenideElement root) { public WishlistFormComponent(SelenideElement root) {
super(root); super(root);
this.titleInput = byIdInRoot("title_input");
this.saveButton = byIdInRoot("save_button");
} }
public void save(String title) { public void save(String title) {
@@ -5,13 +5,11 @@ import com.codeborne.selenide.SelenideElement;
import static com.codeborne.selenide.Condition.text; import static com.codeborne.selenide.Condition.text;
public final class WishlistItemComponent extends BaseMobileComponent { public final class WishlistItemComponent extends BaseMobileComponent {
private final SelenideElement title; private final SelenideElement title = byIdInRoot("title");
private final SelenideElement editButton; private final SelenideElement editButton = byIdInRoot("edit_button");
public WishlistItemComponent(SelenideElement root) { public WishlistItemComponent(SelenideElement root) {
super(root); super(root);
this.title = byIdInRoot("title");
this.editButton = byIdInRoot("edit_button");
} }
public String titleText() { public String titleText() {
@@ -1,19 +1,21 @@
package ru.otus.mobile.component; package ru.otus.mobile.component;
import com.codeborne.selenide.CollectionCondition;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.ElementsCollection; import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import io.appium.java_client.AppiumBy;
import java.time.Duration;
public final class WishlistsContentComponent extends BaseMobileComponent { public final class WishlistsContentComponent extends BaseMobileComponent {
private final ElementsCollection items; private final ElementsCollection items = allByIdInRoot("wishlist_item");
public WishlistsContentComponent(SelenideElement root) { public WishlistsContentComponent(SelenideElement root) {
super(root); super(root);
this.items = root.$$(AppiumBy.id(fullIdValue("wishlist_item")));
} }
public WishlistItemComponent get(int index) { public WishlistItemComponent get(int index) {
return new WishlistItemComponent(items.get(index)); return new WishlistItemComponent(items.get(index).shouldBe(Condition.visible, Duration.ofSeconds(15)));
} }
public WishlistItemComponent first() { public WishlistItemComponent first() {
@@ -21,6 +23,7 @@ public final class WishlistsContentComponent extends BaseMobileComponent {
} }
public WishlistItemComponent byTitle(String title) { public WishlistItemComponent byTitle(String title) {
items.shouldHave(CollectionCondition.sizeGreaterThan(0), Duration.ofSeconds(15));
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
WishlistItemComponent item = get(i); WishlistItemComponent item = get(i);
if (title.equals(item.titleText())) { if (title.equals(item.titleText())) {
@@ -1,11 +1,16 @@
package ru.otus.mobile.config; package ru.otus.mobile.config;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@Singleton
public final class ProjectPaths { public final class ProjectPaths {
private final Path logcatFile; private final Path logcatFile;
@Inject
public ProjectPaths() { public ProjectPaths() {
this.logcatFile = Paths.get("").toAbsolutePath().normalize().resolve("logcat.txt"); this.logcatFile = Paths.get("").toAbsolutePath().normalize().resolve("logcat.txt");
} }
@@ -1,13 +1,17 @@
package ru.otus.mobile.driver; package ru.otus.mobile.driver;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import ru.otus.mobile.config.MobileConfig; import ru.otus.mobile.config.MobileConfig;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@Singleton
public final class EmulatorQueue { public final class EmulatorQueue {
private final BlockingQueue<MobileConfig.Emulator> queue; private final BlockingQueue<MobileConfig.Emulator> queue;
@Inject
public EmulatorQueue(MobileConfig config) { public EmulatorQueue(MobileConfig config) {
this.queue = new LinkedBlockingQueue<>(config.emulators()); this.queue = new LinkedBlockingQueue<>(config.emulators());
} }
@@ -1,5 +1,7 @@
package ru.otus.mobile.driver; package ru.otus.mobile.driver;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.logging.LogEntries; import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry; import org.openqa.selenium.logging.LogEntry;
@@ -11,9 +13,11 @@ import java.nio.file.Files;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.time.Instant; import java.time.Instant;
@Singleton
public final class LogcatCollector { public final class LogcatCollector {
private final ProjectPaths projectPaths; private final ProjectPaths projectPaths;
@Inject
public LogcatCollector(ProjectPaths projectPaths) { public LogcatCollector(ProjectPaths projectPaths) {
this.projectPaths = projectPaths; this.projectPaths = projectPaths;
} }
@@ -1,5 +1,7 @@
package ru.otus.mobile.driver; package ru.otus.mobile.driver;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.android.options.UiAutomator2Options;
import ru.otus.mobile.config.MobileConfig; import ru.otus.mobile.config.MobileConfig;
@@ -7,7 +9,12 @@ import ru.otus.mobile.config.MobileConfig;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
@Singleton
public final class MobileDriverFactory { public final class MobileDriverFactory {
@Inject
public MobileDriverFactory() {
}
public AndroidDriver create(MobileConfig.Emulator emulator) { public AndroidDriver create(MobileConfig.Emulator emulator) {
UiAutomator2Options options = new UiAutomator2Options() UiAutomator2Options options = new UiAutomator2Options()
.setPlatformName("Android") .setPlatformName("Android")
@@ -4,21 +4,13 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides; 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.TestEmulator; 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.LogcatCollector;
import ru.otus.mobile.driver.MobileDriverFactory;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public final class CoreModule extends AbstractModule { public final class CoreModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides @Provides
@Singleton @Singleton
MobileConfig mobileConfig() { MobileConfig mobileConfig() {
@@ -31,12 +23,6 @@ public final class CoreModule extends AbstractModule {
return new MobileConfig(appPackage, appUrl, appiumHost, emulators); return new MobileConfig(appPackage, appUrl, appiumHost, emulators);
} }
@Provides
@Singleton
ProjectPaths projectPaths() {
return new ProjectPaths();
}
@Provides @Provides
@Singleton @Singleton
DbConfig dbConfig() { DbConfig dbConfig() {
@@ -46,24 +32,6 @@ public final class CoreModule extends AbstractModule {
return new DbConfig(url, user, password); return new DbConfig(url, user, password);
} }
@Provides
@Singleton
EmulatorQueue emulatorQueue(MobileConfig config) {
return new EmulatorQueue(config);
}
@Provides
@Singleton
MobileDriverFactory mobileDriverFactory() {
return new MobileDriverFactory();
}
@Provides
@Singleton
LogcatCollector logcatCollector(ProjectPaths projectPaths) {
return new LogcatCollector(projectPaths);
}
private String requiredValue(String property, String env) { private String requiredValue(String property, String env) {
String value = value(property, env, null); String value = value(property, env, null);
if (value == null) { if (value == null) {
@@ -3,9 +3,6 @@ package ru.otus.mobile.page;
import ru.otus.mobile.component.BottomNavigationComponent; import ru.otus.mobile.component.BottomNavigationComponent;
public abstract class AbsBasePage extends AbsPageObject { public abstract class AbsBasePage extends AbsPageObject {
protected final BottomNavigationComponent bottomNavigation; protected final BottomNavigationComponent bottomNavigation =
new BottomNavigationComponent(byId("bottom_navigation"));
protected AbsBasePage(BottomNavigationComponent bottomNavigation) {
this.bottomNavigation = bottomNavigation;
}
} }
@@ -1,6 +1,5 @@
package ru.otus.mobile.page; package ru.otus.mobile.page;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.SelenideElement; import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.WebDriverRunner; import com.codeborne.selenide.WebDriverRunner;
import com.codeborne.selenide.appium.SelenideAppiumCollection; import com.codeborne.selenide.appium.SelenideAppiumCollection;
@@ -21,21 +20,6 @@ public abstract class AbsPageObject {
return $$(AppiumBy.id(fullIdValue(id))); return $$(AppiumBy.id(fullIdValue(id)));
} }
protected void type(String id, String value) {
SelenideElement input = byId(id).shouldBe(Condition.visible);
input.click();
input.clear();
input.sendKeys(value);
}
protected void tap(String id) {
byId(id).shouldBe(Condition.visible).click();
}
protected boolean exists(String id) {
return byId(id).exists();
}
protected void back() { protected void back() {
WebDriverRunner.getWebDriver().navigate().back(); WebDriverRunner.getWebDriver().navigate().back();
} }
@@ -1,41 +1,38 @@
package ru.otus.mobile.page; package ru.otus.mobile.page;
import com.codeborne.selenide.Condition; import com.codeborne.selenide.Condition;
import com.google.inject.Inject; import com.codeborne.selenide.SelenideElement;
import ru.otus.mobile.component.BottomNavigationComponent; import com.google.inject.Singleton;
import ru.otus.mobile.component.GiftsContentComponent;
import ru.otus.mobile.component.GiftFormComponent; import ru.otus.mobile.component.GiftFormComponent;
import ru.otus.mobile.component.GiftsContentComponent;
@Singleton
public final class GiftsPage extends AbsBasePage { public final class GiftsPage extends AbsBasePage {
private final GiftFormComponent form; private final SelenideElement giftsContentRoot = byId("gifts_content");
private final com.codeborne.selenide.SelenideElement addButton = byId("add_button"); private final SelenideElement addButton = byId("add_button");
private final SelenideElement formRoot = byId("gift_edit_bottom_sheet");
@Inject private final GiftsContentComponent content = new GiftsContentComponent(giftsContentRoot);
public GiftsPage(BottomNavigationComponent bottomNavigation, GiftFormComponent form) { private final GiftFormComponent form = new GiftFormComponent(formRoot);
super(bottomNavigation);
this.form = form;
}
public void createGift(String name) { public void createGift(String name) {
addButton.click(); addButton.click();
form.save(name, "100"); form.save(name, "100");
giftsContentRoot.shouldBe(Condition.visible);
} }
public void editGift(String oldName, String newName) { public void editGift(String oldName, String newName) {
openGift(oldName); openGift(oldName);
content().byTitle(oldName).edit(); content.byTitle(oldName).edit();
form.save(newName, "100"); form.save(newName, "100");
giftsContentRoot.shouldBe(Condition.visible);
} }
public void shouldSeeGift(String name) { public void shouldSeeGift(String name) {
content().byTitle(name).shouldHaveTitle(name); giftsContentRoot.shouldBe(Condition.visible);
content.byTitle(name).shouldHaveTitle(name);
} }
private void openGift(String name) { private void openGift(String name) {
content().byTitle(name).open(); content.byTitle(name).open();
}
private GiftsContentComponent content() {
return new GiftsContentComponent(byId("gifts_content"));
} }
} }
@@ -1,28 +1,33 @@
package ru.otus.mobile.page; package ru.otus.mobile.page;
import com.google.inject.Inject; import com.codeborne.selenide.SelenideElement;
import com.google.inject.Singleton;
import ru.otus.mobile.component.AlertDialogComponent; import ru.otus.mobile.component.AlertDialogComponent;
import ru.otus.mobile.config.TestAccount; import ru.otus.mobile.config.TestAccount;
@Singleton
public final class LoginPage extends AbsPageObject { public final class LoginPage extends AbsPageObject {
private final AlertDialogComponent alertDialog; private final SelenideElement usernameInput = byId("username_text_input");
private final SelenideElement passwordInput = byId("password_text_input");
@Inject private final SelenideElement loginButton = byId("log_in_button");
public LoginPage(AlertDialogComponent alertDialog) { private final SelenideElement appMainContainer = byId("app_main_fragment_container");
this.alertDialog = alertDialog; private final AlertDialogComponent alertDialog = new AlertDialogComponent(appMainContainer);
}
public void login(TestAccount account) { public void login(TestAccount account) {
if (!isOpened()) { if (!isOpened()) {
return; return;
} }
type("username_text_input", account.username()); usernameInput.click();
type("password_text_input", account.password()); usernameInput.clear();
tap("log_in_button"); usernameInput.sendKeys(account.username());
passwordInput.click();
passwordInput.clear();
passwordInput.sendKeys(account.password());
loginButton.click();
alertDialog.acceptIfVisible(); alertDialog.acceptIfVisible();
} }
public boolean isOpened() { public boolean isOpened() {
return exists("username_text_input") && exists("password_text_input"); return usernameInput.exists() && passwordInput.exists();
} }
} }
@@ -1,8 +1,8 @@
package ru.otus.mobile.page; package ru.otus.mobile.page;
import com.codeborne.selenide.Condition; import com.codeborne.selenide.Condition;
import com.google.inject.Inject; import com.codeborne.selenide.SelenideElement;
import ru.otus.mobile.component.BottomNavigationComponent; import com.google.inject.Singleton;
import ru.otus.mobile.component.GiftsContentComponent; import ru.otus.mobile.component.GiftsContentComponent;
import ru.otus.mobile.component.TopBarComponent; import ru.otus.mobile.component.TopBarComponent;
import ru.otus.mobile.component.UsersContentComponent; import ru.otus.mobile.component.UsersContentComponent;
@@ -11,75 +11,59 @@ import ru.otus.mobile.component.WishlistsContentComponent;
import java.time.Duration; import java.time.Duration;
@Singleton
public final class UsersPage extends AbsBasePage { public final class UsersPage extends AbsBasePage {
private final TopBarComponent topBar; private final SelenideElement topBarRoot = byId("top_app_bar");
private final SelenideElement usersContentRoot = byId("users_content");
private final SelenideElement usersFilterBottomSheet = byId("users_filter_bottom_sheet");
private final SelenideElement firstUserItem = byId("user_item");
private final SelenideElement wishlistsContentRoot = byId("wishlists_content");
private final SelenideElement giftsContentRoot = byId("gifts_content");
private final SelenideElement reservedToggle = byId("reserved");
@Inject private final TopBarComponent topBar = new TopBarComponent(topBarRoot);
public UsersPage(BottomNavigationComponent bottomNavigation) { private final UsersContentComponent usersContent = new UsersContentComponent(usersContentRoot);
super(bottomNavigation); private final UsersFilterComponent usersFilter = new UsersFilterComponent(usersFilterBottomSheet);
this.topBar = new TopBarComponent(byId("android:id/content")); private final WishlistsContentComponent wishlistsContent = new WishlistsContentComponent(wishlistsContentRoot);
} private final GiftsContentComponent giftsContent = new GiftsContentComponent(giftsContentRoot);
public void open() { public void open() {
bottomNavigation.openUsers(); bottomNavigation.openUsers();
usersContentRoot().shouldBe(Condition.visible, Duration.ofSeconds(15)); usersContentRoot.shouldBe(Condition.visible, Duration.ofSeconds(15));
} }
public void filterByUsername(String username) { public void filterByUsername(String username) {
topBar.openUsersFilter(); topBar.openUsersFilter();
byId("users_filter_bottom_sheet").shouldBe(Condition.visible, Duration.ofSeconds(15)); usersFilterBottomSheet.shouldBe(Condition.visible, Duration.ofSeconds(15));
new UsersFilterComponent(byId("users_filter_bottom_sheet")).applyByUsername(username); usersFilter.applyByUsername(username);
byId("user_item").shouldBe(Condition.visible, Duration.ofSeconds(15)); firstUserItem.shouldBe(Condition.visible, Duration.ofSeconds(15));
} }
public void openUser(String username) { public void openUser(String username) {
usersContent().byUsername(username).open(); usersContent.byUsername(username).open();
} }
public void openFirstWishlist() { public void openFirstWishlist() {
wishlistsContent().get(0).open(); wishlistsContent.get(0).open();
} }
public void openWishlist(String name) { public void openWishlist(String name) {
wishlistsContent().byTitle(name).open(); wishlistsContent.byTitle(name).open();
} }
public void openFirstGift() { public void openFirstGift() {
new GiftsContentComponent(byId("gifts_content")).get(0).open(); giftsContent.get(0).open();
} }
public void openGift(String name) { public void openGift(String name) {
new GiftsContentComponent(byId("gifts_content")).byTitle(name).open(); giftsContent.byTitle(name).open();
} }
public boolean isReserved() { public boolean isReserved() {
return Boolean.parseBoolean(byId("reserved").shouldBe(Condition.visible).getAttribute("checked")); return Boolean.parseBoolean(reservedToggle.shouldBe(Condition.visible).getAttribute("checked"));
} }
public void toggleReservation() { public void toggleReservation() {
byId("reserved").shouldBe(Condition.visible).click(); reservedToggle.shouldBe(Condition.visible).click();
} }
private UsersContentComponent usersContent() {
return new UsersContentComponent(usersContentRoot());
}
private WishlistsContentComponent wishlistsContent() {
return new WishlistsContentComponent(wishlistsContentRoot());
}
private com.codeborne.selenide.SelenideElement usersContentRoot() {
if (byId("users_content").exists()) {
return byId("users_content");
}
return byId("users");
}
private com.codeborne.selenide.SelenideElement wishlistsContentRoot() {
if (byId("wishlists_content").exists()) {
return byId("wishlists_content");
}
return byId("wishlists");
}
} }
@@ -1,24 +1,24 @@
package ru.otus.mobile.page; package ru.otus.mobile.page;
import com.codeborne.selenide.Condition; import com.codeborne.selenide.Condition;
import com.google.inject.Inject; import com.codeborne.selenide.SelenideElement;
import ru.otus.mobile.component.BottomNavigationComponent; import com.google.inject.Singleton;
import ru.otus.mobile.component.WishlistsContentComponent; import ru.otus.mobile.component.WishlistsContentComponent;
import ru.otus.mobile.component.WishlistFormComponent; import ru.otus.mobile.component.WishlistFormComponent;
public final class WishlistsPage extends AbsBasePage { import java.time.Duration;
private final WishlistFormComponent form;
private final com.codeborne.selenide.SelenideElement addButton = byId("add_button");
@Inject @Singleton
public WishlistsPage(BottomNavigationComponent bottomNavigation, WishlistFormComponent form) { public final class WishlistsPage extends AbsBasePage {
super(bottomNavigation); private final SelenideElement wishlistsContentRoot = byId("wishlists_content");
this.form = form; private final SelenideElement addButton = byId("add_button");
} private final SelenideElement formRoot = byId("wishlist_edit_bottom_sheet");
private final WishlistsContentComponent content = new WishlistsContentComponent(wishlistsContentRoot);
private final WishlistFormComponent form = new WishlistFormComponent(formRoot);
public void open() { public void open() {
bottomNavigation.openWishlists(); bottomNavigation.openWishlists();
contentRoot().shouldBe(Condition.visible); wishlistsContentRoot.shouldBe(Condition.visible, Duration.ofSeconds(15));
} }
public void createWishlist(String name) { public void createWishlist(String name) {
@@ -27,41 +27,19 @@ public final class WishlistsPage extends AbsBasePage {
} }
public void editWishlist(String oldName, String newName) { public void editWishlist(String oldName, String newName) {
ensureWishlistsList(); content.byTitle(oldName).edit();
content().byTitle(oldName).edit();
form.save(newName); form.save(newName);
} }
public void shouldSeeWishlist(String name) { public void shouldSeeWishlist(String name) {
content().byTitle(name).shouldHaveTitle(name); content.byTitle(name).shouldHaveTitle(name);
} }
public void openWishlist(String name) { public void openWishlist(String name) {
content().byTitle(name).open(); content.byTitle(name).open();
} }
public void openFirstWishlist() { public void openFirstWishlist() {
content().first().open(); content.first().open();
}
private void ensureWishlistsList() {
if (exists("wishlist_item") || contentRoot().exists()) {
return;
}
if (exists("gifts_content") || exists("gift_item") || exists("add_button")) {
back();
}
contentRoot().shouldBe(Condition.visible);
}
private WishlistsContentComponent content() {
return new WishlistsContentComponent(contentRoot());
}
private com.codeborne.selenide.SelenideElement contentRoot() {
if (byId("wishlists_content").exists()) {
return byId("wishlists_content");
}
return byId("wishlists");
} }
} }