0

我正在使用 Selenium Page 工厂,我想对其进行某些扩展,但不能因为它们是密封的,所以我想编写自己的自定义逻辑。

问题:PageFactory.InitElements 如何工作,以便所有属性在使用时加载它们的值,而不是在调用此方法时加载它们的值。

所以,用一个例子来解释它

    //// Button on page load 
    [FindsBy(How = How.CssSelector, Using = "#lst-ib")]
    public IWebElement Btn;

    //// Button redirecting to Page 2
    [FindsBy(How = How.CssSelector, Using = "#lst-ib")]
    public IWebElement LinkBtn;

    ////Button on second page
    [FindsBy(How=How.CssSelector, Using = "#rso > div:nth-child(1) > div > div:nth-child(1) > div > div > h3 > a")]
    public IWebElement NewBtn;

因此,他们的页面工厂的美妙之处在于,所有元素都已加载,但在使用时它们会转换为 webelements,因为如果所有属性在初始化时都分配了值,那么 NewBtn 属性总是会失败,就像在第 2 页上一样。

因此,他们可能会使用什么概念来初始化属性,以便在使用时而不是在运行时分配它们,任何虚拟代码都会很好,并且很高兴理解

提前致谢

4

2 回答 2

1

我在 C# 方面完全没有经验,但我检查了 C# selenium 实现的源代码,看起来与 Java 代码几乎相同。

PageFactory.cs - 这个类提供了如何初始化元素的整体框架。initElements()获取pageobject. _ 对于每个字段,都会获得它们的注释。然后它为每个字段创建一个Proxy。然后它存储要使用的实际定位器。实际调用在代理findElement or findElements的方法内。Invoke

这一切都由两个类处理 - DefaultPageObjectMemberDecorator.csDefaultElementLocator.cs。有两个代理处理调用 - WebElementProxy.csWebElementListProxy.cs

因此,您想要编写的自定义逻辑可以通过创建实现适当接口的新类来完成。然后将这些新类传递给PageFactoryinitElement()类的适当方法。

详细了解看class的Decorate()方法。DefaultPageObjectMemberDecorator.cs

于 2018-04-10T10:10:06.367 回答
0

在创建页面对象时,“页面对象逻辑”(IMO,根据我的经验以及我迄今为止从 c# 和 selenium 了解到的内容)它期望元素映射中提到的所有元素都存在于 DOM 中。

如果您的 NewBtn 存在于圆顶中但被隐藏(并且在导航到第二页时变得可见,基本上是当页面没有刷新并且有一些 ajax 时),那么元素映射就不会有处理元素的任何问题。您只需要通过 IF 语句确保元素可见或添加等待(以查看您是否确实在第二页)。

如果在导航到第二个页面时页面被刷新,那么只需重新初始化页面对象,new MyPageObject()以便所有元素再次映射,以避免 StaleElement 和/或 ElementNotFound 异常等。

于 2018-04-10T09:46:48.407 回答