3
\$\begingroup\$

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);
    }
  }
}
\$\endgroup\$
2
  • \$\begingroup\$ Your title should describe what it is your code actually does, not what you are hoping for from the review. A more detailed description in the body of your question is also likely to help reviewers. \$\endgroup\$
    – forsvarir
    Commented Nov 7, 2016 at 11:02
  • \$\begingroup\$ Thanks, have added a bit more detail to the description. \$\endgroup\$
    – alex
    Commented Nov 7, 2016 at 15:29

2 Answers 2

3
\$\begingroup\$

I see you're using Selenium automated testing, so I would recommend reviewing Selenium best practices.

There's several problems with the code you showed, most of which stem from it being essentially one long method. I would suggest refactoring, with the following objectives:

  • It is a standard approach to create your own automation framework tailored to the website you're testing.
  • Use Page Object pattern for modelling the UI.
  • Split the code into smaller modules with small responsibilities (e.g. finding a specific control, clicking a specific button etc) - having these as small building blocks would enable you to write (a) a more readable test and (b) more tests in the future (by reusing the framwork).
  • Consider implementing it as a fluent API to make the tests more readable by people not intimately familiar with the website.

The end results of a well-done framework are tests that look like this (simplifying somewhat):

LoginPage.WithUsername("foo").WithPassword("bar").Login();
MainPage.NavigateTo(SitePage.Reports);
ReportsPage.SpecifyDate("2013-04-17").ThenGenerate();
Assert.That(ReportsPage.TheReport.RowCount, Is.EqualTo(50));
////etc.
\$\endgroup\$
1
\$\begingroup\$

Additional thoughts not related to @Misza answer.

  • Extract TestInitialize to base class. Your test doesn't need to know what browser are you using, base url to application and all other stuff you would need to duplicate in all test classes. To know what you can extract to TestBase (Only stuff related to driver setup) you can create another test class and try to write a test. What you need to duplicate (involving driver) needs to be abstracted.
  • Avoid using Thread.Sleep() at all costs. Two issues can occur - sleep value was too little and your test failed. Sleep value was too big - your test execution time was too long. Both are equally bad.
  • Create separate objects (not page objects) for elements like Dropdown where you initialize SelectElement. It's good to abstract yourself from other libs.
  • Don't use fluent API (as suggested) everywhere.At least not on page objects. It's a bit too much. Even though it's sometimes nice to abstract yourself from selenium fluently. Like:

    Assert.Element(someElement).IsPresent(); Wait.WithBrowser(driver).ForAjax();

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.