From 44b9e94328c3a749e06e0d43365e434ed5595663 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Sun, 8 Feb 2026 20:56:04 +0000 Subject: [PATCH 1/6] WIP #259 - Written on phone --- .../docs/extensions/webApis/index.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md index ef1a52e2..c9e65366 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md @@ -1 +1,22 @@ -TODO: Write this docs page +# CSF.Screenplay.WebApis Extension + +The Web APIs Extension allows [Actors] to communicate with HTTP web API endpoints within a Screenplay [Performance]. +In practice, this translates to sending HTTP(S) requests and receiving responses. + +## Endpoints + +**Endpoints** are a fundamental, first class concept in this extension. An endpoint object is used to define: + +* The URL (route) at which the endpoint is found +* Whether use of the endpoint requires any parameters + * How many parameters + * The .NET types of the parameter values + * How those parameters are communicated to the endpoint +* The endpoint's expected response/result type, if it is expected to return one + +Users of this extension *are encouraged to build a library of endpoint objects*, describing the 'surface area' of the API that they wish to exercise. + +[Actors]: xref:CSF.Screenplay.Actor +[Performance]: xref:CSF.Screenplay.IPerformance +[Actions]: ../../glossary/Action.md +[Questions]: ../../glossary/Question.md From f9ba839577c586ae75b32edbda2a53816636eef1 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Mon, 9 Feb 2026 13:58:37 +0000 Subject: [PATCH 2/6] Updates to docs #259 --- .../docs/extensions/webApis/index.md | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md index c9e65366..e5489bce 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md @@ -1,7 +1,31 @@ # CSF.Screenplay.WebApis Extension The Web APIs Extension allows [Actors] to communicate with HTTP web API endpoints within a Screenplay [Performance]. -In practice, this translates to sending HTTP(S) requests and receiving responses. + +## Overview + +The diagram below shows how this extension works. +The concepts of the [Actor] and [Ability] (the ability is named [`MakeWebApiRequests`]) are explained in Screenplay's core documentation. +Other concepts are explained below. +Note that the **Live API service** in this diagram is not a part of Screenplay or this extension. +The Live API service represents an actual HTTP(S) web server which hosts the API with which Screenplay is communicating. + +```mermaid +erDiagram + Actor ||--o{ Request : makes + Actor ||--|| Ability : "has ability" + Request ||--|| Endpoint : uses + api["Live API service"] + Request ||--|| api : "sends via Ability" + Ability ||--|| api : sends + api ||--|| Response : returns + Response }o--|| Actor : recieves + style api fill:#ee9,stroke:#bb6 +``` + +[Actor]: xref:CSF.Screenplay.Actor +[Ability]: xref:AbilityGlossaryItem +[`MakeWebApiRequests`]: xref:CSF.Screenplay.WebApis.MakeWebApiRequests ## Endpoints From 503d06fe703bea2c9b2412d7abe28d3a468d6d9e Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Mon, 9 Feb 2026 20:18:54 +0000 Subject: [PATCH 3/6] WIP #259 --- .../docs/extensions/webApis/Endpoints.md | 18 ++++++++++++++ .../docs/extensions/webApis/index.md | 24 +++++++------------ 2 files changed, 26 insertions(+), 16 deletions(-) create mode 100644 CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md b/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md new file mode 100644 index 00000000..4f22fb6c --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md @@ -0,0 +1,18 @@ +# Endpoints +**Endpoints** are fundamental to this extension; they are .NET class instances which describe a piece of API functionality which may be consumed. +The single most important (and obvious) piece of information stored in an endpoint object is the URL (route) which is used to communicate with the API function. +## Three endpoint classes +The WebAPIs extension offers three classes for which to use in defining the endpoints which you consume. + + + +, first class concept in this extension. An endpoint object is used to define: + +* The URL (route) at which the endpoint is found +* Whether use of the endpoint requires any parameters + * How many parameters + * The .NET types of the parameter values + * How those parameters are communicated to the endpoint +* The endpoint's expected response/result type, if it is expected to return one + +Users of this extension *are encouraged to build a library of endpoint objects*, describing the 'surface area' of the API that they wish to exercise. diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md index e5489bce..1f9672d4 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md @@ -2,6 +2,8 @@ The Web APIs Extension allows [Actors] to communicate with HTTP web API endpoints within a Screenplay [Performance]. +[Actors]: xref:CSF.Screenplay.Actor +[Performance]: xref:CSF.Screenplay.IPerformance ## Overview The diagram below shows how this extension works. @@ -20,6 +22,7 @@ erDiagram Ability ||--|| api : sends api ||--|| Response : returns Response }o--|| Actor : recieves + style api fill:#ee9,stroke:#bb6 ``` @@ -27,20 +30,9 @@ erDiagram [Ability]: xref:AbilityGlossaryItem [`MakeWebApiRequests`]: xref:CSF.Screenplay.WebApis.MakeWebApiRequests -## Endpoints - -**Endpoints** are a fundamental, first class concept in this extension. An endpoint object is used to define: - -* The URL (route) at which the endpoint is found -* Whether use of the endpoint requires any parameters - * How many parameters - * The .NET types of the parameter values - * How those parameters are communicated to the endpoint -* The endpoint's expected response/result type, if it is expected to return one +This extension provides **[Actions]** which allow the Actor to build and send [HTTP requests] based upon [Endpoint] definitions. +These requests are sent via the HTTP client which is exposed by the [`MakeWebApiRequests`] Ability, to a live API server. +The server returns an [HTTP Response], which the extension formats into a result object. -Users of this extension *are encouraged to build a library of endpoint objects*, describing the 'surface area' of the API that they wish to exercise. - -[Actors]: xref:CSF.Screenplay.Actor -[Performance]: xref:CSF.Screenplay.IPerformance -[Actions]: ../../glossary/Action.md -[Questions]: ../../glossary/Question.md +[Actions]: ../../../glossary/Action.md +[Endpoint]: Endpoints.md From 3b4e1a81f7b0a19db25f078c5ea56e34904a6010 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Mon, 9 Feb 2026 22:19:04 +0000 Subject: [PATCH 4/6] WIP #259 - Web API docs --- CSF.Screenplay.Docs/docfx.json | 3 +- CSF.Screenplay.Docs/docs/extensions/index.md | 8 +++ .../webApis/ChoosingEndpointsAndRequests.md | 51 ++++++++++++++++ .../docs/extensions/webApis/Endpoints.md | 44 ++++++++++---- .../docs/extensions/webApis/Requests.md | 32 ++++++++++ .../docs/extensions/webApis/Responses.md | 21 +++++++ .../docs/extensions/webApis/index.md | 41 +++++++------ .../docs/extensions/webApis/toc.yml | 10 ++++ .../docs/performables/WebApis.md | 59 ------------------- .../docs/performables/index.md | 8 --- CSF.Screenplay.Docs/docs/performables/toc.yml | 2 - CSF.Screenplay.Docs/docs/toc.yml | 7 +++ CSF.Screenplay.Docs/glossary/Extension.md | 16 ++--- .../ParameterizedEndpoint.withResult.cs | 6 +- 14 files changed, 195 insertions(+), 113 deletions(-) create mode 100644 CSF.Screenplay.Docs/docs/extensions/index.md create mode 100644 CSF.Screenplay.Docs/docs/extensions/webApis/ChoosingEndpointsAndRequests.md create mode 100644 CSF.Screenplay.Docs/docs/extensions/webApis/Requests.md create mode 100644 CSF.Screenplay.Docs/docs/extensions/webApis/Responses.md create mode 100644 CSF.Screenplay.Docs/docs/extensions/webApis/toc.yml delete mode 100644 CSF.Screenplay.Docs/docs/performables/WebApis.md diff --git a/CSF.Screenplay.Docs/docfx.json b/CSF.Screenplay.Docs/docfx.json index c356164d..0c6b88cf 100644 --- a/CSF.Screenplay.Docs/docfx.json +++ b/CSF.Screenplay.Docs/docfx.json @@ -11,7 +11,8 @@ "**/obj/**", "Tests/**", "Old/**", - "CSF.Screenplay.JsonToHtmlReport.Template/**" + "CSF.Screenplay.JsonToHtmlReport.Template/**", + "CSF.Screenplay.SpecFlow/**" ] } ], diff --git a/CSF.Screenplay.Docs/docs/extensions/index.md b/CSF.Screenplay.Docs/docs/extensions/index.md new file mode 100644 index 00000000..08e4278c --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/index.md @@ -0,0 +1,8 @@ +# Screenplay extensions + +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 \ No newline at end of file diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/ChoosingEndpointsAndRequests.md b/CSF.Screenplay.Docs/docs/extensions/webApis/ChoosingEndpointsAndRequests.md new file mode 100644 index 00000000..66ab52bb --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/ChoosingEndpointsAndRequests.md @@ -0,0 +1,51 @@ +# Common combinations of requests and endpoints + +The appropriate combination of [Request action] type and [Endpoint] type depends upon your use case. +Common use cases are summarised in the table below. +Information about reading this table follows. + +| Request payload | Response type | Endpoint type | Request action type | +| --------------- | ------------- | ------------- | ---------------- | +| _None_ | _None_ | [`Endpoint`] | [`SendTheHttpRequest`] | +| _None_ | Deserialized with custom logic | [`Endpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | +| _None_ | Deserialized from JSON | [`Endpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | +| Serialized with custom logic | _None_ | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequest`] | +| Serialized with custom logic | Deserialized with custom logic | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | +| Serialized with custom logic | Deserialized from JSON | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | +| Serialized with JSON | _None_ | [`JsonEndpoint`] | [`SendTheHttpRequest`] | +| Serialized with JSON | Deserialized with custom logic | [`JsonEndpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | +| Serialized with JSON | Deserialized from JSON | [`JsonEndpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | + +> [!TIP] +> To decide which types of endpoint & performable: +> _Choose the **endpoint type** based upon the needs of the **request**, adding an extra generic type parameter if the response is to be strongly-typed. +> Choose the **action type** based upon the technical details of reading the **response**._ + +[Request action]: Requests.md +[Endpoint]: Endpoints.md +[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint +[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint`1 +[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`1 +[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`2 +[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`1 +[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`2 +[`SendTheHttpRequest`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequest +[`SendTheHttpRequestAndGetTheResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1 +[`SendTheHttpRequestAndGetJsonResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1 + +## The first two columns + +The first two columns indicate: + +1. The kind of **request payload** which will be sent
+ These are the parameters to the API function described by the endpoint +1. The type of the expected **response body**
+ Where an API function returns a response, this is the .NET type which will be used to represent that response + +Where _None_ is listed in either column this means _"not applicable"_. +For example, an API function which uses no parameters will have no request payload. +In the case of responses, _None_ might mean that the response body will be ignored. + +## The second two columns + +The second two columns indicate the Endpoint type and Request action type which are recommended in this scenario. diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md b/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md index 4f22fb6c..c36ca623 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/Endpoints.md @@ -1,18 +1,40 @@ # Endpoints + **Endpoints** are fundamental to this extension; they are .NET class instances which describe a piece of API functionality which may be consumed. -The single most important (and obvious) piece of information stored in an endpoint object is the URL (route) which is used to communicate with the API function. -## Three endpoint classes -The WebAPIs extension offers three classes for which to use in defining the endpoints which you consume. +The single most important (and obvious) piece of information stored in an endpoint object is the URL (route) which is used to communicate with the API function. + +## Endpoint classes + +The WebAPIs Screenplay extension provides a number of classes by which to describe endpoints. +Developers using this extension are encouraged to create 'libraries' of Endpoints within their own logic. +Such a library might be as simple as a `static class` which contains `public static` get-only properties, each of which returns a named endpoint. +Every endpoint class derives from a base class named [`EndpointBase`]. + +The endpoint classes available are listed below. +There is also [an article indicating how to choose an appropriate combination] of Endpoint and [Request action]. +* [`Endpoint`] +* [`Endpoint`] +* [`ParameterizedEndpoint`] - _intended to be used as a base class_ +* [`ParameterizedEndpoint`] - _intended to be used as a base class_ +* [`JsonEndpoint`] +* [`JsonEndpoint`] +[`EndpointBase`]: xref:CSF.Screenplay.WebApis.EndpointBase +[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint +[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint`1 +[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`1 +[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`2 +[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`1 +[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`2 +[an article indicating how to choose an appropriate combination]: ChoosingEndpointsAndRequests.md +[Request action]: Requests.md -, first class concept in this extension. An endpoint object is used to define: +## Common to all endpoints -* The URL (route) at which the endpoint is found -* Whether use of the endpoint requires any parameters - * How many parameters - * The .NET types of the parameter values - * How those parameters are communicated to the endpoint -* The endpoint's expected response/result type, if it is expected to return one +All endpoints describe: -Users of this extension *are encouraged to build a library of endpoint objects*, describing the 'surface area' of the API that they wish to exercise. +* [The URL pattern to reach the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.%23ctor(System.Uri,System.Net.Http.HttpMethod)) +* [The HTTP method used with the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.%23ctor(System.Uri,System.Net.Http.HttpMethod)) +* [A human-readable name for the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.Name) +* [An optional timeout for the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.Timeout) diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/Requests.md b/CSF.Screenplay.Docs/docs/extensions/webApis/Requests.md new file mode 100644 index 00000000..04ee079e --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/Requests.md @@ -0,0 +1,32 @@ +# Request actions + +Sending an HTTP request to an API is accomplished using a Screenplay [Action]. +There are three action types available; which to use depends upon the expected response from the API. +[This article helps you choose the appropriate combination of Request Action and Endpoint types]. + +[Action]: ../../../glossary/Action.md +[This article helps you choose the appropriate combination of Request Action and Endpoint types]: ChoosingEndpointsAndRequests.md + +## The three action types + +As might be evident from their names, each request action type is used for a different kind of expected response message. +In the case of `SendTheHttpRequest`, there is no response expected (or the response will be ignored). +The other two types are for either a JSON response or a response which requires custom deserialization. + +* [`SendTheHttpRequest`](xref:CSF.Screenplay.WebApis.SendTheHttpRequest) +* [`SendTheHttpRequestAndGetJsonResponse`](xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1) +* [`SendTheHttpRequestAndGetTheResponse`](xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1) + +## Use `WebApiBuilder` to simplify usage + +A builder/helper class is available to simplify getting the appropriate Request action; this is [`WebApiBuilder`]. +The recommended way to consume this is to add `using static CSF.Screenplay.WebApis.WebApiBuilder;` to the source file for any [Performable] you write which consumes Web APIs via this extension. + +When an approproate [Endpoint] type has been used, the [`WebApiBuilder`] class will make it very easy to select the correct action, via type inference. +To get a request for an API function which is expected to return a JSON-formatted response, use the method `GetTheJsonResult`. +To get a request for any other API function, use the method `SendTheHttpRequest`. +Both of these methods have several overloads, for each type of endpoint which could use them. + +[`WebApiBuilder`]: xref:CSF.Screenplay.WebApis.WebApiBuilder +[Performable]: ../../../glossary/Performable.md +[Endpoint]: Endpoints.md diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/Responses.md b/CSF.Screenplay.Docs/docs/extensions/webApis/Responses.md new file mode 100644 index 00000000..a845f2fb --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/Responses.md @@ -0,0 +1,21 @@ +# Responses + +The WebAPIs extension for Screenplay supports two kinds of responses. + +## JSON + +For JSON-based endpoints, use the [`SendTheHttpRequestAndGetJsonResponse`] [request action type] and the response from the API function will automatically be deserialized into an instance of the `TResponse` type. + +[`SendTheHttpRequestAndGetJsonResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1 +[request action type]: Requests.md + +## Other response types + +For other endpoints with non-JSON responses, it is up to the consumer to deserialize the response using whatever logic is appropriate. +In this case, using the [`SendTheHttpRequestAndGetTheResponse`] request action type, the returned value from `PerformAsAsync` is an instance of [`HttpResponseMessageAndResponseType`]. +This model object includes the raw/original [`HttpResponseMessage`] which was returned from the HTTP Client, but the class is generic for the intended type of the response. +This should provide sufficient information to deserialize the response accordingly. + +[`SendTheHttpRequestAndGetTheResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1 +[`HttpResponseMessageAndResponseType`]: xref:CSF.Screenplay.WebApis.HttpResponseMessageAndResponseType`1 +[`HttpResponseMessage`]: xref:System.Net.Http.HttpResponseMessage diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md index 1f9672d4..904e3ac4 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md @@ -1,38 +1,43 @@ +--- +uid: WebApisArticle +--- + # CSF.Screenplay.WebApis Extension The Web APIs Extension allows [Actors] to communicate with HTTP web API endpoints within a Screenplay [Performance]. [Actors]: xref:CSF.Screenplay.Actor [Performance]: xref:CSF.Screenplay.IPerformance + ## Overview -The diagram below shows how this extension works. +The fundamentals of this Screenplay extension are shown in the diagram below. The concepts of the [Actor] and [Ability] (the ability is named [`MakeWebApiRequests`]) are explained in Screenplay's core documentation. Other concepts are explained below. -Note that the **Live API service** in this diagram is not a part of Screenplay or this extension. -The Live API service represents an actual HTTP(S) web server which hosts the API with which Screenplay is communicating. + +This extension provides **[Actions]** which allow the Actor to build and send [HTTP requests] based upon [Endpoint] definitions. +These requests are sent via the HTTP client which is exposed by the [`MakeWebApiRequests`] Ability, to a live API server. +The server returns an [HTTP Response], which the extension formats into a result object. ```mermaid -erDiagram - Actor ||--o{ Request : makes - Actor ||--|| Ability : "has ability" - Request ||--|| Endpoint : uses - api["Live API service"] - Request ||--|| api : "sends via Ability" - Ability ||--|| api : sends - api ||--|| Response : returns - Response }o--|| Actor : recieves - +flowchart + Ability -- "Has ability" --> Actor + Actor -- "Makes requests" --> Request + Endpoint -- "Requests target" --> Request + Request --> api["Live API"] + Ability -- "Facilitates request" --> api + api --> Response + style api fill:#ee9,stroke:#bb6 ``` +Note that the **Live API** in this diagram _is not a part of Screenplay or this extension_. +The Live API represents an actual HTTP(S) web server which hosts the API with which Screenplay is communicating. + [Actor]: xref:CSF.Screenplay.Actor [Ability]: xref:AbilityGlossaryItem [`MakeWebApiRequests`]: xref:CSF.Screenplay.WebApis.MakeWebApiRequests - -This extension provides **[Actions]** which allow the Actor to build and send [HTTP requests] based upon [Endpoint] definitions. -These requests are sent via the HTTP client which is exposed by the [`MakeWebApiRequests`] Ability, to a live API server. -The server returns an [HTTP Response], which the extension formats into a result object. - [Actions]: ../../../glossary/Action.md +[HTTP requests]: Requests.md [Endpoint]: Endpoints.md +[HTTP Response]: Responses.md diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/toc.yml b/CSF.Screenplay.Docs/docs/extensions/webApis/toc.yml new file mode 100644 index 00000000..08d0ea3a --- /dev/null +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/toc.yml @@ -0,0 +1,10 @@ +- name: Web APIs + href: index.md +- name: Endpoints + href: Endpoints.md +- name: Requests + href: Requests.md +- name: Choosing endpoint & request types + href: ChoosingEndpointsAndRequests.md +- name: Responses + href: Responses.md \ No newline at end of file diff --git a/CSF.Screenplay.Docs/docs/performables/WebApis.md b/CSF.Screenplay.Docs/docs/performables/WebApis.md deleted file mode 100644 index 70bd3341..00000000 --- a/CSF.Screenplay.Docs/docs/performables/WebApis.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -uid: WebApisArticle ---- - -# Web APIs - -Screenplay may be used to interact with Web APIs. -Key to this is [Ability] class [`MakeWebApiRequests`], along with a number of performables and types which represent API endpoints. - -## Use `WebApiBuilder` to simplify usage - -The section & table below indicates the combinations of 'endpoint' & performable to use for several common use cases. -If the correct endpoint has been used though, the [`WebApiBuilder`] class will make it very easy to select the correct performable, by type inference. - -For any requests which are expecting to read a response as a JSON string, to be deserialized, use an overload of `GetTheJsonResult` from the static web API builder. -For any other requests, use an overload of `SendTheHttpRequest`. - -The recommended way to use this builder is via `using static CSF.Screenplay.WebApis.WebApiBuilder;` in the source file -for a custom [performable]. - -[`WebApiBuilder`]: xref:CSF.Screenplay.WebApis.WebApiBuilder -[performable]: ../../glossary/Performable.md - -## Combinations of endpoints & performables for common usages - -The performable which should be used, along with the approproate endpoint type depends upon your use case, summarised in the table below. -The table is organised by the expected body/content of the HTTP request, _the request payload_ and the expected type of the response body. - -Where _None_ is listed, this usually means that either the request or response have no body, such as an HTTP GET request that does not send a body or an empty response. -In the case of responses this might alternatively mean that the response body will be ignored or will not be interpreted as an instance of any particular type. - -| Request payload | Response type | Endpoint type | Performable type | -| --------------- | ------------- | ------------- | ---------------- | -| _None_ | _None_ | [`Endpoint`] | [`SendTheHttpRequest`] | -| _None_ | Deserialized with custom logic | [`Endpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | -| _None_ | Deserialized from JSON | [`Endpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | -| Serialized with custom logic | _None_ | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequest`] | -| Serialized with custom logic | Deserialized with custom logic | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | -| Serialized with custom logic | Deserialized from JSON | Derive from [`ParameterizedEndpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | -| Serialized with JSON | _None_ | [`JsonEndpoint`] | [`SendTheHttpRequest`] | -| Serialized with JSON | Deserialized with custom logic | [`JsonEndpoint`] | [`SendTheHttpRequestAndGetTheResponse`] | -| Serialized with JSON | Deserialized from JSON | [`JsonEndpoint`] | [`SendTheHttpRequestAndGetJsonResponse`] | - -> [!TIP] -> The rule to decide which types of endpoint & performable to choose is: -> _Choose the **endpoint type** based upon the needs of the **request**, adding an extra generic type parameter if the response is to be strongly-typed. -> Choose the **performable type** based upon how you intend to read the **response**._ - -[Ability]: ../../glossary/Ability.md -[`MakeWebApiRequests`]: xref:CSF.Screenplay.WebApis.MakeWebApiRequests -[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint -[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint`1 -[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`1 -[`ParameterizedEndpoint`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`2 -[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`1 -[`JsonEndpoint`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`2 -[`SendTheHttpRequest`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequest -[`SendTheHttpRequestAndGetTheResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1 -[`SendTheHttpRequestAndGetJsonResponse`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1 diff --git a/CSF.Screenplay.Docs/docs/performables/index.md b/CSF.Screenplay.Docs/docs/performables/index.md index 1cc74718..1a8734d5 100644 --- a/CSF.Screenplay.Docs/docs/performables/index.md +++ b/CSF.Screenplay.Docs/docs/performables/index.md @@ -16,14 +16,6 @@ These are all accessible from the builder class [`StopwatchBuilder`]. [`UseAStopwatch`]: xref:CSF.Screenplay.Abilities.UseAStopwatch [`StopwatchBuilder`]: xref:CSF.Screenplay.Performables.StopwatchBuilder -## Interacting with web APIs - -The NuGet package [CSF.Screenplay.WebApis] provides an ability, performables and supporting types to interact with web API endpoints. -Further information is available on [the web API documentation page]. - -[CSF.Screenplay.WebApis]: https://www.nuget.org/packages/CSF.Screenplay.WebApis/ -[the web API documentation page]: WebApis.md - ## TimeSpan builder The [`TimeSpanBuilder`] is not a complete performable builder; it is intended to supplement other builders such as those of your own design. diff --git a/CSF.Screenplay.Docs/docs/performables/toc.yml b/CSF.Screenplay.Docs/docs/performables/toc.yml index d80c2102..b34ca748 100644 --- a/CSF.Screenplay.Docs/docs/performables/toc.yml +++ b/CSF.Screenplay.Docs/docs/performables/toc.yml @@ -2,7 +2,5 @@ href: index.md - name: Stopwatch uid: CSF.Screenplay.Performables.StopwatchBuilder -- name: Web APIs - href: WebApis.md - name: TimeSpan builder uid: CSF.Screenplay.Performables.TimeSpanBuilder`1 \ No newline at end of file diff --git a/CSF.Screenplay.Docs/docs/toc.yml b/CSF.Screenplay.Docs/docs/toc.yml index a32c26c8..ecc58f7a 100644 --- a/CSF.Screenplay.Docs/docs/toc.yml +++ b/CSF.Screenplay.Docs/docs/toc.yml @@ -28,6 +28,13 @@ href: dependencyInjection/index.md - name: In the testing stack href: concepts/ScreenplayInTheTestingStack.md +- name: Extensions + href: extensions/index.md + items: + - name: Selenium + href: extensions/selenium/index.md + - name: Web APIs + href: extensions/webApis/index.md - name: Reference items: - name: Performables diff --git a/CSF.Screenplay.Docs/glossary/Extension.md b/CSF.Screenplay.Docs/glossary/Extension.md index daf3a7f6..dd5b892c 100644 --- a/CSF.Screenplay.Docs/glossary/Extension.md +++ b/CSF.Screenplay.Docs/glossary/Extension.md @@ -4,24 +4,18 @@ The Screenplay library doesn't do much on its own. The packages CSF.Screenplay.Abstractions and CSF.Screenplay offer very little in the way of [Abilities], [Actions] or [Questions]. Since these are the building blocks for writing [Tasks] and [Performances], developers won't get very far without installing one or more extensions. +There are [a few extensions available] which are maintained by the authors of CSF.Screenplay. + [Abilities]: Ability.md [Actions]: Action.md [Questions]: Question.md [Tasks]: Task.md [Performances]: xref:CSF.Screenplay.IPerformance +[a few extensions available]: ../docs/extensions/index.md -## Extensions developed by the authors of CSF.Screenplay - -This is a list of extensions which are developed and tested alongside Screenplay itself. - -| Name | Summary | -| ---- | ------- | -| CSF.Screenplay.Selenium | For using Screenplay to control a Selenium Web Driver, for browser automation | -| CSF.Screenplay.WebApis | For using Screenplay to send/receive requests/responses to/from web API endpoints | - -## Developers are free to write their own extensions +## Can't see what you need? -Developers are encouraged to write new extensions if they would like. +Developers are encouraged to write new extensions if they would like; it's not difficult. See the [extending Screenplay documentation] for more information. [extending Screenplay documentation]: ../docs/extendingScreenplay/ScreenplayExtensions.md diff --git a/CSF.Screenplay.WebApis/ParameterizedEndpoint.withResult.cs b/CSF.Screenplay.WebApis/ParameterizedEndpoint.withResult.cs index 23cb9d85..91aedad8 100644 --- a/CSF.Screenplay.WebApis/ParameterizedEndpoint.withResult.cs +++ b/CSF.Screenplay.WebApis/ParameterizedEndpoint.withResult.cs @@ -39,8 +39,8 @@ namespace CSF.Screenplay.WebApis /// /// /// The type of the parameters object which is required to create an HTTP request message - /// The type of response that the endpoint is expected to return. - public abstract class ParameterizedEndpoint : EndpointBase + /// The type of response that the endpoint is expected to return. + public abstract class ParameterizedEndpoint : EndpointBase { /// /// Gets a from the state of the current instance @@ -55,7 +55,7 @@ public abstract class ParameterizedEndpoint : EndpointBas /// /// The parameters required to create an HTTP request builder /// An HTTP request message builder - public abstract HttpRequestMessageBuilder GetHttpRequestMessageBuilder(TParameters parameters); + public abstract HttpRequestMessageBuilder GetHttpRequestMessageBuilder(TParameters parameters); /// /// Initializes a new instance of with a relative URI and an optional HTTP method. From 54363fb967e49562578c2925f429bbe9d86e9314 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Mon, 9 Feb 2026 22:32:26 +0000 Subject: [PATCH 5/6] Add usage example --- .../docs/extensions/webApis/index.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md index 904e3ac4..894db05e 100644 --- a/CSF.Screenplay.Docs/docs/extensions/webApis/index.md +++ b/CSF.Screenplay.Docs/docs/extensions/webApis/index.md @@ -41,3 +41,23 @@ The Live API represents an actual HTTP(S) web server which hosts the API with w [HTTP requests]: Requests.md [Endpoint]: Endpoints.md [HTTP Response]: Responses.md + +## Usage example + +Here is a brief usage example for using a JSON API with a defined endpoint, identified by URL and HTTP method. +The endpoint expects a parameter of a `PersonId` (a fictitious class, which accepts a person's name as a constructor parameter). +The endpoint returns a JSON-formatted response which is a representation of an `Animal` (another fictitious class, which has a string `Name` property). + +```csharp +using static CSF.Screenplay.WebApis.WebApiBuilder; + +static readonly JsonEndpoint getFavouriteAnimal = new ("https://api.example.com/person/getFavouriteAnimal", HttpMethod.Post); + +// this method would appear as part of a custom-written Task class, +// deriving from IPerformableWithResult +public async ValueTask PerformAsAsync(ICanPerform actor, CancellationToken cancellationToken) +{ + var animal = await actor.PerformAsync(GetTheJsonResult(getFavouriteAnimal, new("Jane Doe")), cancellationToken); + return animal.Name; +} +``` From 811bdd4dd9f3e47095efb2bc0e933ff8b106d083 Mon Sep 17 00:00:00 2001 From: Craig Fowler Date: Tue, 10 Feb 2026 13:25:22 +0000 Subject: [PATCH 6/6] Resolve #259 - Add extensions to getting started guide --- CSF.Screenplay.Docs/docs/index.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CSF.Screenplay.Docs/docs/index.md b/CSF.Screenplay.Docs/docs/index.md index c8554672..c652b639 100644 --- a/CSF.Screenplay.Docs/docs/index.md +++ b/CSF.Screenplay.Docs/docs/index.md @@ -1,6 +1,8 @@ # Get started with Screenplay -To get started with Screenplay, the first step is to decide how you'd like to use it: +## 1. Install Screenplay + +The first step is to decide how you'd like to use it: * [As a testing tool, with NUnit 3] * [As a testing tool, with Reqnroll] @@ -11,3 +13,15 @@ To get started with Screenplay, the first step is to decide how you'd like to us [As a testing tool, with Reqnroll]: gettingStarted/reqnroll/index.md [the retired SpecFlow]: https://reqnroll.net/news/2025/01/specflow-end-of-life-has-been-announced/ [As a process automation library]: gettingStarted/nonTesting/index.md + +## 2. Pick extensions + +To get the most from Screenplay you should install one or more [extensions]. +These give Screenplay the capability to interact with and control other systems. + +Here is [a list of the extensions which are authored alongside Screenplay's core]. +If you'd like, you are also encouraged to [write your own extension], adding new capabilities to Screenplay. + +[extensions]: ../glossary/Extension.md +[a list of the extensions which are authored alongside Screenplay's core]: extensions/index.md +[write your own extension]: extendingScreenplay/index.md