Чтобы объяснить мой вопрос, я привел небольшой сценарий:
Допустим, у меня есть страница входа.
public class LoginPage
{
[FindsBy(How = How.Id, Using = "SomeReallyLongIdBecauseOfAspNetControlsAndPanels_username"]
public IWebElement UsernameField { get; set; }
[FindsBy(How = How.Id, Using = "SomeReallyLongIdBecauseOfAspNetControlsAndPanels_password"]
public IWebElement PasswordField { get; set; }
[FindsBy(How = How.Id, Using = "submitButtonId")]
public IWebElement SubmitButton { get; set; }
private readonly IWebDriver driver;
public LoginPage(IWebDriver driver)
{
this.driver = driver;
if(!driver.Url.Contains("Login.aspx"))
{
throw new NotFoundException("This is not the login page.");
}
PageFactory.InitElements(driver, this);
}
public HomePage Login(Credentials cred)
{
UsernameField.sendKeys(cred.Username);
PasswordField.SendKeys(cred.Password);
SubmitButton.Click();
return new HomePage(driver);
}
}
[TestFixture]
public class Test : TestBase
{
private IWebDriver driver;
[SetUp]
public void SetUp()
{
driver = StartDriver(); // some function which returns my driver in a wrapped event or something so I can log everything it does.
}
[Test]
public void Test()
{
new LoginPage(driver)
.Login(new Credentials
{ Username = "username",
Password = "password" })
.SomeHomePageFunction()
}
В конце концов, я знаю, что конфигурация страницы изменится, идентификатор будетв основном остаются такими же, но все быстро меняется в моих проектах.Я знаю, что xPath - это еще одна альтернатива, но из-за того, как страницы генерируются на основе определенных критериев, это все равно станет болезненным, поскольку путь не всегда будет одинаковым.
С текущим кодом, приведенным выше, страницазагрузил и PageFactory инициализирует элементы через конструктор страниц.Все здорово.Это то, что я использую в данный момент.
В настоящее время, если некоторые вещи не всегда генерируются на странице до определенного шага.Я обычно делаю следующее:
private const string ThisIsTheUserNameFieldId = "usernamefield";
Затем запускаю веб-драйвер, используя следующее:
// Navigate to login page
// code here
// Enter in credentials
driver.FindElement(By.Id(ThisIsTheUserNameFieldId)).SendKeys(cred.Username);
Не так хорошо структурирован, как PageFactory, но это, безусловно, требование, которого я не придерживаюсьсмог обойтись.
Недавно я натолкнулся на некоторый код jQuery Selector для использования с C # .Net, который расширяет функциональность RemoteWebDriver, где я могу использовать селекторы jQuery для поиска своих элементов на странице.
Selenium jQuery для C # .Net (включая источник)
// So I can do things like this:
driver.FindElement(By.jQuery("a").Find(":contains('Home')").Next())
Кто-нибудь знает, как я могу расширить атрибут [FindsBy] в Selenium WebDriver, чтобы это было возможноиспользовать что-то вроде следующего (псевдокод)?
[FindsBy(How = How.jQuery, Using = "div[id$='txtUserName']")]
public IWebElement UsernameField { get; set; }