@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.
Files changed (133) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/esm/Ensure.d.ts +110 -0
  3. package/esm/Ensure.d.ts.map +1 -0
  4. package/esm/Ensure.js +148 -0
  5. package/esm/Ensure.js.map +1 -0
  6. package/esm/EnsureEventually.d.ts +98 -0
  7. package/esm/EnsureEventually.d.ts.map +1 -0
  8. package/esm/EnsureEventually.js +142 -0
  9. package/esm/EnsureEventually.js.map +1 -0
  10. package/esm/expectations/and.d.ts +23 -0
  11. package/esm/expectations/and.d.ts.map +1 -0
  12. package/esm/expectations/and.js +46 -0
  13. package/esm/expectations/and.js.map +1 -0
  14. package/esm/expectations/contain.d.ts +27 -0
  15. package/esm/expectations/contain.d.ts.map +1 -0
  16. package/esm/expectations/contain.js +28 -0
  17. package/esm/expectations/contain.js.map +1 -0
  18. package/esm/expectations/containAtLeastOneItemThat.d.ts +24 -0
  19. package/esm/expectations/containAtLeastOneItemThat.d.ts.map +1 -0
  20. package/esm/expectations/containAtLeastOneItemThat.js +53 -0
  21. package/esm/expectations/containAtLeastOneItemThat.js.map +1 -0
  22. package/esm/expectations/containItemsWhereEachItem.d.ts +24 -0
  23. package/esm/expectations/containItemsWhereEachItem.d.ts.map +1 -0
  24. package/esm/expectations/containItemsWhereEachItem.js +53 -0
  25. package/esm/expectations/containItemsWhereEachItem.js.map +1 -0
  26. package/esm/expectations/endsWith.d.ts +22 -0
  27. package/esm/expectations/endsWith.d.ts.map +1 -0
  28. package/esm/expectations/endsWith.js +22 -0
  29. package/esm/expectations/endsWith.js.map +1 -0
  30. package/esm/expectations/equals.d.ts +28 -0
  31. package/esm/expectations/equals.d.ts.map +1 -0
  32. package/esm/expectations/equals.js +29 -0
  33. package/esm/expectations/equals.js.map +1 -0
  34. package/esm/expectations/includes.d.ts +41 -0
  35. package/esm/expectations/includes.d.ts.map +1 -0
  36. package/esm/expectations/includes.js +41 -0
  37. package/esm/expectations/includes.js.map +1 -0
  38. package/esm/expectations/index.d.ts +21 -0
  39. package/esm/expectations/index.d.ts.map +1 -0
  40. package/esm/expectations/index.js +21 -0
  41. package/esm/expectations/index.js.map +1 -0
  42. package/esm/expectations/isAfter.d.ts +42 -0
  43. package/esm/expectations/isAfter.d.ts.map +1 -0
  44. package/esm/expectations/isAfter.js +50 -0
  45. package/esm/expectations/isAfter.js.map +1 -0
  46. package/esm/expectations/isBefore.d.ts +42 -0
  47. package/esm/expectations/isBefore.d.ts.map +1 -0
  48. package/esm/expectations/isBefore.js +50 -0
  49. package/esm/expectations/isBefore.js.map +1 -0
  50. package/esm/expectations/isCloseTo.d.ts +24 -0
  51. package/esm/expectations/isCloseTo.d.ts.map +1 -0
  52. package/esm/expectations/isCloseTo.js +34 -0
  53. package/esm/expectations/isCloseTo.js.map +1 -0
  54. package/esm/expectations/isFalse.d.ts +21 -0
  55. package/esm/expectations/isFalse.d.ts.map +1 -0
  56. package/esm/expectations/isFalse.js +24 -0
  57. package/esm/expectations/isFalse.js.map +1 -0
  58. package/esm/expectations/isGreaterThan.d.ts +45 -0
  59. package/esm/expectations/isGreaterThan.d.ts.map +1 -0
  60. package/esm/expectations/isGreaterThan.js +45 -0
  61. package/esm/expectations/isGreaterThan.js.map +1 -0
  62. package/esm/expectations/isLessThan.d.ts +45 -0
  63. package/esm/expectations/isLessThan.d.ts.map +1 -0
  64. package/esm/expectations/isLessThan.js +45 -0
  65. package/esm/expectations/isLessThan.js.map +1 -0
  66. package/esm/expectations/isPresent.d.ts +65 -0
  67. package/esm/expectations/isPresent.d.ts.map +1 -0
  68. package/esm/expectations/isPresent.js +96 -0
  69. package/esm/expectations/isPresent.js.map +1 -0
  70. package/esm/expectations/isTrue.d.ts +21 -0
  71. package/esm/expectations/isTrue.d.ts.map +1 -0
  72. package/esm/expectations/isTrue.js +24 -0
  73. package/esm/expectations/isTrue.js.map +1 -0
  74. package/esm/expectations/matches.d.ts +22 -0
  75. package/esm/expectations/matches.d.ts.map +1 -0
  76. package/esm/expectations/matches.js +22 -0
  77. package/esm/expectations/matches.js.map +1 -0
  78. package/esm/expectations/not.d.ts +24 -0
  79. package/esm/expectations/not.d.ts.map +1 -0
  80. package/esm/expectations/not.js +48 -0
  81. package/esm/expectations/not.js.map +1 -0
  82. package/esm/expectations/or.d.ts +23 -0
  83. package/esm/expectations/or.d.ts.map +1 -0
  84. package/esm/expectations/or.js +53 -0
  85. package/esm/expectations/or.js.map +1 -0
  86. package/esm/expectations/property.d.ts +62 -0
  87. package/esm/expectations/property.d.ts.map +1 -0
  88. package/esm/expectations/property.js +82 -0
  89. package/esm/expectations/property.js.map +1 -0
  90. package/esm/expectations/startsWith.d.ts +22 -0
  91. package/esm/expectations/startsWith.d.ts.map +1 -0
  92. package/esm/expectations/startsWith.js +22 -0
  93. package/esm/expectations/startsWith.js.map +1 -0
  94. package/esm/index.d.ts +4 -0
  95. package/esm/index.d.ts.map +1 -0
  96. package/esm/index.js +4 -0
  97. package/esm/index.js.map +1 -0
  98. package/lib/Ensure.d.ts +1 -1
  99. package/lib/Ensure.d.ts.map +1 -1
  100. package/lib/Ensure.js +2 -2
  101. package/lib/Ensure.js.map +1 -1
  102. package/lib/EnsureEventually.d.ts +1 -1
  103. package/lib/EnsureEventually.d.ts.map +1 -1
  104. package/lib/expectations/contain.js +2 -2
  105. package/lib/expectations/contain.js.map +1 -1
  106. package/lib/expectations/equals.js +2 -2
  107. package/lib/expectations/equals.js.map +1 -1
  108. package/lib/expectations/index.d.ts +20 -20
  109. package/lib/expectations/index.d.ts.map +1 -1
  110. package/lib/expectations/index.js +20 -20
  111. package/lib/expectations/index.js.map +1 -1
  112. package/lib/expectations/isAfter.d.ts +1 -1
  113. package/lib/expectations/isBefore.d.ts +1 -1
  114. package/lib/expectations/isFalse.js +2 -2
  115. package/lib/expectations/isFalse.js.map +1 -1
  116. package/lib/expectations/isTrue.js +2 -2
  117. package/lib/expectations/isTrue.js.map +1 -1
  118. package/lib/index.d.ts +3 -3
  119. package/lib/index.d.ts.map +1 -1
  120. package/lib/index.js +3 -3
  121. package/lib/index.js.map +1 -1
  122. package/lib/package.json +1 -0
  123. package/package.json +31 -8
  124. package/src/Ensure.ts +2 -2
  125. package/src/EnsureEventually.ts +1 -1
  126. package/src/expectations/contain.ts +1 -1
  127. package/src/expectations/equals.ts +1 -1
  128. package/src/expectations/index.ts +20 -20
  129. package/src/expectations/isFalse.ts +1 -1
  130. package/src/expectations/isTrue.ts +1 -1
  131. package/src/index.ts +3 -3
  132. package/tsconfig-cjs.build.json +17 -0
  133. 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
@@ -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"}