# How Ocaramba Manages WebDriver Instances: A Deep Dive into DriverContext

> Discover how Ocaramba manages WebDriver instances efficiently with DriverContext. Centralize browser initialization, configuration, and cleanup for streamlined automation.

- Repository: [Accenture/ocaramba](https://github.com/accenture/ocaramba)
- Tags: deep-dive
- Published: 2026-02-23

---

**Ocaramba centralizes WebDriver lifecycle management in the `DriverContext` class, which handles browser initialization, configuration, and cleanup through a single, reusable API.**

The `accenture/ocaramba` test automation framework abstracts the complexity of Selenium WebDriver management into a dedicated context class. Understanding how Ocaramba manages WebDriver instances helps you write cleaner, more maintainable tests while leveraging built-in support for multiple browsers, remote grids, and mobile platforms.

## Centralized Driver Management with DriverContext

All WebDriver lifecycle operations in Ocaramba reside in [`OcarambaLite/DriverContext.cs`](https://github.com/accenture/ocaramba/blob/main/OcarambaLite/DriverContext.cs). This class acts as the single owner of the Selenium `IWebDriver` instance, eliminating the need for test code to handle raw driver construction or disposal.

The `DriverContext` exposes a public read-only property `Driver` of type `IWebDriver`, which test methods access after initialization. This design pattern ensures that configuration, event logging, and cleanup logic remain decoupled from test business logic.

## Initializing WebDriver Instances in Ocaramba

### The Start() Method and Browser Selection

The `Start()` method in `DriverContext` serves as the entry point for driver initialization. It uses a switch statement to delegate to browser-specific methods based on the `BaseConfiguration.TestBrowser` setting:

```csharp
public void Start()
{
    switch (BaseConfiguration.TestBrowser)
    {
        case BrowserType.Firefox:      this.StartFirefox();      break;
        case BrowserType.Chrome:       this.StartChrome();       break;
        case BrowserType.Edge:         this.StartEdge();         break;
        case BrowserType.Safari:       this.StartSafari();       break;
        case BrowserType.RemoteWebDriver: this.SetupRemoteWebDriver(); break;
        case BrowserType.BrowserStack:   this.SetupBrowserStack();  break;
        case BrowserType.Appium:          this.StartAppium();       break;
        default: throw new NotSupportedException(
                 $"Driver {BaseConfiguration.TestBrowser} is not supported");
    }

    if (BaseConfiguration.EnableEventFiringWebDriver)
        this.driver = new MyEventFiringWebDriver(this.driver);
}

```

This architecture supports Firefox, Chrome, Edge (Chromium), Safari, Internet Explorer, RemoteWebDriver for Selenium Grid, BrowserStack cloud testing, and Appium for mobile automation.

### Configuring Driver Options

Each browser-specific method constructs its respective `*Options` object (e.g., `ChromeOptions`, `FirefoxOptions`) using private properties in `DriverContext`. These properties read configuration values from `App.config` or [`appsettings.json`](https://github.com/accenture/ocaramba/blob/main/appsettings.json) through `BaseConfiguration` and [`OcarambaLite/DriversCustomSettings.cs`](https://github.com/accenture/ocaramba/blob/main/OcarambaLite/DriversCustomSettings.cs).

Configuration includes driver binary locations, browser executable paths, proxy settings, custom preferences, extensions, command-line arguments, and timeouts. The `SetDriverOptions()` method applies these settings consistently across browser types.

### Event-Firing Driver Wrapper

When `BaseConfiguration.EnableEventFiringWebDriver` is set to `true`, `DriverContext` wraps the initialized driver in `MyEventFiringWebDriver`. This enables automatic logging of Selenium events such as element clicks, navigation, and exceptions without requiring explicit logging calls in test code.

## Accessing and Using the Driver in Tests

Test classes typically inherit from a base class that manages the `DriverContext` lifecycle. The pattern found in [`Ocaramba.Tests.NUnit/ProjectTestBase.cs`](https://github.com/accenture/ocaramba/blob/main/Ocaramba.Tests.NUnit/ProjectTestBase.cs) demonstrates best practices:

```csharp
public class ProjectTestBase
{
    private readonly DriverContext driverContext = new DriverContext();

    [SetUp]
    public void SetUp()
    {
        driverContext.Start();
        driverContext.WindowMaximize();
        driverContext.DeleteAllCookies();
    }

    [TearDown]
    public void TearDown()
    {
        if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
        {
            var screenshot = driverContext.TakeScreenshot();
            // Save screenshot for debugging
        }
        
        driverContext.Stop();
    }

    protected IWebDriver Driver => driverContext.Driver;
}

```

Tests access the initialized driver through the `Driver` property, while the base class handles all setup and teardown operations. This ensures consistent browser state and proper resource cleanup across the test suite.

## Cleaning Up WebDriver Instances

The `Stop()` method in `DriverContext` ensures clean termination of browser processes. It disposes any driver service instances (such as `ChromeDriverService` or `EdgeDriverService`) and calls `driver.Quit()` to close all browser windows and terminate the WebDriver session.

This centralized cleanup prevents resource leaks and orphaned browser processes that commonly occur when tests fail to properly dispose of driver instances.

## Summary

- **Centralized management**: `DriverContext` in [`OcarambaLite/DriverContext.cs`](https://github.com/accenture/ocaramba/blob/main/OcarambaLite/DriverContext.cs) owns the single `IWebDriver` instance per test context.
- **Configuration-driven**: `BaseConfiguration` and [`DriversCustomSettings.cs`](https://github.com/accenture/ocaramba/blob/main/DriversCustomSettings.cs) populate browser options from `App.config` or [`appsettings.json`](https://github.com/accenture/ocaramba/blob/main/appsettings.json).
- **Multi-browser support**: The `Start()` method supports Chrome, Firefox, Edge, Safari, RemoteWebDriver, BrowserStack, and Appium through a unified API.
- **Event logging**: Optional `MyEventFiringWebDriver` wrapper enables automatic Selenium event logging without test code changes.
- **Lifecycle safety**: `Start()` initializes and configures drivers; `Stop()` ensures proper disposal of services and browser processes.

## Frequently Asked Questions

### How do I configure which browser Ocaramba uses for tests?

Set the `TestBrowser` key in your `App.config` or [`appsettings.json`](https://github.com/accenture/ocaramba/blob/main/appsettings.json) file to the desired browser type. Valid values include `Chrome`, `Firefox`, `Edge`, `Safari`, `RemoteWebDriver`, `BrowserStack`, and `Appium`. The `DriverContext.Start()` method reads this value from `BaseConfiguration.TestBrowser` and initializes the appropriate driver.

### Can I use Ocaramba with Selenium Grid or cloud providers like BrowserStack?

Yes. Set `TestBrowser` to `RemoteWebDriver` for Selenium Grid connections or `BrowserStack` for BrowserStack cloud testing. The `SetupRemoteWebDriver()` and `SetupBrowserStack()` methods in `DriverContext` handle the creation of `RemoteWebDriver` instances with capabilities derived from your configuration file, including grid URL, credentials, and desired capabilities.

### How does Ocaramba handle driver cleanup if a test fails?

The `Stop()` method in `DriverContext` is designed to run during test teardown, typically in a `[TearDown]` or `[OneTimeTearDown]` method. It disposes any driver services and calls `driver.Quit()` regardless of test outcome. For capturing failure evidence, you can call `TakeScreenshot()` before `Stop()` to save a screenshot of the browser state at failure time, as demonstrated in [`ProjectTestBase.cs`](https://github.com/accenture/ocaramba/blob/main/ProjectTestBase.cs).

### What is the purpose of the EventFiringWebDriver in Ocaramba?

When `EnableEventFiringWebDriver` is set to `true` in configuration, `DriverContext` wraps the base driver in `MyEventFiringWebDriver` after initialization. This wrapper class extends Selenium's `EventFiringWebDriver` to automatically log actions like element clicks, navigation events, and exceptions without requiring explicit logging code in your test methods. It provides non-invasive observability for debugging and audit trails.