Skip to content

Commit 0cd6ee5

Browse files
authored
Merge pull request #302 from csf-dev:craigfowler/issue258
Resolve #258 - Selenium documentation
2 parents 1253880 + 8c338a6 commit 0cd6ee5

84 files changed

Lines changed: 2723 additions & 513 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CSF.Screenplay.Docs/docfx.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
"_appTitle": "Screenplay",
4949
"_enableSearch": true,
5050
"pdf": false
51-
}
51+
},
52+
"xref": [
53+
"https://www.selenium.dev/selenium/docs/api/dotnet/xrefmap.yml",
54+
"https://csf-dev.github.io/CSF.Extensions.WebDriver/xrefmap.yml"
55+
]
5256
}
5357
}

CSF.Screenplay.Docs/docs/Assets.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
uid: AssetsArticle
3+
---
4+
5+
# Report assets
6+
7+
TODO: Write this docco page; #301

CSF.Screenplay.Docs/docs/extensions/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ This page lists the officially-supported **[Screenplay Extensions]**.
55
* **[Selenium](selenium/index.md)**: _remote control Web Browsers using Selenium Web Driver_
66
* **[Web APIs](webApis/index.md)**: _communicate with Web APIs with an HTTP Client_
77

8-
[Screenplay Extensions]: ../../glossary/Extension.md
8+
[Screenplay Extensions]: ../../glossary/Extension.md
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Selenium actions
2+
3+
The Selenium extension for Screenplay provides numerous [Actions], each of which represents one of the smallest possible interactions with a web browser/page.
4+
Broadly, these actions fall into the following categories:
5+
6+
* 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.
7+
* Actions which interact directly with the web browser, such as _"take a screenshot"_ or _"clear the cookies for the current domain"_.
8+
* Actions which represent waiting for something, such as _"wait until the progress bar reaches 100%"_ or _"wait until the shopping cart items are visible"_.
9+
10+
Recall that Screenplay Actions _do something_ without getting any result.
11+
To interrogate a web page (to observe it in some manner), use [one of the Selenium extension's Questions].
12+
Below is a summary of each of these actions' usage, with a link to their detailed documentation page.
13+
14+
[Actions]: ../../../glossary/Action.md
15+
[a target]: Targets.md
16+
[one of the Selenium extension's Questions]: Questions.md
17+
18+
## Actions that work with targets
19+
20+
| Action | Usage |
21+
| ------ | ----- |
22+
| [`ClearTheContents`] | Remove/clear all text from the specified element, such as an `<input>` |
23+
| [`Click`] | Click on the specified element |
24+
| [`DeselectByIndex`] | Deselect an option from the specified `<select>` element by its index |
25+
| [`DeselectByText`] | Deselect an option from the specified `<select>` element by its displayed text |
26+
| [`DeselectByValue`] | Deselect an option from the specified `<select>` element by its underlying value |
27+
| [`DeselectAll`] | Deselects every option from the specified `<select>` element |
28+
| [`SelectByIndex`] | Select an option from the specified `<select>` element by its index |
29+
| [`SelectByText`] | Select an option from the specified `<select>` element by its displayed text |
30+
| [`SelectByValue`] | Select an option from the specified `<select>` element by its underlying value |
31+
| [`SendKeys`] | Type text (send keystrokes) whilst a specified element has focus |
32+
33+
[`ClearTheContents`]: xref:CSF.Screenplay.Selenium.Actions.ClearTheContents
34+
[`Click`]: xref:CSF.Screenplay.Selenium.Actions.Click
35+
[`DeselectByIndex`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByIndex
36+
[`DeselectByText`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByText
37+
[`DeselectByValue`]: xref:CSF.Screenplay.Selenium.Actions.DeselectByValue
38+
[`DeselectAll`]: xref:CSF.Screenplay.Selenium.Actions.DeselectAll
39+
[`SelectByIndex`]: xref:CSF.Screenplay.Selenium.Actions.SelectByIndex
40+
[`SelectByText`]: xref:CSF.Screenplay.Selenium.Actions.SelectByText
41+
[`SelectByValue`]: xref:CSF.Screenplay.Selenium.Actions.SelectByValue
42+
[`SendKeys`]: xref:CSF.Screenplay.Selenium.Actions.SendKeys
43+
44+
## Actions which work with the browser
45+
46+
| Action | Usage |
47+
| ------ | ----- |
48+
| [`ClearCookies`] | Clear the web browser cookies for the current site (domain) |
49+
| [`ClearLocalStorage`] | Clear the web browser [local storage] for the current site (domain) |
50+
| [`DeleteTheCookie`] | Delete a single named cookie |
51+
| [`ExecuteJavaScript`] | Executes a JavaScript directly in the browser |
52+
| [`OpenUrl`] | Directs the browser to open a specified URL |
53+
| [`SaveScreenshot`] | Saves a screenshot to a file |
54+
55+
[`OpenUrl`]: xref:CSF.Screenplay.Selenium.Actions.OpenUrl
56+
[`SaveScreenshot`]: xref:CSF.Screenplay.Selenium.Actions.SaveScreenshot
57+
[`ClearCookies`]: xref:CSF.Screenplay.Selenium.Actions.ClearCookies
58+
[`ClearLocalStorage`]: xref:CSF.Screenplay.Selenium.Actions.ClearLocalStorage
59+
[`DeleteTheCookie`]: xref:CSF.Screenplay.Selenium.Actions.DeleteTheCookie
60+
[`ExecuteJavaScript`]: xref:CSF.Screenplay.Selenium.Actions.ExecuteJavaScript
61+
[local storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
62+
63+
## Actions which wait
64+
65+
| Action | Usage |
66+
| ------ | ----- |
67+
| [`Wait`] | Pauses the [Performance] until a condition is true |
68+
| [`WaitForSomeTime`] | Pauses the [Performance] for an arbitrary amount of time |
69+
70+
[Performance]: xref:CSF.Screenplay.IPerformance
71+
[`Wait`]: xref:CSF.Screenplay.Selenium.Actions.Wait
72+
[`WaitForSomeTime`]: xref:CSF.Screenplay.Selenium.Actions.WaitForSomeTime
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
uid: NamedScriptsArticle
3+
---
4+
# Named JavaScripts
5+
6+
Sometimes it is neccesary to execute JavaScript in the web browser.
7+
This might be to work around a limitation in a WebDriver implementation, such as [web browsers which cannot enter values into date fields].
8+
At other times, JavaScript might be used to perform large-scale operations which would perform very poorly if conducted through many WebDriver interactions.
9+
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.
10+
11+
Named scripts provide a mechanism by which developers may build a library of reusable pre-defined scripts and give them human-readable names.
12+
This way, when those scripts are used, they produce clear and concise entries in [the Screenplay report].
13+
Additionally, named scripts provide .NET type safety via generic type parameters.
14+
15+
[web browsers which cannot enter values into date fields]: xref:CSF.Screenplay.Selenium.BrowserQuirks.CannotSetInputTypeDateWithSendKeys
16+
[the Screenplay report]: ../../GettingReports.md
17+
18+
## The classes
19+
20+
There are many script classes available, differing primarily in the number of paramaters which they accept.
21+
Here is a table listing them all.
22+
Pick the one which returns/does not return a result and which has the correct number of parameters for your script.
23+
24+
| Params | No result | With result |
25+
| ------ | --------- | ----------- |
26+
| 0 | [`NamedScript`] | [`NamedScriptWithResult<TResult>`] |
27+
| 1 | [`NamedScript<T1>`] | [`NamedScriptWithResult<T1,TResult>`] |
28+
| 2 | [`NamedScript<T1,T2>`] | [`NamedScriptWithResult<T1,T2,TResult>`] |
29+
| 3 | [`NamedScript<T1,T2,T3>`] | [`NamedScriptWithResult<T1,T2,T3,TResult>`] |
30+
| 4 | [`NamedScript<T1,T2,T3,T4>`] | [`NamedScriptWithResult<T1,T2,T3,T4,TResult>`] |
31+
| 5 | [`NamedScript<T1,T2,T3,T4,T5>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,TResult>`] |
32+
| 6 | [`NamedScript<T1,T2,T3,T4,T5,T6>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,TResult>`] |
33+
| 7 | [`NamedScript<T1,T2,T3,T4,T5,T6,T7>`] | [`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,T7,TResult>`] |
34+
35+
[`NamedScript`]: xref:CSF.Screenplay.Selenium.NamedScript
36+
[`NamedScriptWithResult<TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`1
37+
[`NamedScript<T1>`]: xref:CSF.Screenplay.Selenium.NamedScript`1
38+
[`NamedScriptWithResult<T1,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`2
39+
[`NamedScript<T1,T2>`]: xref:CSF.Screenplay.Selenium.NamedScript`2
40+
[`NamedScriptWithResult<T1,T2,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`3
41+
[`NamedScript<T1,T2,T3>`]: xref:CSF.Screenplay.Selenium.NamedScript`3
42+
[`NamedScriptWithResult<T1,T2,T3,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`4
43+
[`NamedScript<T1,T2,T3,T4>`]: xref:CSF.Screenplay.Selenium.NamedScript`4
44+
[`NamedScriptWithResult<T1,T2,T3,T4,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`5
45+
[`NamedScript<T1,T2,T3,T4,T5>`]: xref:CSF.Screenplay.Selenium.NamedScript`5
46+
[`NamedScriptWithResult<T1,T2,T3,T4,T5,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`6
47+
[`NamedScript<T1,T2,T3,T4,T5,T6>`]: xref:CSF.Screenplay.Selenium.NamedScript`6
48+
[`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`7
49+
[`NamedScript<T1,T2,T3,T4,T5,T6,T7>`]: xref:CSF.Screenplay.Selenium.NamedScript`7
50+
[`NamedScriptWithResult<T1,T2,T3,T4,T5,T6,T7,TResult>`]: xref:CSF.Screenplay.Selenium.NamedScriptWithResult`8
51+
52+
## Using a script
53+
54+
Execute scripts within your performables using the builder method [`PerformableBuilder.ExecuteAScript`] or one of its many same-named overloads.
55+
Generic type inference will offer the appropriate number and types of parameters and will expose a strongly-typed result if applicable.
56+
57+
Within the JavaScript body, the parameters are accessible via an `arguments` object.
58+
Each parameter is assigned to this object using a zero-based index.
59+
So, the first parameter value is `arguments[0]`, the second `arguments[1]` and so on.
60+
61+
[`PerformableBuilder.ExecuteAScript`]: xref:CSF.Screenplay.Selenium.PerformableBuilder.ExecuteAScript(CSF.Screenplay.Selenium.NamedScript)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
uid: SeleniumQueriesArticle
3+
---
4+
5+
# Queries
6+
7+
Queries are a unified mechanism by which [Elements] are interrogated/observed.
8+
Queries broadly serve two purposes, as described below.
9+
10+
[Elements]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElement
11+
12+
## Observing the state of elements
13+
14+
Queries are used directly by the [`SingleElementQuery<TResult>`] and [`ElementCollectionQuery<TResult>`] questions which are included in the Selenium extension for Screenplay.
15+
In this usage, the query indicates which piece of state is to be retrieved from the element(s) and returned to the consuming performable.
16+
17+
[`SingleElementQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.SingleElementQuery`1
18+
[`ElementCollectionQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.ElementCollectionQuery`1
19+
20+
## Specifying criteria
21+
22+
A mechanism which parallels queries is present in the class [`QueryPredicatePrototypeBuilder`].
23+
This mechanism uses the combination of a query and a predicate to specify criteria by which element(s) may be matched.
24+
This applies to two use-cases:
25+
26+
The methods of [`TargetExtensions`] may be used to build instances of the [`Wait`] action.
27+
Together, the query and predicate specify the condition for the wait to end.
28+
29+
The query prototype builder is also used by one of the overloads of the [`ForThoseWhich`] builder method.
30+
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.
31+
32+
[`QueryPredicatePrototypeBuilder`]: xref:CSF.Screenplay.Selenium.Builders.QueryPredicatePrototypeBuilder
33+
[`TargetExtensions`]: xref:CSF.Screenplay.Selenium.Elements.TargetExtensions
34+
[`Wait`]: xref:CSF.Screenplay.Selenium.Actions.Wait
35+
[`ForThoseWhich`]: xref:CSF.Screenplay.Selenium.Builders.FilterElementsBuilder.ForThoseWhich(System.Func{CSF.Screenplay.Selenium.Builders.QueryPredicatePrototypeBuilder,CSF.Screenplay.Selenium.Builders.IBuildsElementPredicates})
36+
[`FilterElements`]: xref:CSF.Screenplay.Selenium.Questions.FilterElements
37+
38+
## List of queries
39+
40+
The available queries are best found by reading the list of methods available on two classes.
41+
For usages of queries to observe/read a piece of information, see the functionality present upon the [`QuestionQueryBuilder`] class.
42+
For usages relating the the creation of criteria, see the members of the [`QueryPredicatePrototypeBuilder`] class.
43+
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.
44+
45+
[`QuestionQueryBuilder`]: xref:CSF.Screenplay.Selenium.Builders.QuestionQueryBuilder
46+
[an HTML element]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElement
47+
[elements in a collection]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElementCollection
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Selenium questions
2+
3+
The Selenium extension for Screenplay provides [Questions], each of which observes the web browser and its current contents in some manner, returning a result.
4+
There are three broad categories of questions in the Selenium extension:
5+
6+
* Questions which read something from a specified element or elements, such as _"get the text of the username label"_ or _"get the color of each of the status indicators"_.
7+
* Questions which find or query-for HTML elements, such as _find all checkboxes in the to-do list which are checked_ or _get the first status label which has a red background_.
8+
* Questions which interact directly with the web browser.
9+
10+
What is common to all Screenplay Questions is that they get information, or a result object.
11+
They do not make changes to the state of the application/web browser.
12+
To interact with the web page in a way which could change its state, use [one of the Selenium extension's Actions].
13+
Below is a summary of each of these questions' usage, with a link to their detailed documentation page.
14+
15+
[Questions]: ../../../glossary/Question.md
16+
[one of the Selenium extension's Actions]: Actions.md
17+
18+
## Questions which query the state of elements
19+
20+
Questions which read-from or observe HTML elements operate using a common mechamism, named [Queries].
21+
Queries provide a builder-friendly manner by which to read state from either one or a collection of elements.
22+
Each of the Questions listed below makes use of a Query to identify the state which is to be read from the element.
23+
24+
| Question | Usage |
25+
| -------- | ----- |
26+
| [`SingleElementQuery<TResult>`] | Reads the state from a [target] representing a single element |
27+
| [`ElementCollectionQuery<TResult>`] | Reads the state from a [target] representing a collection of elements |
28+
29+
[Queries]: Queries.md
30+
[`SingleElementQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.SingleElementQuery`1
31+
[`ElementCollectionQuery<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.ElementCollectionQuery`1
32+
[target]: Targets.md
33+
34+
## Questions which find or filter elements
35+
36+
There are many ways to use these questions, chosen by the way in which you use the relevant builder(s).
37+
The possibilities are explained in detail on the questions' detailed documentation pages.
38+
39+
| Question | Usage |
40+
| -------- | ----- |
41+
| [`FindElement`] | Gets [an element] which matches a [`Locator`] |
42+
| [`FindElements`] | Gets [a collection of elements] which match a [`Locator`] |
43+
| [`FilterElements`] | Filters [a collection of elements] for those which match a [query] |
44+
45+
[`FindElement`]: xref:CSF.Screenplay.Selenium.Questions.FindElement
46+
[`FindElements`]: xref:CSF.Screenplay.Selenium.Questions.FindElements
47+
[`FilterElements`]: xref:CSF.Screenplay.Selenium.Questions.FilterElements
48+
[`Locator`]: xref:CSF.Screenplay.Selenium.Elements.Locator
49+
[query]: Queries.md
50+
[an element]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElement
51+
[a collection of elements]: xref:CSF.Screenplay.Selenium.Elements.SeleniumElementCollection
52+
53+
## Questions for the web browser
54+
55+
These questions don't neccesarily involve elements, instead they query the web browser directly.
56+
57+
| Question | Usage |
58+
| -------- | ----- |
59+
| [`ExecuteJavaScriptAndGetResult<TResult>`] | Executes a JavaScript directly in the browser and reads the result |
60+
| [`GetWindowTitle`] | Reads the text of the Window/Tab title |
61+
| [`TakeScreenshot`] | Takes a Screenshot of the browser window |
62+
63+
[`ExecuteJavaScriptAndGetResult<TResult>`]: xref:CSF.Screenplay.Selenium.Questions.ExecuteJavaScriptAndGetResult`1
64+
[`GetWindowTitle`]: xref:CSF.Screenplay.Selenium.Questions.GetWindowTitle
65+
[`TakeScreenshot`]: xref:CSF.Screenplay.Selenium.Questions.TakeScreenshot
66+

0 commit comments

Comments
 (0)