@serenity-js/rest 3.0.0-rc.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +80 -1851
  2. package/README.md +8 -10
  3. package/lib/index.d.ts +2 -1
  4. package/lib/index.d.ts.map +1 -0
  5. package/lib/index.js +6 -2
  6. package/lib/index.js.map +1 -1
  7. package/lib/models/DeleteRequest.d.ts +66 -0
  8. package/lib/models/DeleteRequest.d.ts.map +1 -0
  9. package/lib/models/DeleteRequest.js +73 -0
  10. package/lib/models/DeleteRequest.js.map +1 -0
  11. package/lib/models/GetRequest.d.ts +73 -0
  12. package/lib/models/GetRequest.d.ts.map +1 -0
  13. package/lib/models/GetRequest.js +80 -0
  14. package/lib/models/GetRequest.js.map +1 -0
  15. package/lib/models/HTTPRequest.d.ts +48 -0
  16. package/lib/models/HTTPRequest.d.ts.map +1 -0
  17. package/lib/{model → models}/HTTPRequest.js +14 -23
  18. package/lib/models/HTTPRequest.js.map +1 -0
  19. package/lib/models/HeadRequest.d.ts +58 -0
  20. package/lib/models/HeadRequest.d.ts.map +1 -0
  21. package/lib/models/HeadRequest.js +65 -0
  22. package/lib/models/HeadRequest.js.map +1 -0
  23. package/lib/models/OptionsRequest.d.ts +61 -0
  24. package/lib/models/OptionsRequest.d.ts.map +1 -0
  25. package/lib/models/OptionsRequest.js +68 -0
  26. package/lib/models/OptionsRequest.js.map +1 -0
  27. package/lib/models/PatchRequest.d.ts +65 -0
  28. package/lib/models/PatchRequest.d.ts.map +1 -0
  29. package/lib/models/PatchRequest.js +74 -0
  30. package/lib/models/PatchRequest.js.map +1 -0
  31. package/lib/models/PostRequest.d.ts +105 -0
  32. package/lib/models/PostRequest.d.ts.map +1 -0
  33. package/lib/models/PostRequest.js +114 -0
  34. package/lib/models/PostRequest.js.map +1 -0
  35. package/lib/models/PutRequest.d.ts +75 -0
  36. package/lib/models/PutRequest.d.ts.map +1 -0
  37. package/lib/models/PutRequest.js +84 -0
  38. package/lib/models/PutRequest.js.map +1 -0
  39. package/lib/{model → models}/index.d.ts +1 -0
  40. package/lib/models/index.d.ts.map +1 -0
  41. package/lib/{model → models}/index.js +5 -1
  42. package/lib/models/index.js.map +1 -0
  43. package/lib/screenplay/abilities/CallAnApi.d.ts +88 -99
  44. package/lib/screenplay/abilities/CallAnApi.d.ts.map +1 -0
  45. package/lib/screenplay/abilities/CallAnApi.js +94 -107
  46. package/lib/screenplay/abilities/CallAnApi.js.map +1 -1
  47. package/lib/screenplay/abilities/index.d.ts +1 -0
  48. package/lib/screenplay/abilities/index.d.ts.map +1 -0
  49. package/lib/screenplay/abilities/index.js +5 -1
  50. package/lib/screenplay/abilities/index.js.map +1 -1
  51. package/lib/screenplay/index.d.ts +1 -0
  52. package/lib/screenplay/index.d.ts.map +1 -0
  53. package/lib/screenplay/index.js +5 -1
  54. package/lib/screenplay/index.js.map +1 -1
  55. package/lib/screenplay/interactions/ChangeApiConfig.d.ts +96 -95
  56. package/lib/screenplay/interactions/ChangeApiConfig.d.ts.map +1 -0
  57. package/lib/screenplay/interactions/ChangeApiConfig.js +98 -107
  58. package/lib/screenplay/interactions/ChangeApiConfig.js.map +1 -1
  59. package/lib/screenplay/interactions/Send.d.ts +24 -41
  60. package/lib/screenplay/interactions/Send.d.ts.map +1 -0
  61. package/lib/screenplay/interactions/Send.js +37 -51
  62. package/lib/screenplay/interactions/Send.js.map +1 -1
  63. package/lib/screenplay/interactions/index.d.ts +1 -1
  64. package/lib/screenplay/interactions/index.d.ts.map +1 -0
  65. package/lib/screenplay/interactions/index.js +5 -2
  66. package/lib/screenplay/interactions/index.js.map +1 -1
  67. package/lib/screenplay/questions/LastResponse.d.ts +152 -98
  68. package/lib/screenplay/questions/LastResponse.d.ts.map +1 -0
  69. package/lib/screenplay/questions/LastResponse.js +149 -97
  70. package/lib/screenplay/questions/LastResponse.js.map +1 -1
  71. package/lib/screenplay/questions/index.d.ts +1 -0
  72. package/lib/screenplay/questions/index.d.ts.map +1 -0
  73. package/lib/screenplay/questions/index.js +5 -1
  74. package/lib/screenplay/questions/index.js.map +1 -1
  75. package/package.json +20 -43
  76. package/src/index.ts +1 -1
  77. package/src/models/DeleteRequest.ts +73 -0
  78. package/src/models/GetRequest.ts +80 -0
  79. package/src/{model → models}/HTTPRequest.ts +17 -26
  80. package/src/models/HeadRequest.ts +65 -0
  81. package/src/models/OptionsRequest.ts +68 -0
  82. package/src/models/PatchRequest.ts +75 -0
  83. package/src/models/PostRequest.ts +115 -0
  84. package/src/models/PutRequest.ts +85 -0
  85. package/src/screenplay/abilities/CallAnApi.ts +90 -108
  86. package/src/screenplay/interactions/ChangeApiConfig.ts +99 -111
  87. package/src/screenplay/interactions/Send.ts +46 -61
  88. package/src/screenplay/interactions/index.ts +0 -1
  89. package/src/screenplay/questions/LastResponse.ts +153 -100
  90. package/tsconfig.build.json +10 -0
  91. package/lib/model/DeleteRequest.d.ts +0 -63
  92. package/lib/model/DeleteRequest.js +0 -70
  93. package/lib/model/DeleteRequest.js.map +0 -1
  94. package/lib/model/GetRequest.d.ts +0 -70
  95. package/lib/model/GetRequest.js +0 -77
  96. package/lib/model/GetRequest.js.map +0 -1
  97. package/lib/model/HTTPRequest.d.ts +0 -56
  98. package/lib/model/HTTPRequest.js.map +0 -1
  99. package/lib/model/HeadRequest.d.ts +0 -55
  100. package/lib/model/HeadRequest.js +0 -62
  101. package/lib/model/HeadRequest.js.map +0 -1
  102. package/lib/model/OptionsRequest.d.ts +0 -58
  103. package/lib/model/OptionsRequest.js +0 -65
  104. package/lib/model/OptionsRequest.js.map +0 -1
  105. package/lib/model/PatchRequest.d.ts +0 -65
  106. package/lib/model/PatchRequest.js +0 -74
  107. package/lib/model/PatchRequest.js.map +0 -1
  108. package/lib/model/PostRequest.d.ts +0 -102
  109. package/lib/model/PostRequest.js +0 -111
  110. package/lib/model/PostRequest.js.map +0 -1
  111. package/lib/model/PutRequest.d.ts +0 -75
  112. package/lib/model/PutRequest.js +0 -84
  113. package/lib/model/PutRequest.js.map +0 -1
  114. package/lib/model/index.js.map +0 -1
  115. package/lib/screenplay/interactions/ChangeApiUrl.d.ts +0 -82
  116. package/lib/screenplay/interactions/ChangeApiUrl.js +0 -97
  117. package/lib/screenplay/interactions/ChangeApiUrl.js.map +0 -1
  118. package/src/model/DeleteRequest.ts +0 -71
  119. package/src/model/GetRequest.ts +0 -78
  120. package/src/model/HeadRequest.ts +0 -63
  121. package/src/model/OptionsRequest.ts +0 -66
  122. package/src/model/PatchRequest.ts +0 -76
  123. package/src/model/PostRequest.ts +0 -113
  124. package/src/model/PutRequest.ts +0 -86
  125. package/src/screenplay/interactions/ChangeApiUrl.ts +0 -97
  126. package/tsconfig.eslint.json +0 -10
  127. /package/src/{model → models}/index.ts +0 -0
@@ -1,72 +1,74 @@
1
- import { Ability, ConfigurationError, LogicError, TestCompromisedError, UsesAbilities } from '@serenity-js/core';
2
- import axios, { AxiosError, AxiosInstance, AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
3
- const mergeConfig = require('axios/lib/core/mergeConfig'); // eslint-disable-line @typescript-eslint/no-var-requires
4
- const buildFullPath = require('axios/lib/core/buildFullPath'); // eslint-disable-line @typescript-eslint/no-var-requires
1
+ import { Ability, ConfigurationError, LogicError, TestCompromisedError } from '@serenity-js/core';
2
+ import axios, { AxiosDefaults, AxiosError, AxiosInstance, AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
5
3
 
6
4
  /**
7
- * @desc
8
- * An {@link @serenity-js/core/lib/screenplay~Ability} that enables the {@link Actor} to call a HTTP API.
9
- * If you need to connect via a proxy, check out [this article](https://janmolak.com/node-js-axios-behind-corporate-proxies-8b17a6f31f9d).
5
+ * An {@apilink Ability} that enables the {@apilink Actor} to call an HTTP API.
10
6
  *
11
- * @example <caption>Using a default Axios HTTP client</caption>
12
- * import { Actor } from '@serenity-js/core';
13
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
14
- * import { Ensure, equals } from '@serenity-js/assertions';
7
+ * If you need to connect via a proxy, check out ["Using Axios behind corporate proxies"](https://janmolak.com/node-js-axios-behind-corporate-proxies-8b17a6f31f9d).
15
8
  *
16
- * const actor = Actor.named('Apisit').whoCan(
17
- * CallAnApi.at('https://myapp.com/api'),
18
- * );
9
+ * ## Using the default Axios HTTP client
19
10
  *
20
- * actor.attemptsTo(
21
- * Send.a(GetRequest.to('/users/2')),
22
- * Ensure.that(LastResponse.status(), equals(200)),
23
- * );
11
+ * ```ts
12
+ * import { actorCalled } from '@serenity-js/core'
13
+ * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
14
+ * import { Ensure, equals } from '@serenity-js/assertions'
24
15
  *
25
- * @example <caption>Using Axios client with custom configuration</caption>
26
- * import { Actor } from '@serenity-js/core';
27
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
28
- * import { Ensure, equals } from '@serenity-js/assertions';
16
+ * await actorCalled('Apisitt')
17
+ * .whoCan(
18
+ * CallAnApi.at('https://api.example.org/')
19
+ * )
20
+ * .attemptsTo(
21
+ * Send.a(GetRequest.to('/users/2')),
22
+ * Ensure.that(LastResponse.status(), equals(200)),
23
+ * )
24
+ * ```
29
25
  *
30
- * import axios from 'axios';
26
+ * ## Using Axios client with custom configuration
31
27
  *
32
- * const axiosInstance = axios.create({
33
- * timeout: 5 * 1000,
34
- * headers: {
35
- * 'X-Custom-Api-Key': 'secret-key',
36
- * },
37
- * });
28
+ * ```ts
29
+ * import { actorCalled } from '@serenity-js/core'
30
+ * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
31
+ * import { Ensure, equals } from '@serenity-js/assertions'
38
32
  *
39
- * const actor = Actor.named('Apisit').whoCan(
40
- * CallAnApi.using(axiosInstance),
41
- * );
33
+ * import * as axios from 'axios'
42
34
  *
43
- * actor.attemptsTo(
44
- * Send.a(GetRequest.to('/users/2')),
45
- * Ensure.that(LastResponse.status(), equals(200)),
46
- * );
35
+ * const axiosInstance = axios.create({
36
+ * timeout: 5 * 1000,
37
+ * headers: {
38
+ * 'X-Custom-Api-Key': 'secret-key',
39
+ * },
40
+ * });
47
41
  *
48
- * @see https://github.com/axios/axios
49
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
42
+ * await actorCalled('Apisitt')
43
+ * .whoCan(
44
+ * CallAnApi.using(axiosInstance),
45
+ * )
46
+ * .attemptsTo(
47
+ * Send.a(GetRequest.to('/users/2')),
48
+ * Ensure.that(LastResponse.status(), equals(200)),
49
+ * )
50
+ * ```
50
51
  *
51
- * @public
52
- * @implements {@link @serenity-js/core/lib/screenplay~Ability}
52
+ * ## Learn more
53
+ * - https://github.com/axios/axios
54
+ * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
55
+ *
56
+ * @group Abilities
53
57
  */
54
- export class CallAnApi implements Ability {
58
+ export class CallAnApi extends Ability {
55
59
 
56
60
  /** @private */
57
61
  private lastResponse: AxiosResponse;
58
62
 
59
63
  /**
60
- * @desc
61
- * Ability to Call and api at a specified baseUrl
64
+ * Produces an {@apilink Ability|ability} to call a REST api at a specified baseUrl
62
65
  *
63
- * Default timeout is set to 2s.
66
+ * Default timeout is set to 2s.
64
67
  *
65
- * Default request headers:
66
- * - Accept: application/json,application/xml
68
+ * Default request headers:
69
+ * - `Accept`: `application/json,application/xml`
67
70
  *
68
- * @param {string} baseURL
69
- * @returns {CallAnApi}
71
+ * @param baseURL
70
72
  */
71
73
  static at(baseURL: string): CallAnApi {
72
74
  return new CallAnApi(axios.create({
@@ -77,111 +79,91 @@ export class CallAnApi implements Ability {
77
79
  }
78
80
 
79
81
  /**
80
- * @desc
81
- * Ability to Call a REST API using a given axios instance.
82
+ * Produces an {@apilink Ability|ability} to call a REST API using a given axios instance.
82
83
  *
83
- * Useful when you need to customise Axios to
84
- * [make it aware of proxies](https://janmolak.com/node-js-axios-behind-corporate-proxies-8b17a6f31f9d),
85
- * for example.
84
+ * Useful when you need to customise Axios to
85
+ * [make it aware of proxies](https://janmolak.com/node-js-axios-behind-corporate-proxies-8b17a6f31f9d),
86
+ * for example.
86
87
  *
87
- * @param {AxiosInstance} axiosInstance
88
- * @returns {CallAnApi}
88
+ * #### Learn more
89
+ * - [AxiosInstance](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L235-L238)
89
90
  *
90
- * @see {@link AxiosInstance}
91
+ * @param axiosInstance
91
92
  */
92
93
  static using(axiosInstance: AxiosInstance): CallAnApi {
93
94
  return new CallAnApi(axiosInstance);
94
95
  }
95
96
 
96
97
  /**
97
- * @desc
98
- * Used to access the Actor's ability to {@link CallAnApi}
99
- * from within the {@link @serenity-js/core/lib/screenplay~Interaction} classes,
100
- * such as {@link Send}.
98
+ * #### Learn more
99
+ * - [AxiosInstance](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L235-L238)
101
100
  *
102
- * @param {UsesAbilities} actor
103
- * @return {CallAnApi}
104
- */
105
- static as(actor: UsesAbilities): CallAnApi {
106
- return actor.abilityTo(CallAnApi);
107
- }
108
-
109
- /**
110
- * @param {AxiosInstance} axiosInstance
101
+ * @param axiosInstance
111
102
  * A pre-configured instance of the Axios HTTP client
112
- *
113
- * @see {@link AxiosInstance}
114
103
  */
115
104
  constructor(private readonly axiosInstance: AxiosInstance) {
105
+ super();
116
106
  }
117
107
 
118
108
  /**
119
- * @desc
120
- * Allows for the original Axios config to be changed after
121
- * the {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}
122
- * has been instantiated and given to the {@link Actor}.
109
+ * Allows for the original Axios config to be changed after
110
+ * the {@apilink Ability|ability} to {@apilink CallAnApi}
111
+ * has been instantiated and given to the {@apilink Actor}.
123
112
  *
124
- * @param {function (original: AxiosRequestConfig): any} fn
125
- * @returns {void}
113
+ * #### Learn more
114
+ * - [AxiosRequestConfig](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L75-L113)
126
115
  *
127
- * @see {@link AxiosRequestConfig}
116
+ * @param fn
128
117
  */
129
- modifyConfig(fn: (original: AxiosRequestConfig) => any): void {
118
+ modifyConfig(fn: (original: AxiosDefaults<any>) => any): void {
130
119
  fn(this.axiosInstance.defaults);
131
120
  }
132
121
 
133
122
  /**
134
- * @desc
135
- * Sends a HTTP request to a specified url.
136
- * Response will be cached and available via {@link CallAnApi#mapLastResponse}
137
- *
138
- * @param {AxiosRequestConfig} config
139
- * Axios request configuration, which can be used to override the defaults
140
- * provided when the {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability} is instantiated
123
+ * Sends an HTTP request to a specified url.
124
+ * Response will be cached and available via {@apilink mapLastResponse}
141
125
  *
142
- * @returns {Promise<AxiosResponse>}
143
- * A promise of an AxiosResponse
126
+ * #### Learn more
127
+ * - [AxiosRequestConfig](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L75-L113)
128
+ * - [AxiosResponse](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L133-L140)
144
129
  *
145
- * @see {@link AxiosRequestConfig}
146
- * @see {@link AxiosResponse}
130
+ * @param config
131
+ * Axios request configuration, which can be used to override the defaults
132
+ * provided when the {@apilink Ability|ability} to {@apilink CallAnApi} was instantiated.
147
133
  */
148
134
  request(config: AxiosRequestConfig): Promise<AxiosResponse> {
149
135
  return this.captureResponseOf(this.axiosInstance.request(config));
150
136
  }
151
137
 
152
138
  /**
153
- * @desc
154
- * Resolves the final URL, based on the {@link AxiosRequestConfig} provided
155
- * any any defaults {@link AxiosInstance} has been configured with.
139
+ * Resolves the final URL, based on the {@apilink AxiosRequestConfig} provided
140
+ * and any defaults that the {@apilink AxiosInstance} has been configured with.
156
141
  *
157
- * @param {AxiosRequestConfig} config
158
- * @returns {string}
142
+ * #### Learn more
143
+ * - [AxiosRequestConfig](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L75-L113)
144
+ * - [AxiosInstance](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L235-L238)
159
145
  *
160
- * @see {@link AxiosRequestConfig}
161
- * @see {@link AxiosInstance}
146
+ * @param config
162
147
  */
163
148
  resolveUrl(config: AxiosRequestConfig): string {
164
- const merged = mergeConfig(this.axiosInstance.defaults, config);
165
-
166
- return buildFullPath(merged.baseURL, merged.url);
149
+ return this.axiosInstance.getUri(config);
167
150
  }
168
151
 
169
152
  /**
170
- * @desc
171
- * Maps the last cached response to another type.
172
- * Useful when you need to extract a portion of the {@link AxiosResponse} object.
153
+ * Maps the last cached response to another type.
154
+ * Useful when you need to extract a portion of the {@apilink AxiosResponse} object.
173
155
  *
174
- * @param {function<T>(AxiosResponse): T} fn - mapper function
175
- * @returns {T}
156
+ * #### Learn more
157
+ * - [AxiosResponse](https://github.com/axios/axios/blob/v0.27.2/index.d.ts#L133-L140)
176
158
  *
177
- * @see {@link AxiosResponse}
159
+ * @param mappingFunction
178
160
  */
179
- mapLastResponse<T>(fn: (response: AxiosResponse) => T): T {
161
+ mapLastResponse<T>(mappingFunction: (response: AxiosResponse) => T): T {
180
162
  if (!this.lastResponse) {
181
163
  throw new LogicError(`Make sure to perform a HTTP API call before checking on the response`);
182
164
  }
183
165
 
184
- return fn(this.lastResponse);
166
+ return mappingFunction(this.lastResponse);
185
167
  }
186
168
 
187
169
  private captureResponseOf(promisedResponse: AxiosPromise): AxiosPromise {
@@ -1,123 +1,123 @@
1
- import { Answerable, AnswersQuestions, CollectsArtifacts, Interaction, LogicError, UsesAbilities } from '@serenity-js/core';
1
+ import { Answerable, AnswersQuestions, CollectsArtifacts, d, Interaction, LogicError, UsesAbilities } from '@serenity-js/core';
2
2
  import { URL } from 'url';
3
3
 
4
4
  import { CallAnApi } from '../abilities';
5
5
 
6
6
  /**
7
- * @desc
8
- * Changes configuration of the {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}
9
- * the {@link @serenity-js/core/lib/screenplay/actor~Actor}
10
- * executing this {@link @serenity-js/core/lib/screenplay~Interaction} has been configured with.
11
- *
12
- * @example <caption>Changing API URL for all subsequent requests</caption>
13
- * import { actorCalled } from '@serenity-js/core';
14
- * import { Navigate, Target, Text } from '@serenity-js/protractor';
15
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
16
- * import { Ensure, equals } from '@serenity-js/assertions';
17
- * import { protractor, by } from 'protractor';
18
- *
19
- * import axios from 'axios';
20
- *
21
- * const actor = actorCalled('Apisitt').whoCan(
22
- * BrowseTheWeb.using(protractor.browser),
23
- *
24
- * // Note: no default base URL is given when the axios instance is created
25
- * CallAnApi.using(axios.create()),
26
- * );
27
- *
28
- * // Let's imagine that the website under test displays
29
- * // a dynamically generated API URL we'd like to use
30
- * const ApiDetailsWidget = {
31
- * Url: Target.the('API URL').located(by.id('api-url')),
32
- * }
33
- *
34
- * actor.attemptsTo(
35
- * Navigate.to('/profile'),
36
- *
37
- * // We change the API URL based on the text displayed in the widget
38
- * // (although we could change it to some arbitrary string too).
39
- * ChangeApiConfig.setUrlTo(Text.of(ApiDetailsWidget.Url)),
40
- *
41
- * // Any subsequent request will be sent to the newly set URL
42
- * Send.a(GetRequest.to('/projects')),
43
- * Ensure.that(LastResponse.status(), equals(200)),
44
- * );
45
- *
46
- * @example <caption>Changing API port for all subsequent requests</caption>
47
- * import { actorCalled } from '@serenity-js/core';
48
- * import { LocalServer, ManageALocalServer, StartLocalServer } from '@serenity-js/local-server';
49
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
50
- * import { Ensure, equals } from '@serenity-js/assertions';
51
- *
52
- * const actor = actorCalled('Apisitt').whoCan(
53
- * ManageALocalServer.runningAHttpListener(someServer),
54
- * CallAnApi.at('http://localhost'),
55
- * );
56
- *
57
- * actor.attemptsTo(
58
- * StartALocalServer.onRandomPort(),
59
- * ChangeApiConfig.setPortTo(LocalServer.port()),
60
- * Send.a(GetRequest.to('/api')),
61
- * Ensure.that(LastResponse.status(), equals(200)),
62
- * );
63
- *
64
- * @example <caption>Setting a header for all subsequent requests</caption>
65
- * import { actorCalled, Question } from '@serenity-js/core';
66
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest';
67
- * import { Ensure, equals } from '@serenity-js/assertions';
68
- *
69
- * const actor = actorCalled('Apisitt').whoCan(
70
- * CallAnApi.at('http://localhost'),
71
- * );
72
- *
73
- * // A sample Question reading Node process environment variable
74
- * const EnvVar = (var_name: string) =>
75
- * Question.about(`${ name } environment variable`, actor => process.env[var_name]);
76
- *
77
- * actor.attemptsTo(
78
- * ChangeApiConfig.setHeader('Authorization', EnvVar('TOKEN')),
79
- * Send.a(GetRequest.to('/api')),
80
- * Ensure.that(LastResponse.status(), equals(200)),
81
- * );
7
+ * Changes configuration of the {@apilink Ability|ability} to {@apilink CallAnApi}
8
+ * that the {@apilink Actor|actor} executing this {@apilink Interaction|interaction} has been configured with.
9
+ *
10
+ * ## Changing API URL for all subsequent requests
11
+ *
12
+ * ```ts
13
+ * import { actorCalled } from '@serenity-js/core';
14
+ * import { By Navigate, PageElement, Text } from '@serenity-js/web';
15
+ * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
16
+ * import { Ensure, equals } from '@serenity-js/assertions';
17
+ *
18
+ * import * as axios from 'axios';
19
+ *
20
+ * // Let's imagine that the website under test displays
21
+ * // a dynamically generated API URL that we would like to use
22
+ * const ApiDetailsWidget = {
23
+ * url: () => PageElement.located(By.id('api-url')).describedAs('API URL'),
24
+ * }
25
+ *
26
+ * await actorCalled('Apisitt')
27
+ * .whoCan(
28
+ * BrowseTheWeb.using(protractor.browser),
29
+ *
30
+ * // Note: no default base URL is given when the axios instance is created
31
+ * CallAnApi.using(axios.create()),
32
+ * )
33
+ * .attemptsTo(
34
+ * Navigate.to('/profile'),
35
+ *
36
+ * // We change the API URL based on the text displayed in the widget
37
+ * // (although we could change it to some arbitrary string too).
38
+ * ChangeApiConfig.setUrlTo(Text.of(ApiDetailsWidget.url())),
39
+ *
40
+ * // Any subsequent request will be sent to the newly set URL
41
+ * Send.a(GetRequest.to('/projects')),
42
+ * Ensure.that(LastResponse.status(), equals(200)),
43
+ * )
44
+ * ```
45
+ *
46
+ * ## Changing API port for all subsequent requests
47
+ *
48
+ * ```ts
49
+ * import { actorCalled } from '@serenity-js/core'
50
+ * import { LocalServer, ManageALocalServer, StartLocalServer } from '@serenity-js/local-server'
51
+ * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
52
+ * import { Ensure, equals } from '@serenity-js/assertions'
53
+ *
54
+ * await actorCalled('Apisitt')
55
+ * .whoCan(
56
+ * ManageALocalServer.runningAHttpListener(someServer),
57
+ * CallAnApi.at('http://localhost'),
58
+ * )
59
+ * .attemptsTo(
60
+ * StartALocalServer.onRandomPort(),
61
+ * ChangeApiConfig.setPortTo(LocalServer.port()),
62
+ * Send.a(GetRequest.to('/api')),
63
+ * Ensure.that(LastResponse.status(), equals(200)),
64
+ * )
65
+ * ```
66
+ *
67
+ * ## Setting a header for all subsequent requests
68
+ *
69
+ * ```ts
70
+ * import { actorCalled, Question } from '@serenity-js/core'
71
+ * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
72
+ * import { Ensure, equals } from '@serenity-js/assertions'
73
+ *
74
+ * // A sample Question reading a Node process environment variable
75
+ * const EnvVar = (var_name: string) =>
76
+ * Question.about(`${ name } environment variable`, actor => process.env[var_name]);
77
+ *
78
+ * await actorCalled('Apisitt')
79
+ * .whoCan(
80
+ * CallAnApi.at('http://localhost'),
81
+ * )
82
+ * .attemptsTo(
83
+ * ChangeApiConfig.setHeader('Authorization', EnvVar('TOKEN')),
84
+ * Send.a(GetRequest.to('/api')),
85
+ * Ensure.that(LastResponse.status(), equals(200)),
86
+ * )
87
+ * ```
88
+ *
89
+ * @group Activities
82
90
  */
83
91
  export class ChangeApiConfig {
84
92
 
85
93
  /**
86
- * @desc
87
- * Instructs the {@link @serenity-js/core/lib/screenplay/actor~Actor}
88
- * to change the base URL of their {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}
94
+ * Instructs the {@apilink Actor|actor} to change the base URL
95
+ * of their {@apilink Ability|ability} to {@apilink CallAnApi}
89
96
  *
90
- * @param {@serenity-js/core/lib/screenplay~Answerable<string>} newApiUrl
91
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
97
+ * @param newApiUrl
92
98
  */
93
99
  static setUrlTo(newApiUrl: Answerable<string>): Interaction {
94
100
  return new ChangeApiConfigSetUrl(newApiUrl);
95
101
  }
96
102
 
97
103
  /**
98
- * @desc
99
- * Instructs the {@link @serenity-js/core/lib/screenplay/actor~Actor}
100
- * to change the port configured in the base URL of their {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}
104
+ * Instructs the {@apilink Actor|actor} to change the port configured in the base URL
105
+ * of their {@apilink Ability|ability} to {@apilink CallAnApi}
101
106
  *
102
- * @param {@serenity-js/core/lib/screenplay~Answerable<string>} newApiPort
103
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
107
+ * @param newApiPort
104
108
  */
105
109
  static setPortTo(newApiPort: Answerable<number>): Interaction {
106
110
  return new ChangeApiConfigSetPort(newApiPort)
107
111
  }
108
112
 
109
113
  /**
110
- * @desc
111
- * Instructs the {@link @serenity-js/core/lib/screenplay/actor~Actor}
112
- * to modify the configuration of the {@link AxiosInstance}
113
- * used by {@link CallAnApi} {@link @serenity-js/core/lib/screenplay~Ability}
114
- * and set a HTTP request header for any subsequent {@link HTTPRequest}
115
- * issued via {@link Send}.
114
+ * Instructs the {@apilink Actor|actor} to change the configuration of the {@apilink AxiosInstance}
115
+ * used by their {@apilink Ability|ability} to {@apilink CallAnApi}
116
+ * and set an HTTP request header for any subsequent {@apilink HTTPRequest|HTTPRequests}
117
+ * issued via {@apilink Send}.
116
118
  *
117
- * @param {@serenity-js/core/lib/screenplay~Answerable<string>} name
118
- * @param {@serenity-js/core/lib/screenplay~Answerable<string>} value
119
- *
120
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
119
+ * @param name
120
+ * @param value
121
121
  */
122
122
  static setHeader(name: Answerable<string>, value: Answerable<string>): Interaction {
123
123
  return new ChangeApiConfigSetHeader(name, value);
@@ -129,17 +129,13 @@ export class ChangeApiConfig {
129
129
  */
130
130
  class ChangeApiConfigSetUrl extends Interaction {
131
131
  constructor(private readonly newApiUrl: Answerable<string>) {
132
- super();
132
+ super(d`#actor changes API url configuration to ${ newApiUrl }`);
133
133
  }
134
134
 
135
135
  performAs(actor: UsesAbilities & CollectsArtifacts & AnswersQuestions): Promise<void> {
136
136
  return actor.answer(this.newApiUrl)
137
137
  .then(newApiUrl => CallAnApi.as(actor).modifyConfig(config => config.baseURL = newApiUrl));
138
138
  }
139
-
140
- toString(): string {
141
- return `#actor changes API URL configuration to ${ this.newApiUrl }`;
142
- }
143
139
  }
144
140
 
145
141
  /**
@@ -147,7 +143,7 @@ class ChangeApiConfigSetUrl extends Interaction {
147
143
  */
148
144
  class ChangeApiConfigSetPort extends Interaction {
149
145
  constructor(private readonly newPort: Answerable<number | string>) {
150
- super();
146
+ super(`#actor changes API port configuration to ${ newPort }`);
151
147
  }
152
148
 
153
149
  performAs(actor: UsesAbilities & CollectsArtifacts & AnswersQuestions): Promise<void> {
@@ -167,10 +163,6 @@ class ChangeApiConfigSetPort extends Interaction {
167
163
  }
168
164
  }));
169
165
  }
170
-
171
- toString(): string {
172
- return `#actor changes API port configuration to ${ this.newPort }`;
173
- }
174
166
  }
175
167
 
176
168
  /**
@@ -184,7 +176,7 @@ class ChangeApiConfigSetHeader extends Interaction {
184
176
  private readonly name: Answerable<string>,
185
177
  private readonly value: Answerable<string>
186
178
  ) {
187
- super();
179
+ super(`#actor changes API URL and sets header "${ name }" to "${ value }"`);
188
180
  }
189
181
 
190
182
  performAs(actor: UsesAbilities & CollectsArtifacts & AnswersQuestions): Promise<void> {
@@ -205,8 +197,4 @@ class ChangeApiConfigSetHeader extends Interaction {
205
197
  });
206
198
  });
207
199
  }
208
-
209
- toString(): string {
210
- return `#actor changes API URL and sets header "${ this.name }" to "${ this.value }"`;
211
- }
212
200
  }