Powered By Blogger

Search Here!

Saturday, July 14, 2012

BDD Setting up with Event Definition using SpecFlow !

Event Definition helps us to run the test scripts or scenarios in the definite manner and pattern. I have run the scenarios as feature basis, when one feature completes then WebDriver stops and re-initiate when next feature starts whatever the number of scenarios it contain. This helps us to save the execution time and get the maximum throughput for our test suite. Below is the structure of event definition file,

[Binding]
    public class BaseTestScript
    {
        public static IWebDriver WebDriver = null;
        public static ISelenium BackedSelenium= null;
        public static SqlConnection DatConnection = DatabaseTools.GetSqlConnection();
        static readonly string Browser = ConfigurationManager.AppSettings["browser"];


        // Purpose: To Start WebDriver
        public static void WebDriverStart()
        {
            try
            {
                WebDriver.Navigate().GoToUrl(ConfigurationManager.AppSettings["browserUrl"]);
                Thread.Sleep(3000);
                WebDriver.FindElement(By.Id("ImgPoweredBy"));
                WebDriver.Manage().Window.Maximize();
                Thread.SetData(Thread.GetNamedDataSlot("webdriverInstance"), WebDriver);
                Thread.SetData(Thread.GetNamedDataSlot("backedseleniumInstance"), BackedSelenium);
            }
            catch (Exception e)
            {
                if (Browser != null) throw new TypeLoadException(Browser+" cannot display the webpage, Please Try Again");
            }
            Console.WriteLine("WebDriver Started");
        }

        // Purpose: To Stop WebDriver
        public static void WebDriverStop()
        {
            if (WebDriver == null)
                return;
            try
            {
                WebDriver.Manage().Cookies.DeleteAllCookies();
                WebDriver.Dispose();
                if (Browser.Equals("IE"))
                {
                    Process[] iexpPro = Process.GetProcessesByName("iexplore");
                    if (iexpPro.Length > 0)
                    {
                        foreach (Process clsProcess in iexpPro)
                        {
                            clsProcess.Kill();
                        }
                    }
                }
                if (Browser.Equals("Firefox"))
                {
                    Process[] fireFoxPro = Process.GetProcessesByName("firefox");
                    if (fireFoxPro.Length > 0)
                    {
                        foreach (Process clsProcess in fireFoxPro)
                        {
                            clsProcess.Kill();
                        }
                    }
                }
                if (Browser.Equals("Safari"))
                {
                    Process[] safariPro = Process.GetProcessesByName("safari");
                    if (safariPro.Length > 0)
                    {
                        foreach (Process clsProcess in safariPro)
                        {
                            clsProcess.Kill();
                        }
                    }
                }
                Process[] selcomwin = Process.GetProcessesByName("mshta");
                if (selcomwin.Length > 0)
                {
                    foreach (Process clsProcess in selcomwin)
                    {
                        clsProcess.Kill();
                    }
                }
                Process[] ieDriverserver = Process.GetProcessesByName("IEDriverServer");
                if (ieDriverserver.Length > 0)
                {
                    foreach (Process clsProcess in ieDriverserver)
                    {
                        clsProcess.Kill();
                    }
                }
            }
            catch (Exception e)
            {
                //throw new Exception("Unable To Stop WebDriver: Please Try Again.");
            }
            WebDriver = null;
            Console.WriteLine("WebDriver Stopped");
        }

        [BeforeTestRun]
        // Purpose: To Initialize TestScript
        public static void TestInitialize()
        {
            try
            {
                //Purpose: Opening DB Connection
                DatConnection.Open();
            }
            catch (Exception e)
            {
                throw new Exception("Unable To Open Database Connection: Please Try Again.");
            }
            //Purpose : Call Method To Select Browser
            BrowserSetup();
            //Purpose : Call Method To Start WebDriver
            WebDriverStart();
        }

        [AfterTestRun]
        // Purpose: To Dispose TestScript
        public static void TearDown()
        {
            try
            {
                //Purpose: Closing DB Connection
                DatConnection.Close();
            }
            catch (Exception e)
            {
                throw new Exception("Unable To Close WebDriver: Please Try Again.");
            }
            WebDriverStop();
            Thread.SetData(Thread.GetNamedDataSlot("webdriverInstance"), WebDriver);
            Thread.SetData(Thread.GetNamedDataSlot("backedseleniumInstance"), BackedSelenium);
        }

        //Purpose: Selecting Browser To Run Test
        public static void BrowserSetup()
        {
            if (Browser.Equals("IE"))
            {
                string ieDriverPath = ConfigurationManager.AppSettings["ieDriverPath"];
                var options = new InternetExplorerOptions { IntroduceInstabilityByIgnoringProtectedModeSettings = true };
                WebDriver = new InternetExplorerDriver(ieDriverPath, options);
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
            }
            if (Browser.Equals("Firefox"))
            {
                WebDriver = new FirefoxDriver();
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
            }
            if (Browser.Equals("Safari"))
            {
                WebDriver = new SafariDriver();
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
            }
        }
    }

WebdriverBackedSelenium in C# using WebDriver !

Using WebDriverBackedSelenium with different browser(s) setting contains the .NET bindings for the older, more procedural Selenium Remote Control (or Selenium RC) API, but implemented using the newer WebDriver technology. It does not require a running instance of the Selenium Server.

if (Browser.Equals("IE"))
            {
                string ieDriverPath = ConfigurationManager.AppSettings["ieDriverPath"];
                var options = new InternetExplorerOptions { IntroduceInstabilityByIgnoringProtectedModeSettings = true };
                WebDriver = new InternetExplorerDriver(ieDriverPath, options);
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
WebDriver.Navigate().GoToUrl(ConfigurationManager.AppSettings["browserUrl"]);

            }
            if (Browser.Equals("Firefox"))
            {
                WebDriver = new FirefoxDriver();
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
WebDriver.Navigate().GoToUrl(ConfigurationManager.AppSettings["browserUrl"]);
            }
            if (Browser.Equals("Safari"))
            {
                WebDriver = new SafariDriver();
                BackedSelenium = new WebDriverBackedSelenium(WebDriver, ConfigurationManager.AppSettings["browserUrl"]);
                BackedSelenium.Start();
WebDriver.Navigate().GoToUrl(ConfigurationManager.AppSettings["browserUrl"]);
            }

Tuesday, July 3, 2012

Using Scope Bindings with SpecFlow !

Hi, again I have learned a new thing in BDD using SpecFlow i.e. Scope Binding. Let’s take a look at how to do this with a very generic example. I’m going to be write tests for creating user and course, Create User and Create Course.  In both cases, I’m supposed to click on the link at the top of the page, although they’re different links that are the requirements are set in freeze, and will not re-write them as we can assume to understand the context based on the feature.
So, let’s write the add each feature and scenario.  We’re going to need two feature files.  One for checking the ‘Create New User’ link, and one for the ‘Create New Course’ link.

Feature: US58858 - User Creation
 In order to Creation of User 
 As a WS Admin
 I want to create user

Scenario: Create the new User using create user link 
Given I am on the User Creation Page
When  I clicked the link at top of the page
Then  I should see the "Create New User" popup
When  I create the user  with user details     
    | Field              | Value      |
    | txtLoginName       | Teacher    |
    | txtPassword        | pwd        
    | txtFirstName       | FN         |
    | txtLastName        | LN         |
    | txtEmail           | Email      |
Then  It should display successful message "New user created successfully."
And   I clicked on the Logout link to get logged out from the application

-------------------------------------------------

Feature: US58857 -  Course Creation
 In order to Creation of Course 
 As a WS Admin
 I want to create course(s) as a Empty Course, Container Course, Master Library 
and Master Course
Scenario Outline: Create the new Course using create course link
 Given I am on the Course Creation page
 When  I clicked the link at top of the page
 Then  I should see the "Create New Course" popup
 When  I creted the course as name with prefix 
 Then  It should display successful message "New course created successfully."
 Then  I should see the created  course
 Examples:
 | coursename |
 | BDDEC         |
 | BDDML        |
 | BDDCC         |
 | BDDMC       |
And  I clicked on the Logout link to get logged out from the application

Now, we’re going to add some context to each of these.  I’m going to add the @user tag to the scenarios in the US58858 - User Creation feature, while adding the @course tag to the scenarios in the US58857 -  Course Creation feature.

@user
Scenario: Create the new User using create user link 
Given I am on the User Creation Page
When  I clicked the link at top of the page
Then  I should see the "Create New User" popup
When  I create the user  with user details     
    | Field                          | Value        |
    | txtLoginName       | Teacher    |
    | txtPassword           | pwd           
    | txtFirstName         | FN              |
    | txtLastName         | LN              |
    | txtEmail                  | Email        |
Then  It should display successful message "New user created successfully."
And   I clicked on the Logout link to get logged out from the application
 --------------------------------------------------------------
@course
Scenario Outline: Create the new Course using create course link
 Given I am on the Course Creation page
 When  I clicked the link at top of the page
 Then  I should see the "Create New Course" popup
 When  I creted the course as name with prefix 
 Then  It should display successful message "New course created successfully."
 Then  I should see the created  course
 Examples:
 | coursename |
 | BDDEC           |
 | BDDML         |
 | BDDCC          |
 | BDDMC        |
And  I clicked on the Logout link to get logged out from the application
 
Now, let’s write the code for this the way that we normally would.  We can see that 
we have a builderror however.  This is because we have two of the exact same When’s.  
We need to find a way to separate these. We could, and should rewrite this, 
but as I said earlier, we were told that the way that they were written has to 
stay exactly as it was.  Instead, let’s use the Scope tags to add some context.  
The way that has worked best for me, is to start separating some of the code into folders, 
to keep everything organized.  We’re going to do this for the Create user and Create Course. 
Next, we’re going to add a stepdefinition file to each of those folders to help keep our 
code a little more organized.
Now that we have this setup, let’s write our When methods in their respective step 
definition files.  As a note, you can put any step definitions you want into any class 
so long as you add the [Binding] tagto the class.  Unless you have a need to duplicate code, 
I recommend only putting the steps that contain scope into these new classes, 
or at least, that’s what’s worked well for me so far.
 
 namespace Pegasus_SpecFlow
 {
 [Binding]
  public class CreateUserStepDefinitions : Helper
  {
 [When(@"I click the link at the top of the page")]
 public void WhenIClickTheLinkAtTheTopOfThePage()
 {
 Click(user);
 }
 }
 }
  
namespace Pegasus_SpecFlow
{
[Binding]
public class CreateCourseStepDefinitions : Helper
{
[When(@"I click the link at the top of the page")]
public void WhenIClickTheLinkAtTheTopOfThePage()
{
Click(course);
}
}
}
 
Now, we want to add our scope.  We can do this at the class level, or the step level.  
Normally, I would do this at the step level, but, as I was writing this, 
I learned that you can do this at the class level.
Scoped Binding at the class level
 
 namespace Pegasus_SpecFlow
 {
 [Binding]
 [Scope(Feature="US58858 - User Creation")]
 public class CreateUserStepDefinitions : Helper
 {
 [When(@"I click the link at the top of the page")]
 public void WhenIClickTheLinkAtTheTopOfThePage()
 {
 Click(user);
 }
 }
 }
OR
 
Scoped Binding at the method, or step level
 
namespace Pegasus_SpecFlow
{
[Binding]
public class CreateUserStepDefinitions : Helper
{
[When(@"I click the link at the top of the page"),
Scope(Tag="user")]
public void WhenIClickTheLinkAtTheTopOfThePage()
{
Click(user);
}
}
}
 
I’m pretty certain that our tests should run.  After a little bit of debugging, 
I make sure that my webdriver code works.  Then, find a way to make your test fail 
to ensure that it’s working correctly and you should be good to go.