In my last article Standardize Page Objects with Visual Studio Item Templates, I showed you how to generate Visual Studio item templates so that you can create predefined page objects' classes with a few clicks. However, I don't think that the standard page objects' classes are the best ones. In my article Page Objects That Make Code More Maintainable I explain how to create more maintainable tests using partial classes to separate the page objects' responsibilities- logic, maps and asserts. So you cannot use the single file item templates to generate these. In this publication, I will explain to you how to modify the standard template so that three files to be generated.
What Problem We Are Trying to Solve?
Regular Page Objects
Below you can find the code of the regular page object used by most people.
public class BingMainPage
{
private readonly IWebDriver driver;
private readonly string url = @"http://www.bing.com/";
public BingMainPage(IWebDriver browser)
{
this.driver = browser;
PageFactory.InitElements(browser, this);
}
[FindsBy(How = How.Id, Using = "sb_form_q")]
public IWebElement SearchBox { get; set; }
[FindsBy(How = How.Id, Using = "sb_form_go")]
public IWebElement GoButton { get; set; }
[FindsBy(How = How.Id, Using = "b_tween")]
public IWebElement ResultsCountDiv { get; set; }
public void Navigate()
{
this.driver.Navigate().GoToUrl(this.url);
}
public void Search(string textToType)
{
this.SearchBox.Clear();
this.SearchBox.SendKeys(textToType);
this.GoButton.Click();
}
public void ValidateResultsCount(string expectedCount)
{
Assert.IsTrue(this.ResultsCountDiv.Text.Contains(expectedCount), "The results DIV doesn't contains the specified text.");
}
}
More Maintainable Page Objects
This is the class that contains the primary logic that can be executed on the page.
public partial class BingMainPage : BasePage
{
public BingMainPage(IWebDriver driver) : base(driver)
{
}
public override string Url
{
get
{
return @"http://www.bing.com/";
}
}
public void Search(string textToType)
{
this.SearchBox.Clear();
this.SearchBox.SendKeys(textToType);
this.GoButton.Click();
}
public int GetResultsCount()
{
int resultsCount = default(int);
resultsCount = int.Parse(this.ResultsCountDiv.Text);
return resultsCount;
}
}
Тhis partial class consists only of the elements of the page.
>
public partial class BingMainPage : BasePage
{
public IWebElement SearchBox
{
get
{
return this.driver.FindElement(By.Id("sb_form_q"));
}
}
public IWebElement GoButton
{
get
{
return this.driver.FindElement(By.Id("sb_form_go"));
}
}
public IWebElement ResultsCountDiv
{
get
{
return this.driver.FindElement(By.Id("b_tween"));
}
}
}
I modified thе class a little bit compared to the version presented in my article- Page Objects That Make Code More Maintainable. Now the class is not static, and the methods are not implemented as extension methods on the page itself. Rather this class as the other two is now partial and the methods are not static. This means that you don't have to pass the page as a parameter since you can access the elements directly.
Current Version
public partial class BingMainPage
{
public void AssertResultsCountIsAsExpected(int expectedCount)
{
Assert.AreEqual(this.ResultsCountDiv.Text, expectedCount, "The results count is not as expected.");
}
}
Previous Version
public static class BingMainPageAsserter
{
public static void AssertResultsCountIsAsExpected(this BingMainPage page, int expectedCount)
{
Assert.AreEqual(page.ResultsCountDiv.Text, expectedCount, "The results count is not as expected.");
}
}
These are the three classes (files) that we want to generate with a single item template.
Create Multiple Files Item Template
1. Generate single item template. Follow the steps described in my previous article- Standardize Page Objects with Visual Studio Item Templates.
2. Open the folder where the template is located. The default location is- ..Users/<username>/Documents/Visual Studio <Version>/My Exported Templates/
3. Unzip the template file
This is the code of the auto-generated template.
<vstemplate type="Item" version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<templatedata>
<defaultname>SystemTestingFrameworkPage.cs</defaultname>
<name>SystemTestingFrameworkPage</name>
<description>Creates system testing framework's page, element map and asserter</description>
<projecttype>CSharp</projecttype>
<sortorder>10</sortorder>
<icon>__TemplateIcon.png</icon>
<previewimage>__PreviewImage.png</previewimage>
</templatedata>
<templatecontent>
<references>
<projectitem replaceparameters="true" subtype="" targetfilename="$fileinputname$.cs">TestPage.cs</projectitem>
</references></templatecontent>
</vstemplate>
4. Next, you need to create clean file templates for the page, map and the asserter.
Page Clean File Item Template
using System;
using OpenQA.Selenium;
namespace $rootnamespace$
{
public partial class $safeitemname$
{
private IWebDriver driver;
public $safeitemname$(IWebDriver driver) : base(driver)
{
this.asserter = asserter;
}
public void SampleAction()
{
}
}
}
Page Element Map Clean File Item Template
using OpenQA.Selenium;
namespace $rootnamespace$
{
public partial class $safeitemname$
{
}
}
Page Asserter Clean File Item Template
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace $rootnamespace$
{
public partial class $safeitemname$
{
public void AssertSomething()
{
Assert.IsTrue(true);
}
}
}
The $safeitemname$ will be replaced by the name you specify in the new item window. $rootnamespace$ will be determined by the current folder structure where you place the new file.
5. Copy the three new clean file templates to the template's extracted folder.
6. Add two new project items to the template pointing the element map and the asserter. The final template should look like the code below.
<vstemplate type="Item" version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<templatedata>
<defaultname>SystemTestingFrameworkPage.cs</defaultname>
<name>SystemTestingFrameworkPage</name>
<description>Creates system testing framework's page, element map and asserter</description>
<projecttype>CSharp</projecttype>
<sortorder>10</sortorder>
<icon>__TemplateIcon.png</icon>
<previewimage>__PreviewImage.png</previewimage>
</templatedata>
<templatecontent>
<references>
<projectitem replaceparameters="true" subtype="" targetfilename="$fileinputname$.cs">TestPage.cs</projectitem>
<projectitem replaceparameters="true" subtype="" targetfilename="$fileinputname$.Map.cs">TestPage.Map.cs</projectitem>
<projectitem replaceparameters="true" subtype="" targetfilename="$fileinputname$.Asserter.cs">TestPage.Asserter.cs</projectitem>
</references></templatecontent>
</vstemplate>
7. Create a zip with all of the template's files
Create Multiple Files Page Objects
After you follow the import steps from my previous article, you will be able to use the modified template.
Three files are generated with file names corresponding to the specified name in the new items' window.
Download the Page Object Item Template
Automation Tools Series
The post Create Multiple Files Page Objects with Visual Studio Item Templates appeared first on Automate The Planet.