@serenity-js/web 3.23.2 → 3.24.1

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 (96) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/lib/screenplay/interactions/Clear.js +1 -1
  3. package/lib/screenplay/interactions/Clear.js.map +1 -1
  4. package/lib/screenplay/interactions/Click.js +1 -1
  5. package/lib/screenplay/interactions/Click.js.map +1 -1
  6. package/lib/screenplay/interactions/DoubleClick.js +1 -1
  7. package/lib/screenplay/interactions/DoubleClick.js.map +1 -1
  8. package/lib/screenplay/interactions/Enter.d.ts.map +1 -1
  9. package/lib/screenplay/interactions/Enter.js +3 -1
  10. package/lib/screenplay/interactions/Enter.js.map +1 -1
  11. package/lib/screenplay/interactions/ExecuteScript.d.ts +1 -1
  12. package/lib/screenplay/interactions/ExecuteScript.d.ts.map +1 -1
  13. package/lib/screenplay/interactions/ExecuteScript.js +3 -3
  14. package/lib/screenplay/interactions/ExecuteScript.js.map +1 -1
  15. package/lib/screenplay/interactions/Hover.js +1 -1
  16. package/lib/screenplay/interactions/Hover.js.map +1 -1
  17. package/lib/screenplay/interactions/Navigate.d.ts.map +1 -1
  18. package/lib/screenplay/interactions/Navigate.js +1 -1
  19. package/lib/screenplay/interactions/Navigate.js.map +1 -1
  20. package/lib/screenplay/interactions/PageElementInteraction.d.ts +1 -1
  21. package/lib/screenplay/interactions/PageElementInteraction.d.ts.map +1 -1
  22. package/lib/screenplay/interactions/PageElementInteraction.js.map +1 -1
  23. package/lib/screenplay/interactions/Press.d.ts.map +1 -1
  24. package/lib/screenplay/interactions/Press.js +3 -20
  25. package/lib/screenplay/interactions/Press.js.map +1 -1
  26. package/lib/screenplay/interactions/RightClick.js +1 -1
  27. package/lib/screenplay/interactions/RightClick.js.map +1 -1
  28. package/lib/screenplay/interactions/Scroll.d.ts.map +1 -1
  29. package/lib/screenplay/interactions/Scroll.js +3 -3
  30. package/lib/screenplay/interactions/Scroll.js.map +1 -1
  31. package/lib/screenplay/interactions/Select.d.ts +2 -3
  32. package/lib/screenplay/interactions/Select.d.ts.map +1 -1
  33. package/lib/screenplay/interactions/Select.js +5 -6
  34. package/lib/screenplay/interactions/Select.js.map +1 -1
  35. package/lib/screenplay/interactions/Switch.d.ts.map +1 -1
  36. package/lib/screenplay/interactions/Switch.js +2 -2
  37. package/lib/screenplay/interactions/Switch.js.map +1 -1
  38. package/lib/screenplay/interactions/TakeScreenshot.d.ts.map +1 -1
  39. package/lib/screenplay/interactions/TakeScreenshot.js +1 -1
  40. package/lib/screenplay/interactions/TakeScreenshot.js.map +1 -1
  41. package/lib/screenplay/models/ArgumentDehydrator.js +1 -1
  42. package/lib/screenplay/models/ArgumentDehydrator.js.map +1 -1
  43. package/lib/screenplay/models/Cookie.d.ts.map +1 -1
  44. package/lib/screenplay/models/Cookie.js +1 -1
  45. package/lib/screenplay/models/Cookie.js.map +1 -1
  46. package/lib/screenplay/models/PageElement.js +2 -2
  47. package/lib/screenplay/models/PageElement.js.map +1 -1
  48. package/lib/screenplay/models/PageElementsLocator.d.ts +0 -3
  49. package/lib/screenplay/models/PageElementsLocator.d.ts.map +1 -1
  50. package/lib/screenplay/models/PageElementsLocator.js +3 -11
  51. package/lib/screenplay/models/PageElementsLocator.js.map +1 -1
  52. package/lib/screenplay/models/dialogs/ModalDialog.js +2 -2
  53. package/lib/screenplay/models/dialogs/ModalDialog.js.map +1 -1
  54. package/lib/screenplay/questions/Attribute.d.ts +0 -9
  55. package/lib/screenplay/questions/Attribute.d.ts.map +1 -1
  56. package/lib/screenplay/questions/Attribute.js +4 -19
  57. package/lib/screenplay/questions/Attribute.js.map +1 -1
  58. package/lib/screenplay/questions/ComputedStyle.d.ts +0 -9
  59. package/lib/screenplay/questions/ComputedStyle.d.ts.map +1 -1
  60. package/lib/screenplay/questions/ComputedStyle.js +5 -20
  61. package/lib/screenplay/questions/ComputedStyle.js.map +1 -1
  62. package/lib/screenplay/questions/CssClasses.d.ts.map +1 -1
  63. package/lib/screenplay/questions/CssClasses.js +1 -1
  64. package/lib/screenplay/questions/CssClasses.js.map +1 -1
  65. package/lib/screenplay/questions/Selected.js +4 -4
  66. package/lib/screenplay/questions/Selected.js.map +1 -1
  67. package/lib/screenplay/questions/Text.js +3 -3
  68. package/lib/screenplay/questions/Text.js.map +1 -1
  69. package/lib/screenplay/questions/Value.js +1 -1
  70. package/lib/screenplay/questions/Value.js.map +1 -1
  71. package/package.json +7 -7
  72. package/src/screenplay/interactions/Clear.ts +2 -2
  73. package/src/screenplay/interactions/Click.ts +2 -2
  74. package/src/screenplay/interactions/DoubleClick.ts +2 -2
  75. package/src/screenplay/interactions/Enter.ts +6 -2
  76. package/src/screenplay/interactions/ExecuteScript.ts +5 -5
  77. package/src/screenplay/interactions/Hover.ts +2 -2
  78. package/src/screenplay/interactions/Navigate.ts +2 -2
  79. package/src/screenplay/interactions/PageElementInteraction.ts +1 -1
  80. package/src/screenplay/interactions/Press.ts +4 -24
  81. package/src/screenplay/interactions/RightClick.ts +5 -5
  82. package/src/screenplay/interactions/Scroll.ts +4 -4
  83. package/src/screenplay/interactions/Select.ts +5 -7
  84. package/src/screenplay/interactions/Switch.ts +3 -3
  85. package/src/screenplay/interactions/TakeScreenshot.ts +2 -2
  86. package/src/screenplay/models/ArgumentDehydrator.ts +2 -2
  87. package/src/screenplay/models/Cookie.ts +2 -2
  88. package/src/screenplay/models/PageElement.ts +3 -3
  89. package/src/screenplay/models/PageElementsLocator.ts +5 -16
  90. package/src/screenplay/models/dialogs/ModalDialog.ts +3 -3
  91. package/src/screenplay/questions/Attribute.ts +6 -23
  92. package/src/screenplay/questions/ComputedStyle.ts +2 -21
  93. package/src/screenplay/questions/CssClasses.ts +3 -3
  94. package/src/screenplay/questions/Selected.ts +5 -5
  95. package/src/screenplay/questions/Text.ts +4 -4
  96. package/src/screenplay/questions/Value.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, Interaction, UsesAbilities } from '@serenity-js/core';
2
- import { d } from '@serenity-js/core';
2
+ import { the } from '@serenity-js/core';
3
3
 
4
4
  import type { PageElement } from '../models';
5
5
  import { PageElementInteraction } from './PageElementInteraction';
@@ -66,7 +66,7 @@ export class Hover extends PageElementInteraction {
66
66
  }
67
67
 
68
68
  protected constructor(private readonly element: Answerable<PageElement>) {
69
- super(d `#actor hovers the mouse over ${ element }`);
69
+ super(the `#actor hovers the mouse over ${ element }`);
70
70
  }
71
71
 
72
72
  /**
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, UsesAbilities } from '@serenity-js/core';
2
- import { d, Interaction, TestCompromisedError } from '@serenity-js/core';
2
+ import { Interaction, TestCompromisedError, the } from '@serenity-js/core';
3
3
 
4
4
  import { BrowseTheWeb } from '../abilities';
5
5
 
@@ -167,7 +167,7 @@ export class Navigate {
167
167
  */
168
168
  class NavigateToUrl extends Interaction {
169
169
  constructor(private readonly url: Answerable<string>) {
170
- super(d`#actor navigates to ${ url }`);
170
+ super(the`#actor navigates to ${ url }`);
171
171
  }
172
172
 
173
173
  /**
@@ -14,7 +14,7 @@ import type { PageElement } from '../models';
14
14
  */
15
15
  export abstract class PageElementInteraction extends Interaction {
16
16
 
17
- protected constructor(description: string, location: FileSystemLocation = Interaction.callerLocation(4)) {
17
+ protected constructor(description: Answerable<string>, location: FileSystemLocation = Interaction.callerLocation(4)) {
18
18
  super(description, location);
19
19
  }
20
20
 
@@ -1,5 +1,5 @@
1
1
  import type { Activity, Answerable, AnswersQuestions, UsesAbilities } from '@serenity-js/core';
2
- import { d, Interaction, Question } from '@serenity-js/core';
2
+ import { Interaction, Question, the } from '@serenity-js/core';
3
3
  import { asyncMap } from '@serenity-js/core/lib/io';
4
4
 
5
5
  import { BrowseTheWeb } from '../abilities';
@@ -94,7 +94,7 @@ export class Press extends PageElementInteraction {
94
94
  protected constructor(
95
95
  private readonly keys: Answerable<Array<Key | string>>
96
96
  ) {
97
- super(d `#actor presses ${ keys }`);
97
+ super(the `#actor presses ${ keys }`);
98
98
  }
99
99
 
100
100
  /**
@@ -119,7 +119,7 @@ class PressKeyInField extends PageElementInteraction {
119
119
  private readonly keys: Answerable<Array<Key | string>>,
120
120
  private readonly field: Answerable<PageElement> /* todo | Question<AlertPromise> | AlertPromise */,
121
121
  ) {
122
- super(d `#actor presses ${ keys } in ${ field }`, Interaction.callerLocation(3));
122
+ super(the`#actor presses ${ keys } in ${ field }`, Interaction.callerLocation(3));
123
123
  }
124
124
 
125
125
  /**
@@ -147,15 +147,12 @@ class PressKeyInField extends PageElementInteraction {
147
147
  * @package
148
148
  */
149
149
  class KeySequence extends Question<Promise<Array<Key | string>>> {
150
- private subject: string;
151
-
152
150
  static of(keys: Array<Answerable<Key | string | Key[] | string[]>>) {
153
151
  return new KeySequence(keys);
154
152
  }
155
153
 
156
154
  constructor(private readonly keys: Array<Answerable<Key | string | Key[] | string[]>>) {
157
- super();
158
- this.subject = KeySequence.describe(keys);
155
+ super(KeySequence.describe(keys));
159
156
  }
160
157
 
161
158
  async answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<Array<string | Key>> {
@@ -166,23 +163,6 @@ class KeySequence extends Question<Promise<Array<Key | string>>> {
166
163
  .filter(key => !! key);
167
164
  }
168
165
 
169
- /**
170
- * Changes the description of this question's subject.
171
- *
172
- * @param subject
173
- */
174
- describedAs(subject: string): this {
175
- this.subject = subject;
176
- return this;
177
- }
178
-
179
- /**
180
- * @inheritDoc
181
- */
182
- toString(): string {
183
- return this.subject;
184
- }
185
-
186
166
  private static describe(keys: Array<Answerable<Key | string | Key[] | string[]>>): string {
187
167
  const prefix = keys.length === 1 ? 'key' : 'keys';
188
168
 
@@ -1,7 +1,7 @@
1
- import type { Answerable, AnswersQuestions, Interaction, UsesAbilities } from '@serenity-js/core';
2
- import { d } from '@serenity-js/core';
3
-
4
- import type { PageElement } from '../models';
1
+ import type { Answerable, AnswersQuestions, Interaction, UsesAbilities } from '@serenity-js/core';
2
+ import { the } from '@serenity-js/core';
3
+
4
+ import type { PageElement } from '../models';
5
5
  import { PageElementInteraction } from './PageElementInteraction';
6
6
 
7
7
  /**
@@ -80,7 +80,7 @@ export class RightClick extends PageElementInteraction {
80
80
  }
81
81
 
82
82
  protected constructor(private readonly pageElement: Answerable<PageElement>) {
83
- super(d `#actor right-clicks on ${ pageElement }`);
83
+ super(the `#actor right-clicks on ${ pageElement }`);
84
84
  }
85
85
 
86
86
  /**
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, UsesAbilities } from '@serenity-js/core';
2
- import { d, Interaction } from '@serenity-js/core';
2
+ import { Interaction, the } from '@serenity-js/core';
3
3
 
4
4
  import type { PageElement } from '../models';
5
5
 
@@ -63,14 +63,14 @@ export class Scroll extends Interaction {
63
63
  }
64
64
 
65
65
  protected constructor(private readonly element: Answerable<PageElement>) {
66
- super(d`#actor scrolls to ${ element }`);
66
+ super(the`#actor scrolls to ${ element }`);
67
67
  }
68
68
 
69
69
  /**
70
70
  * @inheritDoc
71
71
  */
72
72
  async performAs(actor: UsesAbilities & AnswersQuestions): Promise<void> {
73
- const target = await actor.answer(this.element);
74
- await target.scrollIntoView();
73
+ const pageElement = await actor.answer(this.element);
74
+ await pageElement.scrollIntoView();
75
75
  }
76
76
  }
@@ -1,10 +1,8 @@
1
- import type { Answerable} from '@serenity-js/core';
2
- import { d } from '@serenity-js/core';
1
+ import { type Answerable, Interaction,the } from '@serenity-js/core';
3
2
  import { asyncMap, commaSeparated } from '@serenity-js/core/lib/io';
4
3
  import { stringified } from '@serenity-js/core/lib/io/stringified';
5
- import { Interaction } from '@serenity-js/core/lib/screenplay';
6
4
 
7
- import type { PageElement} from '../models';
5
+ import type { PageElement } from '../models';
8
6
  import { SelectOption } from '../models';
9
7
 
10
8
  /**
@@ -33,7 +31,7 @@ export class Select {
33
31
  * <option value='PL'>Poland</option>
34
32
  * <option value='US'>United States</option>
35
33
  * </select>
36
- * ```
34
+ * ```C
37
35
  *
38
36
  * #### Lean Page Object describing the widget
39
37
  *
@@ -72,7 +70,7 @@ export class Select {
72
70
  static value(value: Answerable<string>): { from: (pageElement: Answerable<PageElement>) => Interaction } {
73
71
  return {
74
72
  from: (pageElement: Answerable<PageElement>): Interaction =>
75
- Interaction.where(d`#actor selects value ${ value } from ${ pageElement }`, async actor => {
73
+ Interaction.where(the`#actor selects value ${ value } from ${ pageElement }`, async actor => {
76
74
  const element = await actor.answer(pageElement);
77
75
  const desiredValue = await actor.answer(value);
78
76
 
@@ -203,7 +201,7 @@ export class Select {
203
201
  static option(value: Answerable<string>): { from: (pageElement: Answerable<PageElement>) => Interaction } {
204
202
  return {
205
203
  from: (pageElement: Answerable<PageElement>): Interaction =>
206
- Interaction.where(d`#actor selects ${ value } from ${ pageElement }`, async actor => {
204
+ Interaction.where(the`#actor selects ${ value } from ${ pageElement }`, async actor => {
207
205
  const element = await actor.answer(pageElement);
208
206
  const desiredLabel = await actor.answer(value);
209
207
 
@@ -1,5 +1,5 @@
1
1
  import type { Activity, Actor, Answerable, AnswersQuestions, UsesAbilities } from '@serenity-js/core';
2
- import { Interaction, Task } from '@serenity-js/core';
2
+ import { Interaction, Task, the } from '@serenity-js/core';
3
3
 
4
4
  import type { Switchable } from '../models';
5
5
 
@@ -117,7 +117,7 @@ export class Switch extends Interaction {
117
117
  }
118
118
 
119
119
  protected constructor(private readonly switchable: Answerable<Switchable>) {
120
- super(`#actor switches to ${ switchable }`);
120
+ super(the`#actor switches to ${ switchable }`);
121
121
  }
122
122
 
123
123
  /**
@@ -151,7 +151,7 @@ class SwitchAndPerformActivities extends Task {
151
151
  private readonly switchable: Answerable<Switchable>,
152
152
  private readonly activities: Activity[]
153
153
  ) {
154
- super(`#actor switches to ${ switchable }`);
154
+ super(the `#actor switches to ${ switchable }`);
155
155
  }
156
156
 
157
157
  /**
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, CollectsArtifacts, UsesAbilities } from '@serenity-js/core';
2
- import { d, Interaction } from '@serenity-js/core';
2
+ import { Interaction, the } from '@serenity-js/core';
3
3
  import { Name, Photo } from '@serenity-js/core/lib/model';
4
4
 
5
5
  import { BrowseTheWeb } from '../abilities';
@@ -45,7 +45,7 @@ export class TakeScreenshot extends Interaction {
45
45
  }
46
46
 
47
47
  protected constructor(private readonly name: Answerable<string>) {
48
- super(d`#actor takes a screenshot of ${ name }`);
48
+ super(the`#actor takes a screenshot of ${ name }`);
49
49
  }
50
50
 
51
51
  /**
@@ -1,4 +1,4 @@
1
- import { isPlainObject } from '@serenity-js/core/lib/io';
1
+ import { ValueInspector } from '@serenity-js/core/lib/io';
2
2
 
3
3
  /* eslint-disable @typescript-eslint/indent */
4
4
  type TransformedArgument<T, U> =
@@ -43,7 +43,7 @@ export class ArgumentDehydrator<T, U> {
43
43
  };
44
44
  }
45
45
 
46
- if (isPlainObject(arg)) {
46
+ if (ValueInspector.isPlainObject(arg)) {
47
47
  const { args: nestedArgs, refs: nestedRefs, refsCount: currentRefsCount } = await this.dehydrateRecursively(Object.values(arg), refsCount);
48
48
  return {
49
49
  args: [ ...args, Object.fromEntries(Object.keys(arg).map((key, i) => [ key, nestedArgs[i] ])) ],
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, Optional, QuestionAdapter, WithAnswerableProperties } from '@serenity-js/core';
2
- import { d, Interaction, Question, Timestamp } from '@serenity-js/core';
2
+ import { Interaction, Question, the, Timestamp } from '@serenity-js/core';
3
3
  import type { Predicate } from 'tiny-types';
4
4
  import { ensure, isBoolean, isDefined, isInstanceOf, isOneOf, isPlainObject, isString } from 'tiny-types';
5
5
 
@@ -101,7 +101,7 @@ export abstract class Cookie implements Optional {
101
101
  */
102
102
  static set(cookieData: Answerable<WithAnswerableProperties<CookieData>>): Interaction {
103
103
 
104
- return Interaction.where(d `#actor sets cookie: ${ cookieData }`, async actor => {
104
+ return Interaction.where(the`#actor sets cookie: ${ cookieData }`, async actor => {
105
105
  const cookie = ensure('cookieData', await actor.answer(Question.fromObject(cookieData)) as CookieData, isDefined(), isPlainObject());
106
106
 
107
107
  const page = await BrowseTheWeb.as(actor).currentPage();
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, MetaQuestionAdapter, Optional } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
  import { ensure, isDefined } from 'tiny-types';
4
4
 
5
5
  import { BrowseTheWeb } from '../abilities';
@@ -31,7 +31,7 @@ export abstract class PageElement<Native_Element_Type = any> implements Optional
31
31
  }
32
32
 
33
33
  static located<NET>(selector: Answerable<Selector>): MetaQuestionAdapter<PageElement<NET>, PageElement<NET>> {
34
- return Question.about(d`page element located ${ selector }`, async actor => {
34
+ return Question.about(the`page element located ${ selector }`, async actor => {
35
35
  const bySelector = await actor.answer(selector);
36
36
  const currentPage = await BrowseTheWeb.as<BrowseTheWeb<NET>>(actor).currentPage();
37
37
 
@@ -43,7 +43,7 @@ export abstract class PageElement<Native_Element_Type = any> implements Optional
43
43
  childElement: MetaQuestionAdapter<PageElement<NET>, PageElement<NET>> | PageElement<NET>,
44
44
  parentElement: Answerable<PageElement<NET>>
45
45
  ): MetaQuestionAdapter<PageElement<NET>, PageElement<NET>> {
46
- return Question.about(d`${ childElement } of ${ parentElement }`, async actor => {
46
+ return Question.about(the`${ childElement } of ${ parentElement }`, async actor => {
47
47
  const parent = await actor.answer(parentElement);
48
48
  const child = childElement.of(parent)
49
49
 
@@ -1,5 +1,5 @@
1
- import type { Answerable, AnswersQuestions, ChainableMetaQuestion, UsesAbilities } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
1
+ import type { Answerable, AnswersQuestions, ChainableMetaQuestion, UsesAbilities } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
 
4
4
  import { BrowseTheWeb } from '../abilities';
5
5
  import type { Locator } from './Locator';
@@ -15,7 +15,7 @@ export class PageElementsLocator<Native_Element_Type = any>
15
15
  {
16
16
  static fromDocumentRoot<NET>(selector: Answerable<Selector>): PageElementsLocator<NET> {
17
17
  return new PageElementsLocator(
18
- Question.about(d`page elements located ${ selector }`, async actor => {
18
+ Question.about(the`page elements located ${ selector }`, async actor => {
19
19
  const bySelector = await actor.answer(selector);
20
20
  const currentPage = await BrowseTheWeb.as<BrowseTheWeb<NET>>(actor).currentPage();
21
21
 
@@ -24,15 +24,13 @@ export class PageElementsLocator<Native_Element_Type = any>
24
24
  );
25
25
  }
26
26
 
27
- private subject?: string;
28
-
29
27
  constructor(private readonly locator: Answerable<Locator<Native_Element_Type>>) {
30
- super();
28
+ super(the`${ locator }`);
31
29
  }
32
30
 
33
31
  of(parent: Answerable<PageElement<Native_Element_Type>>): Question<Promise<Array<PageElement<Native_Element_Type>>>> & ChainableMetaQuestion<PageElement<Native_Element_Type>, Question<Promise<Array<PageElement<Native_Element_Type>>>>> {
34
32
  return new PageElementsLocator(
35
- Question.about(this.toString() + d` of ${ parent }`, async actor => {
33
+ Question.about(the`${ this } of ${ parent }`, async actor => {
36
34
  const locator: Locator<Native_Element_Type> = await actor.answer(this.locator);
37
35
  const parentElement: PageElement<Native_Element_Type> = await actor.answer(parent);
38
36
 
@@ -45,13 +43,4 @@ export class PageElementsLocator<Native_Element_Type = any>
45
43
  const resolved: Locator<Native_Element_Type> = await actor.answer(this.locator);
46
44
  return resolved.allElements();
47
45
  }
48
-
49
- describedAs(subject: string): this {
50
- this.subject = subject;
51
- return this;
52
- }
53
-
54
- toString(): string {
55
- return this.subject ?? d`${ this.locator }`;
56
- }
57
46
  }
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, Interaction, Optional, Question, QuestionAdapter } from '@serenity-js/core';
2
- import { d } from '@serenity-js/core';
2
+ import { the } from '@serenity-js/core';
3
3
 
4
4
  import { Page } from '../Page';
5
5
 
@@ -140,7 +140,7 @@ export abstract class ModalDialog implements Optional {
140
140
  */
141
141
  static acceptNextWithValue(value: Answerable<string | number>): Interaction {
142
142
  return Page.current().modalDialog().acceptNextWithValue(value)
143
- .describedAs(d`#actor accepts next modal dialog window with value ${ value }`);
143
+ .describedAs(the`#actor accepts next modal dialog window with value ${ value }`);
144
144
  }
145
145
 
146
146
  /**
@@ -148,7 +148,7 @@ export abstract class ModalDialog implements Optional {
148
148
  */
149
149
  static dismissNext(): Interaction {
150
150
  return Page.current().modalDialog().dismissNext()
151
- .describedAs(d`#actor dismisses next modal dialog window`);
151
+ .describedAs(the`#actor dismisses next modal dialog window`);
152
152
  }
153
153
 
154
154
  /**
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, MetaQuestion, MetaQuestionAdapter, Optional, QuestionAdapter, UsesAbilities } from '@serenity-js/core';
2
- import { d, LogicError, Question } from '@serenity-js/core';
2
+ import { d, LogicError, Question, the } from '@serenity-js/core';
3
3
 
4
4
  import { PageElement } from '../models';
5
5
 
@@ -99,8 +99,6 @@ export class Attribute<Native_Element_Type>
99
99
  extends Question<Promise<string>>
100
100
  implements MetaQuestion<PageElement<Native_Element_Type>, Question<Promise<string>>>, Optional
101
101
  {
102
- private subject: string;
103
-
104
102
  /**
105
103
  * Instantiates a {@apilink Question} that uses
106
104
  * the {@apilink Actor|actor's} {@apilink Ability|ability} to {@apilink BrowseTheWeb} to retrieve
@@ -117,10 +115,10 @@ export class Attribute<Native_Element_Type>
117
115
  private readonly name: Answerable<string>,
118
116
  private readonly element?: QuestionAdapter<PageElement> | PageElement,
119
117
  ) {
120
- super();
121
- this.subject = element
122
- ? d`${ name } attribute of ${ element }`
123
- : d`${ name } attribute`
118
+ super(element
119
+ ? the`${ name } attribute of ${ element }`
120
+ : the`${ name } attribute`
121
+ );
124
122
  }
125
123
 
126
124
  /**
@@ -161,24 +159,9 @@ export class Attribute<Native_Element_Type>
161
159
  * @inheritDoc
162
160
  */
163
161
  isPresent(): QuestionAdapter<boolean> {
164
- return Question.about(this.subject, async actor => {
162
+ return Question.about(this.toString(), async actor => {
165
163
  const attribute = await this.answeredBy(actor);
166
164
  return attribute !== null && attribute !== undefined;
167
165
  });
168
166
  }
169
-
170
- /**
171
- * @inheritDoc
172
- */
173
- describedAs(subject: string): this {
174
- this.subject = subject;
175
- return this;
176
- }
177
-
178
- /**
179
- * @inheritDoc
180
- */
181
- toString(): string {
182
- return this.subject;
183
- }
184
167
  }
@@ -105,8 +105,6 @@ export class ComputedStyle<Native_Element_Type>
105
105
  extends Question<Promise<string>>
106
106
  implements MetaQuestion<PageElement<Native_Element_Type>, Question<Promise<string>>>
107
107
  {
108
- private subject: string;
109
-
110
108
  /**
111
109
  * Instantiates a {@apilink Question} that uses
112
110
  * the {@apilink Actor|actor's} {@apilink Ability|ability} to {@apilink BrowseTheWeb} to retrieve
@@ -124,13 +122,11 @@ export class ComputedStyle<Native_Element_Type>
124
122
  private readonly element?: QuestionAdapter<PageElement<Native_Element_Type>> | PageElement<Native_Element_Type>,
125
123
  private readonly pseudoElement?: Answerable<string>,
126
124
  ) {
127
- super();
128
-
129
- this.subject = [
125
+ super([
130
126
  d`computed style property ${ name }`,
131
127
  pseudoElement && d`of pseudo-element ${ pseudoElement }`,
132
128
  element && d`of ${ element }`,
133
- ].filter(Boolean).join(' ');
129
+ ].filter(Boolean).join(' '));
134
130
  }
135
131
 
136
132
  /**
@@ -188,19 +184,4 @@ export class ComputedStyle<Native_Element_Type>
188
184
 
189
185
  return page.executeScript('return window.getComputedStyle(arguments[0], arguments[1]).getPropertyValue(arguments[2])', element, pseudoElement, name);
190
186
  }
191
-
192
- /**
193
- * @inheritDoc
194
- */
195
- describedAs(subject: string): this {
196
- this.subject = subject;
197
- return this;
198
- }
199
-
200
- /**
201
- * @inheritDoc
202
- */
203
- toString(): string {
204
- return this.subject;
205
- }
206
187
  }
@@ -1,5 +1,5 @@
1
- import type { Answerable,MetaQuestionAdapter, QuestionAdapter } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
1
+ import type { Answerable, MetaQuestionAdapter, QuestionAdapter } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
 
4
4
  import { PageElement } from '../models';
5
5
 
@@ -110,7 +110,7 @@ export class CssClasses {
110
110
  * @param pageElement
111
111
  */
112
112
  static of(pageElement: QuestionAdapter<PageElement> | PageElement): MetaQuestionAdapter<PageElement, string[]> {
113
- return Question.about(d`CSS classes of ${ pageElement }`,
113
+ return Question.about(the`CSS classes of ${ pageElement }`,
114
114
  async actor => {
115
115
  const element = await actor.answer(pageElement);
116
116
 
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, QuestionAdapter } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
 
4
4
  import type { PageElement } from '../models';
5
5
 
@@ -67,7 +67,7 @@ export class Selected {
67
67
  * A {@apilink PageElement} identifying the `<select>` element of interest
68
68
  */
69
69
  static valueOf(pageElement: Answerable<PageElement>): QuestionAdapter<string> {
70
- return Question.about(d`value selected in ${ pageElement }`, async actor => {
70
+ return Question.about(the`value selected in ${ pageElement }`, async actor => {
71
71
  const element = await actor.answer(pageElement);
72
72
  const options = await element.selectedOptions();
73
73
 
@@ -126,7 +126,7 @@ export class Selected {
126
126
  * A {@apilink PageElement} identifying the `<select>` element of interest
127
127
  */
128
128
  static valuesOf(pageElement: Answerable<PageElement>): QuestionAdapter<Array<string>> {
129
- return Question.about(d`values selected in ${ pageElement }`, async actor => {
129
+ return Question.about(the`values selected in ${ pageElement }`, async actor => {
130
130
  const element = await actor.answer(pageElement);
131
131
 
132
132
  const options = await element.selectedOptions();
@@ -187,7 +187,7 @@ export class Selected {
187
187
  * A {@apilink PageElement} identifying the `<select>` element of interest
188
188
  */
189
189
  static optionIn(pageElement: Answerable<PageElement>): QuestionAdapter<string> {
190
- return Question.about(d`option selected in ${ pageElement }`, async actor => {
190
+ return Question.about(the`option selected in ${ pageElement }`, async actor => {
191
191
  const element = await actor.answer(pageElement);
192
192
 
193
193
  const options = await element.selectedOptions();
@@ -248,7 +248,7 @@ export class Selected {
248
248
  * A {@apilink PageElement} identifying the `<select>` element of interest
249
249
  */
250
250
  static optionsIn(pageElement: Answerable<PageElement>): QuestionAdapter<Array<string>> {
251
- return Question.about(d`options selected in ${ pageElement }`, async actor => {
251
+ return Question.about(the`options selected in ${ pageElement }`, async actor => {
252
252
  const element = await actor.answer(pageElement);
253
253
 
254
254
  const options = await element.selectedOptions();
@@ -1,5 +1,5 @@
1
1
  import type { Answerable, AnswersQuestions, MetaQuestionAdapter, QuestionAdapter } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
  import { asyncMap } from '@serenity-js/core/lib/io';
4
4
 
5
5
  import type { PageElements } from '../models';
@@ -105,7 +105,7 @@ export class Text {
105
105
  * @param pageElement
106
106
  */
107
107
  static of(pageElement: QuestionAdapter<PageElement> | PageElement): MetaQuestionAdapter<PageElement, string> {
108
- return Question.about(d`the text of ${ pageElement }`,
108
+ return Question.about(the`the text of ${ pageElement }`,
109
109
  async actor => {
110
110
  const element = await actor.answer(pageElement);
111
111
 
@@ -130,14 +130,14 @@ export class Text {
130
130
  static ofAll(pageElements: Answerable<PageElement[]>): QuestionAdapter<string[]>
131
131
  static ofAll(pageElements: PageElements | Answerable<PageElement[]>): QuestionAdapter<string[]> {
132
132
  if (Question.isAMetaQuestion(pageElements)) {
133
- return Question.about(d`the text of ${ pageElements }`,
133
+ return Question.about(the`the text of ${ pageElements }`,
134
134
  textOfMultiple(pageElements),
135
135
  (parent: Answerable<PageElement>) =>
136
136
  Text.ofAll(pageElements.of(parent))
137
137
  );
138
138
  }
139
139
 
140
- return Question.about(d`the text of ${ pageElements }`, textOfMultiple(pageElements));
140
+ return Question.about(the`the text of ${ pageElements }`, textOfMultiple(pageElements));
141
141
  }
142
142
  }
143
143
 
@@ -1,5 +1,5 @@
1
1
  import type { Answerable,MetaQuestionAdapter, QuestionAdapter } from '@serenity-js/core';
2
- import { d, Question } from '@serenity-js/core';
2
+ import { Question, the } from '@serenity-js/core';
3
3
 
4
4
  import { PageElement } from '../models';
5
5
 
@@ -70,7 +70,7 @@ export class Value {
70
70
  * @param pageElement
71
71
  */
72
72
  static of(pageElement: QuestionAdapter<PageElement> | PageElement): MetaQuestionAdapter<PageElement, string> {
73
- return Question.about(d`the value of ${ pageElement }`,
73
+ return Question.about(the`the value of ${ pageElement }`,
74
74
  async actor => {
75
75
  const element = await actor.answer(pageElement);
76
76
  return element.value();