页面对象模型页面初始化

时间:2019-04-04 04:40:24

标签: c# selenium design-patterns

我正在使用SeleniumExtras.PageObjects,因此为应用程序中的不同页面开发了一个专用的类。

因此,如果某个测试涉及多个页面,那么我需要在测试开始时包括3个单独的页面初始化语句:

var pageOne = new PageOne(driver);
PageFactory.InitElements(driver, pageOne);

var pageTwo = new PageTwo(driver);
PageFactory.InitElements(driver, pageTwo);

var pageTherr = new PageThree(driver);
PageFactory.InitElements(driver, pageThree);

Test starts...

这会使代码变得混乱。在代码中是否有一种优雅的方式可以在单个语句中调用所有aval页面对象,以便在测试中使用它们?

谢谢。

2 个答案:

答案 0 :(得分:2)

在使用三个页面对象之前,您不应该对其进行初始化。每个页面对象应在其构造函数内调用PageFactory.InitElements(...)。页面对象上应具有将您转换到下一页并返回下一页的页面对象的方法。解决方法实际上是两部分:

  1. 初始化页面对象构造函数中的元素

  2. 向页面对象添加方法,以返回下一页的页面对象。

第一部分基本上是already answered on this question

public class PageOne
{
    public PageOne(IWebDriver driver)
    {
        PageFactory.InitElements(driver, this);
    }
}

public class PageTwo
{
    public PageTwo(IWebDriver driver)
    {
        PageFactory.InitElements(driver, this);
    }
}

public class PageThree
{
    public PageThree(IWebDriver driver)
    {
        PageFactory.InitElements(driver, this);
    }
}

在您的代码中,第1页指向第2页,而第2页指向第3页。PageOne类需要一个执行动作并返回PageTwo实例的方法。由于您提供的名称含糊不清,因此我将以创建新博客帖子为例:

public class AddEditBlogPostPageObject
{
    [FindsBy(How = How.Id, Using = "Title")]
    public IWebElement TitleField { get; set; }

    [FindsBy(How = How.Id, Using = "PostDate")]
    public IWebElement DateField { get; set; }

    [FindsBy(How = How.Id, Using = "BodyText")]
    public IWebElement BodyTextField { get; set; }

    [FindsBy(How = How.XPath, Using = "//button[contains(., 'Save Blog Post')]")]
    public IWebElement SaveButton { get; set; }

    private readonly IWebDriver driver;

    public AddEditBlogPostPageObject(IWebDriver driver)
    {
        this.driver = driver;
        PageFactory.InitElements(driver, this);
    }

    public ViewBlogPostPageObject CreateNewPost(string title, DateTime blogPostDate, string bodyText)
    {
        TitleField.SendKeys(title);
        DateField.SendKeys(blogPostDate.ToShortDateString());
        BodyTextField.SendKeys(bodyText);
        SaveButton.Click();

        return new ViewBlogPostPageObject(driver);
    }
}

并使用它:

var addBlogPostPage = new AddEditBlogPostPageObject(driver);

var viewBlogPostPage = addBlogPostPage.CreateNewPost(
    "How to use Selenium Page Objects",
    DateTime.Today,
    "All about how to use the page object pattern with Selenium.");

// Use viewBlogPostPage to assert something, or navigate to another page

这样,您无需在使用所有页面对象之前对其进行初始化。您初始化一个页面对象,在其上调用一个方法,该方法返回下一个页面对象。这使重构测试更容易以匹配应用程序流,因为您只需要重构页面对象上的方法即可返回工作流中的“下一页”。

答案 1 :(得分:0)

您可以将其添加到基础页面对象中

public abstract class AbstractPage
{
    public AbstractPage(IWebDriver driver)
    {
        PageFactory.InitElements(driver, this);          
    }
}

public class PageOne : AbstractPage
{
    public PageOne(IWebDriver driver) : base(driver)
    {
    }
}