我正在使用PageFactory在Selenium WebDriver for C#中构建页面对象模型。
不幸的是,我发现FindsByAttribute不会初始化SelectElement(HTML <select>标签/下拉菜单)。到目前为止,我已经遇到或想出了一些解决方案,但没有一个是理想的:
FindsByAttribute
SelectElement
<select>
PageFactory
sealed
IWebElement
NoSuchElementException
到目前为止,最好的选择是#3,为此编写一个包装器SelectElement只会给每个方法增加一个等待时间。尽管此解决方案可以 工作 ,但它将大量堆积每个页面的代码,而不是下面的(假设的)漂亮代码:
[FindsBy(How = How.Id, Using = "MonthDropdown")] public SelectElement MonthDropdown;
我被包装纸包裹住了(我宁愿避免),并且:
[FindsBy(How = How.Id, Using = "MonthDropdown")] private IWebElement _monthDropdown; public Selector MonthDropdown { get { return new Selector(MonthDropdown, Wait); } }
随着Selector作为SelectElement包装,也必须采取的IWait<IWebDriver>,因此它可以等待,和一个新的实例Selector访问它的每一次。
Selector
IWait<IWebDriver>
有更好的方法吗?
编辑: 悄悄地放错了访问修饰符。固定。谢谢@JimEvans。
首先,.NET PageFactory实现中没有“内置等待” 。您可以在调用中轻松指定一个InitElements(稍后对此进行详细说明)。目前,最适合您的选择是您的选择3,尽管我不会公开该IWebElement成员。我会做到的private,因为PageFactory可以像枚举公共成员一样轻松地枚举私有成员。因此您的页面对象将如下所示:
InitElements
private
[FindsBy(How = How.Id, Using = "MonthDropdown")] private IWebElement dropDown; public SelectElement MonthDropdownElement { get { return new SelectElement(dropdown); } }
IWebElement在需要时如何获得实际值?自从SelectElement实现以来IWrappedElement,WrappedElement如果您需要访问IWebElement接口提供的元素的方法和属性,则可以简单地调用属性。
IWrappedElement
WrappedElement
.NET绑定的最新版本已将重组PageFactory为更可扩展。要添加所需的“内置等待”,可以执行以下操作:
// Assumes you have a page object of type MyPage. // Note the default timeout for RetryingElementLocator is // 5 seconds, if unspecified. // The generic version of this code looks like this: // MyPage page = PageFactory.InitElements<MyPage>(new RetryingElementLocator(driver), TimeSpan.FromSeconds(10)); MyPage page = new MyPage(); PageFactory.InitElements(page, new RetryingElementLocator(driver, TimeSpan.FromSeconds(10)));
此外,如果您 确实 需要自定义事物的工作方式,那么始终欢迎您实施IPageObjectMemberDecorator,它使您可以完全自定义枚举属性的方式以及将值设置为用这些属性修饰的属性或字段的方式。的(非泛型)重载之一PageFactory.InitElements采用对象实现的实例IPageObjectMemberDecorator。
IPageObjectMemberDecorator
PageFactory.InitElements
我将撇开严格定义的页面对象模式的正确实现,不要在每个页面对象之外公开任何WebDriver对象。否则,您所实现的只是一个“页面包装器”,这是一种非常有效的方法,而不是所谓的“页面对象”。