@serenity-js/core 3.15.1 → 3.16.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 (38) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/lib/io/RequirementsHierarchy.d.ts +16 -0
  3. package/lib/io/RequirementsHierarchy.d.ts.map +1 -0
  4. package/lib/io/RequirementsHierarchy.js +76 -0
  5. package/lib/io/RequirementsHierarchy.js.map +1 -0
  6. package/lib/io/index.d.ts +1 -0
  7. package/lib/io/index.d.ts.map +1 -1
  8. package/lib/io/index.js +1 -0
  9. package/lib/io/index.js.map +1 -1
  10. package/lib/model/tags/Tag.js +1 -1
  11. package/lib/model/tags/Tag.js.map +1 -1
  12. package/lib/screenplay/Actor.d.ts +1 -4
  13. package/lib/screenplay/Actor.d.ts.map +1 -1
  14. package/lib/screenplay/Actor.js +1 -4
  15. package/lib/screenplay/Actor.js.map +1 -1
  16. package/lib/screenplay/artifacts/CollectsArtifacts.d.ts +54 -0
  17. package/lib/screenplay/artifacts/CollectsArtifacts.d.ts.map +1 -1
  18. package/lib/screenplay/questions/Masked.d.ts +35 -0
  19. package/lib/screenplay/questions/Masked.d.ts.map +1 -0
  20. package/lib/screenplay/questions/Masked.js +40 -0
  21. package/lib/screenplay/questions/Masked.js.map +1 -0
  22. package/lib/screenplay/questions/index.d.ts +1 -0
  23. package/lib/screenplay/questions/index.d.ts.map +1 -1
  24. package/lib/screenplay/questions/index.js +1 -0
  25. package/lib/screenplay/questions/index.js.map +1 -1
  26. package/lib/screenplay/time/models/Timestamp.d.ts +2 -2
  27. package/lib/screenplay/time/models/Timestamp.d.ts.map +1 -1
  28. package/lib/screenplay/time/models/Timestamp.js +39 -14
  29. package/lib/screenplay/time/models/Timestamp.js.map +1 -1
  30. package/package.json +2 -3
  31. package/src/io/RequirementsHierarchy.ts +87 -0
  32. package/src/io/index.ts +1 -0
  33. package/src/model/tags/Tag.ts +1 -1
  34. package/src/screenplay/Actor.ts +1 -4
  35. package/src/screenplay/artifacts/CollectsArtifacts.ts +54 -0
  36. package/src/screenplay/questions/Masked.ts +38 -0
  37. package/src/screenplay/questions/index.ts +1 -0
  38. package/src/screenplay/time/models/Timestamp.ts +45 -12
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
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.16.0](https://github.com/serenity-js/serenity-js/compare/v3.15.1...v3.16.0) (2024-02-01)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **core:** introduced RequirementsHierarchy to centralise requirements detection logic ([0a3d6f0](https://github.com/serenity-js/serenity-js/commit/0a3d6f013a3b94ca471edc263e1157b7c41131be))
12
+ * **core:** recognise `specs` as a potential requirements hierarchy root ([d95d850](https://github.com/serenity-js/serenity-js/commit/d95d85058fd5e4e01aec689b7196989ece5e303f))
13
+ * **core:** removed dependency on Moment.js ([edd1d64](https://github.com/serenity-js/serenity-js/commit/edd1d64f30893983b92bd600d102c81577c0ecb1))
14
+ * **core:** simplified the Timestampt validation regex and improved error messages ([b453a23](https://github.com/serenity-js/serenity-js/commit/b453a23de419dbd811927b9447c17678e39f8cc8))
15
+ * **core:** support for timezones and simplified date time strings when creating Timestamps ([754f8e2](https://github.com/serenity-js/serenity-js/commit/754f8e260d2fc5130075a78ec58084eafcf2c83f))
16
+
17
+
18
+ ### Features
19
+
20
+ * **core:** added Masked.valueOf() Question ([e9ff5ab](https://github.com/serenity-js/serenity-js/commit/e9ff5ab62e8b305aa7ef2238f482be5369d890c1)), closes [#2165](https://github.com/serenity-js/serenity-js/issues/2165)
21
+ * **mocha:** support for nested requirements reporting ([f8e70ce](https://github.com/serenity-js/serenity-js/commit/f8e70ce8a317ab6e8bdf4d058110f110b4c8deda))
22
+ * **serenity-bdd:** upgraded Serenity BDD to 4.0.44 ([4e2f1e3](https://github.com/serenity-js/serenity-js/commit/4e2f1e3b273712c44a7f749ba9570f121520cdd5))
23
+
24
+
25
+
26
+
27
+
6
28
  ## [3.15.1](https://github.com/serenity-js/serenity-js/compare/v3.15.0...v3.15.1) (2024-01-19)
7
29
 
8
30
  **Note:** Version bump only for package @serenity-js/core
@@ -0,0 +1,16 @@
1
+ import { Tag } from '../model';
2
+ import type { FileSystem } from './FileSystem';
3
+ import { Path } from './Path';
4
+ export declare class RequirementsHierarchy {
5
+ private readonly fileSystem;
6
+ private readonly userDefinedSpecDirectory?;
7
+ private root;
8
+ private static readonly specDirectoryCandidates;
9
+ constructor(fileSystem: FileSystem, userDefinedSpecDirectory?: Path);
10
+ requirementTagsFor(pathToSpec: Path, featureName?: string): Tag[];
11
+ hierarchyFor(pathToSpec: Path): string[];
12
+ rootDirectory(): Path;
13
+ private guessRootDirectory;
14
+ private resolve;
15
+ }
16
+ //# sourceMappingURL=RequirementsHierarchy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementsHierarchy.d.ts","sourceRoot":"","sources":["../../src/io/RequirementsHierarchy.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,GAAG,EAAY,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,qBAAa,qBAAqB;IAc1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAb9C,OAAO,CAAC,IAAI,CAAO;IAEnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAO7C;gBAGmB,UAAU,EAAE,UAAU,EACtB,wBAAwB,CAAC,EAAE,IAAI;IAIpD,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE;IAgBjE,YAAY,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,EAAE;IAiBxC,aAAa,IAAI,IAAI;IAUrB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,OAAO;CAOlB"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequirementsHierarchy = void 0;
4
+ const errors_1 = require("../errors");
5
+ const model_1 = require("../model");
6
+ const Path_1 = require("./Path");
7
+ class RequirementsHierarchy {
8
+ fileSystem;
9
+ userDefinedSpecDirectory;
10
+ root;
11
+ static specDirectoryCandidates = [
12
+ `features`,
13
+ `specs`,
14
+ `spec`,
15
+ `tests`,
16
+ `test`,
17
+ `src`,
18
+ ];
19
+ constructor(fileSystem, userDefinedSpecDirectory) {
20
+ this.fileSystem = fileSystem;
21
+ this.userDefinedSpecDirectory = userDefinedSpecDirectory;
22
+ }
23
+ requirementTagsFor(pathToSpec, featureName) {
24
+ const [fileBasedFeatureName, capabilityName, ...themeNames] = this.hierarchyFor(pathToSpec).reverse().filter(segment => !['.', '..'].includes(segment));
25
+ const themeTags = themeNames.reverse().map(themeName => model_1.Tag.humanReadable(model_1.ThemeTag, themeName));
26
+ const capabilityTag = capabilityName && model_1.Tag.humanReadable(model_1.CapabilityTag, capabilityName);
27
+ const featureTag = featureName
28
+ ? new model_1.FeatureTag(featureName)
29
+ : model_1.Tag.humanReadable(model_1.FeatureTag, fileBasedFeatureName);
30
+ return [
31
+ ...themeTags,
32
+ capabilityTag,
33
+ featureTag
34
+ ].filter(Boolean);
35
+ }
36
+ hierarchyFor(pathToSpec) {
37
+ const relative = this.rootDirectory().relative(pathToSpec);
38
+ return relative.split().map((segment, i, segments) => {
39
+ // return all the segments as-is, except for the last one
40
+ if (i < segments.length - 1) {
41
+ return segment;
42
+ }
43
+ // Strip the extension, like `.feature` or `.spec.ts`
44
+ const firstDotIndex = segment.indexOf('.');
45
+ return firstDotIndex === -1
46
+ ? segment
47
+ : segment.slice(0, firstDotIndex);
48
+ });
49
+ }
50
+ rootDirectory() {
51
+ if (!this.root) {
52
+ this.root = this.userDefinedSpecDirectory
53
+ ? this.resolve(this.userDefinedSpecDirectory)
54
+ : this.guessRootDirectory();
55
+ }
56
+ return this.root;
57
+ }
58
+ guessRootDirectory() {
59
+ for (const candidate of RequirementsHierarchy.specDirectoryCandidates) {
60
+ const candidateSpecDirectory = Path_1.Path.from(candidate);
61
+ if (this.fileSystem.exists(Path_1.Path.from(candidate))) {
62
+ return this.fileSystem.resolve(candidateSpecDirectory);
63
+ }
64
+ }
65
+ // default to current working directory
66
+ return this.fileSystem.resolve(Path_1.Path.from('.'));
67
+ }
68
+ resolve(userDefinedRootDirectory) {
69
+ if (!this.fileSystem.exists(userDefinedRootDirectory)) {
70
+ throw new errors_1.ConfigurationError(`Configured specDirectory \`${userDefinedRootDirectory}\` does not exist`);
71
+ }
72
+ return this.fileSystem.resolve(userDefinedRootDirectory);
73
+ }
74
+ }
75
+ exports.RequirementsHierarchy = RequirementsHierarchy;
76
+ //# sourceMappingURL=RequirementsHierarchy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementsHierarchy.js","sourceRoot":"","sources":["../../src/io/RequirementsHierarchy.ts"],"names":[],"mappings":"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"}
package/lib/io/index.d.ts CHANGED
@@ -10,5 +10,6 @@ export * from './inspectedObject';
10
10
  export * from './loader';
11
11
  export * from './Path';
12
12
  export * from './reflection';
13
+ export * from './RequirementsHierarchy';
13
14
  export * from './trimmed';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,WAAW,CAAC"}
package/lib/io/index.js CHANGED
@@ -26,5 +26,6 @@ __exportStar(require("./inspectedObject"), exports);
26
26
  __exportStar(require("./loader"), exports);
27
27
  __exportStar(require("./Path"), exports);
28
28
  __exportStar(require("./reflection"), exports);
29
+ __exportStar(require("./RequirementsHierarchy"), exports);
29
30
  __exportStar(require("./trimmed"), exports);
30
31
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,mDAAiC;AACjC,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,uDAAqC;AACrC,2CAAyB;AACzB,8CAA4B;AAC5B,oDAAkC;AAClC,2CAAyB;AACzB,yCAAuB;AACvB,+CAA6B;AAC7B,4CAA0B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,mDAAiC;AACjC,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,uDAAqC;AACrC,2CAAyB;AACzB,8CAA4B;AAC5B,oDAAkC;AAClC,2CAAyB;AACzB,yCAAuB;AACvB,+CAA6B;AAC7B,0DAAwC;AACxC,4CAA0B"}
@@ -36,7 +36,7 @@ class Tag extends tiny_types_1.TinyType {
36
36
  // based on https://github.com/serenity-bdd/serenity-core/blob/8f7d14c6dad47bb58a1585fef5f9d9a44bb963fd/serenity-model/src/main/java/net/thucydides/core/requirements/AbstractRequirementsTagProvider.java#L36
37
37
  const name = String(tagName)
38
38
  .trim()
39
- .match(/[\dA-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g)
39
+ .match(/[\dA-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z-]+\d*|[A-Z]|\d+/g)
40
40
  .map(chunk => /^[A-Z]+$/.test(chunk) ? chunk : chunk.toLowerCase())
41
41
  .join('_')
42
42
  .replaceAll(/[\s_]+/g, ' ');
@@ -1 +1 @@
1
- {"version":3,"file":"Tag.js","sourceRoot":"","sources":["../../../src/model/tags/Tag.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAA4F;AAE5F,kDAAoC;AAEpC;;GAEG;AACH,MAAsB,GAAI,SAAQ,qBAAQ;IA0BA;IAA8B;IAzBpE,MAAM,CAAC,aAAa,CAAC,cAAyC,EAAE,OAAe;QAC3E,8MAA8M;QAC9M,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;aACvB,IAAI,EAAE;aACN,KAAK,CAAC,6DAA6D,CAAC;aACpE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;aAClE,IAAI,CAAC,GAAG,CAAC;aACT,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAC9B;QAED,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,CAAa;QACzB,MAAM,IAAI,GAAW,IAAA,mBAAM,EAAC,qBAAqB,EAAE,CAAC,CAAC,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,GAAE,CAAW,CAAC;QAE9F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;QAEvG,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,EAAE;YACnE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACtC;QAED,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,YAAsC,IAAY,EAAkB,IAAY;QAC5E,KAAK,EAAE,CAAC;QAD0B,SAAI,GAAJ,IAAI,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAQ;QAG5E,IAAA,mBAAM,EAAC,UAAU,EAAE,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,EAAC,QAAQ,EAAE,IAAA,0BAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAA,mBAAM,EAAC,UAAU,EAAE,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,EAAC,QAAQ,EAAE,IAAA,0BAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,MAAM;QACF,OAAO,KAAK,CAAC,MAAM,EAAoC,CAAC;IAC5D,CAAC;CACJ;AApCD,kBAoCC"}
1
+ {"version":3,"file":"Tag.js","sourceRoot":"","sources":["../../../src/model/tags/Tag.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAA4F;AAE5F,kDAAoC;AAEpC;;GAEG;AACH,MAAsB,GAAI,SAAQ,qBAAQ;IA0BA;IAA8B;IAzBpE,MAAM,CAAC,aAAa,CAAC,cAAyC,EAAE,OAAe;QAC3E,8MAA8M;QAC9M,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;aACvB,IAAI,EAAE;aACN,KAAK,CAAC,8DAA8D,CAAC;aACrE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;aAClE,IAAI,CAAC,GAAG,CAAC;aACT,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC,CAC9B;QAED,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,CAAa;QACzB,MAAM,IAAI,GAAW,IAAA,mBAAM,EAAC,qBAAqB,EAAE,CAAC,CAAC,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,GAAE,CAAW,CAAC;QAE9F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;QAEvG,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,EAAE;YACnE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACtC;QAED,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,YAAsC,IAAY,EAAkB,IAAY;QAC5E,KAAK,EAAE,CAAC;QAD0B,SAAI,GAAJ,IAAI,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAQ;QAG5E,IAAA,mBAAM,EAAC,UAAU,EAAE,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,EAAC,QAAQ,EAAE,IAAA,0BAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAA,mBAAM,EAAC,UAAU,EAAE,IAAI,EAAE,IAAA,sBAAS,GAAE,EAAE,IAAA,qBAAQ,EAAC,QAAQ,EAAE,IAAA,0BAAa,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,MAAM;QACF,OAAO,KAAK,CAAC,MAAM,EAAoC,CAAC;IAC5D,CAAC;CACJ;AApCD,kBAoCC"}
@@ -116,10 +116,7 @@ export declare class Actor implements PerformsActivities, UsesAbilities, CanHave
116
116
  */
117
117
  answer<T>(answerable: Answerable<T>): Promise<T>;
118
118
  /**
119
- * Announce collection of an {@apilink Artifact} so that it can be picked up by a {@apilink StageCrewMember}.
120
- *
121
- * @param artifact
122
- * @param name
119
+ * @inheritDoc
123
120
  */
124
121
  collect(artifact: Artifact, name?: string | Name): void;
125
122
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Actor.d.ts","sourceRoot":"","sources":["../../src/screenplay/Actor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,IAAI,EAAG,MAAM,UAAU,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EACR,WAAW,EACX,gBAAgB,EAGhB,aAAa,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,OAAO,EAGV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,qBAAa,KAAM,YAAW,kBAAkB,EAC5C,aAAa,EACb,gBAAgB,CAAC,KAAK,CAAC,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS;aAKW,IAAI,EAAE,MAAM;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJ1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgF;gBAGtF,IAAI,EAAE,MAAM,EACX,KAAK,EAAE,KAAK,EAC7B,SAAS,GAAE,OAAO,EAAO;IAS7B;;;;;;;;;;OAUG;IACH,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;IAc5D;;;;;;OAMG;IACH,UAAU,CAAC,GAAG,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK;IAMtC;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUvD;;OAEG;IACH,WAAW,IAAI,SAAS;IAIxB;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAMlB,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IASzB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;CAKnB"}
1
+ {"version":3,"file":"Actor.d.ts","sourceRoot":"","sources":["../../src/screenplay/Actor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,IAAI,EAAG,MAAM,UAAU,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EACR,WAAW,EACX,gBAAgB,EAGhB,aAAa,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,OAAO,EAGV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,qBAAa,KAAM,YAAW,kBAAkB,EAC5C,aAAa,EACb,gBAAgB,CAAC,KAAK,CAAC,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS;aAKW,IAAI,EAAE,MAAM;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJ1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgF;gBAGtF,IAAI,EAAE,MAAM,EACX,KAAK,EAAE,KAAK,EAC7B,SAAS,GAAE,OAAO,EAAO;IAS7B;;;;;;;;;;OAUG;IACH,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;IAc5D;;;;;;OAMG;IACH,UAAU,CAAC,GAAG,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK;IAMtC;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUvD;;OAEG;IACH,WAAW,IAAI,SAAS;IAIxB;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAMlB,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IASzB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;CAKnB"}
@@ -140,10 +140,7 @@ class Actor {
140
140
  return abilities_1.AnswerQuestions.as(this).answer(answerable);
141
141
  }
142
142
  /**
143
- * Announce collection of an {@apilink Artifact} so that it can be picked up by a {@apilink StageCrewMember}.
144
- *
145
- * @param artifact
146
- * @param name
143
+ * @inheritDoc
147
144
  */
148
145
  collect(artifact, name) {
149
146
  this.stage.announce(new events_1.ActivityRelatedArtifactGenerated(this.stage.currentSceneId(), this.stage.currentActivityId(), this.nameFrom(name || new model_1.Name(artifact.constructor.name)), artifact, this.stage.currentTime()));
@@ -1 +1 @@
1
- {"version":3,"file":"Actor.js","sourceRoot":"","sources":["../../src/screenplay/Actor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Actor.js","sourceRoot":"","sources":["../../src/screenplay/Actor.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,60 @@ export interface CollectsArtifacts {
13
13
  /**
14
14
  * Makes the {@apilink Actor} collect an {@apilink Artifact} so that it can be included in the test report.
15
15
  *
16
+ * #### Implementing a custom interaction to attach artifacts
17
+ *
18
+ * ```ts
19
+ * import * as fs from 'node:fs'
20
+ * import { Answerable, Interaction } from '@serenity-js/core'
21
+ * import { Path } from '@serenity-js/core/lib/io'
22
+ * import { Name, TextData } from '@serenity-js/core/lib/model'
23
+ *
24
+ * export class Attach {
25
+ *
26
+ * static contentsOf = (pathToFile: Path): Interaction =>
27
+ * Interaction.where(`#actor attaches contents of ${ pathToFile.basename() }`, async actor => {
28
+ * const data = fs.readFileSync(pathToFile.value).toString('utf-8');
29
+ *
30
+ * actor.collect(
31
+ * TextData.fromJSON({ contentType: 'text/plain', data }),
32
+ * new Name(pathToFile.basename()),
33
+ * )
34
+ * })
35
+ *
36
+ * static textData = (contents: Answerable<string>, name?: string): Interaction =>
37
+ * Interaction.where(`#actor attaches text data`, async actor => {
38
+ * const data = await actor.answer(contents);
39
+ *
40
+ * actor.collect(
41
+ * TextData.fromJSON({ contentType: 'text/plain', data }),
42
+ * name && new Name(name),
43
+ * )
44
+ * })
45
+ * }
46
+ * ```
47
+ *
48
+ * #### Attaching plain text
49
+ *
50
+ * ```ts
51
+ * import { actorCalled } from '@serenity-js/core'
52
+ * import { Path } from '@serenity-js/core/lib/io'
53
+ *
54
+ * actorCalled('Alice').attemptsTo(
55
+ * Attach.textData('some text', 'some name'),
56
+ * )
57
+ * ```
58
+ *
59
+ * #### Attaching contents of a text file
60
+ *
61
+ * ```ts
62
+ * import { actorCalled } from '@serenity-js/core'
63
+ * import { Log } from '@serenity-js/core'
64
+ *
65
+ * actorCalled('Alice').attemptsTo(
66
+ * Attach.contentsOf(Path.from(__dirname, 'output/server.log')),
67
+ * )
68
+ * ```
69
+ *
16
70
  * @param artifact
17
71
  * The artifact to be collected, such as {@apilink JSONData}
18
72
  *
@@ -1 +1 @@
1
- {"version":3,"file":"CollectsArtifacts.d.ts","sourceRoot":"","sources":["../../../src/screenplay/artifacts/CollectsArtifacts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAE9B;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAClD"}
1
+ {"version":3,"file":"CollectsArtifacts.d.ts","sourceRoot":"","sources":["../../../src/screenplay/artifacts/CollectsArtifacts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8DG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAClD"}
@@ -0,0 +1,35 @@
1
+ import type { QuestionAdapter } from '..';
2
+ import { type Answerable } from '..';
3
+ /**
4
+ * This question masks sensitive data handled by the actors and prevents
5
+ * it from being shown in Serenity/JS reports and console logs.
6
+ * You should use it to wrap passwords, secret tokens, phone numbers,
7
+ * credit card numbers, or any other personally identifiable information (PII).
8
+ * However, even though the wrapped value is masked in the output,
9
+ * you can still retrieve the unmasked value by making the actor answer
10
+ * the question in your custom interactions.
11
+ *
12
+ * @group Questions
13
+ */
14
+ export declare class Masked {
15
+ /**
16
+ * Retrieves the value of a sensitive parameter and mask it in any report.
17
+ *
18
+ * #### Example
19
+ *
20
+ * ```ts
21
+ * import { actorCalled, Masked } from '@serenity-js/core';
22
+ * import { Ensure, equals } from '@serenity-js/assertions';
23
+ *
24
+ * await actorCalled('John')
25
+ * .attemptsTo(
26
+ * Enter.theValue(Masked.valueOf('your little secret').into(Form.exampleInput())
27
+ * );
28
+ * ```
29
+ *
30
+ * @param parameter - An {@link Answerable} representing the masked value.
31
+ * @returns A {@link QuestionAdapter} representing the masked value.
32
+ */
33
+ static valueOf(parameter: Answerable<string>): QuestionAdapter<string>;
34
+ }
35
+ //# sourceMappingURL=Masked.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Masked.d.ts","sourceRoot":"","sources":["../../../src/screenplay/questions/Masked.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,KAAK,UAAU,EAAW,MAAM,IAAI,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,qBAAa,MAAM;IAEf;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,GAAK,eAAe,CAAC,MAAM,CAAC;CAG3E"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Masked = void 0;
4
+ const __1 = require("..");
5
+ /**
6
+ * This question masks sensitive data handled by the actors and prevents
7
+ * it from being shown in Serenity/JS reports and console logs.
8
+ * You should use it to wrap passwords, secret tokens, phone numbers,
9
+ * credit card numbers, or any other personally identifiable information (PII).
10
+ * However, even though the wrapped value is masked in the output,
11
+ * you can still retrieve the unmasked value by making the actor answer
12
+ * the question in your custom interactions.
13
+ *
14
+ * @group Questions
15
+ */
16
+ class Masked {
17
+ /**
18
+ * Retrieves the value of a sensitive parameter and mask it in any report.
19
+ *
20
+ * #### Example
21
+ *
22
+ * ```ts
23
+ * import { actorCalled, Masked } from '@serenity-js/core';
24
+ * import { Ensure, equals } from '@serenity-js/assertions';
25
+ *
26
+ * await actorCalled('John')
27
+ * .attemptsTo(
28
+ * Enter.theValue(Masked.valueOf('your little secret').into(Form.exampleInput())
29
+ * );
30
+ * ```
31
+ *
32
+ * @param parameter - An {@link Answerable} representing the masked value.
33
+ * @returns A {@link QuestionAdapter} representing the masked value.
34
+ */
35
+ static valueOf(parameter) {
36
+ return __1.Question.about('[a masked value]', async (actor) => actor.answer(parameter));
37
+ }
38
+ }
39
+ exports.Masked = Masked;
40
+ //# sourceMappingURL=Masked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Masked.js","sourceRoot":"","sources":["../../../src/screenplay/questions/Masked.ts"],"names":[],"mappings":";;;AACA,0BAA8C;AAE9C;;;;;;;;;;GAUG;AACH,MAAa,MAAM;IAEf;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,OAAO,CAAC,SAA6B;QACxC,OAAO,YAAQ,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;IACrF,CAAC;CACJ;AAvBD,wBAuBC"}
@@ -4,6 +4,7 @@ export * from './Check';
4
4
  export * from './Expectation';
5
5
  export * from './expectations';
6
6
  export * from './List';
7
+ export * from './Masked';
7
8
  export * from './MetaQuestion';
8
9
  export * from './q';
9
10
  export * from './Unanswered';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,KAAK,CAAC;AACpB,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,KAAK,CAAC;AACpB,cAAc,cAAc,CAAC"}
@@ -20,6 +20,7 @@ __exportStar(require("./Check"), exports);
20
20
  __exportStar(require("./Expectation"), exports);
21
21
  __exportStar(require("./expectations"), exports);
22
22
  __exportStar(require("./List"), exports);
23
+ __exportStar(require("./Masked"), exports);
23
24
  __exportStar(require("./MetaQuestion"), exports);
24
25
  __exportStar(require("./q"), exports);
25
26
  __exportStar(require("./Unanswered"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,0DAAwC;AACxC,0CAAwB;AACxB,gDAA8B;AAC9B,iDAA+B;AAC/B,yCAAuB;AACvB,iDAA+B;AAC/B,sCAAoB;AACpB,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/questions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,0DAAwC;AACxC,0CAAwB;AACxB,gDAA8B;AAC9B,iDAA+B;AAC/B,yCAAuB;AACvB,2CAAyB;AACzB,iDAA+B;AAC/B,sCAAoB;AACpB,+CAA6B"}
@@ -16,8 +16,8 @@ import { Duration } from './Duration';
16
16
  export declare class Timestamp extends TinyType {
17
17
  readonly value: Date;
18
18
  static fromJSON(v: string): Timestamp;
19
- static fromTimestampInSeconds(v: number): Timestamp;
20
- static fromTimestampInMilliseconds(v: number): Timestamp;
19
+ static fromTimestampInSeconds(value: number): Timestamp;
20
+ static fromTimestampInMilliseconds(value: number): Timestamp;
21
21
  static now(): Timestamp;
22
22
  constructor(value?: Date);
23
23
  diff(another: Timestamp): Duration;
@@ -1 +1 @@
1
- {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../../src/screenplay/time/models/Timestamp.ts"],"names":[],"mappings":";AACA,OAAO,EAA8C,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,qBAAa,SAAU,SAAQ,QAAQ;aAiBP,KAAK,EAAE,IAAI;IAhBvC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS;IAIrC,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS;IAInD,MAAM,CAAC,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS;IAIxD,MAAM,CAAC,GAAG,IAAI,SAAS;gBAIK,KAAK,GAAE,IAAiB;IAKpD,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ;IAKlC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS;IAKnC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS;IAKnC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAKrC,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAK5C,OAAO,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAKpC,cAAc,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAK3C,cAAc,IAAI,MAAM;IAIxB,SAAS,IAAI,MAAM;IAInB,MAAM,IAAI,MAAM;IAIhB,WAAW,IAAI,MAAM;IAIrB,QAAQ,IAAI,MAAM;IAIlB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM;CAG7B"}
1
+ {"version":3,"file":"Timestamp.d.ts","sourceRoot":"","sources":["../../../../src/screenplay/time/models/Timestamp.ts"],"names":[],"mappings":";AAAA,OAAO,EAA8C,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,qBAAa,SAAU,SAAQ,QAAQ;aAiBP,KAAK,EAAE,IAAI;IAhBvC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS;IAIrC,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAIvD,MAAM,CAAC,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAI5D,MAAM,CAAC,GAAG,IAAI,SAAS;gBAIK,KAAK,GAAE,IAAiB;IAKpD,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ;IAKlC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS;IAKnC,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS;IAKnC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAKrC,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAK5C,OAAO,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAKpC,cAAc,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO;IAK3C,cAAc,IAAI,MAAM;IAIxB,SAAS,IAAI,MAAM;IAInB,MAAM,IAAI,MAAM;IAIhB,WAAW,IAAI,MAAM;IAIrB,QAAQ,IAAI,MAAM;IAIlB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM;CAG7B"}
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Timestamp = void 0;
7
- const moment_1 = __importDefault(require("moment"));
8
4
  const tiny_types_1 = require("tiny-types");
9
5
  const util_1 = require("util");
10
6
  const Duration_1 = require("./Duration");
@@ -24,11 +20,11 @@ class Timestamp extends tiny_types_1.TinyType {
24
20
  static fromJSON(v) {
25
21
  return new Timestamp(new Date((0, tiny_types_1.ensure)(Timestamp.name, v, isSerialisedISO8601Date())));
26
22
  }
27
- static fromTimestampInSeconds(v) {
28
- return Timestamp.fromTimestampInMilliseconds(v * 1000);
23
+ static fromTimestampInSeconds(value) {
24
+ return Timestamp.fromTimestampInMilliseconds(value * 1000);
29
25
  }
30
- static fromTimestampInMilliseconds(v) {
31
- return new Timestamp((0, moment_1.default)(v).toDate());
26
+ static fromTimestampInMilliseconds(value) {
27
+ return new Timestamp(new Date(value));
32
28
  }
33
29
  static now() {
34
30
  return new Timestamp();
@@ -40,15 +36,15 @@ class Timestamp extends tiny_types_1.TinyType {
40
36
  }
41
37
  diff(another) {
42
38
  (0, tiny_types_1.ensure)('timestamp', another, (0, tiny_types_1.isDefined)());
43
- return new Duration_1.Duration(Math.abs((0, moment_1.default)(this.value).diff(another.value, 'ms', true)));
39
+ return new Duration_1.Duration(Math.abs(this.toMilliseconds() - another.toMilliseconds()));
44
40
  }
45
41
  plus(duration) {
46
42
  (0, tiny_types_1.ensure)('duration', duration, (0, tiny_types_1.isDefined)());
47
- return new Timestamp((0, moment_1.default)(this.value).add(duration.inMilliseconds(), 'ms').toDate());
43
+ return new Timestamp(new Date(this.toMilliseconds() + duration.inMilliseconds()));
48
44
  }
49
45
  less(duration) {
50
46
  (0, tiny_types_1.ensure)('duration', duration, (0, tiny_types_1.isDefined)());
51
- return new Timestamp((0, moment_1.default)(this.value).subtract(duration.inMilliseconds(), 'ms').toDate());
47
+ return new Timestamp(new Date(this.toMilliseconds() - duration.inMilliseconds()));
52
48
  }
53
49
  isBefore(another) {
54
50
  (0, tiny_types_1.ensure)('timestamp', another, (0, tiny_types_1.isDefined)());
@@ -67,10 +63,10 @@ class Timestamp extends tiny_types_1.TinyType {
67
63
  return this.value.getTime() >= another.value.getTime();
68
64
  }
69
65
  toMilliseconds() {
70
- return (0, moment_1.default)(this.value).valueOf();
66
+ return this.value.getTime();
71
67
  }
72
68
  toSeconds() {
73
- return (0, moment_1.default)(this.value).unix();
69
+ return Math.floor(this.toMilliseconds() / 1000);
74
70
  }
75
71
  toJSON() {
76
72
  return this.value.toJSON();
@@ -86,7 +82,36 @@ class Timestamp extends tiny_types_1.TinyType {
86
82
  }
87
83
  }
88
84
  exports.Timestamp = Timestamp;
85
+ /**
86
+ * Based on the implementation by Brock Adams:
87
+ * - https://stackoverflow.com/a/3143231/264502 by Brock Adams
88
+ * - https://www.w3.org/TR/NOTE-datetime
89
+ */
89
90
  function isSerialisedISO8601Date() {
90
- return tiny_types_1.Predicate.to(`be an ISO-8601-compliant date`, (value) => (0, moment_1.default)(value, moment_1.default.ISO_8601, true).isValid());
91
+ const yyyyMMdd = `\\d{4}-[01]\\d-[0-3]\\d`;
92
+ const hh = `[0-2]\\d`;
93
+ const mm = `[0-5]\\d`;
94
+ const ss = `[0-5]\\d`;
95
+ const ms = `\\d+`;
96
+ const T = `[Tt\\s]`;
97
+ const offset = `[+-]${hh}:${mm}|Z`;
98
+ const pattern = new RegExp('^' + [
99
+ // Full precision - YYYY-MM-DDThh:mm:ss.sss
100
+ `(${yyyyMMdd}${T}${hh}:${mm}:${ss}\\.${ms}(${offset})?)`,
101
+ // No milliseconds - YYYY-MM-DDThh:mm:ss
102
+ `(${yyyyMMdd}${T}${hh}:${mm}:${ss}(${offset})?)`,
103
+ // No seconds - YYYY-MM-DDThh:mm
104
+ `(${yyyyMMdd}${T}${hh}:${mm}(${offset})?)`,
105
+ // Just the date - YYYY-MM-DD
106
+ `(${yyyyMMdd})`,
107
+ ].join('|') + '$');
108
+ return tiny_types_1.Predicate.to(`follow the ISO8601 format: YYYY-MM-DD[Thh:mm[:ss[.sss]]]`, (value) => {
109
+ if (!pattern.test(value)) {
110
+ return false;
111
+ }
112
+ const date = new Date(value);
113
+ return date instanceof Date
114
+ && !Number.isNaN(date.getTime());
115
+ });
91
116
  }
92
117
  //# sourceMappingURL=Timestamp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Timestamp.js","sourceRoot":"","sources":["../../../../src/screenplay/time/models/Timestamp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Timestamp.js","sourceRoot":"","sources":["../../../../src/screenplay/time/models/Timestamp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/core",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "description": "Serenity/JS Screenplay, reporting engine and core interfaces.",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -40,7 +40,6 @@
40
40
  "fast-glob": "3.3.2",
41
41
  "filenamify": "4.3.0",
42
42
  "graceful-fs": "4.2.11",
43
- "moment": "2.30.1",
44
43
  "semver": "7.5.4",
45
44
  "tiny-types": "1.21.0",
46
45
  "upath": "2.0.1",
@@ -72,5 +71,5 @@
72
71
  "engines": {
73
72
  "node": "^16.13 || ^18.12 || ^20"
74
73
  },
75
- "gitHead": "4df79de3820acd9fb18d76843feb0468c55c8e7f"
74
+ "gitHead": "242771e55bd6becc5baeaac03edf945e4cdaf7a4"
76
75
  }
@@ -0,0 +1,87 @@
1
+ import { ConfigurationError } from '../errors';
2
+ import { CapabilityTag, FeatureTag, Tag, ThemeTag } from '../model';
3
+ import type { FileSystem } from './FileSystem';
4
+ import { Path } from './Path';
5
+
6
+ export class RequirementsHierarchy {
7
+
8
+ private root: Path;
9
+
10
+ private static readonly specDirectoryCandidates = [
11
+ `features`,
12
+ `specs`,
13
+ `spec`,
14
+ `tests`,
15
+ `test`,
16
+ `src`,
17
+ ];
18
+
19
+ constructor(
20
+ private readonly fileSystem: FileSystem,
21
+ private readonly userDefinedSpecDirectory?: Path,
22
+ ) {
23
+ }
24
+
25
+ requirementTagsFor(pathToSpec: Path, featureName?: string): Tag[] {
26
+ const [ fileBasedFeatureName, capabilityName, ...themeNames ] = this.hierarchyFor(pathToSpec).reverse().filter(segment => !['.', '..'].includes(segment));
27
+
28
+ const themeTags = themeNames.reverse().map(themeName => Tag.humanReadable(ThemeTag, themeName));
29
+ const capabilityTag = capabilityName && Tag.humanReadable(CapabilityTag, capabilityName);
30
+ const featureTag = featureName
31
+ ? new FeatureTag(featureName)
32
+ : Tag.humanReadable(FeatureTag, fileBasedFeatureName)
33
+
34
+ return [
35
+ ...themeTags,
36
+ capabilityTag,
37
+ featureTag
38
+ ].filter(Boolean);
39
+ }
40
+
41
+ hierarchyFor(pathToSpec: Path): string[] {
42
+ const relative = this.rootDirectory().relative(pathToSpec);
43
+
44
+ return relative.split().map((segment, i, segments) => {
45
+ // return all the segments as-is, except for the last one
46
+ if (i < segments.length - 1) {
47
+ return segment;
48
+ }
49
+
50
+ // Strip the extension, like `.feature` or `.spec.ts`
51
+ const firstDotIndex = segment.indexOf('.');
52
+ return firstDotIndex === -1
53
+ ? segment
54
+ : segment.slice(0, firstDotIndex);
55
+ });
56
+ }
57
+
58
+ rootDirectory(): Path {
59
+ if (!this.root) {
60
+ this.root = this.userDefinedSpecDirectory
61
+ ? this.resolve(this.userDefinedSpecDirectory)
62
+ : this.guessRootDirectory();
63
+ }
64
+
65
+ return this.root;
66
+ }
67
+
68
+ private guessRootDirectory(): Path {
69
+ for (const candidate of RequirementsHierarchy.specDirectoryCandidates) {
70
+ const candidateSpecDirectory = Path.from(candidate);
71
+ if (this.fileSystem.exists(Path.from(candidate))) {
72
+ return this.fileSystem.resolve(candidateSpecDirectory);
73
+ }
74
+ }
75
+
76
+ // default to current working directory
77
+ return this.fileSystem.resolve(Path.from('.'));
78
+ }
79
+
80
+ private resolve(userDefinedRootDirectory: Path): Path {
81
+ if (!this.fileSystem.exists(userDefinedRootDirectory)) {
82
+ throw new ConfigurationError(`Configured specDirectory \`${ userDefinedRootDirectory }\` does not exist`);
83
+ }
84
+
85
+ return this.fileSystem.resolve(userDefinedRootDirectory);
86
+ }
87
+ }
package/src/io/index.ts CHANGED
@@ -10,4 +10,5 @@ export * from './inspectedObject';
10
10
  export * from './loader';
11
11
  export * from './Path';
12
12
  export * from './reflection';
13
+ export * from './RequirementsHierarchy';
13
14
  export * from './trimmed';
@@ -11,7 +11,7 @@ export abstract class Tag extends TinyType {
11
11
  // based on https://github.com/serenity-bdd/serenity-core/blob/8f7d14c6dad47bb58a1585fef5f9d9a44bb963fd/serenity-model/src/main/java/net/thucydides/core/requirements/AbstractRequirementsTagProvider.java#L36
12
12
  const name = String(tagName)
13
13
  .trim()
14
- .match(/[\dA-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g)
14
+ .match(/[\dA-Z]{2,}(?=[A-Z][a-z]+\d*|\b)|[A-Z]?[a-z-]+\d*|[A-Z]|\d+/g)
15
15
  .map(chunk => /^[A-Z]+$/.test(chunk) ? chunk : chunk.toLowerCase())
16
16
  .join('_')
17
17
  .replaceAll(/[\s_]+/g, ' ')
@@ -174,10 +174,7 @@ export class Actor implements PerformsActivities,
174
174
  }
175
175
 
176
176
  /**
177
- * Announce collection of an {@apilink Artifact} so that it can be picked up by a {@apilink StageCrewMember}.
178
- *
179
- * @param artifact
180
- * @param name
177
+ * @inheritDoc
181
178
  */
182
179
  collect(artifact: Artifact, name?: string | Name): void {
183
180
  this.stage.announce(new ActivityRelatedArtifactGenerated(
@@ -15,6 +15,60 @@ export interface CollectsArtifacts {
15
15
  /**
16
16
  * Makes the {@apilink Actor} collect an {@apilink Artifact} so that it can be included in the test report.
17
17
  *
18
+ * #### Implementing a custom interaction to attach artifacts
19
+ *
20
+ * ```ts
21
+ * import * as fs from 'node:fs'
22
+ * import { Answerable, Interaction } from '@serenity-js/core'
23
+ * import { Path } from '@serenity-js/core/lib/io'
24
+ * import { Name, TextData } from '@serenity-js/core/lib/model'
25
+ *
26
+ * export class Attach {
27
+ *
28
+ * static contentsOf = (pathToFile: Path): Interaction =>
29
+ * Interaction.where(`#actor attaches contents of ${ pathToFile.basename() }`, async actor => {
30
+ * const data = fs.readFileSync(pathToFile.value).toString('utf-8');
31
+ *
32
+ * actor.collect(
33
+ * TextData.fromJSON({ contentType: 'text/plain', data }),
34
+ * new Name(pathToFile.basename()),
35
+ * )
36
+ * })
37
+ *
38
+ * static textData = (contents: Answerable<string>, name?: string): Interaction =>
39
+ * Interaction.where(`#actor attaches text data`, async actor => {
40
+ * const data = await actor.answer(contents);
41
+ *
42
+ * actor.collect(
43
+ * TextData.fromJSON({ contentType: 'text/plain', data }),
44
+ * name && new Name(name),
45
+ * )
46
+ * })
47
+ * }
48
+ * ```
49
+ *
50
+ * #### Attaching plain text
51
+ *
52
+ * ```ts
53
+ * import { actorCalled } from '@serenity-js/core'
54
+ * import { Path } from '@serenity-js/core/lib/io'
55
+ *
56
+ * actorCalled('Alice').attemptsTo(
57
+ * Attach.textData('some text', 'some name'),
58
+ * )
59
+ * ```
60
+ *
61
+ * #### Attaching contents of a text file
62
+ *
63
+ * ```ts
64
+ * import { actorCalled } from '@serenity-js/core'
65
+ * import { Log } from '@serenity-js/core'
66
+ *
67
+ * actorCalled('Alice').attemptsTo(
68
+ * Attach.contentsOf(Path.from(__dirname, 'output/server.log')),
69
+ * )
70
+ * ```
71
+ *
18
72
  * @param artifact
19
73
  * The artifact to be collected, such as {@apilink JSONData}
20
74
  *
@@ -0,0 +1,38 @@
1
+ import type { QuestionAdapter } from '..';
2
+ import { type Answerable,Question } from '..';
3
+
4
+ /**
5
+ * This question masks sensitive data handled by the actors and prevents
6
+ * it from being shown in Serenity/JS reports and console logs.
7
+ * You should use it to wrap passwords, secret tokens, phone numbers,
8
+ * credit card numbers, or any other personally identifiable information (PII).
9
+ * However, even though the wrapped value is masked in the output,
10
+ * you can still retrieve the unmasked value by making the actor answer
11
+ * the question in your custom interactions.
12
+ *
13
+ * @group Questions
14
+ */
15
+ export class Masked {
16
+
17
+ /**
18
+ * Retrieves the value of a sensitive parameter and mask it in any report.
19
+ *
20
+ * #### Example
21
+ *
22
+ * ```ts
23
+ * import { actorCalled, Masked } from '@serenity-js/core';
24
+ * import { Ensure, equals } from '@serenity-js/assertions';
25
+ *
26
+ * await actorCalled('John')
27
+ * .attemptsTo(
28
+ * Enter.theValue(Masked.valueOf('your little secret').into(Form.exampleInput())
29
+ * );
30
+ * ```
31
+ *
32
+ * @param parameter - An {@link Answerable} representing the masked value.
33
+ * @returns A {@link QuestionAdapter} representing the masked value.
34
+ */
35
+ static valueOf(parameter: Answerable<string>) : QuestionAdapter<string> {
36
+ return Question.about('[a masked value]', async actor => actor.answer(parameter))
37
+ }
38
+ }
@@ -4,6 +4,7 @@ export * from './Check';
4
4
  export * from './Expectation';
5
5
  export * from './expectations';
6
6
  export * from './List';
7
+ export * from './Masked';
7
8
  export * from './MetaQuestion';
8
9
  export * from './q';
9
10
  export * from './Unanswered';
@@ -1,4 +1,3 @@
1
- import moment from 'moment';
2
1
  import { ensure, isDefined, isInstanceOf, Predicate, TinyType } from 'tiny-types';
3
2
  import { inspect } from 'util';
4
3
 
@@ -20,12 +19,12 @@ export class Timestamp extends TinyType {
20
19
  return new Timestamp(new Date(ensure(Timestamp.name, v, isSerialisedISO8601Date())));
21
20
  }
22
21
 
23
- static fromTimestampInSeconds(v: number): Timestamp {
24
- return Timestamp.fromTimestampInMilliseconds(v * 1000);
22
+ static fromTimestampInSeconds(value: number): Timestamp {
23
+ return Timestamp.fromTimestampInMilliseconds(value * 1000);
25
24
  }
26
25
 
27
- static fromTimestampInMilliseconds(v: number): Timestamp {
28
- return new Timestamp(moment(v).toDate());
26
+ static fromTimestampInMilliseconds(value: number): Timestamp {
27
+ return new Timestamp(new Date(value));
29
28
  }
30
29
 
31
30
  static now(): Timestamp {
@@ -39,17 +38,17 @@ export class Timestamp extends TinyType {
39
38
 
40
39
  diff(another: Timestamp): Duration {
41
40
  ensure('timestamp', another, isDefined());
42
- return new Duration(Math.abs(moment(this.value).diff(another.value, 'ms', true)));
41
+ return new Duration(Math.abs(this.toMilliseconds() - another.toMilliseconds()));
43
42
  }
44
43
 
45
44
  plus(duration: Duration): Timestamp {
46
45
  ensure('duration', duration, isDefined());
47
- return new Timestamp(moment(this.value).add(duration.inMilliseconds(), 'ms').toDate());
46
+ return new Timestamp(new Date(this.toMilliseconds() + duration.inMilliseconds()));
48
47
  }
49
48
 
50
49
  less(duration: Duration): Timestamp {
51
50
  ensure('duration', duration, isDefined());
52
- return new Timestamp(moment(this.value).subtract(duration.inMilliseconds(), 'ms').toDate());
51
+ return new Timestamp(new Date(this.toMilliseconds() - duration.inMilliseconds()));
53
52
  }
54
53
 
55
54
  isBefore(another: Timestamp): boolean {
@@ -73,11 +72,11 @@ export class Timestamp extends TinyType {
73
72
  }
74
73
 
75
74
  toMilliseconds(): number {
76
- return moment(this.value).valueOf();
75
+ return this.value.getTime();
77
76
  }
78
77
 
79
78
  toSeconds(): number {
80
- return moment(this.value).unix();
79
+ return Math.floor(this.toMilliseconds() / 1_000);
81
80
  }
82
81
 
83
82
  toJSON(): string {
@@ -97,7 +96,41 @@ export class Timestamp extends TinyType {
97
96
  }
98
97
  }
99
98
 
99
+ /**
100
+ * Based on the implementation by Brock Adams:
101
+ * - https://stackoverflow.com/a/3143231/264502 by Brock Adams
102
+ * - https://www.w3.org/TR/NOTE-datetime
103
+ */
100
104
  function isSerialisedISO8601Date(): Predicate<string> {
101
- return Predicate.to(`be an ISO-8601-compliant date`, (value: string) =>
102
- moment(value, moment.ISO_8601, true).isValid());
105
+
106
+ const yyyyMMdd = `\\d{4}-[01]\\d-[0-3]\\d`;
107
+ const hh = `[0-2]\\d`;
108
+ const mm = `[0-5]\\d`;
109
+ const ss = `[0-5]\\d`;
110
+ const ms = `\\d+`;
111
+ const T = `[Tt\\s]`;
112
+ const offset = `[+-]${hh}:${mm}|Z`;
113
+
114
+ const pattern = new RegExp('^' + [
115
+ // Full precision - YYYY-MM-DDThh:mm:ss.sss
116
+ `(${yyyyMMdd}${T}${hh}:${mm}:${ss}\\.${ms}(${offset})?)`,
117
+ // No milliseconds - YYYY-MM-DDThh:mm:ss
118
+ `(${yyyyMMdd}${T}${hh}:${mm}:${ss}(${offset})?)`,
119
+ // No seconds - YYYY-MM-DDThh:mm
120
+ `(${yyyyMMdd}${T}${hh}:${mm}(${offset})?)`,
121
+ // Just the date - YYYY-MM-DD
122
+ `(${yyyyMMdd})`,
123
+ ].join('|') + '$');
124
+
125
+ return Predicate.to(`follow the ISO8601 format: YYYY-MM-DD[Thh:mm[:ss[.sss]]]`, (value: string) => {
126
+
127
+ if (! pattern.test(value)) {
128
+ return false;
129
+ }
130
+
131
+ const date = new Date(value);
132
+
133
+ return date instanceof Date
134
+ && ! Number.isNaN(date.getTime());
135
+ });
103
136
  }