C#: Selenium Framework: 2 - A Closer Look

Architecture

Solution Explorer

 

Code Map

  • Abstracted calls to Selenium in the Browser object
  • Abstracted page requests to Pages.cs so page spefic control is possible
  • Created page objects for getting data for the job and another for driving page actions
  • Modeled application form controls ( Text Boxes, Radio Select, DropDown, Checkboxes, etc)
  • Modeled Web Page Tables, which are simply groups of controls
  • Created a Global Data object to hold all the data necessary to process an image through the application
  • Created a file to retrieve data from the XML data source and store in the GlobalData object
  • Created a file to organize the various job types and their associated actions which are essentially steps to fill in each table

Parsing the XML File for Job Data

  • To populate the following page controls, read data from the XML source file and store in the GlobalDataObject that gets data for each test iteration

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JobData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Job id="0000">
        <Name>win7rtmFIXWIM.wim RM(EngOnly)</Name>
        <Services>
            <SiNumber>4505zy</SiNumber>
            <SelectService>160</SelectService>
        </Services>
        <DownloadLocation>
            <Location>1900</Location>
        </DownloadLocation>
        <ImageOs>
            <Os>80</Os>
        </ImageOs>
        <SubFolder>
            <Folder>\original_cust_img\</Folder>
        </SubFolder>
        <SelectImage>
            <Image>id7.wim</Image>
        </SelectImage>
        <OutputImageType>

        ...

  • ‘QW_Submit’ is the page under test
  • Set the path in the XML file for the section of data, “Download Location”

            sectionPath = "/Tables/DownloadLocation";

  • Set the path in the XML file for the current set of objects

            nowPath = basePath + sectionPath + "";

  • Pull data for ‘Select Services’ drop down control: gets the attributes “id” and “control”

 

            Services.SiNumber.id = GetAttrFromXmlFile(nowPath, "id");
Services.SiNumber.Control = GetAttrFromXmlFile(nowPath, "control");

 

 

DataFileName = GlobalData.DataFileNameFormData;
DataXml.Load(DataFileName);
basePath = "/FormData/Page[@Name = 'QW_Submit']";
string sectionPath = "";
string nowPath = "";

 

#region//SECTION : FILE SPECIFIC
sectionPath = "/Tables/DownloadLocation";
nowPath = basePath + sectionPath + "";
DownloadLocation.Location.id = GetAttrFromXmlFile(nowPath, "id");
DownloadLocation.Location.Control = GetAttrFromXmlFile(nowPath, "control");

 

sectionPath = "/Tables/ImageOs";
nowPath = basePath + sectionPath + "";
ImageOs.Os.id = GetAttrFromXmlFile(nowPath, "id");
ImageOs.Os.Control = GetAttrFromXmlFile(nowPath, "control");

 

sectionPath = "/Tables/SubFolder";
nowPath = basePath + sectionPath + "";
SubFolder.Folder.id = GetAttrFromXmlFile(nowPath, "id");
SubFolder.Folder.Control = GetAttrFromXmlFile(nowPath, "control");

 

sectionPath = "/Tables/SelectImage";
nowPath = basePath + sectionPath + "";
SelectImage.Image.id = GetAttrFromXmlFile(nowPath, "id");
SelectImage.Image.Control = GetAttrFromXmlFile(nowPath, "control");

 

sectionPath = "/Tables/OutputImageType";
nowPath = basePath + sectionPath + "";
OutputImageType.Type.id = GetAttrFromXmlFile(nowPath, "id");
OutputImageType.Type.Control = GetAttrFromXmlFile(nowPath, "control");
#endregion

  • Using two helper methods to pull data from the XML source file

// Fetch XML Element Text from              '/curPath/'
public static string ReturnXmlElementText(XmlDocument sourceXml, string curPath, string curId)
{
Debug.WriteLine("ReturnXmlElementText: {0}: Returning: {1}", curPath, curId);
return sourceXml.SelectSingleNode(curPath).InnerText;
// Gets text
// string s= GetAttrFromXmlFile("curPath");
}

        // Fetch XML Attribute Value from           '/curPath'
public static string ReturnXmlAttribValue(XmlDocument sourceXml, string curPath, string curId)
{
var temp = sourceXml.SelectSingleNode(curPath);
string curAttribute = temp.Attributes[curId].Value;
Debug.WriteLine("ReturnXmlAttribValue: {0}: Returning: {1}", curPath, curAttribute);
return curAttribute;
// string s= GetAttrFromXmlFile("curPath",'[@curId]');
}

  • Now PageSubmitActions will use the data for entry on the form.
  • “id” is used by Selenium Webdriver to locate the control with matching “id” attribute

#region///Quick Web Option Tables for Submiting Various Jobs
public void DownloadLocation()
{
var currentObj = PageSubmitDataInit.DownloadLocation;

var select = Browser.Wait.Until(d =>
{
var element = Browser.Driver.FindElement(By.Id(currentObj.Location.id));
if (element.Displayed == true)
return element;
return null;
}
);
var selectElement = new SelectElement(select);
selectElement.SelectByValue(currentObj.Location.Option);
Thread.Sleep(5000);
}

 

public void ImageOperatingSystem()
{
// Image OS
var currentObj = PageSubmitDataInit.ImageOs;
var selectOs = Browser.Wait.Until(d =>
{
var element1 = Browser.Driver.FindElement(By.Id(currentObj.Os.id));
if (element1.Displayed == true)
return element1;
return null;
}
);

var selectElement = new SelectElement(selectOs);
selectElement.SelectByValue(currentObj.Os.Option);
}

Test Execution

  • Running Test Case #5679 to test a ‘Restore Media’ feature
  • Data is entered via Excel, then the test pulls the data at run-time

/// <summary>
/// Restore Media: Server Selection Test: BOTH Servers
/// </summary>
[TestMethod]
public void Do_5679_RestoreMedia_ServerBOTH()
{
// 4505za @ 106(id7.wim)
jobType = "5679";
PageSubmitDataInit.XmlFormDataInit();
PageSubmitDataInit.XmlJobDataInit(jobType);
currentJob.RestoreMedia();
}

  • Resharper has built-in Testing features to allow for running test individually or as a group

Unit Test Explorer with available tests

Tags