@serenity-js/assertions 3.41.1 → 3.42.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.
- package/CHANGELOG.md +20 -0
- package/esm/Ensure.d.ts +110 -0
- package/esm/Ensure.d.ts.map +1 -0
- package/esm/Ensure.js +148 -0
- package/esm/Ensure.js.map +1 -0
- package/esm/EnsureEventually.d.ts +98 -0
- package/esm/EnsureEventually.d.ts.map +1 -0
- package/esm/EnsureEventually.js +142 -0
- package/esm/EnsureEventually.js.map +1 -0
- package/esm/expectations/and.d.ts +23 -0
- package/esm/expectations/and.d.ts.map +1 -0
- package/esm/expectations/and.js +46 -0
- package/esm/expectations/and.js.map +1 -0
- package/esm/expectations/contain.d.ts +27 -0
- package/esm/expectations/contain.d.ts.map +1 -0
- package/esm/expectations/contain.js +28 -0
- package/esm/expectations/contain.js.map +1 -0
- package/esm/expectations/containAtLeastOneItemThat.d.ts +24 -0
- package/esm/expectations/containAtLeastOneItemThat.d.ts.map +1 -0
- package/esm/expectations/containAtLeastOneItemThat.js +53 -0
- package/esm/expectations/containAtLeastOneItemThat.js.map +1 -0
- package/esm/expectations/containItemsWhereEachItem.d.ts +24 -0
- package/esm/expectations/containItemsWhereEachItem.d.ts.map +1 -0
- package/esm/expectations/containItemsWhereEachItem.js +53 -0
- package/esm/expectations/containItemsWhereEachItem.js.map +1 -0
- package/esm/expectations/endsWith.d.ts +22 -0
- package/esm/expectations/endsWith.d.ts.map +1 -0
- package/esm/expectations/endsWith.js +22 -0
- package/esm/expectations/endsWith.js.map +1 -0
- package/esm/expectations/equals.d.ts +28 -0
- package/esm/expectations/equals.d.ts.map +1 -0
- package/esm/expectations/equals.js +29 -0
- package/esm/expectations/equals.js.map +1 -0
- package/esm/expectations/includes.d.ts +41 -0
- package/esm/expectations/includes.d.ts.map +1 -0
- package/esm/expectations/includes.js +41 -0
- package/esm/expectations/includes.js.map +1 -0
- package/esm/expectations/index.d.ts +21 -0
- package/esm/expectations/index.d.ts.map +1 -0
- package/esm/expectations/index.js +21 -0
- package/esm/expectations/index.js.map +1 -0
- package/esm/expectations/isAfter.d.ts +42 -0
- package/esm/expectations/isAfter.d.ts.map +1 -0
- package/esm/expectations/isAfter.js +50 -0
- package/esm/expectations/isAfter.js.map +1 -0
- package/esm/expectations/isBefore.d.ts +42 -0
- package/esm/expectations/isBefore.d.ts.map +1 -0
- package/esm/expectations/isBefore.js +50 -0
- package/esm/expectations/isBefore.js.map +1 -0
- package/esm/expectations/isCloseTo.d.ts +24 -0
- package/esm/expectations/isCloseTo.d.ts.map +1 -0
- package/esm/expectations/isCloseTo.js +34 -0
- package/esm/expectations/isCloseTo.js.map +1 -0
- package/esm/expectations/isFalse.d.ts +21 -0
- package/esm/expectations/isFalse.d.ts.map +1 -0
- package/esm/expectations/isFalse.js +24 -0
- package/esm/expectations/isFalse.js.map +1 -0
- package/esm/expectations/isGreaterThan.d.ts +45 -0
- package/esm/expectations/isGreaterThan.d.ts.map +1 -0
- package/esm/expectations/isGreaterThan.js +45 -0
- package/esm/expectations/isGreaterThan.js.map +1 -0
- package/esm/expectations/isLessThan.d.ts +45 -0
- package/esm/expectations/isLessThan.d.ts.map +1 -0
- package/esm/expectations/isLessThan.js +45 -0
- package/esm/expectations/isLessThan.js.map +1 -0
- package/esm/expectations/isPresent.d.ts +65 -0
- package/esm/expectations/isPresent.d.ts.map +1 -0
- package/esm/expectations/isPresent.js +96 -0
- package/esm/expectations/isPresent.js.map +1 -0
- package/esm/expectations/isTrue.d.ts +21 -0
- package/esm/expectations/isTrue.d.ts.map +1 -0
- package/esm/expectations/isTrue.js +24 -0
- package/esm/expectations/isTrue.js.map +1 -0
- package/esm/expectations/matches.d.ts +22 -0
- package/esm/expectations/matches.d.ts.map +1 -0
- package/esm/expectations/matches.js +22 -0
- package/esm/expectations/matches.js.map +1 -0
- package/esm/expectations/not.d.ts +24 -0
- package/esm/expectations/not.d.ts.map +1 -0
- package/esm/expectations/not.js +48 -0
- package/esm/expectations/not.js.map +1 -0
- package/esm/expectations/or.d.ts +23 -0
- package/esm/expectations/or.d.ts.map +1 -0
- package/esm/expectations/or.js +53 -0
- package/esm/expectations/or.js.map +1 -0
- package/esm/expectations/property.d.ts +62 -0
- package/esm/expectations/property.d.ts.map +1 -0
- package/esm/expectations/property.js +82 -0
- package/esm/expectations/property.js.map +1 -0
- package/esm/expectations/startsWith.d.ts +22 -0
- package/esm/expectations/startsWith.d.ts.map +1 -0
- package/esm/expectations/startsWith.js +22 -0
- package/esm/expectations/startsWith.js.map +1 -0
- package/esm/index.d.ts +4 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -0
- package/lib/Ensure.d.ts +1 -1
- package/lib/Ensure.d.ts.map +1 -1
- package/lib/Ensure.js +2 -2
- package/lib/Ensure.js.map +1 -1
- package/lib/EnsureEventually.d.ts +1 -1
- package/lib/EnsureEventually.d.ts.map +1 -1
- package/lib/expectations/contain.js +2 -2
- package/lib/expectations/contain.js.map +1 -1
- package/lib/expectations/equals.js +2 -2
- package/lib/expectations/equals.js.map +1 -1
- package/lib/expectations/index.d.ts +20 -20
- package/lib/expectations/index.d.ts.map +1 -1
- package/lib/expectations/index.js +20 -20
- package/lib/expectations/index.js.map +1 -1
- package/lib/expectations/isAfter.d.ts +1 -1
- package/lib/expectations/isBefore.d.ts +1 -1
- package/lib/expectations/isFalse.js +2 -2
- package/lib/expectations/isFalse.js.map +1 -1
- package/lib/expectations/isTrue.js +2 -2
- package/lib/expectations/isTrue.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/package.json +1 -0
- package/package.json +31 -8
- package/src/Ensure.ts +2 -2
- package/src/EnsureEventually.ts +1 -1
- package/src/expectations/contain.ts +1 -1
- package/src/expectations/equals.ts +1 -1
- package/src/expectations/index.ts +20 -20
- package/src/expectations/isFalse.ts +1 -1
- package/src/expectations/isTrue.ts +1 -1
- package/src/index.ts +3 -3
- package/tsconfig-cjs.build.json +17 -0
- package/tsconfig-esm.build.json +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.42.0](https://github.com/serenity-js/serenity-js/compare/v3.41.2...v3.42.0) (2026-03-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **core:** add dual ESM/CJS build support for Wave 2 packages ([0e2631c](https://github.com/serenity-js/serenity-js/commit/0e2631ca7cdbe68da7feec343eaf4f7fe9bb64d6))
|
|
12
|
+
* **core:** add ESM/CJS dual build support for web packages ([94c5a64](https://github.com/serenity-js/serenity-js/commit/94c5a6423dc369477bbabbacee5a54f8fca20209))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [3.41.2](https://github.com/serenity-js/serenity-js/compare/v3.41.1...v3.41.2) (2026-03-05)
|
|
19
|
+
|
|
20
|
+
**Note:** Version bump only for package @serenity-js/assertions
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## [3.41.1](https://github.com/serenity-js/serenity-js/compare/v3.41.0...v3.41.1) (2026-02-27)
|
|
7
27
|
|
|
8
28
|
**Note:** Version bump only for package @serenity-js/assertions
|
package/esm/Ensure.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Answerable, AnswersQuestions, CollectsArtifacts, Expectation, RuntimeError, UsesAbilities } from '@serenity-js/core';
|
|
2
|
+
import { Interaction } from '@serenity-js/core';
|
|
3
|
+
import { EnsureEventually } from './EnsureEventually.js';
|
|
4
|
+
/**
|
|
5
|
+
* The [interaction](https://serenity-js.org/api/core/class/Interaction/) to `Ensure`
|
|
6
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
7
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/).
|
|
8
|
+
* If not, it throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
9
|
+
*
|
|
10
|
+
* Use `Ensure` to verify the state of the system under test.
|
|
11
|
+
*
|
|
12
|
+
* ## Basic usage with static values
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
15
|
+
* import { Ensure, equals } from '@serenity-js/assertions'
|
|
16
|
+
*
|
|
17
|
+
* await actorCalled('Erica').attemptsTo(
|
|
18
|
+
* Ensure.that('Hello world!', equals('Hello world!'))
|
|
19
|
+
* )
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ## Composing expectations with `and`
|
|
23
|
+
*
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
26
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
27
|
+
*
|
|
28
|
+
* await actorCalled('Erica').attemptsTo(
|
|
29
|
+
* Ensure.that('Hello world!', and(startsWith('Hello'), endsWith('!'))
|
|
30
|
+
* )
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ## Overriding the type of Error thrown upon assertion failure
|
|
34
|
+
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { actorCalled, TestCompromisedError } from '@serenity-js/core'
|
|
37
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
38
|
+
* import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
|
|
39
|
+
*
|
|
40
|
+
* await actorCalled('Erica')
|
|
41
|
+
* .whoCan(CallAnApi.at('https://example.com'))
|
|
42
|
+
* .attemptsTo(
|
|
43
|
+
* Send.a(GetRequest.to('/api/health')),
|
|
44
|
+
* Ensure.that(LastResponse.status(), equals(200))
|
|
45
|
+
* .otherwiseFailWith(TestCompromisedError, 'The server is down, please cheer it up!')
|
|
46
|
+
* )
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @group Activities
|
|
50
|
+
*/
|
|
51
|
+
export declare class Ensure<Actual> extends Interaction {
|
|
52
|
+
protected readonly actual: Answerable<Actual>;
|
|
53
|
+
protected readonly expectation: Expectation<Actual>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates an [interaction](https://serenity-js.org/api/core/class/Interaction/) to `Ensure`, which
|
|
56
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
57
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/).
|
|
58
|
+
* If not, it immediately throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
59
|
+
*
|
|
60
|
+
* @param {Answerable<Actual_Type>} actual
|
|
61
|
+
* An [`Answerable`](https://serenity-js.org/api/core/#Answerable) describing the actual state of the system.
|
|
62
|
+
*
|
|
63
|
+
* @param {Expectation<Actual_Type>} expectation
|
|
64
|
+
* An [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) you expect the `actual` value to meet
|
|
65
|
+
*
|
|
66
|
+
* @returns {Ensure<Actual_Type>}
|
|
67
|
+
*/
|
|
68
|
+
static that<Actual_Type>(actual: Answerable<Actual_Type>, expectation: Expectation<Actual_Type>): Ensure<Actual_Type>;
|
|
69
|
+
/**
|
|
70
|
+
* Creates an [interaction](https://serenity-js.org/api/core/class/Interaction/) to [`EnsureEventually`](https://serenity-js.org/api/assertions/class/EnsureEventually/),
|
|
71
|
+
* which verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
72
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) within the expected timeframe.
|
|
73
|
+
*
|
|
74
|
+
* After the first try, it waits longer and longer between checks, following a simple exponential backoff pattern (2^try * 100). So 0ms the first
|
|
75
|
+
* time, then 200ms, 400ms, 800ms, 1600ms, 3200ms and so on.
|
|
76
|
+
*
|
|
77
|
+
* If the expectation is not met by the time the timeout expires, the interaction throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
78
|
+
*
|
|
79
|
+
* @param {Answerable<Actual_Type>} actual
|
|
80
|
+
* An [`Answerable`](https://serenity-js.org/api/core/#Answerable) describing the actual state of the system.
|
|
81
|
+
*
|
|
82
|
+
* @param {Expectation<Actual_Type>} expectation
|
|
83
|
+
* An [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) you expect the `actual` value to meet
|
|
84
|
+
*
|
|
85
|
+
* @returns {Ensure<Actual_Type>}
|
|
86
|
+
*/
|
|
87
|
+
static eventually<Actual_Type>(actual: Answerable<Actual_Type>, expectation: Expectation<Actual_Type>): EnsureEventually<Actual_Type>;
|
|
88
|
+
/**
|
|
89
|
+
* @param actual
|
|
90
|
+
* @param expectation
|
|
91
|
+
* @param location
|
|
92
|
+
*/
|
|
93
|
+
private constructor();
|
|
94
|
+
/**
|
|
95
|
+
* @inheritDoc
|
|
96
|
+
*/
|
|
97
|
+
performAs(actor: UsesAbilities & AnswersQuestions & CollectsArtifacts): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Overrides the default [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/) thrown when
|
|
100
|
+
* the actual value does not meet the expectation.
|
|
101
|
+
*
|
|
102
|
+
* @param typeOfRuntimeError
|
|
103
|
+
* A constructor function producing a subtype of [`RuntimeError`](https://serenity-js.org/api/core/class/RuntimeError/) to throw, e.g. [`TestCompromisedError`](https://serenity-js.org/api/core/class/TestCompromisedError/)
|
|
104
|
+
*
|
|
105
|
+
* @param message
|
|
106
|
+
* The message explaining the failure
|
|
107
|
+
*/
|
|
108
|
+
otherwiseFailWith(typeOfRuntimeError: new (message: string, cause?: Error) => RuntimeError, message?: string): Interaction;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=Ensure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ensure.d.ts","sourceRoot":"","sources":["../src/Ensure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAMH,WAAW,EAKd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,MAAM,CAAC,MAAM,CAAE,SAAQ,WAAW;IAgDvC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC;IA/CvD;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;IAIrH;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,gBAAgB,CAAC,WAAW,CAAC;IAIrI;;;;OAIG;IACH,OAAO;IAQP;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB3F;;;;;;;;;OASG;IACH,iBAAiB,CAAC,kBAAkB,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,YAAY,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW;CAgB7H"}
|
package/esm/Ensure.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Activity, AssertionError, ExpectationMet, ExpectationNotMet, f, Interaction, LogicError, Question, RaiseErrors, the } from '@serenity-js/core';
|
|
2
|
+
import { EnsureEventually } from './EnsureEventually.js';
|
|
3
|
+
/**
|
|
4
|
+
* The [interaction](https://serenity-js.org/api/core/class/Interaction/) to `Ensure`
|
|
5
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
6
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/).
|
|
7
|
+
* If not, it throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
8
|
+
*
|
|
9
|
+
* Use `Ensure` to verify the state of the system under test.
|
|
10
|
+
*
|
|
11
|
+
* ## Basic usage with static values
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
14
|
+
* import { Ensure, equals } from '@serenity-js/assertions'
|
|
15
|
+
*
|
|
16
|
+
* await actorCalled('Erica').attemptsTo(
|
|
17
|
+
* Ensure.that('Hello world!', equals('Hello world!'))
|
|
18
|
+
* )
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## Composing expectations with `and`
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
25
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
26
|
+
*
|
|
27
|
+
* await actorCalled('Erica').attemptsTo(
|
|
28
|
+
* Ensure.that('Hello world!', and(startsWith('Hello'), endsWith('!'))
|
|
29
|
+
* )
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* ## Overriding the type of Error thrown upon assertion failure
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { actorCalled, TestCompromisedError } from '@serenity-js/core'
|
|
36
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
37
|
+
* import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
|
|
38
|
+
*
|
|
39
|
+
* await actorCalled('Erica')
|
|
40
|
+
* .whoCan(CallAnApi.at('https://example.com'))
|
|
41
|
+
* .attemptsTo(
|
|
42
|
+
* Send.a(GetRequest.to('/api/health')),
|
|
43
|
+
* Ensure.that(LastResponse.status(), equals(200))
|
|
44
|
+
* .otherwiseFailWith(TestCompromisedError, 'The server is down, please cheer it up!')
|
|
45
|
+
* )
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @group Activities
|
|
49
|
+
*/
|
|
50
|
+
export class Ensure extends Interaction {
|
|
51
|
+
actual;
|
|
52
|
+
expectation;
|
|
53
|
+
/**
|
|
54
|
+
* Creates an [interaction](https://serenity-js.org/api/core/class/Interaction/) to `Ensure`, which
|
|
55
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
56
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/).
|
|
57
|
+
* If not, it immediately throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
58
|
+
*
|
|
59
|
+
* @param {Answerable<Actual_Type>} actual
|
|
60
|
+
* An [`Answerable`](https://serenity-js.org/api/core/#Answerable) describing the actual state of the system.
|
|
61
|
+
*
|
|
62
|
+
* @param {Expectation<Actual_Type>} expectation
|
|
63
|
+
* An [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) you expect the `actual` value to meet
|
|
64
|
+
*
|
|
65
|
+
* @returns {Ensure<Actual_Type>}
|
|
66
|
+
*/
|
|
67
|
+
static that(actual, expectation) {
|
|
68
|
+
return new Ensure(actual, expectation, Activity.callerLocation(5));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Creates an [interaction](https://serenity-js.org/api/core/class/Interaction/) to [`EnsureEventually`](https://serenity-js.org/api/assertions/class/EnsureEventually/),
|
|
72
|
+
* which verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
73
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) within the expected timeframe.
|
|
74
|
+
*
|
|
75
|
+
* After the first try, it waits longer and longer between checks, following a simple exponential backoff pattern (2^try * 100). So 0ms the first
|
|
76
|
+
* time, then 200ms, 400ms, 800ms, 1600ms, 3200ms and so on.
|
|
77
|
+
*
|
|
78
|
+
* If the expectation is not met by the time the timeout expires, the interaction throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
79
|
+
*
|
|
80
|
+
* @param {Answerable<Actual_Type>} actual
|
|
81
|
+
* An [`Answerable`](https://serenity-js.org/api/core/#Answerable) describing the actual state of the system.
|
|
82
|
+
*
|
|
83
|
+
* @param {Expectation<Actual_Type>} expectation
|
|
84
|
+
* An [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) you expect the `actual` value to meet
|
|
85
|
+
*
|
|
86
|
+
* @returns {Ensure<Actual_Type>}
|
|
87
|
+
*/
|
|
88
|
+
static eventually(actual, expectation) {
|
|
89
|
+
return new EnsureEventually(actual, expectation, Activity.callerLocation(5));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* @param actual
|
|
93
|
+
* @param expectation
|
|
94
|
+
* @param location
|
|
95
|
+
*/
|
|
96
|
+
constructor(actual, expectation, location) {
|
|
97
|
+
super(the `#actor ensures that ${actual} does ${expectation}`, location);
|
|
98
|
+
this.actual = actual;
|
|
99
|
+
this.expectation = expectation;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* @inheritDoc
|
|
103
|
+
*/
|
|
104
|
+
async performAs(actor) {
|
|
105
|
+
const outcome = await actor.answer(this.expectation.isMetFor(this.actual));
|
|
106
|
+
if (outcome instanceof ExpectationNotMet) {
|
|
107
|
+
const actualDescription = this.actual === undefined
|
|
108
|
+
? 'undefined'
|
|
109
|
+
: Question.formattedValue().of(this.actual);
|
|
110
|
+
const message = `Expected ${actualDescription} to ${outcome.message}`;
|
|
111
|
+
throw RaiseErrors.as(actor).create(AssertionError, {
|
|
112
|
+
message,
|
|
113
|
+
expectation: outcome.expectation,
|
|
114
|
+
diff: { expected: outcome.expected, actual: outcome.actual },
|
|
115
|
+
location: this.instantiationLocation(),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (!(outcome instanceof ExpectationMet)) {
|
|
119
|
+
throw new LogicError(f `Expectation#isMetFor(actual) should return an instance of an ExpectationOutcome, not ${outcome}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Overrides the default [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/) thrown when
|
|
124
|
+
* the actual value does not meet the expectation.
|
|
125
|
+
*
|
|
126
|
+
* @param typeOfRuntimeError
|
|
127
|
+
* A constructor function producing a subtype of [`RuntimeError`](https://serenity-js.org/api/core/class/RuntimeError/) to throw, e.g. [`TestCompromisedError`](https://serenity-js.org/api/core/class/TestCompromisedError/)
|
|
128
|
+
*
|
|
129
|
+
* @param message
|
|
130
|
+
* The message explaining the failure
|
|
131
|
+
*/
|
|
132
|
+
otherwiseFailWith(typeOfRuntimeError, message) {
|
|
133
|
+
const location = this.instantiationLocation();
|
|
134
|
+
return Interaction.where(this.toString(), async (actor) => {
|
|
135
|
+
try {
|
|
136
|
+
await this.performAs(actor);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw RaiseErrors.as(actor).create(typeOfRuntimeError, {
|
|
140
|
+
message: message ?? error.message,
|
|
141
|
+
location,
|
|
142
|
+
cause: error
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=Ensure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ensure.js","sourceRoot":"","sources":["../src/Ensure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Answerable, AnswersQuestions, CollectsArtifacts, Expectation, RuntimeError, UsesAbilities } from '@serenity-js/core';
|
|
2
|
+
import { Duration, Interaction } from '@serenity-js/core';
|
|
3
|
+
import type { FileSystemLocation } from '@serenity-js/core/io';
|
|
4
|
+
/**
|
|
5
|
+
* The [interaction](https://serenity-js.org/api/core/class/Interaction/) to `EnsureEventually`
|
|
6
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
7
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) within the expected timeframe.
|
|
8
|
+
*
|
|
9
|
+
* If the expectation is not met by the time the timeout expires, the interaction throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
10
|
+
* `EnsureEventually` retries the evaluation if resolving the `actual` results in an [`ListItemNotFoundError`](https://serenity-js.org/api/core/class/ListItemNotFoundError/),
|
|
11
|
+
* but rethrows any other errors.
|
|
12
|
+
*
|
|
13
|
+
* :::tip Use the factory method
|
|
14
|
+
* Use the factory method [`Ensure.eventually`](https://serenity-js.org/api/assertions/class/Ensure/#eventually) to instantiate this interaction.
|
|
15
|
+
* :::
|
|
16
|
+
*
|
|
17
|
+
* ## Basic usage with dynamic values
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
20
|
+
* import { Ensure, equals } from '@serenity-js/assertions'
|
|
21
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
22
|
+
*
|
|
23
|
+
* await actorCalled('Erica').attemptsTo(
|
|
24
|
+
* Ensure.eventually(
|
|
25
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
26
|
+
* equals('Learn Serenity/JS!')
|
|
27
|
+
* )
|
|
28
|
+
* )
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ## Composing expectations with `and`
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
35
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
36
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
37
|
+
*
|
|
38
|
+
* await actorCalled('Erica').attemptsTo(
|
|
39
|
+
* Ensure.eventually(
|
|
40
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
41
|
+
* and(startsWith('Serenity'), endsWith('!'))
|
|
42
|
+
* )
|
|
43
|
+
* )
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ## Overriding the type of Error thrown upon assertion failure
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
50
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
51
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
52
|
+
*
|
|
53
|
+
* await actorCalled('Erica').attemptsTo(
|
|
54
|
+
* Ensure.eventually(
|
|
55
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
56
|
+
* and(startsWith('Serenity'), endsWith('!'))
|
|
57
|
+
* ).otherwiseFailWith(LogicError, `Looks like we're not on the right page`)
|
|
58
|
+
* )
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @experimental
|
|
62
|
+
*
|
|
63
|
+
* @group Activities
|
|
64
|
+
*/
|
|
65
|
+
export declare class EnsureEventually<Actual> extends Interaction {
|
|
66
|
+
protected readonly actual: Answerable<Actual>;
|
|
67
|
+
protected readonly expectation: Expectation<Actual>;
|
|
68
|
+
protected readonly timeout?: Duration;
|
|
69
|
+
/**
|
|
70
|
+
* @param actual
|
|
71
|
+
* @param expectation
|
|
72
|
+
* @param location
|
|
73
|
+
* @param timeout
|
|
74
|
+
*/
|
|
75
|
+
constructor(actual: Answerable<Actual>, expectation: Expectation<Actual>, location: FileSystemLocation, timeout?: Duration);
|
|
76
|
+
/**
|
|
77
|
+
* Override the default timeout set via [`SerenityConfig.interactionTimeout`](https://serenity-js.org/api/core/class/SerenityConfig/#interactionTimeout).
|
|
78
|
+
*
|
|
79
|
+
* @param timeout
|
|
80
|
+
*/
|
|
81
|
+
timeoutAfter(timeout: Duration): EnsureEventually<Actual>;
|
|
82
|
+
/**
|
|
83
|
+
* @inheritDoc
|
|
84
|
+
*/
|
|
85
|
+
performAs(actor: UsesAbilities & AnswersQuestions & CollectsArtifacts): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Overrides the default [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/) thrown when
|
|
88
|
+
* the actual value does not meet the expectation.
|
|
89
|
+
*
|
|
90
|
+
* @param typeOfRuntimeError
|
|
91
|
+
* A constructor function producing a subtype of [`RuntimeError`](https://serenity-js.org/api/core/class/RuntimeError/) to throw, e.g. [`TestCompromisedError`](https://serenity-js.org/api/core/class/TestCompromisedError/)
|
|
92
|
+
*
|
|
93
|
+
* @param message
|
|
94
|
+
* The message explaining the failure
|
|
95
|
+
*/
|
|
96
|
+
otherwiseFailWith(typeOfRuntimeError: new (message: string, cause?: Error) => RuntimeError, message?: string): Interaction;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=EnsureEventually.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnsureEventually.d.ts","sourceRoot":"","sources":["../src/EnsureEventually.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EAEX,YAAY,EACZ,aAAa,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGH,QAAQ,EAER,WAAW,EAMd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,qBAAa,gBAAgB,CAAC,MAAM,CAAE,SAAQ,WAAW;IAQjD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC;IAEnD,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ;IAVzC;;;;;OAKG;gBAEoB,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAC1B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,EACnD,QAAQ,EAAE,kBAAkB,EACT,OAAO,CAAC,EAAE,QAAQ;IAKzC;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAIzD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC3F;;;;;;;;;OASG;IACH,iBAAiB,CAAC,kBAAkB,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,KAAK,YAAY,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW;CAe7H"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { AssertionError, d, Duration, ExpectationMet, Interaction, ListItemNotFoundError, RaiseErrors, ScheduleWork, the, TimeoutExpiredError } from '@serenity-js/core';
|
|
2
|
+
/**
|
|
3
|
+
* The [interaction](https://serenity-js.org/api/core/class/Interaction/) to `EnsureEventually`
|
|
4
|
+
* verifies if the resolved value of the provided [`Answerable`](https://serenity-js.org/api/core/#Answerable)
|
|
5
|
+
* meets the specified [`Expectation`](https://serenity-js.org/api/core/class/Expectation/) within the expected timeframe.
|
|
6
|
+
*
|
|
7
|
+
* If the expectation is not met by the time the timeout expires, the interaction throws an [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/).
|
|
8
|
+
* `EnsureEventually` retries the evaluation if resolving the `actual` results in an [`ListItemNotFoundError`](https://serenity-js.org/api/core/class/ListItemNotFoundError/),
|
|
9
|
+
* but rethrows any other errors.
|
|
10
|
+
*
|
|
11
|
+
* :::tip Use the factory method
|
|
12
|
+
* Use the factory method [`Ensure.eventually`](https://serenity-js.org/api/assertions/class/Ensure/#eventually) to instantiate this interaction.
|
|
13
|
+
* :::
|
|
14
|
+
*
|
|
15
|
+
* ## Basic usage with dynamic values
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
18
|
+
* import { Ensure, equals } from '@serenity-js/assertions'
|
|
19
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
20
|
+
*
|
|
21
|
+
* await actorCalled('Erica').attemptsTo(
|
|
22
|
+
* Ensure.eventually(
|
|
23
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
24
|
+
* equals('Learn Serenity/JS!')
|
|
25
|
+
* )
|
|
26
|
+
* )
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* ## Composing expectations with `and`
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
33
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
34
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
35
|
+
*
|
|
36
|
+
* await actorCalled('Erica').attemptsTo(
|
|
37
|
+
* Ensure.eventually(
|
|
38
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
39
|
+
* and(startsWith('Serenity'), endsWith('!'))
|
|
40
|
+
* )
|
|
41
|
+
* )
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* ## Overriding the type of Error thrown upon assertion failure
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
48
|
+
* import { and, Ensure, startsWith, endsWith } from '@serenity-js/assertions'
|
|
49
|
+
* import { Text, PageElement, By } from '@serenity-js/web'
|
|
50
|
+
*
|
|
51
|
+
* await actorCalled('Erica').attemptsTo(
|
|
52
|
+
* Ensure.eventually(
|
|
53
|
+
* Text.of(PageElement.located(By.css('h1'))),
|
|
54
|
+
* and(startsWith('Serenity'), endsWith('!'))
|
|
55
|
+
* ).otherwiseFailWith(LogicError, `Looks like we're not on the right page`)
|
|
56
|
+
* )
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @experimental
|
|
60
|
+
*
|
|
61
|
+
* @group Activities
|
|
62
|
+
*/
|
|
63
|
+
export class EnsureEventually extends Interaction {
|
|
64
|
+
actual;
|
|
65
|
+
expectation;
|
|
66
|
+
timeout;
|
|
67
|
+
/**
|
|
68
|
+
* @param actual
|
|
69
|
+
* @param expectation
|
|
70
|
+
* @param location
|
|
71
|
+
* @param timeout
|
|
72
|
+
*/
|
|
73
|
+
constructor(actual, expectation, location, timeout) {
|
|
74
|
+
super(the `#actor ensures that ${actual} does eventually ${expectation}`, location);
|
|
75
|
+
this.actual = actual;
|
|
76
|
+
this.expectation = expectation;
|
|
77
|
+
this.timeout = timeout;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Override the default timeout set via [`SerenityConfig.interactionTimeout`](https://serenity-js.org/api/core/class/SerenityConfig/#interactionTimeout).
|
|
81
|
+
*
|
|
82
|
+
* @param timeout
|
|
83
|
+
*/
|
|
84
|
+
timeoutAfter(timeout) {
|
|
85
|
+
return new EnsureEventually(this.actual, this.expectation, this.instantiationLocation(), timeout);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* @inheritDoc
|
|
89
|
+
*/
|
|
90
|
+
async performAs(actor) {
|
|
91
|
+
await ScheduleWork.as(actor).repeatUntil(() => actor.answer(this.expectation.isMetFor(this.actual)), {
|
|
92
|
+
exitCondition: outcome => outcome instanceof ExpectationMet,
|
|
93
|
+
delayBetweenInvocations: (invocation) => invocation === 0
|
|
94
|
+
? Duration.ofMilliseconds(0) // perform the first evaluation straight away
|
|
95
|
+
: Duration.ofMilliseconds(2 ** invocation * 100), // use simple exponential backoff strategy for subsequent calls
|
|
96
|
+
timeout: this.timeout,
|
|
97
|
+
errorHandler: (error, outcome) => {
|
|
98
|
+
if (error instanceof ListItemNotFoundError) {
|
|
99
|
+
return; // ignore, lists might get populated later
|
|
100
|
+
}
|
|
101
|
+
if (error instanceof TimeoutExpiredError) {
|
|
102
|
+
const actualDescription = d `${this.actual}`;
|
|
103
|
+
const message = outcome ? `Expected ${actualDescription} to eventually ${outcome?.message}` : error.message;
|
|
104
|
+
throw RaiseErrors.as(actor).create(AssertionError, {
|
|
105
|
+
message,
|
|
106
|
+
expectation: outcome?.expectation,
|
|
107
|
+
diff: outcome && { expected: outcome?.expected, actual: outcome?.actual },
|
|
108
|
+
location: this.instantiationLocation(),
|
|
109
|
+
cause: error,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
throw error;
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Overrides the default [`AssertionError`](https://serenity-js.org/api/core/class/AssertionError/) thrown when
|
|
118
|
+
* the actual value does not meet the expectation.
|
|
119
|
+
*
|
|
120
|
+
* @param typeOfRuntimeError
|
|
121
|
+
* A constructor function producing a subtype of [`RuntimeError`](https://serenity-js.org/api/core/class/RuntimeError/) to throw, e.g. [`TestCompromisedError`](https://serenity-js.org/api/core/class/TestCompromisedError/)
|
|
122
|
+
*
|
|
123
|
+
* @param message
|
|
124
|
+
* The message explaining the failure
|
|
125
|
+
*/
|
|
126
|
+
otherwiseFailWith(typeOfRuntimeError, message) {
|
|
127
|
+
const location = this.instantiationLocation();
|
|
128
|
+
return Interaction.where(this.toString(), async (actor) => {
|
|
129
|
+
try {
|
|
130
|
+
await this.performAs(actor);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
throw RaiseErrors.as(actor).create(typeOfRuntimeError, {
|
|
134
|
+
message: message ?? error.message,
|
|
135
|
+
location,
|
|
136
|
+
cause: error,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=EnsureEventually.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnsureEventually.js","sourceRoot":"","sources":["../src/EnsureEventually.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Expectation } from '@serenity-js/core';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an [expectation](https://serenity-js.org/api/core/class/Expectation/) that is met when all the `expectations` are met for the given actual value.
|
|
4
|
+
*
|
|
5
|
+
* Use `and` to combine several expectations using logical "and",
|
|
6
|
+
*
|
|
7
|
+
* ## Combining several expectations
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
11
|
+
* import { Ensure, and, startsWith, endsWith } from '@serenity-js/assertions'
|
|
12
|
+
*
|
|
13
|
+
* await actorCalled('Ester').attemptsTo(
|
|
14
|
+
* Ensure.that('Hello World!', and(startsWith('Hello'), endsWith('!'))),
|
|
15
|
+
* )
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @param expectations
|
|
19
|
+
*
|
|
20
|
+
* @group Expectations
|
|
21
|
+
*/
|
|
22
|
+
export declare function and<Actual_Type>(...expectations: Array<Expectation<Actual_Type>>): Expectation<Actual_Type>;
|
|
23
|
+
//# sourceMappingURL=and.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"and.d.ts","sourceRoot":"","sources":["../../src/expectations/and.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAqC,MAAM,mBAAmB,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,GAAG,CAAC,WAAW,EAAE,GAAG,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,CAE3G"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Expectation, ExpectationMet, ExpectationNotMet } from '@serenity-js/core';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an [expectation](https://serenity-js.org/api/core/class/Expectation/) that is met when all the `expectations` are met for the given actual value.
|
|
4
|
+
*
|
|
5
|
+
* Use `and` to combine several expectations using logical "and",
|
|
6
|
+
*
|
|
7
|
+
* ## Combining several expectations
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
11
|
+
* import { Ensure, and, startsWith, endsWith } from '@serenity-js/assertions'
|
|
12
|
+
*
|
|
13
|
+
* await actorCalled('Ester').attemptsTo(
|
|
14
|
+
* Ensure.that('Hello World!', and(startsWith('Hello'), endsWith('!'))),
|
|
15
|
+
* )
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @param expectations
|
|
19
|
+
*
|
|
20
|
+
* @group Expectations
|
|
21
|
+
*/
|
|
22
|
+
export function and(...expectations) {
|
|
23
|
+
return new And(expectations);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @package
|
|
27
|
+
*/
|
|
28
|
+
class And extends Expectation {
|
|
29
|
+
expectations;
|
|
30
|
+
static Separator = ' and ';
|
|
31
|
+
constructor(expectations) {
|
|
32
|
+
const description = expectations.map(expectation => expectation.toString()).join(And.Separator);
|
|
33
|
+
super('and', description, async (actor, actual) => {
|
|
34
|
+
let outcome;
|
|
35
|
+
for (const expectation of expectations) {
|
|
36
|
+
outcome = await actor.answer(expectation.isMetFor(actual));
|
|
37
|
+
if (outcome instanceof ExpectationNotMet) {
|
|
38
|
+
return new ExpectationNotMet(description, outcome.expectation, outcome.expected, outcome.actual);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return new ExpectationMet(description, outcome?.expectation, outcome?.expected, outcome?.actual);
|
|
42
|
+
});
|
|
43
|
+
this.expectations = expectations;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=and.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"and.js","sourceRoot":"","sources":["../../src/expectations/and.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,GAAG,CAAc,GAAG,YAA6C;IAC7E,OAAO,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,GAAY,SAAQ,WAAmB;IAGZ;IAFrB,MAAM,CAAU,SAAS,GAAG,OAAO,CAAC;IAE5C,YAA6B,YAAwC;QACjE,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEhG,KAAK,CACD,KAAK,EACL,WAAW,EACX,KAAK,EAAE,KAAuB,EAAE,MAA0B,EAAE,EAAE;YAC1D,IAAI,OAA2B,CAAC;YAEhC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;gBACrC,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;gBAE1D,IAAI,OAAO,YAAY,iBAAiB,EAAE,CAAC;oBACvC,OAAO,IAAI,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACrG,CAAC;YACL,CAAC;YAED,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACrG,CAAC,CACJ,CAAC;QAnBuB,iBAAY,GAAZ,YAAY,CAA4B;IAoBrE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Expectation } from '@serenity-js/core';
|
|
2
|
+
/**
|
|
3
|
+
* Produces an [expectation](https://serenity-js.org/api/core/class/Expectation/) that is met when the actual array of `Item[]` contains
|
|
4
|
+
* at least one `Item` that is equal to the resolved value of `expected`.
|
|
5
|
+
*
|
|
6
|
+
* Note that the equality check performs comparison **by value**
|
|
7
|
+
* using [TinyTypes `equal`](https://github.com/jan-molak/tiny-types/blob/master/src/objects/equal.ts).
|
|
8
|
+
*
|
|
9
|
+
* ## Ensuring that the array contains the given item
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { actorCalled } from '@serenity-js/core'
|
|
13
|
+
* import { Ensure, and, startsWith, endsWith } from '@serenity-js/assertions'
|
|
14
|
+
*
|
|
15
|
+
* const items = [ { name: 'apples' }, { name: 'bananas' } ]
|
|
16
|
+
*
|
|
17
|
+
* await actorCalled('Ester').attemptsTo(
|
|
18
|
+
* Ensure.that(items, contain({ name: 'bananas' })),
|
|
19
|
+
* )
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param expected
|
|
23
|
+
*
|
|
24
|
+
* @group Expectations
|
|
25
|
+
*/
|
|
26
|
+
export declare const contain: <Item>(expected: import("@serenity-js/core").Answerable<Item>) => Expectation<Item[]>;
|
|
27
|
+
//# sourceMappingURL=contain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contain.d.ts","sourceRoot":"","sources":["../../src/expectations/contain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,OAAO,GAEf,IAAI,gFAER,CAAC"}
|