PageObject 的想法真的很酷。 :)
您可以使用库:https://github.com/DotNetSeleniumTools/DotNetSeleniumExtras
扩展类https://github.com/DotNetSeleniumTools/DotNetSeleniumExtras/blob/master/src/PageObjects/DefaultPageObjectMemberDecorator.cs
你的班级应该是这样的:
class CustomPageObjectMemberDecorator : DefaultPageObjectMemberDecorator, IPageObjectMemberDecorator
{
private BaseDriver driver;
public CustomPageObjectMemberDecorator(BaseDriver driver) => this.driver = driver;
public new object Decorate(MemberInfo member, IElementLocator locator)
{
FieldInfo field = member as FieldInfo;
PropertyInfo property = member as PropertyInfo;
Type targetType = null;
if (field != null)
{
targetType = field.FieldType;
}
bool hasPropertySet = false;
if (property != null)
{
hasPropertySet = property.CanWrite;
targetType = property.PropertyType;
}
var genericType = targetType.GetGenericArguments().FirstOrDefault();
if (field == null & (property == null || !hasPropertySet))
{
return null;
}
// IList<IWebElement>
if (targetType == typeof(IList<IWebElement>))
{
return base.Decorate(member, locator);
}
// IWebElement
else if (targetType == typeof(IWebElement))
{
return base.Decorate(member, locator);
}
// BaseElement and childs
else if (typeof(BaseElement).IsAssignableFrom(targetType))
{
var bys = CreateLocatorList(member);
var cache = ShouldCacheLookup(member);
IWebElement webElement = (IWebElement)WebElementProxy.CreateProxy(locator, bys, cache);
return GetElement(targetType, webElement, driver, field.Name);
}
// IList<BaseElement> and childs
else if (targetType.GetInterfaces().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>)) != null)
{
Type elementOfListTargetType = targetType.GetGenericArguments()[0];
if (typeof(BaseElement).IsAssignableFrom(elementOfListTargetType))
{
var cache = ShouldCacheLookup(member);
IList<By> bys = CreateLocatorList(member);
if (bys.Count > 0)
{
return CustomElementListProxy.CreateProxy(driver, field.Name, elementOfListTargetType, locator, bys, cache);
}
else
{
return null;
}
}
else
{
return null;
}
}
else
{
return null;
}
}
private Element GetElement(Type type, IWebElement webElement, BaseDriver baseDriver, string Name)
{
return (Element)type
.GetConstructor(new[] { typeof(IWebElement), typeof(BaseDriver), typeof(string) })
.Invoke(new object[] { webElement, baseDriver, Name });
}
}
你还需要初始化你的页面:
public BasePage(BaseDriver Driver) : base(Driver)
{
IPageObjectMemberDecorator pageObjectMemberDecorator = new CustomPageObjectMemberDecorator(_driver);
PageFactory.InitElements(this, _driver.RetryingElementLocator, pageObjectMemberDecorator);
}
您的 PageObject 将如下所示:
public class LoginPage : BasePage, ILoad
{
[FindsBy(How = How.XPath, Using = "//*[@class = 'linkButtonFixedHeader office-signIn']")] private Button SignIn;
[FindsBy(How = How.XPath, Using = "//input[@type = 'email']")] private TextInputField Email;
[FindsBy(How = How.XPath, Using = "//input[@type = 'submit']")] private Button Submit;
[FindsBy(How = How.XPath, Using = "//input[@type = 'password']")] private TextInputField Password;
public LoginPage() : base(new BaseDriver(), "https://outlook.live.com/")
{
}
public bool IsLoaded() =>
SignIn.IsVisible() &&
Email.IsVisible() &&
Submit.IsVisible();
public MainMailPage PositiveLogin(User user)
{
SignIn.Click();
Email.SendString(user.Login);
Submit.Click();
Password.SendString(user.Pass);
Submit.Click();
return Page<MainMailPage>();
}
}
你也可以扩展 FindByAttribute 和 PageObject 将被简化:
public class LoginPage : BasePage, ILoad
{
[XPath("//*[@class = 'linkButtonFixedHeader office-signIn']")] private Button SignIn;
[XPath("//input[@type = 'email']")] private TextInputField Email;
[XPath("//input[@type = 'submit']")] private Button Submit;
[XPath("//input[@type = 'password']")] private TextInputField Password;
public LoginPage() : base(new BaseDriver(), "https://outlook.live.com/")
{
}
public bool IsLoaded() =>
SignIn.IsVisible() &&
Email.IsVisible() &&
Submit.IsVisible();
public MainMailPage PositiveLogin(User user)
{
SignIn.Click();
Email.SendString(user.Login);
Submit.Click();
Password.SendString(user.Pass);
Submit.Click();
return Page<MainMailPage>();
}
}