Skip to content

WebBrowserFlags

Craig Fowler edited this page Feb 2, 2018 · 4 revisions

Web browser flags

A difficulty faced by testers designing for cross-browser testing is that some web browsers quite simply behave differently to others.

As an example, no version of Microsoft Internet Explorer has any form of 'native' support for the HTML 5 <input type="date"> element. To IE, this works exactly the same way as an <input type="text"> element. Other browsers though will produce a built-in calendar/date-chooser when this element is focussed, or might offer a masked date-entry field, respecting the platform's current culture.

What are browser flags?

Differences like those in the example above can cause headaches when attempting to write UI test logic which interacts with pages; this is where browser flags may assist. Flags are simply string identifiers which may be attached to instances of IWebDriver and queried via the interface IHasFlags:

var flags = myWebDriver as IHasFlags;
if(flags.HasFlag("UseInputTypeDateAsText"))
{
  // Logic to interact with the element as a text field
}
else if(flags.HasFlag("UseInputTypeDateAsCultureAwareDate"))
{
  // Logic to interact with the element as a culture-aware date string
}
// Further cases ...

Browser flags are somewhat similar to web driver Capabilities, except:

  • They are completely arbitrary, any string is acceptable
  • Flags do not have associated values, they are all boolean (present or not present)

How browser flags are configured

Browser flags are essentially abstractions for combinations of browser name, version and (optionally) platform. The information about which flags a given web driver may have is supplied at the time the web driver is created.

Flags are stored within definition files which are JSON-formatted, and may contain a number of definitions each. Each definition within a file must (at minimum) contain a browser name and one or more flags which do or do not apply to that browser. They may (and usually do) also contain a min/max version and may also optionally be limited by platforms (for scenarios where a browser behaves differently on different operating systems). See the documentation comments on the FlagsDefinition class for more information.

When a web driver is created from a factory, it is queried to determine its true browser name, version and platform, and then this information is matched against all of the available flags definitions. All of the definitions which match the web driver are then queried for their flags to add (include) and flags to remove (exclude); this then creates a list of distinct flags to apply to the web driver.

Flags best practice

Avoid using "Removal"

Avoid writing flags definition files which rely heavily on removing flags, and certainly avoid open-ended version ranges which remove flags.

Flags are removed after all flags have been added, which means that a removed flag will always override an added flag. Removed flags are a mechanism to allow a hand-crafted definitions file to override a compiled set of definitions (perhaps embedded into an assembly as a resource). This may be neccesary if a new browser version is released to which a flag no longer applies, but the compiled/curated flags definitions have not yet been updated.

Name flags for behaviours, not browsers

The names of flags should describe a browser behaviour, such as MustSendCtrlClickForHtmlSelectMultiple. Some browsers accept a click in order to select/deselect single options within a <select multiple>, wheras others require a modifier key to be pressed to deal with single options. Do not name flags after the browser, such as IsInternetExplorer10; this limits the usefulness of the flag.

Avoid duplicating capabilities

Beware of creating flags which are already handled by browser capabilities. The capabilities mechanism is OK for handling all of the information which it currently handles. The purpose of flags is to be able to retain arbitrary data. Many implementations of IHasCapabilities will not permit the addition of arbitrary/unsupported capabilities, which is why flags were created.

Clone this wiki locally