Milo
Milo

Reputation: 3453

C# Extending Selenium Webdriver Class

I would like to add a static string property that will track the name of the current test running. I figured the best way to go about this was to use the WebDriver since it is the only object that is carried throughout all of my page objects.

Is there a way to extend the WebDriver class to add a string property that I can set?

EDIT: Since WebDriver uses the IWebDriver interface rather would I extend the interface perhaps?

EDIT #2: Adding example of what I currently have to load my WebDriver:

protected static NLog.Logger _logger = LogManager.GetCurrentClassLogger();
protected static IWebDriver _driver;

/// <summary>
/// Spins up an instance of FireFox webdriver which controls the browser using a
/// FireFox plugin using a stripped down FireFox Profile.
/// </summary>
protected static void LoadDriver()
{
    ChromeOptions options = new ChromeOptions();
    try
    {
        var profile = new FirefoxProfile();
        profile.SetPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream doc xls pdf txt");

        _driver = new FirefoxDriver(profile);
        _driver.Navigate().GoToUrl("http://portal.test-web01.lbmx.com/login?redirect=%2f");
    }
    catch(Exception e)
    {
        Console.WriteLine(e.Message);
        throw;
    }
}

Upvotes: 3

Views: 6778

Answers (4)

Leon Barkan
Leon Barkan

Reputation: 2703

Ok let's stop the half answer practice (That is the full implementation of generic IWebDriver) after that you can call all the regular methods like you use in standard driver + you have your additional CurrentTest variable.

you can add more constructors for best compatibility.

class MyWebDriver<T> where T : IWebDriver, new()
{
    IWebDriver driver;
    public string CurrentTest { get; set; }

    public MyWebDriver()
    {
        driver = new T();
    }

    public void Dispose()
    {
        this.driver.Dispose();
    }

    public IWebElement FindElement(By by)
    {
        return this.driver.FindElement(by);
    }

    public ReadOnlyCollection<IWebElement> FindElements(By by)
    {
        return this.driver.FindElements(by);
    }

    public void Close()
    {
        this.driver.Close();
    }

    public void Quit()
    {
        this.driver.Quit();
    }

    public IOptions Manage()
    {
        return this.driver.Manage();
    }

    public INavigation Navigate()
    {
        return driver.Navigate();
    }

    public ITargetLocator SwitchTo()
    {
        return this.SwitchTo();
    }

    public string Url
    {
        get
        {
            return this.driver.Url;
        }
        set
        {
            this.driver.Url = value;
        }
    }

    public string Title
    {
        get
        {
            return this.driver.Title;
        }
    }

    public string PageSource
    {
        get
        {
            return this.driver.PageSource;
        }
    }

    public string CurrentWindowHandle
    {
        get
        {
            return this.driver.CurrentWindowHandle;
        }
    }

    public ReadOnlyCollection<string> WindowHandles
    {
        get
        {
            return this.WindowHandles;
        }
    }
}

public class MyTest
{
    public void main()
    {
        MyWebDriver<FirefoxDriver> driver = new MyWebDriver<FirefoxDriver>();
        driver.CurrentTest = "Entering to google website with Firefox Driver";
        driver.Navigate().GoToUrl("www.google.com");
    }
}

Upvotes: 5

Brendan
Brendan

Reputation: 4659

Just use a sub class that has WebDriver as its parent:

public class MyWebDriver : WebDriver
{
    private string _currentTest;
}

Then you can use MyWebDriver everywhere and set _currentTest as needed.

Upvotes: -2

Leon Barkan
Leon Barkan

Reputation: 2703

what if you do something like

class MyWebDriver
{
   private IWebDriver driver;
   private static string CurrentTest;
   ....
   //make constractors / getters, setters
}

execution

MyWebDriver d = new MyWebDriver(....)
...

Upvotes: 1

Nick Spicer
Nick Spicer

Reputation: 2707

You will need to wrap the WebDriver using the "Decorator" design pattern.

public class MyWebDriver : IWebDriver
{
    private IWebDriver webDriver;
    public string CurrentTest { get; set; }

    public MyWebDriver(IWebDriver webDriver)
    {
        this.webDriver = webDriver
    }

    public Method1()
    {
        webDriver.Method1();
    }

    public Method2()
    {
        webDriver.Method2();
    }

    ...
}

And then pass in whichever driver you are using at the time.

var profile = new FirefoxProfile();
MyWebDriver driver = new MyWebDriver(new FirefoxDriver(profile));

This way you are delegating the interface methods of IWebDriver to FirefoxDriver but can add whatever additions are appropriate.

Upvotes: 3

Related Questions