Общие элементы для Popup и главной страницы

Здравствуйте, на данный момент столкнулся с проблемой работы с Popup окном. Ситуация такая, я тестирую админку в которой есть например кнопка “Создать” и у нее есть локатор обобщенный для всех страниц, включая Popup. Но когда открывается Popup я не знаю как на него правильно переключиться (он накладывается поверх основного, в нем можно открыть еще один P.S. подробнее на скриншоте) чтобы взаимодействовать с такой-же кнопкой.

Из ниже приведенного кода можно увидеть, что кнопка создать, на всех Popup и главной страницы, имеет один и тот же локатор ([ng-click='addRow(row)']), но когда накладывается Popup окно, я могу переключится на него только добавив локатор ([additional-view='0']).
Пожалуйста скажите мне, что есть другой способ сказать коду что я работаю с Popup окном. Если нужен какой-то дополнительный мой код я предоставлю, но пока я рассматриваю это в грубой форме, чтобы понять как оно должно работать.

public class A1{
  @Test
  
public void asd(){
	 
	 /*
		....................
		....................
		....................

	 */
	 
//	  
	 
	  driver.findElement(By.cssSelector("[name='row.__states.ContentAssets'] [ng-click='onAddRow()']")).click(); //нажимаем добавить на главной странице всплывает Popup окно
	  
	  driver.findElement("[additional-view='0'] [name='Аудио PID'] [ng-click='onAddRow()']")).click(); // В этом окне мы хотим добавить Аудио PID, накладывается еще одно Popup
	  
	  driver.findElement(By.cssSelector("[additional-view='1'] [ng-click='addRow(row)']")).click(); //Нажимаем кнопку создать в последнем Popup, оно закрывается и переходит к родительскому Popup
	  
	   driver.findElement(By.cssSelector("[additional-view='0'] [ng-click='addRow(row)']")).click(); //Нажимаем кнопку создать во 2 Popup и переходим на главную страницу

	   driver.findElement(By.cssSelector("[ng-click='addRow(row)']")).click(); //нажимаем кнопку создать на главной странице

	}

String parentHandle = driver.getWindowHandle(); // get the current window handle
driver.findElement(By.xpath("//*[@id='someXpath']")).click(); // click some link that opens a new window

for (String winHandle : driver.getWindowHandles()) {
    driver.switchTo().window(winHandle); // switch focus of WebDriver to the next found window handle (that's your newly opened window)
}

что-то такое поможет .
Может еще чего с Alert

1 лайк

WindowHandles надо использовать, если имеем дело с несколькими окнами браузера. Здесь же ситуация проще: popup-ы - это обычные div

Нет другого способа. В твоем случае popup - это div. Чтобы адресовать в нём элементы, необходимо указывать в xpath, что путь до них пролегает через этот div.

В чём тут сложность? Надо просто правильно организовать архитектуру своего фреймворка, чтобы основная страничка и popup на ней были отдельными классами. Все особенности взаимодействия с элементами интерфейса (xpath с учетом/без учета div) класс скрывает в себе, а из теста всё будет выглядеть прозрачно:

page.clickCreateButton();
popup.clickCreateButton();
1 лайк

Спасибо за ответы, в дополнение к решению вчера нашел тему очень близкую к этой по организации Framework (Заполнение однотипных форм)

Я хотел бы еще такую вещь уточнить. Когда я из теста обращаюсь к popup для редактирования поля, не будет ли хардкорностью писать следующее?:

popup.servicePopup("rules", "Номер по порядку", "10", "fields");

//servicePopup - Тип popup. Я бы мог сделать обобщенный метод для всех попапов, но не получится, так как поведение их бывает разное. Например в одном отобразятся сразу поля, а в другом, перед отображением появится меню.
//rules - popup к которому обращаемся
//Номер по порядку - поле которое будем редактировать
//10 - значение применяемое к полю
//fields - это значение определяет каким образом мы работаем с полем. В данном случае как с текстовым.

Если у тебя разные окна (с разным поведением), то вполне нормально работать с ними через разные классы. Это более правильно, чем пихать всю функциональность разных попапов в один класс

Ситуация складывается такая, попапов может быть вложенных бесконечное множество:

[additional-view='0'] [ng-click='addRow(row)'] //элемент на первом попапе
[additional-view='1'] [ng-click='addRow(row)'] //элемент на вложенном попапе
[additional-view='2'] [ng-click='addRow(row)'] //
[additional-view='3'] [ng-click='addRow(row)'] //
[additional-view='4'] [ng-click='addRow(row)'] //
итд.

Если даже описывать общий функционал Popups, то нужно реализовать какой нибудь метод типо стека, или сделать свой счетчик окон, верно?

Хотел бы поднять опять вопрос по popup. На popup решил выбрать элемент в list2list, но никак не получается это сделать вываливаются исключения (java)

Локатор в итоге получился следующий (проверял в firepath) //*[@additional-view][last()]//section[@name='row.__states.AvalabiltyOnVideoServers']//td[normalize-space(.)='Московский']/input[@ng-model='row.__selected']

Пробовал следующие способы кликнуть элемент в list2list:

  1. element.click(); выбрасывает исключение ElementNotVisibleException
  2. actions.moveToElement(element).click().perform(); выбрасывает исключение MoveTargetOutOfBoundsException
  3. Если попробовать взять координаты element.getLocation().getX() выдает “0
  4. Пытался кликнуть элемент через SeleniumIDE, кликает только через clickAt

Что происходит и как выполнить клик по элементу?

  1. Если окно всплывающее то подождать его появления и возможно конца AJAx. (visibilityOfElementLocated )
  2. C кодировками все ок ? Попробуйте переписать локатор без русских букв .

Спасибо но проблема была в одно лишь точке при поиске локатора. Подробнее тут.

На странице и Popup встречается combobox, я не могу использовать библиотеку Select. Поэтому я написал следующий код во избежании дублирования кода:

public class Combobox{	
	
	private WebDriver driver;
	public Combobox(WebDriver driver){
		this.driver = driver;
		
	}
	
public void editCombobox(WebElement name, String value) {													
				name.click();
				driver.findElement(By.cssSelector("[id='select2-drop'] input")).sendKeys(value);										
				driver.findElement(By.xpath("//div/span[@class='select2-match'][normalize-space(text())='"+value+"']")).click();		
	}
}

То есть описывая страницу я пишу следующее:

public class Videomovies(){
         WebDriver driver;
         Combobox combobox;
@FindBy(css = "[id='s2id_row.contractor'] span")
 	 WebElement row_contractor;

public Videomovies(WebDriver driver){
this.driver = driver
PageFactory.initElements(driver, this);
combobox = new Combobox(driver)
}
public void setContactor(String text){
combobox.editCombobox(row_contractor, text);
}
}

Причем на сайте полно другого объемного функционала, например List2List и там уже больше 2 строчек кода будет. Скажите, такая практика применима при написании framework , или нужно прибегать к другим способам?