Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Вопрос по PageObject, оптимизация методов

page-object
webdriver
Теги: #<Tag:0x00007f7b646cd6d0> #<Tag:0x00007f7b646cd590>

(Василь ) #1

Добрый день. Подскажите как реализовать метод который в зависимости от других факторов может возвращать разные страници:

Например метод clickButtonSubmitLogin -
Если данные валидные возвращаем объект класа “Личний кабинет”, если не валидные - остаемся на текущей странице. Еще можно добавить например если введенные данные - пароль и логин для администратора - переадресация в админ часть (думаю примеров можно еще много добавить).

Интересует именно возможность сделать это одним методом


(Bohdan Harasym) #2

возможно как то так?

public void enterToApp(UserRepository user){
		String userType = user.getUserType();
		switch (userType) {
		case "adminType":
			getAdminHomePage();
			break;
		case "commonUserType":
			getCommonUserHomePage();
			break;
			//..........
			//другие условия
		default:
			getLoginPage();
			break;
		}

(Василь ) #3

спасибо, но если я все верно понял - то не совсем то што надо. До момента нажатия но кнопку я не могу определить валидность данных


(Bohdan Harasym) #4

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


(Алексей Якуничкин) #5

Если я правильно понял вопрос, то можно попробовать через обычный if…then…else

  1. Нажимаем кнопку
  2. if (если найден какой-то уникальный объект для страницы ЛК){
  3. return объект класса личный кабинет
  4. }else{ тут можно проверить, что мы действительно остались на той же странице, если нужно, либо просто сделать return this;}

Если я тоже неправильно понял вопрос, не серчайте, под конец рабочего дня голова пухнет уже…


(Dez Dezsson) #6

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


(Taras) #7

используйте дженерики - если ето Java


(Bohdan Harasym) #8

public class LoginPage extends TopPage {

private class LoginPageUIMap {
	public final ITextField login;
	public final ITextField password;
	public final IButton signin;

	public LoginPageUIMap() {
		this.login = TextField.get().getById("login");
		this.password = TextField.get().getById("password");
		this.signin = Button.get().getById("signin");
	}
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Elements
private LoginPageUIMap controls;

public LoginPage() {
	// super();
	controls = new LoginPageUIMap();
}

// PageObject - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Get Elements

public ITextField getLogin() {
	return this.controls.login;
}

public ITextField getPassword() {
	return this.controls.password;
}

public IButton getSignin() {
	return this.controls.signin;
}

public String getLoginText() {
	return getLogin().getText();
}

public String getPasswordText() {
	return getPassword().getText();
}

// Set Data

public void setLogin(String login) {
	getLogin().sendKeys(login);
}

public void setLoginClear(String login) {
	getLogin().sendKeysClear(login);
}

public void setPassword(String password) {
	getPassword().sendKeys(password);
}

public void setPasswordClear(String password) {
	getPassword().sendKeysClear(password);
}

public void clearLogin() {
	getLogin().clear();
}

public void clearPassword() {
	getPassword().clear();
}

public void clickLogin() {
	getLogin().click();
}

public void clickPassword() {
	getPassword().click();
}

public void clickSignin() {
	getSignin().click();
}



// Functional

private void setLoginData(IUser user) {
	setLoginClear(user.getAccount().getLogin());
	setPasswordClear(user.getAccount().getPassword());
	clickSignin();
}

 public HomePage successUserLogin(IUser user) {
 setLoginData(user);
 // Return a new page object representing the destination.
return new HomePage();
 }

public AdminHomePage successAdminLogin(IUser admin) {
	setLoginData(admin);
	// Return a new page object representing the destination.
	return new AdminHomePage();
}

public RegistratorHomePage successRegistratorLogin(IUser registrator) {
	setLoginData(registrator);
	// Return a new page object representing the destination.
	return new RegistratorHomePage();
}

 public LoginValidatorPage unsuccessfulLogin(IUser invalidUser) {
 setLoginData(invalidUser);
 return new LoginValidatorPage(); 
 }

(5am) #9

у себя решал данную проблему так:

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

public class SomeAuthorizationDSL
{
    public WelcomePage Login(string username, string password)
    {
        ...
        var welcomePage = loginPage.
            FillLoginForm(username, password).
            Submit();
        Assert.AreEqual(true, welcomePage.IsOpened(), "Не удалось открыть страницу продукта после авторизации");
        ...
    }
}

welcomePage это PageObject, у которого в конструкторе задан уникальный для этой страницы локатор (страницы, на которую попадает пользователь в случае успешной авторизации)

public class WelcomePage : SomeBasePage
{
    public WelcomePage()
    {
        SetPageLocator(new Label("Welcome Page", "//div[@class='l-left-menu']"));
    }
    ...
}

метод IsOpened это Web Element is present реализованный в SomeBasePage
p.s.: Label - обертка на Web Element


(asolntsev) #10

@Furik_Vasil правильный ответ - это НЕ НУЖНО делать одним методом. В пэдж объекте должно быть два разных метода: один возвращает страницу А, второй возвращает страницу Б. И каждый тест сам должен знать, какой из методов вызвать.


(Roman Romanik) #11

As an option in java:

public <T extends PageObject> T login(UserModel user, Class<T> pageToReturn) {
   loginAs(user);
   return PageObjectFactory.getInstanceOf(pageToReturn);
}

where method ‘loginAs’ performs entering data into a login form and submits, and ‘PageObjectFactory.getInstance’ return a new object of a desired page.
For safery, if all your pages extend some ‘PageObject’ class, you may include restrictions on the generic type by <T extends PageObject>.

In any case, in a test script you must know for sure which page is to be returned on the basis of the ‘user’ provided, otherwise the test should fail.


(Дмитрий Назаренко) #12

Я поддерживаю @asolntsev, т.к. Вы должны проверить реакцию системы на переданный параметр/условие.
Проектируя тест, вы должны понимать какая страница Вам вернется при каком-то условии. И проверить что вернулась именно та страница ,которую вы ждете, иначе - это ошибка.
Придерживайтесь принципа KISS(Keep it short and simple) и будет счастье :slight_smile:


#13

А про тест ли задан вопрос? или же это хелпер метод по фреймворке, который будет использоваться для логина?

Так ли Вам необходимо вообще что-то возвращать?


(Pavel Ponomaryov) #14

Надо или не надо так делать - скорее холиварный вопрос. Каждый решает для себя сам. Я в некоторых местах использую дженерики и это помогает избежать лишнего кода. Например хелпер для метода refresh страницы.

public class PageUtils {
  public static <T> T refreshPage(Class<T> page) {
        logger.info("refreshing page " + page.getSimpleName());
        Selenide.refresh();
        return Selenide.page(page);
    }
}

Сам pageObject в кострукторе при инициализации обеспечивает проверку, что это именно ожидаемая страница а не какая-то другая. Работает безотказно. Тест упадёт, если открылась не та страница, которую мы ожидали.