Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CSF.Screenplay.Docs/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
"_appTitle": "Screenplay",
"_enableSearch": true,
"pdf": false
}
},
"xref": [
"https://www.selenium.dev/selenium/docs/api/dotnet/xrefmap.yml",
"https://csf-dev.github.io/CSF.Extensions.WebDriver/xrefmap.yml"
]
}
}
7 changes: 7 additions & 0 deletions CSF.Screenplay.Docs/docs/Assets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
uid: AssetsArticle
---

# Report assets

TODO: Write this docco page; #301
2 changes: 1 addition & 1 deletion CSF.Screenplay.Docs/docs/GettingReports.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The default filename includes a representation of the current timestamp, so each
This path may be altered by specifying a different set of options to the [`AddScreenplay`] service collection extension method.

[`ScreenplayOptions.ReportPath`]: xref:CSF.Screenplay.ScreenplayOptions.ReportPath
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{CSF.Screenplay.ScreenplayOptions})
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection)

## Converting JSON to a human-readable report

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ If Screenplay is not being used for testing, then the consuming logic has the fo

[Performance]: xref:CSF.Screenplay.IPerformance
[`Screenplay`]: xref:CSF.Screenplay.Screenplay
[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{CSF.Screenplay.ScreenplayOptions})
[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection})
[`BeginScreenplay`]: xref:CSF.Screenplay.Screenplay.BeginScreenplay
[`ExecuteAsPerformanceAsync<TPerformance>`]: xref:CSF.Screenplay.ScreenplayExtensions.ExecuteAsPerformanceAsync``1(CSF.Screenplay.Screenplay,System.Collections.Generic.IList{CSF.Screenplay.Performances.IdentifierAndName},System.Threading.CancellationToken)
[`ExecuteAsPerformance`]: xref:CSF.Screenplay.ScreenplayExtensions.ExecuteAsPerformance(CSF.Screenplay.Screenplay,System.Func{System.IServiceProvider,System.Nullable{System.Boolean}},System.Collections.Generic.IList{CSF.Screenplay.Performances.IdentifierAndName},System.Threading.CancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
There are two techniques to add dependency services to Screenplay.
You may either integrate Screenplay into an existing container for your application or tests or you may add additional services via the static [`Create`] factory method.

[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{CSF.Screenplay.ScreenplayOptions})
[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection})

## Integrating with an existing container

Expand All @@ -29,7 +29,7 @@ var screenplay = Screenplay.Create(services => {
});
```

[`Screenplay.Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{CSF.Screenplay.ScreenplayOptions})
[`Screenplay.Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection})

## A reminder on lifetime scopes

Expand Down
4 changes: 2 additions & 2 deletions CSF.Screenplay.Docs/docs/dependencyInjection/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Alternatively you may create an instance of [`Screenplay`] which uses its own se

[dependency injection]: https://en.wikipedia.org/wiki/Dependency_injection
[container]: xref:Microsoft.Extensions.DependencyInjection.IServiceCollection
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{CSF.Screenplay.ScreenplayOptions})
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection)
[`Screenplay`]: xref:CSF.Screenplay.Screenplay
[`Screenplay.Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{CSF.Screenplay.ScreenplayOptions})
[`Screenplay.Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection})

## Scopes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ Terminologies differ between testing frameworks; the word [Scenario] is used to

[`Screenplay`]: xref:CSF.Screenplay.Screenplay
[Scenarios]: ../../glossary/Scenario.md
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{CSF.Screenplay.ScreenplayOptions})
[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{CSF.Screenplay.ScreenplayOptions})
[`AddScreenplay`]: xref:CSF.Screenplay.ScreenplayServiceCollectionExtensions.AddScreenplay(Microsoft.Extensions.DependencyInjection.IServiceCollection)
[`Create`]: xref:CSF.Screenplay.Screenplay.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection})
[`IGetsScreenplay`]: xref:CSF.Screenplay.IGetsScreenplay
[`BeginScreenplay()`]: xref:CSF.Screenplay.Screenplay.BeginScreenplay
[`CompleteScreenplay()`]: xref:CSF.Screenplay.Screenplay.CompleteScreenplay
Expand Down
2 changes: 1 addition & 1 deletion CSF.Screenplay.Docs/docs/extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ This page lists the officially-supported **[Screenplay Extensions]**.
* **[Selenium](selenium/index.md)**: _remote control Web Browsers using Selenium Web Driver_
* **[Web APIs](webApis/index.md)**: _communicate with Web APIs with an HTTP Client_

[Screenplay Extensions]: ../../glossary/Extension.md
[Screenplay Extensions]: ../../glossary/Extension.md
72 changes: 72 additions & 0 deletions CSF.Screenplay.Docs/docs/extensions/selenium/Actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Selenium actions

The Selenium extension for Screenplay provides numerous [Actions], each of which represents one of the smallest possible interactions with a web browser/page.
Broadly, these actions fall into the following categories:

* Actions which work with HTML elements (targets), such as _"click on a specified element"_ or _"type some keys into an input box"_. These actions will always require [a target] as a parameter.
* Actions which interact directly with the web browser, such as _"take a screenshot"_ or _"clear the cookies for the current domain"_.
* Actions which represent waiting for something, such as _"wait until the progress bar reaches 100%"_ or _"wait until the shopping cart items are visible"_.

Recall that Screenplay Actions _do something_ without getting any result.
To interrogate a web page (to observe it in some manner), use [one of the Selenium extension's Questions].
Below is a summary of each of these actions' usage, with a link to their detailed documentation page.

[Actions]: ../../../glossary/Action.md
[a target]: Targets.md
[one of the Selenium extension's Questions]: Questions.md

## Actions that work with targets

| Action | Usage |
| ------ | ----- |
| [`ClearTheContents`] | Remove/clear all text from the specified element, such as an `<input>` |
| [`Click`] | Click on the specified element |
| [`DeselectByIndex`] | Deselect an option from the specified `<select>` element by its index |
| [`DeselectByText`] | Deselect an option from the specified `<select>` element by its displayed text |
| [`DeselectByValue`] | Deselect an option from the specified `<select>` element by its underlying value |
| [`DeselectAll`] | Deselects every option from the specified `<select>` element |
| [`SelectByIndex`] | Select an option from the specified `<select>` element by its index |
| [`SelectByText`] | Select an option from the specified `<select>` element by its displayed text |
| [`SelectByValue`] | Select an option from the specified `<select>` element by its underlying value |
| [`SendKeys`] | Type text (send keystrokes) whilst a specified element has focus |

[`ClearTheContents`]: xref:CSF.Screenplay.Selenium.Actions.ClearTheContents
[`Click`]: xref:CSF.Screenplay.Selenium.Actions.Click
[`DeselectByIndex`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByIndex
[`DeselectByText`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByText
[`DeselectByValue`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByValue
[`DeselectAll`]: xref:CSF.Screenplay.Selenium.Actions.DeselectAll
[`SelectByIndex`]: xref:CSF.Screenplay.Selenium.Actions.SelectByIndex
[`SelectByText`]: xref:CSF.Screenplay.Selenium.Actions.SelectByText
[`SelectByValue`]: xref:CSF.Screenplay.Selenium.Actions.SelectByValue
[`SendKeys`]: xref:CSF.Screenplay.Selenium.Actions.SendKeys

## Actions which work with the browser

| Action | Usage |
| ------ | ----- |
| [`ClearCookies`] | Clear the web browser cookies for the current site (domain) |
| [`ClearLocalStorage`] | Clear the web browser [local storage] for the current site (domain) |
| [`DeleteTheCookie`] | Delete a single named cookie |
| [`ExecuteJavaScript`] | Executes a JavaScript directly in the browser |
| [`OpenUrl`] | Directs the browser to open a specified URL |
| [`SaveScreenshot`] | Saves a screenshot to a file |

[`OpenUrl`]: xref:CSF.Screenplay.Selenium.Actions.OpenUrl
[`SaveScreenshot`]: xref:CSF.Screenplay.Selenium.Actions.SaveScreenshot
[`ClearCookies`]: xref:CSF.Screenplay.Selenium.Actions.ClearCookies
[`ClearLocalStorage`]: xref:CSF.Screenplay.Selenium.Actions.ClearLocalStorage
[`DeleteTheCookie`]: xref:CSF.Screenplay.Selenium.Actions.DeleteTheCookie
[`ExecuteJavaScript`]: xref:CSF.Screenplay.Selenium.Actions.ExecuteJavaScript
[local storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

## Actions which wait

| Action | Usage |
| ------ | ----- |
| [`Wait`] | Pauses the [Performance] until a condition is true |
| [`WaitForSomeTime`] | Pauses the [Performance] for an arbitrary amount of time |

[Performance]: xref:CSF.Screenplay.IPerformance
[`Wait`]: xref:CSF.Screenplay.Selenium.Actions.Wait
[`WaitForSomeTime`]: xref:CSF.Screenplay.Selenium.Actions.WaitForSomeTime
61 changes: 61 additions & 0 deletions CSF.Screenplay.Docs/docs/extensions/selenium/NamedScripts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
uid: NamedScriptsArticle
---
# Named JavaScripts

Sometimes it is neccesary to execute JavaScript in the web browser.
This might be to work around a limitation in a WebDriver implementation, such as [web browsers which cannot enter values into date fields].
At other times, JavaScript might be used to perform large-scale operations which would perform very poorly if conducted through many WebDriver interactions.
This is particularly relevant where a Remote WebDriver is being used, in which each individual interaction suffers the latency and overhead of a remote network request/response.

Named scripts provide a mechanism by which developers may build a library of reusable pre-defined scripts and give them human-readable names.
This way, when those scripts are used, they produce clear and concise entries in [the Screenplay report].
Additionally, named scripts provide .NET type safety via generic type parameters.

[web browsers which cannot enter values into date fields]: xref:CSF.Screenplay.Selenium.BrowserQuirks.CannotSetInputTypeDateWithSendKeys
[the Screenplay report]: ../../GettingReports.md

## The classes

There are many script classes available, differing primarily in the number of paramaters which they accept.
Here is a table listing them all.
Pick the one which returns/does not return a result and which has the correct number of parameters for your script.

| Params | No result | With result |
| ------ | --------- | ----------- |
| 0 | [`NamedScript`] | [`NamedScriptWithResult<TResult>`] |
| 1 | [`NamedScript<T1>`] | [`NamedScriptWithResult<T1,TResult>`] |
| 2 | [`NamedScript<T1,T2>`] | [`NamedScriptWithResult<T1,T2,TResult>`] |
| 3 | [`NamedScript<T1,T2,T3>`] | [`NamedScriptWithResult<T1,T2,T3,TResult>`] |
| 4 | [`NamedScript<T1,T2,T3,T4>`] | [`NamedScriptWithResult<T1,T2,T3,T4,TResult>`] |
| 5 | [`NamedScript<T1,T2,T3,T4,T5>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,TResult>`] |
| 6 | [`NamedScript<T1,T2,T3,T4,T5,T6>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,TResult>`] |
| 7 | [`NamedScript<T1,T2,T3,T4,T5,T6,T7>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,T7,TResult>`] |

[`NamedScript`]: xref:CSF.Screenplay.Selenium.NamedScript
[`NamedScriptWithResult<TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`1
[`NamedScript<T1>`]: xref:CSF.Screenplay.Selenium.NamedScript`1
[`NamedScriptWithResult<T1,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`2
[`NamedScript<T1,T2>`]: xref:CSF.Screenplay.Selenium.NamedScript`2
[`NamedScriptWithResult<T1,T2,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`3
[`NamedScript<T1,T2,T3>`]: xref:CSF.Screenplay.Selenium.NamedScript`3
[`NamedScriptWithResult<T1,T2,T3,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`4
[`NamedScript<T1,T2,T3,T4>`]: xref:CSF.Screenplay.Selenium.NamedScript`4
[`NamedScriptWithResult<T1,T2,T3,T4,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`5
[`NamedScript<T1,T2,T3,T4,T5>`]: xref:CSF.Screenplay.Selenium.NamedScript`5
[`NamedScriptWithResult<T1,T2,T3,T4,T5,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`6
[`NamedScript<T1,T2,T3,T4,T5,T6>`]: xref:CSF.Screenplay.Selenium.NamedScript`6
[`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`7
[`NamedScript<T1,T2,T3,T4,T5,T6,T7>`]: xref:CSF.Screenplay.Selenium.NamedScript`7
[`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,T7,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`8

## Using a script

Execute scripts within your performables using the builder method [`PerformableBuilder.ExecuteAScript`] or one of its many same-named overloads.
Generic type inference will offer the appropriate number and types of parameters and will expose a strongly-typed result if applicable.

Within the JavaScript body, the parameters are accessible via an `arguments` object.
Each parameter is assigned to this object using a zero-based index.
So, the first parameter value is `arguments[0]`, the second `arguments[1]` and so on.

[`PerformableBuilder.ExecuteAScript`]: xref:CSF.Screenplay.Selenium.PerformableBuilder.ExecuteAScript(CSF.Screenplay.Selenium.NamedScript)
47 changes: 47 additions & 0 deletions CSF.Screenplay.Docs/docs/extensions/selenium/Queries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
uid: SeleniumQueriesArticle
---

# Queries

Queries are a unified mechanism by which [Elements] are interrogated/observed.
Queries broadly serve two purposes, as described below.

[Elements]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElement

## Observing the state of elements

Queries are used directly by the [`SingleElementQuery<TResult>`] and [`ElementCollectionQuery<TResult>`] questions which are included in the Selenium extension for Screenplay.
In this usage, the query indicates which piece of state is to be retrieved from the element(s) and returned to the consuming performable.

[`SingleElementQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.SingleElementQuery`1
[`ElementCollectionQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.ElementCollectionQuery`1

## Specifying criteria

A mechanism which parallels queries is present in the class [`QueryPredicatePrototypeBuilder`].
This mechanism uses the combination of a query and a predicate to specify criteria by which element(s) may be matched.
This applies to two use-cases:

The methods of [`TargetExtensions`] may be used to build instances of the [`Wait`] action.
Together, the query and predicate specify the condition for the wait to end.

The query prototype builder is also used by one of the overloads of the [`ForThoseWhich`] builder method.
This builder may be used to create the [`FilterElements`] question, to specify the criteria by which to match elements which should be accepted by the filter.

[`QueryPredicatePrototypeBuilder`]: xref:CSF.Screenplay.Selenium.Builders.QueryPredicatePrototypeBuilder
[`TargetExtensions`]: xref:CSF.Screenplay.Selenium.Elements.TargetExtensions
[`Wait`]: xref:CSF.Screenplay.Selenium.Actions.Wait
[`ForThoseWhich`]: xref:CSF.Screenplay.Selenium.Builders.FilterElementsBuilder.ForThoseWhich(System.Func{CSF.Screenplay.Selenium.Builders.QueryPredicatePrototypeBuilder,CSF.Screenplay.Selenium.Builders.IBuildsElementPredicates})
[`FilterElements`]: xref:CSF.Screenplay.Selenium.Questions.FilterElements

## List of queries

The available queries are best found by reading the list of methods available on two classes.
For usages of queries to observe/read a piece of information, see the functionality present upon the [`QuestionQueryBuilder`] class.
For usages relating the the creation of criteria, see the members of the [`QueryPredicatePrototypeBuilder`] class.
Recall, each query reads a piece of information from [an HTML element] (or [elements in a collection]), or it creates a criteria for matching either one or a collection of elements.

[`QuestionQueryBuilder`]: xref:CSF.Screenplay.Selenium.Builders.QuestionQueryBuilder
[an HTML element]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElement
[elements in a collection]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElementCollection
Loading
Loading