Здравствуйте, на данный момент столкнулся с проблемой работы с 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)
}
Нет другого способа. В твоем случае popup - это div. Чтобы адресовать в нём элементы, необходимо указывать в xpath, что путь до них пролегает через этот div.
В чём тут сложность? Надо просто правильно организовать архитектуру своего фреймворка, чтобы основная страничка и popup на ней были отдельными классами. Все особенности взаимодействия с элементами интерфейса (xpath с учетом/без учета div) класс скрывает в себе, а из теста всё будет выглядеть прозрачно:
Я хотел бы еще такую вещь уточнить. Когда я из теста обращаюсь к popup для редактирования поля, не будет ли хардкорностью писать следующее?:
popup.servicePopup("rules", "Номер по порядку", "10", "fields");
//servicePopup - Тип popup. Я бы мог сделать обобщенный метод для всех попапов, но не получится, так как поведение их бывает разное. Например в одном отобразятся сразу поля, а в другом, перед отображением появится меню.
//rules - popup к которому обращаемся
//Номер по порядку - поле которое будем редактировать
//10 - значение применяемое к полю
//fields - это значение определяет каким образом мы работаем с полем. В данном случае как с текстовым.
Если у тебя разные окна (с разным поведением), то вполне нормально работать с ними через разные классы. Это более правильно, чем пихать всю функциональность разных попапов в один класс
Хотел бы поднять опять вопрос по popup. На popup решил выбрать элемент в list2list, но никак не получается это сделать вываливаются исключения (java)
Локатор в итоге получился следующий (проверял в firepath) //*[@additional-view][last()]//section[@name='row.__states.AvalabiltyOnVideoServers']//td[normalize-space(.)='Московский']/input[@ng-model='row.__selected']
Пробовал следующие способы кликнуть элемент в list2list:
На странице и 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 , или нужно прибегать к другим способам?