How Ocaramba Captures Screenshots on Test Failure: Automatic vs. Assertion-Level Methods

Ocaramba captures screenshots through a coordinated set of classes that are invoked either automatically at the end of a test or explicitly when an assertion fails, using Selenium's ITakesScreenshot interface to store PNG files with timestamped filenames.

The accenture/ocaramba framework provides a robust mechanism to capture visual evidence when Selenium tests fail. Understanding how Ocaramba captures screenshots on test failure helps developers debug flaky UI tests and maintain comprehensive test reports. This article examines the source code to reveal the exact execution flow from failure detection to file persistence.

Automatic Screenshot Capture at the Test Level

Ocaramba automatically detects test failures through the DriverContext.IsTestFailed flag and triggers screenshot capture during test cleanup. This approach ensures that every failing test produces visual evidence without requiring explicit code in the test body.

The Test Failure Detection Flow

At the end of every test, the framework invokes TestBase.SaveTestDetailsIfTestFailed to check the failure state. If DriverContext.IsTestFailed evaluates to true, the method calls DriverContext.TakeAndSaveScreenshot(), which coordinates the actual image capture and storage.

// OcarambaLite/TestBase.cs
public string[] SaveTestDetailsIfTestFailed(DriverContext driverContext)
{
    if (driverContext.IsTestFailed)
    {
        var screenshots = driverContext.TakeAndSaveScreenshot();
        var pageSource = this.SavePageSource(driverContext);
        // …
    }
    return null;
}

The TakeAndSaveScreenshot method (implemented in DriverContextHelper.cs) acts as the orchestrator. It first checks the global configuration, then delegates to TakeScreenshot() for image acquisition and SaveScreenshot() for file persistence.

Integration with TearDown Methods

To enable automatic capture, tests inherit from ProjectTestBase and invoke the save method during teardown:

public class MyTest : ProjectTestBase
{
    [Test]
    public void Example()
    {
        // test steps …
    }

    [TearDown]
    public void Cleanup()
    {
        var attachments = this.SaveTestDetailsIfTestFailed(this.DriverContext);
        // Attachments can be added to the test report here
    }
}

Assertion-Level Screenshot Capture with Verify.That

For scenarios requiring screenshots only when specific assertions fail, Ocaramba provides the Verify.That helper method. This approach captures the browser state immediately at the point of failure rather than waiting for the test to complete.

The Verify class wraps assertion blocks and accepts boolean flags to control screenshot and page source capture. When an exception occurs and enableScreenShot is true, the method calls driverContext.TakeAndSaveScreenshot() inside the catch block before logging the error.

// OcarambaLite/Verify.cs (excerpt)
public static void That(DriverContext driverContext, Action myAssert,
                       bool enableScreenShot, bool enableSavePageSource)
{
    try
    {
        myAssert();
    }
    catch (Exception e)
    {
        if (enableScreenShot) { driverContext.TakeAndSaveScreenshot(); }
        if (enableSavePageSource) { driverContext.SavePageSource(driverContext.TestTitle); }
        driverContext.VerifyMessages.Add(new ErrorDetail(null, DateTime.Now, e));
        Logger.Error(...);
    }
}

This pattern is particularly useful for data-driven tests where you need visual evidence only for specific failing iterations:

[Test]
public void VerifyWithScreenshot()
{
    Verify.That(this.DriverContext,
        () => Assert.IsTrue(false, "Force failure"),
        enableScreenShot: true,
        enableSavePageSource: false);
}

Core Screenshot Implementation in DriverContext

The actual screenshot acquisition occurs in DriverContext.cs, which interacts directly with Selenium WebDriver interfaces. The implementation separates concerns between taking the screenshot and saving it to disk.

Capturing the Image

The TakeScreenshot method casts the active WebDriver to ITakesScreenshot and invokes GetScreenshot():

// OcarambaLite/DriverContext.cs
public Screenshot TakeScreenshot()
{
    var screenshotDriver = (ITakesScreenshot)this.driver;
    return screenshotDriver.GetScreenshot();
}

Persisting the File

The SaveScreenshot method handles filename generation, path sanitization, and file writing. It creates timestamped filenames and uses regular expressions to replace invalid characters with underscores:

// OcarambaLite/DriverContext.cs
public string SaveScreenshot(ErrorDetail errorDetail, string folder, string title)
{
    var fileName = $"{title}_{errorDetail.DateTime:yyyy-MM-dd HH-mm-ss-fff}_browser.png";
    var filePath = Path.Combine(folder, Regex.Replace(fileName, "[^0-9a-zA-Z._]+", "_"));
    errorDetail.Screenshot.SaveAsFile(filePath);
    return filePath;
}

Configuration: Enabling and Disabling Screenshots

Ocaramba provides a global configuration switch to control screenshot behavior without code changes. The BaseConfiguration.SeleniumScreenShotEnabled property reads from appsettings.json and defaults to true when unspecified.

// OcarambaLite/BaseConfiguration.cs (excerpt)
public static bool SeleniumScreenShotEnabled
{
    get
    {
        var setting = Builder["appSettings:SeleniumScreenShotEnabled"];
        return string.IsNullOrEmpty(setting) ? true :
               setting.Equals("true", StringComparison.OrdinalIgnoreCase);
    }
}

When this setting is false, the TakeAndSaveScreenshot method returns an empty array immediately, bypassing all capture logic. To disable screenshots globally:

// appsettings.json
{
  "appSettings": {
    "SeleniumScreenShotEnabled": "false"
  }
}

Element-Level Screenshots for Specific UI Components

For cases requiring a screenshot of a single WebElement rather than the full page—such as elements inside iframes or specific modal dialogs—Ocaramba provides the TakeScreenShot helper class.

The TakeScreenShotOfElement method casts the element to ITakesScreenshot and saves it independently of the driver-level screenshot:

// OcarambaLite/Helpers/TakeScreenShot.cs
public static string TakeScreenShotOfElement(IWebElement element, string folder, string screenshotName)
{
    var screenshot = ((ITakesScreenshot)element).GetScreenshot();
    var filePath = Path.Combine(folder, screenshotName);
    screenshot.SaveAsFile(filePath);
    return filePath;
}

Usage example:

var element = driver.FindElement(By.Id("logo"));
string folder = Path.Combine(Directory.GetCurrentDirectory(),
                             BaseConfiguration.ScreenShotFolder);
string screenshotPath = TakeScreenShot.TakeScreenShotOfElement(
                           element, folder, "logo.png");

Summary

  • Test-level capture occurs automatically via TestBase.SaveTestDetailsIfTestFailed checking DriverContext.IsTestFailed during teardown.
  • Assertion-level capture happens immediately inside Verify.That when enableScreenShot is true and an exception occurs.
  • Core implementation resides in DriverContext.TakeScreenshot and SaveScreenshot, which use Selenium's ITakesScreenshot interface and sanitize filenames with regex.
  • Global control is provided by BaseConfiguration.SeleniumScreenShotEnabled, configurable via appsettings.json.
  • Element-specific capture is available through TakeScreenShot.TakeScreenShotOfElement for targeted visual verification.

Frequently Asked Questions

How do I enable automatic screenshots in Ocaramba?

Set SeleniumScreenShotEnabled to true in your appsettings.json file or ensure the key is omitted (it defaults to true). Then ensure your test class calls SaveTestDetailsIfTestFailed in the [TearDown] method to trigger capture when IsTestFailed is true.

Can I capture screenshots for specific assertions only?

Yes. Use the Verify.That method with enableScreenShot: true instead of standard NUnit assertions. This captures the screenshot immediately when that specific assertion fails, rather than at the end of the test.

Where does Ocaramba save screenshot files?

Screenshots are saved to the directory specified by BaseConfiguration.ScreenShotFolder (typically configured in appsettings.json). The filename format is {TestTitle}_{yyyy-MM-dd HH-mm-ss-fff}_browser.png with invalid characters replaced by underscores.

Does Ocaramba support screenshot capture for individual web elements?

Yes. The TakeScreenShot.TakeScreenShotOfElement method in OcarambaLite/Helpers/TakeScreenShot.cs allows capturing specific IWebElement instances, which is useful for elements inside iframes or when you need to isolate a specific component.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →