Skip to content

Commit 892beeb

Browse files
authored
Merge pull request #297 from csf-dev:259-webapi-docs
Resolve #259 - WebAPI documentation
2 parents ca997f1 + 811bdd4 commit 892beeb

14 files changed

Lines changed: 255 additions & 85 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Screenplay extensions
2+
3+
This page lists the officially-supported **[Screenplay Extensions]**.
4+
5+
* **[Selenium](selenium/index.md)**: _remote control Web Browsers using Selenium Web Driver_
6+
* **[Web APIs](webApis/index.md)**: _communicate with Web APIs with an HTTP Client_
7+
8+
[Screenplay Extensions]: ../../glossary/Extension.md
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Common combinations of requests and endpoints
2+
3+
The appropriate combination of [Request action] type and [Endpoint] type depends upon your use case.
4+
Common use cases are summarised in the table below.
5+
Information about reading this table follows.
6+
7+
| Request payload | Response type | Endpoint type | Request action type |
8+
| --------------- | ------------- | ------------- | ---------------- |
9+
| _None_ | _None_ | [`Endpoint`] | [`SendTheHttpRequest`] |
10+
| _None_ | Deserialized with custom logic | [`Endpoint<TResult>`] | [`SendTheHttpRequestAndGetTheResponse<T>`] |
11+
| _None_ | Deserialized from JSON | [`Endpoint<TResult>`] | [`SendTheHttpRequestAndGetJsonResponse<T>`] |
12+
| Serialized with custom logic | _None_ | Derive from [`ParameterizedEndpoint<TParameters>`] | [`SendTheHttpRequest`] |
13+
| Serialized with custom logic | Deserialized with custom logic | Derive from [`ParameterizedEndpoint<TParameters,TResult>`] | [`SendTheHttpRequestAndGetTheResponse<T>`] |
14+
| Serialized with custom logic | Deserialized from JSON | Derive from [`ParameterizedEndpoint<TParameters,TResult>`] | [`SendTheHttpRequestAndGetJsonResponse<T>`] |
15+
| Serialized with JSON | _None_ | [`JsonEndpoint<TParameters>`] | [`SendTheHttpRequest`] |
16+
| Serialized with JSON | Deserialized with custom logic | [`JsonEndpoint<TParameters,TResult>`] | [`SendTheHttpRequestAndGetTheResponse<T>`] |
17+
| Serialized with JSON | Deserialized from JSON | [`JsonEndpoint<TParameters,TResult>`] | [`SendTheHttpRequestAndGetJsonResponse<T>`] |
18+
19+
> [!TIP]
20+
> To decide which types of endpoint & performable:
21+
> _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.
22+
> Choose the **action type** based upon the technical details of reading the **response**._
23+
24+
[Request action]: Requests.md
25+
[Endpoint]: Endpoints.md
26+
[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint
27+
[`Endpoint<TResult>`]: xref:CSF.Screenplay.WebApis.Endpoint`1
28+
[`ParameterizedEndpoint<TParameters>`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`1
29+
[`ParameterizedEndpoint<TParameters,TResult>`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`2
30+
[`JsonEndpoint<TParameters>`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`1
31+
[`JsonEndpoint<TParameters,TResult>`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`2
32+
[`SendTheHttpRequest`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequest
33+
[`SendTheHttpRequestAndGetTheResponse<T>`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1
34+
[`SendTheHttpRequestAndGetJsonResponse<T>`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1
35+
36+
## The first two columns
37+
38+
The first two columns indicate:
39+
40+
1. The kind of **request payload** which will be sent<br>
41+
These are the parameters to the API function described by the endpoint
42+
1. The type of the expected **response body**<br>
43+
Where an API function returns a response, this is the .NET type which will be used to represent that response
44+
45+
Where _None_ is listed in either column this means _"not applicable"_.
46+
For example, an API function which uses no parameters will have no request payload.
47+
In the case of responses, _None_ might mean that the response body will be ignored.
48+
49+
## The second two columns
50+
51+
The second two columns indicate the Endpoint type and Request action type which are recommended in this scenario.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Endpoints
2+
3+
**Endpoints** are fundamental to this extension; they are .NET class instances which describe a piece of API functionality which may be consumed.
4+
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.
5+
6+
## Endpoint classes
7+
8+
The WebAPIs Screenplay extension provides a number of classes by which to describe endpoints.
9+
Developers using this extension are encouraged to create 'libraries' of Endpoints within their own logic.
10+
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.
11+
Every endpoint class derives from a base class named [`EndpointBase`].
12+
13+
The endpoint classes available are listed below.
14+
There is also [an article indicating how to choose an appropriate combination] of Endpoint and [Request action].
15+
16+
* [`Endpoint`]
17+
* [`Endpoint<TResponse>`]
18+
* [`ParameterizedEndpoint<TParameters>`] - _intended to be used as a base class_
19+
* [`ParameterizedEndpoint<TParameters,TResponse>`] - _intended to be used as a base class_
20+
* [`JsonEndpoint<TParameters>`]
21+
* [`JsonEndpoint<TParameters,TResponse>`]
22+
23+
[`EndpointBase`]: xref:CSF.Screenplay.WebApis.EndpointBase
24+
[`Endpoint`]: xref:CSF.Screenplay.WebApis.Endpoint
25+
[`Endpoint<TResponse>`]: xref:CSF.Screenplay.WebApis.Endpoint`1
26+
[`ParameterizedEndpoint<TParameters>`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`1
27+
[`ParameterizedEndpoint<TParameters,TResponse>`]: xref:CSF.Screenplay.WebApis.ParameterizedEndpoint`2
28+
[`JsonEndpoint<TParameters>`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`1
29+
[`JsonEndpoint<TParameters,TResponse>`]: xref:CSF.Screenplay.WebApis.JsonEndpoint`2
30+
[an article indicating how to choose an appropriate combination]: ChoosingEndpointsAndRequests.md
31+
[Request action]: Requests.md
32+
33+
## Common to all endpoints
34+
35+
All endpoints describe:
36+
37+
* [The URL pattern to reach the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.%23ctor(System.Uri,System.Net.Http.HttpMethod))
38+
* [The HTTP method used with the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.%23ctor(System.Uri,System.Net.Http.HttpMethod))
39+
* [A human-readable name for the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.Name)
40+
* [An optional timeout for the endpoint](xref:CSF.Screenplay.WebApis.EndpointBase.Timeout)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Request actions
2+
3+
Sending an HTTP request to an API is accomplished using a Screenplay [Action].
4+
There are three action types available; which to use depends upon the expected response from the API.
5+
[This article helps you choose the appropriate combination of Request Action and Endpoint types].
6+
7+
[Action]: ../../../glossary/Action.md
8+
[This article helps you choose the appropriate combination of Request Action and Endpoint types]: ChoosingEndpointsAndRequests.md
9+
10+
## The three action types
11+
12+
As might be evident from their names, each request action type is used for a different kind of expected response message.
13+
In the case of `SendTheHttpRequest`, there is no response expected (or the response will be ignored).
14+
The other two types are for either a JSON response or a response which requires custom deserialization.
15+
16+
* [`SendTheHttpRequest`](xref:CSF.Screenplay.WebApis.SendTheHttpRequest)
17+
* [`SendTheHttpRequestAndGetJsonResponse<TResponse>`](xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1)
18+
* [`SendTheHttpRequestAndGetTheResponse<TResponse>`](xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1)
19+
20+
## Use `WebApiBuilder` to simplify usage
21+
22+
A builder/helper class is available to simplify getting the appropriate Request action; this is [`WebApiBuilder`].
23+
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.
24+
25+
When an approproate [Endpoint] type has been used, the [`WebApiBuilder`] class will make it very easy to select the correct action, via type inference.
26+
To get a request for an API function which is expected to return a JSON-formatted response, use the method `GetTheJsonResult`.
27+
To get a request for any other API function, use the method `SendTheHttpRequest`.
28+
Both of these methods have several overloads, for each type of endpoint which could use them.
29+
30+
[`WebApiBuilder`]: xref:CSF.Screenplay.WebApis.WebApiBuilder
31+
[Performable]: ../../../glossary/Performable.md
32+
[Endpoint]: Endpoints.md
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Responses
2+
3+
The WebAPIs extension for Screenplay supports two kinds of responses.
4+
5+
## JSON
6+
7+
For JSON-based endpoints, use the [`SendTheHttpRequestAndGetJsonResponse<TResponse>`] [request action type] and the response from the API function will automatically be deserialized into an instance of the `TResponse` type.
8+
9+
[`SendTheHttpRequestAndGetJsonResponse<TResponse>`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetJsonResponse`1
10+
[request action type]: Requests.md
11+
12+
## Other response types
13+
14+
For other endpoints with non-JSON responses, it is up to the consumer to deserialize the response using whatever logic is appropriate.
15+
In this case, using the [`SendTheHttpRequestAndGetTheResponse<TResponse>`] request action type, the returned value from `PerformAsAsync` is an instance of [`HttpResponseMessageAndResponseType<TResponse>`].
16+
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.
17+
This should provide sufficient information to deserialize the response accordingly.
18+
19+
[`SendTheHttpRequestAndGetTheResponse<TResponse>`]: xref:CSF.Screenplay.WebApis.SendTheHttpRequestAndGetTheResponse`1
20+
[`HttpResponseMessageAndResponseType<TResponse>`]: xref:CSF.Screenplay.WebApis.HttpResponseMessageAndResponseType`1
21+
[`HttpResponseMessage`]: xref:System.Net.Http.HttpResponseMessage
Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,63 @@
1-
TODO: Write this docs page
1+
---
2+
uid: WebApisArticle
3+
---
4+
5+
# CSF.Screenplay.WebApis Extension
6+
7+
The Web APIs Extension allows [Actors] to communicate with HTTP web API endpoints within a Screenplay [Performance].
8+
9+
[Actors]: xref:CSF.Screenplay.Actor
10+
[Performance]: xref:CSF.Screenplay.IPerformance
11+
12+
## Overview
13+
14+
The fundamentals of this Screenplay extension are shown in the diagram below.
15+
The concepts of the [Actor] and [Ability] (the ability is named [`MakeWebApiRequests`]) are explained in Screenplay's core documentation.
16+
Other concepts are explained below.
17+
18+
This extension provides **[Actions]** which allow the Actor to build and send [HTTP requests] based upon [Endpoint] definitions.
19+
These requests are sent via the HTTP client which is exposed by the [`MakeWebApiRequests`] Ability, to a live API server.
20+
The server returns an [HTTP Response], which the extension formats into a result object.
21+
22+
```mermaid
23+
flowchart
24+
Ability -- "Has ability" --> Actor
25+
Actor -- "Makes requests" --> Request
26+
Endpoint -- "Requests target" --> Request
27+
Request --> api["Live API"]
28+
Ability -- "Facilitates request" --> api
29+
api --> Response
30+
31+
style api fill:#ee9,stroke:#bb6
32+
```
33+
34+
Note that the **Live API** in this diagram _is not a part of Screenplay or this extension_.
35+
The Live API represents an actual HTTP(S) web server which hosts the API with which Screenplay is communicating.
36+
37+
[Actor]: xref:CSF.Screenplay.Actor
38+
[Ability]: xref:AbilityGlossaryItem
39+
[`MakeWebApiRequests`]: xref:CSF.Screenplay.WebApis.MakeWebApiRequests
40+
[Actions]: ../../../glossary/Action.md
41+
[HTTP requests]: Requests.md
42+
[Endpoint]: Endpoints.md
43+
[HTTP Response]: Responses.md
44+
45+
## Usage example
46+
47+
Here is a brief usage example for using a JSON API with a defined endpoint, identified by URL and HTTP method.
48+
The endpoint expects a parameter of a `PersonId` (a fictitious class, which accepts a person's name as a constructor parameter).
49+
The endpoint returns a JSON-formatted response which is a representation of an `Animal` (another fictitious class, which has a string `Name` property).
50+
51+
```csharp
52+
using static CSF.Screenplay.WebApis.WebApiBuilder;
53+
54+
static readonly JsonEndpoint<PersonId,Animal> getFavouriteAnimal = new ("https://api.example.com/person/getFavouriteAnimal", HttpMethod.Post);
55+
56+
// this method would appear as part of a custom-written Task class,
57+
// deriving from IPerformableWithResult<string>
58+
public async ValueTask<string> PerformAsAsync(ICanPerform actor, CancellationToken cancellationToken)
59+
{
60+
var animal = await actor.PerformAsync(GetTheJsonResult(getFavouriteAnimal, new("Jane Doe")), cancellationToken);
61+
return animal.Name;
62+
}
63+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
- name: Web APIs
2+
href: index.md
3+
- name: Endpoints
4+
href: Endpoints.md
5+
- name: Requests
6+
href: Requests.md
7+
- name: Choosing endpoint & request types
8+
href: ChoosingEndpointsAndRequests.md
9+
- name: Responses
10+
href: Responses.md

CSF.Screenplay.Docs/docs/index.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Get started with Screenplay
22

3-
To get started with Screenplay, the first step is to decide how you'd like to use it:
3+
## 1. Install Screenplay
4+
5+
The first step is to decide how you'd like to use it:
46

57
* [As a testing tool, with NUnit 3]
68
* [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
1113
[As a testing tool, with Reqnroll]: gettingStarted/reqnroll/index.md
1214
[the retired SpecFlow]: https://reqnroll.net/news/2025/01/specflow-end-of-life-has-been-announced/
1315
[As a process automation library]: gettingStarted/nonTesting/index.md
16+
17+
## 2. Pick extensions
18+
19+
To get the most from Screenplay you should install one or more [extensions].
20+
These give Screenplay the capability to interact with and control other systems.
21+
22+
Here is [a list of the extensions which are authored alongside Screenplay's core].
23+
If you'd like, you are also encouraged to [write your own extension], adding new capabilities to Screenplay.
24+
25+
[extensions]: ../glossary/Extension.md
26+
[a list of the extensions which are authored alongside Screenplay's core]: extensions/index.md
27+
[write your own extension]: extendingScreenplay/index.md

CSF.Screenplay.Docs/docs/performables/WebApis.md

Lines changed: 0 additions & 59 deletions
This file was deleted.

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ These are all accessible from the builder class [`StopwatchBuilder`].
1616
[`UseAStopwatch`]: xref:CSF.Screenplay.Abilities.UseAStopwatch
1717
[`StopwatchBuilder`]: xref:CSF.Screenplay.Performables.StopwatchBuilder
1818

19-
## Interacting with web APIs
20-
21-
The NuGet package [CSF.Screenplay.WebApis] provides an ability, performables and supporting types to interact with web API endpoints.
22-
Further information is available on [the web API documentation page].
23-
24-
[CSF.Screenplay.WebApis]: https://www.nuget.org/packages/CSF.Screenplay.WebApis/
25-
[the web API documentation page]: WebApis.md
26-
2719
## TimeSpan builder
2820

2921
The [`TimeSpanBuilder<TOtherBuilder>`] is not a complete performable builder; it is intended to supplement other builders such as those of your own design.

0 commit comments

Comments
 (0)