I'm new to coding and have cobbled together some code to run an automated test against a web application. The code works but I have some complexity rule violations (CA1505, CA1502 and CA1506) and would be grateful to anyone with insight on how to go about improving the code.
The code logs into the UI, makes sure the user is on the correct account and the correct data set. Then goes through 4 different report tables and checks the table data against expected outcome files. I have made some changes already suggested which have improved the violation levels slightly but not enough to suppress them...
namespace ObservatoryAutomatedFunctional.Tests
{
[TestClass]
public class LineDetailAnalysisTests: IDisposable
{
private IWebDriver driver;
private FirefoxBinary binary;
private string baseUrl = Tests.Urls.BaseUrl;
private string firefoxPath = Tests.DriverSetup.FirefoxPath;
private string driverPath = Tests.DriverSetup.DriverPath;
private string actualData = Tests.OutcomeFileLocations.ActualOutcome + "Analyse_SpendBySubjective_Act.csv";
private string expectedData = Tests.OutcomeFileLocations.ExpectedOutcome + "Analyse_SpendBySubjective_Exp.csv";
private string actualData2 = Tests.OutcomeFileLocations.ActualOutcome + "Analyse_SpendByDirectorate_Act.csv";
private string expectedData2 = Tests.OutcomeFileLocations.ExpectedOutcome + "Analyse_SpendByDirectorate_Exp.csv";
private string actualData3 = Tests.OutcomeFileLocations.ActualOutcome + "Analyse_SpendByCostCentre_Act.csv";
private string expectedData3 = Tests.OutcomeFileLocations.ExpectedOutcome + "Analyse_SpendByCostCentre_Exp.csv";
private string actualData4 = Tests.OutcomeFileLocations.ActualOutcome + "Analyse_SpendByDepartment_Act.csv";
private string expectedData4 = Tests.OutcomeFileLocations.ExpectedOutcome + "Analyse_SpendByDepartment_Exp.csv";
[TestInitialize()]
//Set the browswer from a build
public void MyTestInitialize()
{
//Point to a specified version of FireFox
FirefoxProfile profile = new FirefoxProfile();
binary = new FirefoxBinary(firefoxPath);
//Choose browser based on value in ParameterValues file
if (Tests.DriverSetup.Browser.Equals("ff"))
{
driver = new FirefoxDriver(binary, profile);
}
else if (Tests.DriverSetup.Browser.Equals("ie"))
{
driver = new InternetExplorerDriver(driverPath);
}
else if (Tests.DriverSetup.Browser.Equals("ch"))
{
driver = new ChromeDriver(driverPath);
}
}
[TestMethod]
[TestCategory("Selenium")]
public void LineDetailAnalysis()
{
//Maximize the browser window
driver.Manage().Window.Maximize();
//Login with user
driver.Url = baseUrl;
IWebElement Username = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_txtUsername"));
IWebElement Password = driver.FindElement(By.Id("ctl00_ContentPlaceHolder1_txtPassword"));
Username.Clear();
Username.SendKeys(Tests.UserDetails.User1);
Password.Clear();
Password.SendKeys(Tests.UserDetails.Password1);
Password.SendKeys(Keys.Enter);
//Switch focus to the header frame
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.HeaderMenuFrame);
WebDriverWait wait10 = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
WebDriverWait wait30 = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
//Wait for "Home" menu to be visible
wait10.Until(ExpectedConditions.ElementToBeClickable((By.XPath("//*[@alt='Home']")))).Click();
//Switch focus to the left side menu
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.LeftMenuFrame);
wait10.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(@id, 'menuContainer')]/div/div[contains(text(),'Admin')]")))).GetAttribute("Id");
//Wait for the "Admin" arrow to be visible, then click
wait10.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(@id, 'menuContainer')]/div/div[contains(text(),'Admin')]/following-sibling::node()[contains(@id,'menuInfo')]")))).Click();
//Wait for the "Web Admin" report to be visible
wait10.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(@id,'menuContentArea')]/li[1]/span[contains(text(),'Web Admin')]")))).Click();
//Wait for 1 second to allowsub menu to drop
Thread.Sleep(1000);
//Switch focus to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
// select the client drop down list
var client = driver.FindElement(By.Id("cboAccounts"));
//create select element object
var selectElement = new SelectElement(client);
//select by value
selectElement.SelectByText(Tests.SpendByDirectorate.ClientName);
//Click the "Move here" button
driver.FindElement(By.XPath("//*[@id='cmdMoveHere']")).Click();
//Switch focus to the header frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.HeaderMenuFrame);
//Wait for "Spend Analysis" menu to be visible
IWebElement menuitem = wait10.
Until(ExpectedConditions.ElementIsVisible((By.
XPath("//img[@alt='Spend Analysis']"))));
//Hover over "Measurement" menu
Actions action = new Actions(driver);
action.MoveToElement(menuitem).Perform();
//Wait for 1 second to allowsub menu to drop
Thread.Sleep(1000);
//Switch focus to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait10.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//*[contains(text(),'Analyze')]")))).Click();
//Accept any alerts that may pop up
for (int i = 0; i < 5; i++)
{
if (IsAlertPresent())
{
driver.SwitchTo().Alert().Accept();
System.Diagnostics.Debug.WriteLine("Alert is present");
}
else
{
System.Diagnostics.Debug.WriteLine("No Alerts are present");
break;
}
}
//Switch focus to the left side menu
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.LeftMenuFrame);
wait10.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(@id, 'menuContainer')]/div/div[contains(text(),'Line Detail Analysis')]/following-sibling::node()[contains(@id,'menuInfo')]")))).Click();
//Wait for the "Gains by Lead Buyer" report to be visible
wait10.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(text(),'Spend by Subjective')]"))));
//Wait for 1 second to allowsub menu to drop
Thread.Sleep(1000);
//Move to the "Gains by Lead Buyer" and click
IWebElement element = driver.FindElement(By.
XPath("//*[contains(text(),'Spend by Subjective')]"));
Actions actions = new Actions(driver);
actions.MoveToElement(element).Click().Perform();
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
//Wait for the "Data" tabs frame to be visible
wait30.Until(ExpectedConditions.ElementIsVisible((By.
Id(Tests.LineDetailAnalysis.TableFrame))));
//Switch focus back to the main frame
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='lwDataGrid_Main_Header_Column1'][contains(text(),'Subjective Description')]"))));
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
//Select the required dataset from the dataset panel
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='filter_panel_sidebar']")))).Click();
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//*[@id='fp_dataset']")))).Click();
wait30.Until(ExpectedConditions.ElementToBeClickable(By.
XPath("//*[@id='btn_clear_datasets']"))).Click();
Thread.Sleep(3000);
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[contains(text(),'Rows:')][contains(@id,'gpPanel')]"))));
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='scrolling_dropdown_container']/div/ul/li/label[contains(text(),'UW Eau Claire (Jul 14-Jun 15)')]/preceding-sibling::node()"))));
wait30.Until(ExpectedConditions.InvisibilityOfElementLocated(By.
XPath("//*[@id='dataset_busy_cover_panel']")));
driver.FindElement(By.
XPath("//*[@id='scrolling_dropdown_container']/div/ul/li/label[contains(text(),'UW Eau Claire (Jul 14-Jun 15)')]/preceding-sibling::node()")).Click();
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='scrolling_dropdown_container']/div/ul/li/label[contains(text(),'UW Eau Claire (Jul 14-Jun 15)')]/preceding-sibling::node()"))));
wait30.Until(ExpectedConditions.InvisibilityOfElementLocated(By.
XPath("//*[@id='dataset_busy_cover_panel']")));
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//*[@id='btn_apply_datasets']")))).Click();
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='filter_panel_sidebar']")))).Click();
Thread.Sleep(3000);
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='lwDataGrid_Main_Header_Column1'][contains(text(),'Subjective Description')]"))));
//Wait for the last cell in the table to be available
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//div[@id='lwDataGrid']/table/tbody/tr[last()]/td[last()]"))));
//divided xpath In three parts to pass Row_count and Col_count values.
String firstPart = "//div[@id='lwDataGrid']/table/tbody/tr[";
String secondPart = "]/td[";
String thirdPart = "]";
//Row and Column counts
int rowCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[*]")).Count - 3;
int colCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[1]/td")).Count - 1;
System.Diagnostics.Debug.WriteLine(rowCount + ": This is the number of rows in the table");
System.Diagnostics.Debug.WriteLine(colCount + ": This is the number of columns in the table");
using (StreamWriter sw = new StreamWriter(actualData, false))
{
//Used for loop for number of rows
for (int i = 1; i <= rowCount + 3; i++)
{
if (i == 2 | i == 3)
{
continue;
}
string line = string.Empty;
//Used for loop for number of columns
for (int j = 2; j <= colCount + 1; j++)
{
//Prepared final xpath of specific cell as per values of i and j.
String finalXpath = firstPart + i + secondPart + j + thirdPart;
//Will retrieve value from located cell and print It.
String tableData = driver.FindElement(By.XPath(finalXpath)).Text;
tableData = tableData.Replace(",", "");
//Add double quotes to comma numbers
if (j == colCount + 1)
{
//Do not include 1st (header) row
line = line + string.Format(CultureInfo.CurrentCulture, "{0}", tableData);
}
else
{
line = line + string.Format(CultureInfo.CurrentCulture, "{0},", tableData);
}
}
sw.WriteLine(line.ToString());
//sw.WriteLine(line);
}
}
// Create the IEnumerable data sources.
string[] firstCSV = System.IO.File.ReadAllLines(actualData);
string[] secondCSV = System.IO.File.ReadAllLines(expectedData);
int count = 0;
// Create the query. Note that method syntax must be used here.
IEnumerable<string> szDifference =
firstCSV.Except(secondCSV);
foreach (string szTest in szDifference)
{
count = count + 1;
System.Diagnostics.Debug.WriteLine(szTest + " exist in firstCSV but not in secondCSV");
}
if (count > 0)
{
Assert.Fail("The data does not match the expected outcome file!");
}
else
{
System.Diagnostics.Debug.WriteLine("Data is as expected");
}
//[* * * SPEND BY DIRECTORATES * * *]
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.LeftMenuFrame);
driver.FindElement(By.
XPath("//*[contains(text(),'Spend by Directorate')]")).Click();
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
Thread.Sleep(3000);
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='lwDataGrid_Main_Header_Column1'][contains(text(),'Directorate Description')]"))));
//Wait for the last cell in the table to be available
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//div[@id='lwDataGrid']/table/tbody/tr[last()]/td[last()]"))));
//Row and Column counts
rowCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[*]")).Count - 3;
colCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[1]/td")).Count - 1;
System.Diagnostics.Debug.WriteLine(rowCount + ": This is the number of rows in the table");
System.Diagnostics.Debug.WriteLine(colCount + ": This is the number of columns in the table");
using (StreamWriter sw = new StreamWriter(actualData2, false))
{
//Used for loop for number of rows
for (int i = 1; i <= rowCount + 3; i++)
{
if (i == 2 | i == 3)
{
continue;
}
string line = string.Empty;
//Used for loop for number of columns
for (int j = 2; j <= colCount + 1; j++)
{
//Prepared final xpath of specific cell as per values of i and j.
String finalXpath = firstPart + i + secondPart + j + thirdPart;
//Will retrieve value from located cell and print It.
String tableData = driver.FindElement(By.XPath(finalXpath)).Text;
tableData = tableData.Replace(",", "");
//Add double quotes to comma numbers
if (j == colCount + 1)
{
//Do not include 1st (header) row
line = line + string.Format(CultureInfo.CurrentCulture, "{0}", tableData);
}
else
{
line = line + string.Format(CultureInfo.CurrentCulture, "{0},", tableData);
}
}
sw.WriteLine(line.ToString());
//sw.WriteLine(line);
}
}
// Create the IEnumerable data sources.
firstCSV = System.IO.File.ReadAllLines(actualData2);
secondCSV = System.IO.File.ReadAllLines(expectedData2);
count = 0;
// Create the query. Note that method syntax must be used here.
szDifference =
firstCSV.Except(secondCSV);
foreach (string szTest in szDifference)
{
count = count + 1;
System.Diagnostics.Debug.WriteLine(szTest + " exist in firstCSV but not in secondCSV");
}
if (count > 0)
{
Assert.Fail("The data does not match the expected outcome file!");
}
else
{
System.Diagnostics.Debug.WriteLine("Data is as expected");
}
//[* * * SPEND BY COST CENTRE * * *]
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.LeftMenuFrame);
driver.FindElement(By.
XPath("//*[contains(text(),'Spend by Cost Centre')]")).Click();
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
Thread.Sleep(3000);
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='lwDataGrid_Main_Header_Column1'][contains(text(),'CostCentre Description')]"))));
//Wait for the last cell in the table to be available
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//div[@id='lwDataGrid']/table/tbody/tr[last()]/td[last()]"))));
//Row and Column counts
rowCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[*]")).Count - 3;
colCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[1]/td")).Count - 1;
System.Diagnostics.Debug.WriteLine(rowCount + ": This is the number of rows in the table");
System.Diagnostics.Debug.WriteLine(colCount + ": This is the number of columns in the table");
using (StreamWriter sw = new StreamWriter(actualData3, false))
{
//Used for loop for number of rows
for (int i = 1; i <= rowCount + 3; i++)
{
if (i == 2 | i == 3)
{
continue;
}
string line = string.Empty;
//Used for loop for number of columns
for (int j = 2; j <= colCount + 1; j++)
{
//Prepared final xpath of specific cell as per values of i and j.
String finalXpath = firstPart + i + secondPart + j + thirdPart;
//Will retrieve value from located cell and print It.
String tableData = driver.FindElement(By.XPath(finalXpath)).Text;
tableData = tableData.Replace(",", "");
//Add double quotes to comma numbers
if (j == colCount + 1)
{
//Do not include 1st (header) row
line = line + string.Format(CultureInfo.CurrentCulture, "{0}", tableData);
}
else
{
line = line + string.Format(CultureInfo.CurrentCulture, "{0},", tableData);
}
}
sw.WriteLine(line.ToString());
//sw.WriteLine(line);
}
}
// Create the IEnumerable data sources.
firstCSV = System.IO.File.ReadAllLines(actualData3);
secondCSV = System.IO.File.ReadAllLines(expectedData3);
count = 0;
// Create the query. Note that method syntax must be used here.
szDifference =
firstCSV.Except(secondCSV);
foreach (string szTest in szDifference)
{
count = count + 1;
System.Diagnostics.Debug.WriteLine(szTest + " exist in firstCSV but not in secondCSV");
}
if (count > 0)
{
Assert.Fail("The data does not match the expected outcome file!");
}
else
{
System.Diagnostics.Debug.WriteLine("Data is as expected");
}
//[* * * SPEND BY DEPARTMENT * * *]
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.LeftMenuFrame);
driver.FindElement(By.
XPath("//*[contains(text(),'Spend by Department')]")).Click();
//Switch focus back to the main frame
driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.MainBodyFrame);
Thread.Sleep(3000);
driver.SwitchTo().Frame(Tests.LineDetailAnalysis.TableFrame);
//Wait for the "Measure" sub menu to be visible, then click
wait30.Until(ExpectedConditions.ElementIsVisible((By.
XPath("//*[@id='lwDataGrid_Main_Header_Column1'][contains(text(),'Department Description')]"))));
//Wait for the last cell in the table to be available
wait30.Until(ExpectedConditions.ElementToBeClickable((By.
XPath("//div[@id='lwDataGrid']/table/tbody/tr[last()]/td[last()]"))));
//Row and Column counts
rowCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[*]")).Count - 3;
colCount = driver.FindElements(By.XPath("//div[@id='lwDataGrid']/table/tbody/tr[1]/td")).Count - 1;
System.Diagnostics.Debug.WriteLine(rowCount + ": This is the number of rows in the table");
System.Diagnostics.Debug.WriteLine(colCount + ": This is the number of columns in the table");
using (StreamWriter sw = new StreamWriter(actualData4, false))
{
//Used for loop for number of rows
for (int i = 1; i <= 100 + 3; i++)
{
if (i == 2 | i == 3)
{
continue;
}
string line = string.Empty;
//Used for loop for number of columns
for (int j = 2; j <= colCount + 1; j++)
{
//Prepared final xpath of specific cell as per values of i and j.
String finalXpath = firstPart + i + secondPart + j + thirdPart;
//Will retrieve value from located cell and print It.
String tableData = driver.FindElement(By.XPath(finalXpath)).Text;
tableData = tableData.Replace(",", "");
//Add double quotes to comma numbers
if (j == colCount + 1)
{
//Do not include 1st (header) row
line = line + string.Format(CultureInfo.CurrentCulture, "{0}", tableData);
}
else
{
line = line + string.Format(CultureInfo.CurrentCulture, "{0},", tableData);
}
}
sw.WriteLine(line.ToString());
//sw.WriteLine(line);
}
}
// Create the IEnumerable data sources.
firstCSV = System.IO.File.ReadAllLines(actualData4);
secondCSV = System.IO.File.ReadAllLines(expectedData4);
count = 0;
// Create the query. Note that method syntax must be used here.
szDifference =
firstCSV.Except(secondCSV);
foreach (string szTest in szDifference)
{
count = count + 1;
System.Diagnostics.Debug.WriteLine(szTest + " exist in firstCSV but not in secondCSV");
}
if (count > 0)
{
Assert.Fail("The data does not match the expected outcome file!");
}
else
{
System.Diagnostics.Debug.WriteLine("Data is as expected");
}
}
public Boolean IsAlertPresent()
{
try
{
driver.SwitchTo().Alert();
return true;
} // try
catch (NoAlertPresentException)
{
return false;
//throw;
} // catch
}
[TestCleanup()]
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//dispose managed resources
driver.Close();
binary.Dispose();
//sr.Dispose();
}
//free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}