Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Standardize Page Objects With Visual Studio Item Templates

DZone's Guide to

Standardize Page Objects With Visual Studio Item Templates

How to use page object design patterns in Visual Studio in order to write effective automated UI tests.

· Web Dev Zone
Free Resource

Should you build your own web experimentation solution? Download this whitepaper by Optimizely to find out.

I believe that to write high-quality tests we need to prevent the copy-paste development. To write UI tests we usually utilise the Page Object Design Pattern. To create a new page, most people copy an existing one and delete the redundant code. I believe that this practice is error prompt and tedious. Because of that in this publication, I am going to show you how to create item templates to solve this problem. You can find similar solutions in the other articles from the Automation Tools Series.

What is an Item Template?

Definition

The metadata file (*.vstemplate) that Visual Studio uses to define how to display the project item in the integrated development environment (IDE) and, if you have specified the appropriate properties, to customize how the project item is created.

How to Create Single Page Templates for Standard Page Object

In my article Page Object Pattern in Automated Testing, I showed you how to use the default WebDriver Page Objects. You can find below the default code for a regular page.

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.");
 }
}

view rawBingMainPage.cs hosted by GitHub

Usually, if you want to create a new page, you will copy one of the existing pages, remove the redundant code and start to add the new logic. However, for me, this process is tedious and error-prone. Because of that, I believe that if we create a template for this boilerplate code, we will reduce the amount of the required work and errors.

Create Clean Default Template

1. Copy the above page and start deleting the redundant code. Leave only the bare minimum required.

// <copyright file="PageTemplate.cs" company="Automate The Planet Ltd.">
// Copyright 2016 Automate The Planet Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// <author>Anton Angelov</author>
// <site>http://automatetheplanet.com/</site>
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
namespace PageObjectPattern.Selenium.Bing.Pages
{
 public class PageTemplate
 {
 private readonly IWebDriver driver;
 private readonly string url = @"http://www.bing.com/";
 public PageTemplate(IWebDriver browser)
 {
 this.driver = browser;
 PageFactory.InitElements(browser, this);
 }
 [FindsBy(How = How.Id, Using = "sb_form_q")]
 public IWebElement SampleElement { get; set; }
 public void Navigate()
 {
 this.driver.Navigate().GoToUrl(this.url);
 }
 public void SampleAction()
 {
 }
 public void AssertIsTrue(bool expectedCondition = true)
 {
 Assert.IsTrue(expectedCondition);
 }
 }
}

view rawPageTemplate.cs hosted by GitHub

2. Now it is time to export the file as a template. In the File menu, click Export Template.

Export Item Template

3. Click Item Template, select the project that contains the item and click Next.

Item Template Type Wizard

4. Select the item for which you want to create a template, and click Next.

Select Item for Template

5. You can select the assembly references to be included in the template, but we will skip this part.

Select Item References

6. Next type the icon file name, preview image. You can find the most appropriate from some of the most popular sites such as FlatIcon.

Find Icon

7. Type the template name and description, and click Finish.

Export Template Wizard

The files for the template are added to a .zip file and copied whatever directory you specify in the dialog. The default location is ..Users/<username>/Documents/Visual Studio <Version>/My Exported Templates/ folder.

Import Exported Templates in Visual Studio

My Exported Templates

By default, the template is imported automatically. However, if for some reason you have deleted it. You need to copy the exported template to ..Users/<username>/Documents/Visual Studio <Version>/Templates/ItemTemplates/

How to Use the Created Item Templates

To use your new template add a new item:

Open New Item Window

It is possible not to see your template at first when you open the new item window. To fix the problem close all Visual Studio instances and open your solutions' folder. Delete the .vs folder.

Delete .vs folder

After that, open your solution again and try to create a new item.

Create New Item Page Object

The following new file is created:

// <copyright file="MyNewPage.cs" company="Automate The Planet Ltd.">
// Copyright 2016 Automate The Planet Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
// <author>Anton Angelov</author>
// <site>http://automatetheplanet.com/</site>
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
namespace PageObjectPattern
{
 public class MyNewPage
 {
 private readonly IWebDriver driver;
 private readonly string url = @"http://www.bing.com/";
 public MyNewPage(IWebDriver browser)
 {
 this.driver = browser;
 PageFactory.InitElements(browser, this);
 }
 [FindsBy(How = How.Id, Using = "sb_form_q")]
 public IWebElement SampleElement { get; set; }
 public void Navigate()
 {
 this.driver.Navigate().GoToUrl(this.url);
 }
 public void SampleAction()
 {
 }
 public void AssertIsTrue(bool expectedCondition = true)
 {
 Assert.IsTrue(expectedCondition);
 }
 }
}

view rawMyNewPage.cs hosted by GitHub

The class name and the filename are automatically changed to the value that you have specified in the new item window.

This is how looks the current version of the exported template: MyTemplate.vstemplate file.

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
 <TemplateData>
 <DefaultName>WebDriverPageObjectItemTemplate.cs</DefaultName>
 <Name>WebDriverPageObjecttemTemplate</Name>
 <Description>Creates a WebDriver Page Object</Description>
 <ProjectType>CSharp</ProjectType>
 <SortOrder>10</SortOrder>
 <Icon>__TemplateIcon.png</Icon>
 <PreviewImage>__PreviewImage.png</PreviewImage>
 </TemplateData>
 <TemplateContent>
 <References />
 <ProjectItem SubType="" TargetFileName="$fileinputname$.cs" ReplaceParameters="true">PageTemplate.cs</ProjectItem>
 </TemplateContent>
</VSTemplate>

view rawWebDriverPageObjectTemplate.xml hosted by GitHub

Download the Page Object Item Template

Full Source Code

Implementing an Experimentation Solution: Choosing whether to build or buy?

Topics:
visual studio ,ui testing ,web dev ,testing ,automation

Published at DZone with permission of Anton Angelov, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}