public AccountPage typePhone(String s) {
driver.findElement(By.id("telephone")).click();
driver.findElement(By.id("telephone_i")).sendKeys(s);
return this;
}
Как это выглядило бы с Page Factory:
@FindBy(how = How.ID, using = "telephone")
private WebElement txtTelephone;
@FindBy(how = How.ID, using = "telephone_i")
private WebElement txtTelephone2;
public AccountPage typePhone(String s) {
txtTelephone.click();
txtTelephone2.sendKeys(s);
return this;
}
Проблема: как уменшить код и избавится от второго FindBy если я знаю что в конце второго ID будет всегда +"_i"
как я пытался: сделать чтото типо фреймворка/обертки которая будет доставать из елемента ID и добавлять " _i" (id +" _i"). Проблема в том что мне никак не вытащить ид из элемента.
@FindBy(how = How.ID, using = "telephone")
private WebElement txtTelephone;
public AccountPage typePhone(String s) {
EnterText(txtTelephone, s);
return this;
}
//В новом общем классе:
public void EnterText (WebElemenet element, String s) {
element.Click();
//Вот тут проблема, не знаю как достать id
String tmpstr = element.toString();
//Добавляем к id элемента +"_i"
driver.findElement(By.id(tmpstr+"_i")).sendKeys(s);
}
тут пэйдж фэктори не поможет… либо расширять пэйджфэктори, либо написать метод типа:
public WebElement getPhone(int number) {
if (number==0)
return driver.findElement(By.id(“telephone”));
else
return driver.findElement(By.id(String.format(“telephone_%s”, number)));
}
ну и вызов:
page.getPhone(0).sendKeys(“tralala”)
но удобней конечно же работать с прокси объектами, а не с объектами, возвращаемыми findElement… но это отдельная тема)
Если завтра верстка поменяется? Вы имеете в виду айдишники? Если так, то уже ничего не поможет) один путь - где-то что-то менять:) а по поводу пэйдж фэктори… тут нужно подумать… в данном случае может имеет смысл использовать еще так:
//находит 2 элемента с которыми я потом буду работать
[FindsBy(How = How.XPath, Using = ".//*[@id='telephone' or @id='telephone_i']")]
public IList<IWebElement> txtPhone { get; set; }
internal AccountPage TypePhone(string value)
{
EnterText(txtPhone, value);
return this;
}
private void EnterText(IList<IWebElement> element, string value)
{
element[0].Click();
element[1].SendKeys(value);
}
Дополнительный вопрос: На сколько правильно будет использовать такой подход с точки зрения написания тестов (скорость выполнения кода/нахождения элементов или др аспекты) по сравнению с этим:
правильний только тогда если при каждом обращении по такому локатору будет только один елемент находить, а так можно просто написать локатор через contains как советовали више…вообше что ето за прикол со сменой id ? Пните UI разработчика - пусть class меняет при таком поведении , а не id
Using = “.//*[@id=‘telephone’ or @id=‘telephone_i’]” какраз находит 2 элемента с которыми я потом буду работать для ввода текста. один на который кликнуть, тогда второй становится “visible” и можно ввести текст.
Пните UI разработчика - пусть class меняет при таком поведении , а не id
Я бы с радостью:) К сожалению это Out-Of box продукт Microsoft Dynamics CRM (который тяжело кастомизируется под нужды клиента)
А вы уверены, что элемент с id=‘telephone_i’ существует в дереве элементов одновременно с элементом c id=‘telephone’ ? Я понял из примера, что или первый или второй отображается в дереве элементов.