如何在页面对象模型设计中使用 selenium ExpectedConditions?
How do you use selenium ExpectedConditions in a page object model design?
希望我不是第一个遇到这个问题的人。
我正在用 C# 编写一些 selenium 测试,在尝试采用页面对象模型设计的同时还需要对 ExpectedConditions class.
进行一些显式等待时,我遇到了两难选择
假设我将我的元素存储在一个元素映射 class 中,它只是一个 属性,它使用存储在资源文件中的 XPath 调用 .FindElement 方法...
public class PageObject {
public IWebElement Element
{
get { return DriverContext.Driver.FindElement(By.XPath(Resources.Element)); }
}
}
然后我会继续在各种 selenium 方法中使用 属性。
我遇到的问题是我还需要检查这个元素在页面上是否可见,在我执行检查之前它会出错(例如使用 WebDriverWait,将 ExpectedConditions.ElementIsVisible(by) 传递给.until 方法)。
如何彻底分离 IWebElement 和 By 定位器并允许在需要时使用此显式 wait/check?
TLDR - 我如何维护页面对象模型设计,同时还可以根据元素的 By 定位器灵活地使用显式等待。
非常感谢,
我一直使用页面对象,但我在 class 的顶部有定位器而不是元素。然后我根据需要使用定位器点击按钮等。这样做的好处是我只在需要时访问页面上的元素,这避免了陈旧的元素异常等。请参见下面的简单示例。
class SamplePage
{
public IWebDriver Driver;
private By waitForLocator = By.Id("sampleId");
// please put the variable declarations in alphabetical order
private By sampleElementLocator = By.Id("sampleId");
public SamplePage(IWebDriver webDriver)
{
this.Driver = webDriver;
// wait for page to finish loading
new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(waitForLocator));
// see if we're on the right page
if (!Driver.Url.Contains("samplePage.jsp"))
{
throw new InvalidOperationException("This is not the Sample page. Current URL: " + Driver.Url);
}
}
public void ClickSampleElement()
{
Driver.FindElement(sampleElementLocator).Click();
}
}
我建议不要将定位器存储在单独的文件中,因为它打破了页面对象模型的一个原则,即与页面有关的所有内容都在页面对象中。您无需打开任何文件即可对页面 X(页面对象 class.
执行任何操作
希望我不是第一个遇到这个问题的人。
我正在用 C# 编写一些 selenium 测试,在尝试采用页面对象模型设计的同时还需要对 ExpectedConditions class.
进行一些显式等待时,我遇到了两难选择假设我将我的元素存储在一个元素映射 class 中,它只是一个 属性,它使用存储在资源文件中的 XPath 调用 .FindElement 方法...
public class PageObject {
public IWebElement Element
{
get { return DriverContext.Driver.FindElement(By.XPath(Resources.Element)); }
}
}
然后我会继续在各种 selenium 方法中使用 属性。
我遇到的问题是我还需要检查这个元素在页面上是否可见,在我执行检查之前它会出错(例如使用 WebDriverWait,将 ExpectedConditions.ElementIsVisible(by) 传递给.until 方法)。
如何彻底分离 IWebElement 和 By 定位器并允许在需要时使用此显式 wait/check?
TLDR - 我如何维护页面对象模型设计,同时还可以根据元素的 By 定位器灵活地使用显式等待。
非常感谢,
我一直使用页面对象,但我在 class 的顶部有定位器而不是元素。然后我根据需要使用定位器点击按钮等。这样做的好处是我只在需要时访问页面上的元素,这避免了陈旧的元素异常等。请参见下面的简单示例。
class SamplePage
{
public IWebDriver Driver;
private By waitForLocator = By.Id("sampleId");
// please put the variable declarations in alphabetical order
private By sampleElementLocator = By.Id("sampleId");
public SamplePage(IWebDriver webDriver)
{
this.Driver = webDriver;
// wait for page to finish loading
new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(waitForLocator));
// see if we're on the right page
if (!Driver.Url.Contains("samplePage.jsp"))
{
throw new InvalidOperationException("This is not the Sample page. Current URL: " + Driver.Url);
}
}
public void ClickSampleElement()
{
Driver.FindElement(sampleElementLocator).Click();
}
}
我建议不要将定位器存储在单独的文件中,因为它打破了页面对象模型的一个原则,即与页面有关的所有内容都在页面对象中。您无需打开任何文件即可对页面 X(页面对象 class.
执行任何操作