Table of Contents

Class BrowseTheWeb

Namespace
CSF.Screenplay.Selenium
Assembly
CSF.Screenplay.Selenium.dll

Screenplay ability which allows an Actor to browse the web using a Selenium WebDriver.

public class BrowseTheWeb : ICanReport, IDisposable
Inheritance
BrowseTheWeb
Implements
Inherited Members
Extension Methods

Examples

Imagine you have configuration like the following in your appsettings.json, following the Microsoft Options Pattern, with a configuration file.

{
  "WebDriverFactory": {
    "DriverConfigurations": {
      "LocalChrome": { "DriverType": "ChromeDriver" },
      "LocalFirefox": { "DriverType": "FirefoxDriver" },
    },
  }
}

You could now use the following technique when you configure your Actor with this ability. The following example shows how to do this using an IPersona.

In addition to the configuration above and the persona shown below, run this code whilst an environment variable named WebDriverFactory__SelectedConfiguration is defined and set to LocalFirefox. This environment variable selects which of the two configured WebDrivers is used (in this case, Firefox). Developers may use the configuration to store a library of available WebDriver configurations, and use a single environment variable to switch between them at execution time.

using CSF.Extensions.WebDriver;
using CSF.Screenplay.Selenium;

public class Webster(IGetsWebDriver webDriverFactory) : IPersona
{
    public string Name => "Webster";

    public Actor GetActor(Guid performanceIdentity)
    {
        var webster = new Actor(Name, performanceIdentity);
        var browseTheWeb = new BrowseTheWeb(webDriverFactory);
        webster.IsAbleTo(browseTheWeb);
        return webster;
    }
}

Remarks

The 'Browse the Web' ability wraps a Selenium WebDriver and provides access to it via the WebDriver property. It also provide access to the options which were used to create the web driver, via the DriverOptions property. Following Selenium's architecture, both of these properties are abstract/interfaces and offer only the base/lowest common denominator types. Often, this is sufficient. Developers may check for other Selenium-related interfaces if they are required, using patterns such as the following:

if(browseTheWeb.WebDriver is OpenQA.Selenium.ISupportsPrint printingDriver)
    /* ... exercise printingDriver ... */

This ability makes use of the Universal Web Driver Factory from the CSF.Extensions.WebDriver package. This provides a configurable manner, using the .NET Options pattern, to specify the WebDriver without hard-coding the choice.

The Selenium Extension to Screenplay makes the IGetsWebDriver web driver factory available via dependency injection. The recommended way in which to grant an Actor this ability is via an IPersona. The web driver factory may be safely constructor-injected into the persona class.

Constructors

BrowseTheWeb(IGetsWebDriver, string)

Initializes a new instance of the BrowseTheWeb class.

public BrowseTheWeb(IGetsWebDriver webDriverFactory, string webDriverName = null)

Parameters

webDriverFactory IGetsWebDriver

A universal WebDriver factory instance

webDriverName string

An optional name, specifying the WebDriver configuration (within those available in the factory) to use.

Remarks

It is quite normal to omit the webDriverName parameter, leaving it with its default null value. If the WebDriver name is omitted or null then the GetDefaultWebDriver(Action<DriverOptions>) method will be used to get the WebDriver. This requires that the WebDriver factory is configured with a default driver. This could be done via the SelectedConfiguration property of the JSON configuration, or via an environment variable (see the example code in the remarks to this class) or any other way which the Microsoft Configuration Pattern supports. Alternatively, to activate a specific named configuration, you may specify the WebDriver name here.

It is normal to retrieve the webDriverFactory parameter via Dependency Injection. The Selenium Extension to Screenplay makes the factory available in that manner.

Properties

DriverOptions

Gets the WebDriver options which were used to create WebDriver.

public DriverOptions DriverOptions { get; }

Property Value

DriverOptions

Remarks

These options are for reference only; there is no effect on the WebDriver instance if you modify them. The purpose of this property is to allow developers to inspect the options which were used to create the WebDriver.

WebDriver

Gets the Selenium WebDriver associated with the current ability instance.

public IWebDriver WebDriver { get; }

Property Value

IWebDriver

Methods

Dispose()

public void Dispose()

Dispose(bool)

Disposes the resources used by the BrowseTheWeb class.

protected virtual void Dispose(bool disposing)

Parameters

disposing bool

A boolean value indicating whether the method is called from the Dispose method.

GetReportFragment(Actor, IFormatsReportFragment)

Gets a fragment of a Screenplay report, specific to the execution (performables) or gaining (abilities) of the current instance, for the specified actor.

public ReportFragment GetReportFragment(Actor actor, IFormatsReportFragment formatter)

Parameters

actor Actor

An actor for whom to write the report fragment

formatter IFormatsReportFragment

A report-formatting service

Returns

ReportFragment

A human-readable report fragment.

Examples

For a performable which clicks a button (where the button itself has been constructor-injected into the performable instance), then a suitable return value might be a formatted string such as {Actor name} clicks {Button}, where the two placeholders indicated by braces: {} are substituted with the actor's Name and a string representation of the button.

For a performable which reads the temperature from a thermometer, a suitable return value might be a string in the format {Actor name} reads the temperature.

For an ability which allows the actor to wash dishes then a suitable return value might be a string in the format {Actor name} is able to wash the dishes.

Remarks

Implementers should return a string which indicates that the named actor is performing (present tense) the performable, for types which also implement a performable interface. For types which represent abilities, the implementer should return a string which indicates that the named actor is able to do something. In particular for abilities, to make them easily recognisable in reports, it helps to stick to the convention {Actor name} is able to {Ability summary}.

For performables which return a value (Questions, or Tasks which behave like Questions), there is no need to include the returned value within the report fragment. The framework will include the return value in the report and will format it via a different mechanism.

Good report fragments are concise. Be aware that report fragments for Tasks (which are composed from other performables) do not need to go into detail about what they do. Users reading Screenplay reports are able to drill-down into Tasks to see what they are composed from, so if the user is curious as to what the task does, it is easy to discover. It is also strongly recommended to avoid periods (full stops) at the end of a report fragment. Whilst report fragments tend to be complete sentences, punctuation like this is distracting and reports are seldom presented as paragraphs of prose.

See Also