当前位置: 首页 > 面试题库 >

在Selenium C#中使用PageFactory / FindsBy时如何初始化SelectElements?

乔伯寅
2023-03-14
问题内容

我正在使用PageFactory在Selenium WebDriver for C#中构建页面对象模型。

不幸的是,我发现FindsByAttribute不会初始化SelectElement(HTML
<select>标签/下拉菜单)。到目前为止,我已经遇到或想出了一些解决方案,但没有一个是理想的:

  1. PageFactory并且FindsByAttributesealed,因此我不能仅通过继承它们来强制使用。
  2. 在每种方法中SelectElementhtml" target="_blank">实例手动实例化a IWebElement都是很麻烦且重复的。除非我每次都添加一个等待,否则它也会忽略明显的内置等待PageFactory并抛出NoSuchElementExceptions,这将需要在各处重复定位器,从而破坏了POM的(部分)用途。
  3. IWebElement属性包装每个属性的SelectElement麻烦程度较小,但仍存在与上述相同的等待问题。

到目前为止,最好的选择是#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访问它的每一次。

有更好的方法吗?

编辑: 悄悄地放错了访问修饰符。固定。谢谢@JimEvans。


问题答案:

首先,.NET PageFactory实现中没有“内置等待”
。您可以在调用中轻松指定一个InitElements(稍后对此进行详细说明)。目前,最适合您的选择是您的选择3,尽管我不会公开该IWebElement成员。我会做到的private,因为PageFactory可以像枚举公共成员一样轻松地枚举私有成员。因此您的页面对象将如下所示:

[FindsBy(How = How.Id, Using = "MonthDropdown")]
private IWebElement dropDown;
public SelectElement MonthDropdownElement
{
    get { return new SelectElement(dropdown); }
}

IWebElement在需要时如何获得实际值?自从SelectElement实现以来IWrappedElementWrappedElement如果您需要访问IWebElement接口提供的元素的方法和属性,则可以简单地调用属性。

.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

我将撇开严格定义的页面对象模式的正确实现,不要在每个页面对象之外公开任何WebDriver对象。否则,您所实现的只是一个“页面包装器”,这是一种非常有效的方法,而不是所谓的“页面对象”。



 类似资料:
  • 我试图从WebClient中替换RestTemplate,因为根据Java文档,RestTemple将被弃用。Spring团队建议尽可能使用WebClient。 之前的RestTempalte代码如下 我想从WebClient替换RestTemplate。所以我实现了类WebClientConnection,如下所示 我使用这个依赖项 Webclient create 上有堆栈溢出错误 如何正确地

  • 更新代码: 页面对象: 页面库: 测试基地: 看起来框架没有考虑等待预期条件-元素的可见性。我怀疑与“visibilityOf(element)”的实现和@FindBy初始化元素的方式有关 异常的堆栈跟踪: 原因:org。openqa。硒。NoSuchElementException:没有这样的元素:无法定位元素:{“方法”:“xpath”,“选择器”:“/*[@id='container']]/

  • 问题内容: 我无法按照以下代码初始化列表: 我遇到以下错误: 无法实例化类型 我该如何实例化? 问题答案: 如果你检查API,则会注意到它说: 作为一种手段,它无法实例化(不可能)。 如果你检查该链接,则会发现一些实现的: 所有已知的实施类: 那些可以实例化。使用它们的链接来了解有关它们的更多信息,即IE:知道哪个更适合你的需求。 三种最常用的可能是: 奖励: 你还可以使用,以更简单的方式使用值实

  • 问题内容: 我正在跟踪Swift和Objective-C Runtime,它适用于常规方法。 我喜欢使用init方法,据我了解,init就像一个类方法。因此,我尝试将初始化作为实例和类方法。但这似乎不起作用 我可以使用Objective C使其工作,只是想知道如何在Swift中使其工作 摘录自我的要旨 问题答案: 为方法创建选择器时,应使用Obj C方法签名作为选择器的基础,因为使用Obj C运行

  • 第一行代码是什么意思?它如何调整数组大小?第二行代码如何初始化该字节数组(如果是)?

  • 据我所知,在Java11中,这两个操作可以在一行中完成,不是吗?