@axinom/mosaic-e2e-page-model 0.1.0-rc.3

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 (66) hide show
  1. package/README.md +22 -0
  2. package/dist/index.d.ts +6 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +18 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/managed-services/image-selection-explorer.d.ts +16 -0
  7. package/dist/managed-services/image-selection-explorer.d.ts.map +1 -0
  8. package/dist/managed-services/image-selection-explorer.js +39 -0
  9. package/dist/managed-services/image-selection-explorer.js.map +1 -0
  10. package/dist/managed-services/image-service.d.ts +65 -0
  11. package/dist/managed-services/image-service.d.ts.map +1 -0
  12. package/dist/managed-services/image-service.js +120 -0
  13. package/dist/managed-services/image-service.js.map +1 -0
  14. package/dist/managed-services/index.d.ts +4 -0
  15. package/dist/managed-services/index.d.ts.map +1 -0
  16. package/dist/managed-services/index.js +16 -0
  17. package/dist/managed-services/index.js.map +1 -0
  18. package/dist/managed-services/managed-service-model.d.ts +46 -0
  19. package/dist/managed-services/managed-service-model.d.ts.map +1 -0
  20. package/dist/managed-services/managed-service-model.js +33 -0
  21. package/dist/managed-services/managed-service-model.js.map +1 -0
  22. package/dist/managed-services/monetization-service.d.ts +208 -0
  23. package/dist/managed-services/monetization-service.d.ts.map +1 -0
  24. package/dist/managed-services/monetization-service.js +459 -0
  25. package/dist/managed-services/monetization-service.js.map +1 -0
  26. package/dist/managed-services/payment-provider-settings-field.d.ts +7 -0
  27. package/dist/managed-services/payment-provider-settings-field.d.ts.map +1 -0
  28. package/dist/managed-services/payment-provider-settings-field.js +37 -0
  29. package/dist/managed-services/payment-provider-settings-field.js.map +1 -0
  30. package/dist/page-model.d.ts +44 -0
  31. package/dist/page-model.d.ts.map +1 -0
  32. package/dist/page-model.js +56 -0
  33. package/dist/page-model.js.map +1 -0
  34. package/dist/service-model.d.ts +43 -0
  35. package/dist/service-model.d.ts.map +1 -0
  36. package/dist/service-model.js +32 -0
  37. package/dist/service-model.js.map +1 -0
  38. package/dist/sign-in/index.d.ts +5 -0
  39. package/dist/sign-in/index.d.ts.map +1 -0
  40. package/dist/sign-in/index.js +17 -0
  41. package/dist/sign-in/index.js.map +1 -0
  42. package/dist/sign-in/sign-in-page.d.ts +27 -0
  43. package/dist/sign-in/sign-in-page.d.ts.map +1 -0
  44. package/dist/sign-in/sign-in-page.js +38 -0
  45. package/dist/sign-in/sign-in-page.js.map +1 -0
  46. package/dist/sign-in/sign-in-with-ax-auth-form.d.ts +24 -0
  47. package/dist/sign-in/sign-in-with-ax-auth-form.d.ts.map +1 -0
  48. package/dist/sign-in/sign-in-with-ax-auth-form.js +48 -0
  49. package/dist/sign-in/sign-in-with-ax-auth-form.js.map +1 -0
  50. package/dist/sign-in/sign-in-with-google-form.d.ts +23 -0
  51. package/dist/sign-in/sign-in-with-google-form.d.ts.map +1 -0
  52. package/dist/sign-in/sign-in-with-google-form.js +51 -0
  53. package/dist/sign-in/sign-in-with-google-form.js.map +1 -0
  54. package/dist/sign-in/sign-in-with-microsoft-form.d.ts +24 -0
  55. package/dist/sign-in/sign-in-with-microsoft-form.d.ts.map +1 -0
  56. package/dist/sign-in/sign-in-with-microsoft-form.js +58 -0
  57. package/dist/sign-in/sign-in-with-microsoft-form.js.map +1 -0
  58. package/dist/ui-selectors/index.d.ts +2 -0
  59. package/dist/ui-selectors/index.d.ts.map +1 -0
  60. package/dist/ui-selectors/index.js +14 -0
  61. package/dist/ui-selectors/index.js.map +1 -0
  62. package/dist/ui-selectors/ui-shell-model.d.ts +80 -0
  63. package/dist/ui-selectors/ui-shell-model.d.ts.map +1 -0
  64. package/dist/ui-selectors/ui-shell-model.js +134 -0
  65. package/dist/ui-selectors/ui-shell-model.js.map +1 -0
  66. package/package.json +37 -0
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @axinom/mosaic-e2e-page-model
2
+
3
+ ## About the Package
4
+
5
+ This package is part of the Axinom Mosaic development platform. More information
6
+ can be found at https://portal.axinom.com/mosaic.
7
+
8
+ This library models the Mosaic management system for use in Playwright tests.
9
+ The shell UI and managed services are modelled.
10
+
11
+ Customized services should be modelled with `@axinom/mosaic-e2e-ui-selectors`
12
+ which is intended to be used in concert with this library.
13
+
14
+ ## License
15
+
16
+ This package can be licensed under the
17
+ [Axinom Products Licensing Agreement](https://portal.axinom.com/mosaic/contracts/products-licensing-agreement)
18
+ or evaluated under the
19
+ [Axinom Products Evaluation Agreement](https://portal.axinom.com/mosaic/contracts/products-evaluation-agreement).
20
+ No part of Axinom's software may be copied, modified, propagated, or distributed
21
+ except in accordance with the terms contained in the Axinom Products Licensing
22
+ Agreement and Axinom Products Evaluation Agreement.
@@ -0,0 +1,6 @@
1
+ export * from './managed-services';
2
+ export * from './page-model';
3
+ export * from './service-model';
4
+ export * from './sign-in';
5
+ export * from './ui-selectors';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./managed-services"), exports);
14
+ __exportStar(require("./page-model"), exports);
15
+ __exportStar(require("./service-model"), exports);
16
+ __exportStar(require("./sign-in"), exports);
17
+ __exportStar(require("./ui-selectors"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAmC;AACnC,+CAA6B;AAC7B,kDAAgC;AAChC,4CAA0B;AAC1B,iDAA+B"}
@@ -0,0 +1,16 @@
1
+ import { SelectionExplorer } from '@axinom/mosaic-e2e-ui-selectors';
2
+ /** A mod*e*l for the mod*a*l image explorer component used to select images. */
3
+ export declare class ImageSelectionExplorer extends SelectionExplorer {
4
+ /**
5
+ * Select an image by title.
6
+ * If the image explorer modal is not showing or the selected title does not exist then an exception will be raised.
7
+ *
8
+ * The following steps will be taken:
9
+ * - Verify that the page header title is 'Select Image'
10
+ * - Filter by title and verify that at least one result is shown
11
+ * - Select the first result by row action
12
+ * - Wait for the modal to be closed
13
+ */
14
+ selectImage(imageTitle: string): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=image-selection-explorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-selection-explorer.d.ts","sourceRoot":"","sources":["../../src/managed-services/image-selection-explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,gFAAgF;AAChF,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D;;;;;;;;;OASG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBrD"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageSelectionExplorer = void 0;
4
+ const mosaic_e2e_ui_selectors_1 = require("@axinom/mosaic-e2e-ui-selectors");
5
+ /** A mod*e*l for the mod*a*l image explorer component used to select images. */
6
+ class ImageSelectionExplorer extends mosaic_e2e_ui_selectors_1.SelectionExplorer {
7
+ /**
8
+ * Select an image by title.
9
+ * If the image explorer modal is not showing or the selected title does not exist then an exception will be raised.
10
+ *
11
+ * The following steps will be taken:
12
+ * - Verify that the page header title is 'Select Image'
13
+ * - Filter by title and verify that at least one result is shown
14
+ * - Select the first result by row action
15
+ * - Wait for the modal to be closed
16
+ */
17
+ async selectImage(imageTitle) {
18
+ // verify the modal header
19
+ await this.pageHeader.title.waitFor({ state: 'visible' });
20
+ if ((await this.pageHeader.title.textContent()) !== 'Select Image') {
21
+ throw new Error('Image explorer modal must be showing.');
22
+ }
23
+ await this.list.waitForData();
24
+ await this.filters
25
+ .getFilterByName('title')
26
+ .asFreeTextFilter()
27
+ .setValue(imageTitle);
28
+ await this.list.waitForData();
29
+ // verify that one result is showing
30
+ if ((await this.list.allVisibleRows.count()) === 0) {
31
+ throw new Error('An image with the specified title was not found.');
32
+ }
33
+ await this.list.getRow(1).selectButton.click();
34
+ // wait for the modal to close
35
+ await this.pageHeader.title.waitFor({ state: 'detached' });
36
+ }
37
+ }
38
+ exports.ImageSelectionExplorer = ImageSelectionExplorer;
39
+ //# sourceMappingURL=image-selection-explorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-selection-explorer.js","sourceRoot":"","sources":["../../src/managed-services/image-selection-explorer.ts"],"names":[],"mappings":";;;AAAA,6EAAoE;AAEpE,gFAAgF;AAChF,MAAa,sBAAuB,SAAQ,2CAAiB;IAC3D;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,CAAC,UAAkB;QAClC,0BAA0B;QAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,cAAc,EAAE;YAClE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;SAC1D;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE9B,MAAM,IAAI,CAAC,OAAO;aACf,eAAe,CAAC,OAAO,CAAC;aACxB,gBAAgB,EAAE;aAClB,QAAQ,CAAC,UAAU,CAAC,CAAC;QACxB,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE9B,oCAAoC;QACpC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE;YAClD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAE/C,8BAA8B;QAC9B,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF;AAnCD,wDAmCC"}
@@ -0,0 +1,65 @@
1
+ import { ImageSelectionExplorer } from './image-selection-explorer';
2
+ import { ManagedServiceModel } from './managed-service-model';
3
+ /** A model for the managed image service. */
4
+ export declare class ImageService extends ManagedServiceModel {
5
+ /**
6
+ * This method navigates to an image details station by title.
7
+ * The management system must be loaded & signed in before using this method.
8
+ * If there is not exactly one matching image an exception will be raised.
9
+ *
10
+ * The following steps will be taken:
11
+ * - Navigate to the home breadcrumb then the 'Images' tile
12
+ * - Filter by title and verify that a single result is shown
13
+ * - Click the image row action
14
+ * - Wait for the image details station to load
15
+ */
16
+ navigateToImageDetails(filterBy: {
17
+ title: string;
18
+ }): Promise<void>;
19
+ /**
20
+ * This method uploads an image file from the local file system.
21
+ * The management system must be loaded & signed in before using this method.
22
+ * A unique image title and a valid image type must be provided.
23
+ *
24
+ * The following steps will be taken:
25
+ * - Navigate to the home breadcrumb then the 'Images' tile
26
+ * - Click the 'Upload' action
27
+ * - Enter file and image type inputs then click 'Proceed'
28
+ * - Edit the image title
29
+ * - Click the 'refresh' breadcrumb and wait for the image details station to reload
30
+ */
31
+ uploadImage(properties: {
32
+ /** Path to a local image file. */
33
+ localFilename: string;
34
+ /** A unique image title. */
35
+ title: string;
36
+ /** An existing image type. */
37
+ imageType: string;
38
+ }): Promise<void>;
39
+ /**
40
+ * This method archives an image by title.
41
+ * The management system must be loaded & signed in before using this method.
42
+ * If a single matching, non-archived image is not found then an exception will be raised.
43
+ *
44
+ * The following steps will be taken:
45
+ * - Navigate to the home breadcrumb then the 'Images' tile
46
+ * - Filter by title and verify that a single result is shown
47
+ * - Navigate to the image with the row action
48
+ * - Click 'Archive' and confirm
49
+ * - Wait for the image explorer station to load
50
+ */
51
+ archiveImage(filters: {
52
+ title: string;
53
+ }): Promise<void>;
54
+ /**
55
+ * A reference to the ImageSelectionExplorer component mod*e*l which can be used
56
+ * to select images in a mod*a*l. e.g.
57
+ * ```
58
+ * await app.ui.form.modal
59
+ * .as(app.imageService.ImageSelectionExplorer)
60
+ * .selectImage('My image title');
61
+ * ```
62
+ */
63
+ readonly ImageSelectionExplorer: typeof ImageSelectionExplorer;
64
+ }
65
+ //# sourceMappingURL=image-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-service.d.ts","sourceRoot":"","sources":["../../src/managed-services/image-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,6CAA6C;AAC7C,qBAAa,YAAa,SAAQ,mBAAmB;IACnD;;;;;;;;;;OAUG;IACG,sBAAsB,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBxE;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,UAAU,EAAE;QAC5B,kCAAkC;QAClC,aAAa,EAAE,MAAM,CAAC;QACtB,4BAA4B;QAC5B,KAAK,EAAE,MAAM,CAAC;QACd,8BAA8B;QAC9B,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCjB;;;;;;;;;;;OAWG;IACG,YAAY,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7D;;;;;;;;OAQG;IACH,QAAQ,CAAC,sBAAsB,gCAA0B;CAC1D"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageService = void 0;
4
+ const mosaic_e2e_ui_selectors_1 = require("@axinom/mosaic-e2e-ui-selectors");
5
+ const image_selection_explorer_1 = require("./image-selection-explorer");
6
+ const managed_service_model_1 = require("./managed-service-model");
7
+ /** A model for the managed image service. */
8
+ class ImageService extends managed_service_model_1.ManagedServiceModel {
9
+ constructor() {
10
+ super(...arguments);
11
+ /**
12
+ * A reference to the ImageSelectionExplorer component mod*e*l which can be used
13
+ * to select images in a mod*a*l. e.g.
14
+ * ```
15
+ * await app.ui.form.modal
16
+ * .as(app.imageService.ImageSelectionExplorer)
17
+ * .selectImage('My image title');
18
+ * ```
19
+ */
20
+ this.ImageSelectionExplorer = image_selection_explorer_1.ImageSelectionExplorer;
21
+ }
22
+ /**
23
+ * This method navigates to an image details station by title.
24
+ * The management system must be loaded & signed in before using this method.
25
+ * If there is not exactly one matching image an exception will be raised.
26
+ *
27
+ * The following steps will be taken:
28
+ * - Navigate to the home breadcrumb then the 'Images' tile
29
+ * - Filter by title and verify that a single result is shown
30
+ * - Click the image row action
31
+ * - Wait for the image details station to load
32
+ */
33
+ async navigateToImageDetails(filterBy) {
34
+ const { form, list, filters } = this.uiManagedWorkflows;
35
+ await this.uiShell.navigateToLandingPageTile('Images');
36
+ await list.waitForData();
37
+ // filter to the item
38
+ await filters
39
+ .getFilterByName('title')
40
+ .asFreeTextFilter()
41
+ .setValue(filterBy.title);
42
+ await list.waitForData();
43
+ // Verify that there is exactly one matching row
44
+ if ((await list.allVisibleRows.count()) !== 1) {
45
+ throw new Error(`Failed to find exactly one image with title '${filterBy.title}'.`);
46
+ }
47
+ // navigate
48
+ await list.getRow(1).actionButton.click();
49
+ await this.uiShell.waitForPageTransition();
50
+ await form.waitForData();
51
+ }
52
+ /**
53
+ * This method uploads an image file from the local file system.
54
+ * The management system must be loaded & signed in before using this method.
55
+ * A unique image title and a valid image type must be provided.
56
+ *
57
+ * The following steps will be taken:
58
+ * - Navigate to the home breadcrumb then the 'Images' tile
59
+ * - Click the 'Upload' action
60
+ * - Enter file and image type inputs then click 'Proceed'
61
+ * - Edit the image title
62
+ * - Click the 'refresh' breadcrumb and wait for the image details station to reload
63
+ */
64
+ async uploadImage(properties) {
65
+ const { form, pageHeader, actions } = this.uiManagedWorkflows;
66
+ await this.uiShell.navigateToLandingPageTile('Images');
67
+ await pageHeader.actions.getActionByLabel('Upload').click();
68
+ await this.uiShell.waitForPageTransition();
69
+ // Setting image upload input
70
+ await form
71
+ .getFieldByName('file')
72
+ .asFileUploadField()
73
+ .setValue(properties.localFilename);
74
+ // Set image type.
75
+ await form
76
+ .getFieldByName('imageType')
77
+ .asSelectField()
78
+ .setValue(properties.imageType);
79
+ // Submitting the upload
80
+ await actions.getActionByLabel(mosaic_e2e_ui_selectors_1.ActionLabel.Proceed).click();
81
+ await this.uiShell.waitForPageTransition();
82
+ await form.waitForData();
83
+ // Set image title.
84
+ await form
85
+ .getFieldByName('title')
86
+ .asSingleLineTextField()
87
+ .setValue(properties.title);
88
+ // Refresh to save
89
+ await this.uiShell.navigateToBreadcrumbRefresh();
90
+ await form.waitForData();
91
+ }
92
+ /**
93
+ * This method archives an image by title.
94
+ * The management system must be loaded & signed in before using this method.
95
+ * If a single matching, non-archived image is not found then an exception will be raised.
96
+ *
97
+ * The following steps will be taken:
98
+ * - Navigate to the home breadcrumb then the 'Images' tile
99
+ * - Filter by title and verify that a single result is shown
100
+ * - Navigate to the image with the row action
101
+ * - Click 'Archive' and confirm
102
+ * - Wait for the image explorer station to load
103
+ */
104
+ async archiveImage(filters) {
105
+ const { list, actions } = this.uiManagedWorkflows;
106
+ await this.navigateToImageDetails(filters);
107
+ try {
108
+ await actions.getActionByLabel('Archive').waitFor({ state: 'visible' });
109
+ }
110
+ catch (_a) {
111
+ throw new Error(`The image archive button is not visible.`);
112
+ }
113
+ await actions.getActionByLabel('Archive').click();
114
+ await actions.confirmButton.click();
115
+ await this.uiShell.waitForPageTransition();
116
+ await list.waitForData();
117
+ }
118
+ }
119
+ exports.ImageService = ImageService;
120
+ //# sourceMappingURL=image-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-service.js","sourceRoot":"","sources":["../../src/managed-services/image-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './image-selection-explorer';
2
+ export * from './image-service';
3
+ export * from './monetization-service';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/managed-services/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./image-selection-explorer"), exports);
14
+ __exportStar(require("./image-service"), exports);
15
+ __exportStar(require("./monetization-service"), exports);
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/managed-services/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6DAA2C;AAC3C,kDAAgC;AAChC,yDAAuC"}
@@ -0,0 +1,46 @@
1
+ import { UiWorkflowsModel } from '@axinom/mosaic-e2e-ui-selectors';
2
+ import { Page } from 'playwright-core';
3
+ import { UiShellModel } from '../ui-selectors/ui-shell-model';
4
+ /**
5
+ * An abstract model representing a Mosaic managed service.
6
+ */
7
+ export declare abstract class ManagedServiceModel {
8
+ /** The playwright page object. */
9
+ protected readonly page: Page;
10
+ /**
11
+ * A model representing the Mosaic UI shell including methods for navigation.
12
+ *
13
+ * Use this model to interact with:
14
+ * - The breadcrumbs bar (on any page)
15
+ * - The landing page
16
+ * - The settings hub page
17
+ */
18
+ protected readonly uiShell: UiShellModel;
19
+ /**
20
+ * A model representing Mosaic UI workflows.
21
+ *
22
+ * Use this model to interact with workflows or mod*a*ls of any managed
23
+ * service (Image, Video, Monetization, etc).
24
+ */
25
+ protected readonly uiManagedWorkflows: UiWorkflowsModel;
26
+ constructor(
27
+ /** The playwright page object. */
28
+ page: Page,
29
+ /**
30
+ * A model representing the Mosaic UI shell including methods for navigation.
31
+ *
32
+ * Use this model to interact with:
33
+ * - The breadcrumbs bar (on any page)
34
+ * - The landing page
35
+ * - The settings hub page
36
+ */
37
+ uiShell: UiShellModel,
38
+ /**
39
+ * A model representing Mosaic UI workflows.
40
+ *
41
+ * Use this model to interact with workflows or mod*a*ls of any managed
42
+ * service (Image, Video, Monetization, etc).
43
+ */
44
+ uiManagedWorkflows: UiWorkflowsModel);
45
+ }
46
+ //# sourceMappingURL=managed-service-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-service-model.d.ts","sourceRoot":"","sources":["../../src/managed-services/managed-service-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D;;GAEG;AACH,8BAAsB,mBAAmB;IAErC,kCAAkC;IAClC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI;IAE7B;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY;IAExC;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,gBAAgB;;IAnBvD,kCAAkC;IACf,IAAI,EAAE,IAAI;IAE7B;;;;;;;OAOG;IACgB,OAAO,EAAE,YAAY;IAExC;;;;;OAKG;IACgB,kBAAkB,EAAE,gBAAgB;CAE1D"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ManagedServiceModel = void 0;
4
+ /**
5
+ * An abstract model representing a Mosaic managed service.
6
+ */
7
+ class ManagedServiceModel {
8
+ constructor(
9
+ /** The playwright page object. */
10
+ page,
11
+ /**
12
+ * A model representing the Mosaic UI shell including methods for navigation.
13
+ *
14
+ * Use this model to interact with:
15
+ * - The breadcrumbs bar (on any page)
16
+ * - The landing page
17
+ * - The settings hub page
18
+ */
19
+ uiShell,
20
+ /**
21
+ * A model representing Mosaic UI workflows.
22
+ *
23
+ * Use this model to interact with workflows or mod*a*ls of any managed
24
+ * service (Image, Video, Monetization, etc).
25
+ */
26
+ uiManagedWorkflows) {
27
+ this.page = page;
28
+ this.uiShell = uiShell;
29
+ this.uiManagedWorkflows = uiManagedWorkflows;
30
+ }
31
+ }
32
+ exports.ManagedServiceModel = ManagedServiceModel;
33
+ //# sourceMappingURL=managed-service-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-service-model.js","sourceRoot":"","sources":["../../src/managed-services/managed-service-model.ts"],"names":[],"mappings":";;;AAIA;;GAEG;AACH,MAAsB,mBAAmB;IACvC;IACE,kCAAkC;IACf,IAAU;IAE7B;;;;;;;OAOG;IACgB,OAAqB;IAExC;;;;;OAKG;IACgB,kBAAoC;QAlBpC,SAAI,GAAJ,IAAI,CAAM;QAUV,YAAO,GAAP,OAAO,CAAc;QAQrB,uBAAkB,GAAlB,kBAAkB,CAAkB;IACtD,CAAC;CACL;AAvBD,kDAuBC"}
@@ -0,0 +1,208 @@
1
+ import { ManagedServiceModel } from './managed-service-model';
2
+ /** A model for the managed monetization service. */
3
+ export declare class MonetizationService extends ManagedServiceModel {
4
+ /** Verify the URL is a subscription plan details station. */
5
+ private verifySubscriptionPlanDetailsUrl;
6
+ /** Verify the URL is a payment plan details station. */
7
+ private verifyPaymentPlanDetailsUrl;
8
+ /** Verify the URL is a claim set details station. */
9
+ private verifyClaimSetDetailsUrl;
10
+ /**
11
+ * This method navigates to the subscription plans explorer station.
12
+ * The management system must be loaded & signed in before using this method.
13
+ *
14
+ * The following steps will be taken:
15
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Subscription Plans'
16
+ * - Wait for the page transition to complete
17
+ */
18
+ navigateToSubscriptionPlans(): Promise<void>;
19
+ /**
20
+ * This method navigates to the claim sets explorer station.
21
+ * The management system must be loaded & signed in before using this method.
22
+ *
23
+ * The following steps will be taken:
24
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Claim Sets'
25
+ * - Wait for the page transition to complete
26
+ */
27
+ navigateToClaimSets(): Promise<void>;
28
+ /**
29
+ * This method navigates to a subscription plan details station by title.
30
+ * The management system must be loaded & signed in before using this method.
31
+ * If there is not exactly one matching subscription plan an exception will be raised.
32
+ *
33
+ * The following steps will be taken:
34
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Subscription Plans'
35
+ * - Filter by title and verify that a single result is shown
36
+ * - Click the subscription plan row action
37
+ * - Wait for the subscription plan details page to load
38
+ */
39
+ navigateToSubscriptionPlanDetails(filterBy: {
40
+ title: string;
41
+ }): Promise<void>;
42
+ /**
43
+ * This method navigates to a claim set details station by unique key.
44
+ * The management system must be loaded & signed in before using this method.
45
+ * If there is not exactly one matching claim set an exception will be raised.
46
+ *
47
+ * The following steps will be taken:
48
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Claim Sets'
49
+ * - Filter by unique key and verify that a single result is shown
50
+ * - Click the claim set row action
51
+ * - Wait for the claim set details station to load
52
+ */
53
+ navigateToClaimSetDetails(filterBy: {
54
+ uniqueKey: string;
55
+ }): Promise<void>;
56
+ /**
57
+ * This method creates a new subscription plan.
58
+ * The management system must be loaded & signed in before using this method.
59
+ * When this method completes, the new subscription plan details station will be loaded.
60
+ *
61
+ * The following steps will be taken:
62
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Subscription Plans'
63
+ * - Click 'NEW', enter the title then click 'Proceed'
64
+ * - Wait for the subscription plan details station to load
65
+ */
66
+ createSubscriptionPlan(properties: {
67
+ title: string;
68
+ }): Promise<void>;
69
+ /**
70
+ * This method configures a payment provider for the subscription plan.
71
+ * The subscription plan details station must be loaded before using this method.
72
+ * If the payment provider is not enabled for the environment, or is already added an exception will be raised.
73
+ *
74
+ * The following steps will be taken:
75
+ * - Verify that a subscription plan details station is loaded
76
+ * - Add a payment provider by key, and set the external Id field (if it is shown).
77
+ * - Click the 'refresh' breadcrumb and wait for the subscription plan details station to reload
78
+ */
79
+ subscriptionPlanAddPaymentProvider(paymentProviderSettings: {
80
+ providerKey: string;
81
+ externalId?: string;
82
+ }): Promise<void>;
83
+ /**
84
+ * This method assigns a claim set to the subscription plan.
85
+ * The subscription plan details station must be loaded before using this method.
86
+ * If the claim set does not exist, or is already added to this subscription plan then an exception will be raised.
87
+ *
88
+ * The following steps will be taken:
89
+ * - Verify that a subscription plan details station is loaded
90
+ * - Click 'Claim Sets'
91
+ * - Open the claim sets explorer modal, filter by key and select the first result
92
+ * - Click the 'previous' breadcrumb and wait for the subscription plan details station to load
93
+ */
94
+ subscriptionPlanAssignClaimSet(claimSetKey: string): Promise<void>;
95
+ /**
96
+ * This method publishes the subscription plan.
97
+ * The subscription plan details station must be loaded before using this method.
98
+ * If the subscription plan cannot be published then an exception will be raised.
99
+ *
100
+ * The following steps will be taken:
101
+ * - Verify that a subscription plan details station is loaded
102
+ * - Click 'Publishing'
103
+ * - Click 'Publish' and confirm
104
+ * - Wait for the subscription plan details station to load and verify that the publication state is 'PUBLISHED'
105
+ */
106
+ subscriptionPlanPublish(): Promise<void>;
107
+ /**
108
+ * This method creates a new payment plan owned by the subscription plan.
109
+ * The subscription plan details station must be loaded before using this method.
110
+ *
111
+ * The following steps will be taken:
112
+ * - Verify that a subscription plan details station is loaded
113
+ * - Click 'Payment Plans' then click 'NEW'
114
+ * - Enter the title and click 'Proceed'
115
+ * - Edit the recurrence period fields
116
+ * - Click the 'refresh' breadcrumb and wait for the payment plan details station to reload
117
+ */
118
+ subscriptionPlanCreatePaymentPlan(properties: {
119
+ title: string;
120
+ recurrencePeriodQuantity: number;
121
+ recurrencePeriodUnit: 'DAY' | 'WEEK' | 'MONTH' | 'YEAR';
122
+ }): Promise<void>;
123
+ /**
124
+ * This method configures a payment provider for the payment plan.
125
+ * The subscription plan details station must be loaded before using this method.
126
+ * If the payment provider is not added to the parent subscription plan, or is already added to this payment plan then an exception will be raised.
127
+ *
128
+ * The following steps will be taken:
129
+ * - Verify that a payment plan details station is loaded
130
+ * - Add a payment provider by key, and set the external Id field (if it is shown).
131
+ * - Click the 'refresh' breadcrumb and wait for the payment plan details station to reload.
132
+ */
133
+ paymentPlanAddPaymentProvider(paymentProviderSettings: {
134
+ providerKey: string;
135
+ externalId?: string;
136
+ }): Promise<void>;
137
+ /**
138
+ * This method sets a price for the payment plan for a specific country.
139
+ * The payment plan details station must be loaded before using this method.
140
+ *
141
+ * The following steps will be taken:
142
+ * - Verify that a payment plan details station is loaded
143
+ * - Click 'Price per Country'
144
+ * - Enter new price details and click the add button
145
+ * - Click the 'previous' breadcrumb and wait for the payment plan details station to load
146
+ */
147
+ paymentPlanAddPrice(pricePerCountry: {
148
+ country: string;
149
+ currency: string;
150
+ price: number;
151
+ }): Promise<void>;
152
+ /**
153
+ * This method creates a new claim set.
154
+ * The management system must be loaded & signed in before using this method.
155
+ * When this method completes, the new claim set details station will be loaded.
156
+ *
157
+ * The following steps will be taken:
158
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Claim Sets'
159
+ * - Click 'NEW', enter the title and key then click 'Proceed'
160
+ * - Wait for the claim set details station to load
161
+ */
162
+ createClaimSet(properties: {
163
+ title: string;
164
+ key: string;
165
+ }): Promise<void>;
166
+ /**
167
+ * This method assigns claims to a claim set.
168
+ * This claim set details station must be loaded before using this method.
169
+ * NOTE: Only claims which can be added by radio or checkbox are supported.
170
+ *
171
+ * The following steps will be taken:
172
+ * - Verify that a claim set details station is loaded
173
+ * - Click 'Claims'
174
+ * - Add each claim by checkbox or radio button
175
+ * - Click the 'previous' breadcrumb and wait for the claim set details station to load
176
+ */
177
+ claimSetAssignClaims(claims: string[]): Promise<void>;
178
+ /**
179
+ * This method publishes a claim set.
180
+ * The claim set details station must be loaded before using this method.
181
+ * If the claim set cannot be published then an exception will be raised.
182
+ *
183
+ * The following steps will be taken:
184
+ * - Verify that a claim set details station is loaded
185
+ * - Click 'Publishing'
186
+ * - Click 'Publish' and confirm
187
+ * - Wait for the claim set details station to load and verify that the publication state is 'PUBLISHED'
188
+ */
189
+ claimSetPublish(): Promise<void>;
190
+ /**
191
+ * This method deletes a claim set by unique key.
192
+ * The management system must be loaded & signed in before using this method.
193
+ * If the claim set is published then it will first be unpublished.
194
+ * If the claim set cannot be deleted then an exception will be raised.
195
+ *
196
+ * The following steps will be taken:
197
+ * - Navigate to the home breadcrumb, then tiles: 'Monetization', 'Claim Sets'
198
+ * - Filter by unique key and verify that a single result is shown
199
+ * - Navigate to the claim set with the row action
200
+ * - If the action is shown, click 'Unpublish' and confirm
201
+ * - Click 'Delete' and confirm
202
+ * - Wait for the claim sets explorer to load
203
+ */
204
+ deleteClaimSet(filterBy: {
205
+ uniqueKey: string;
206
+ }): Promise<void>;
207
+ }
208
+ //# sourceMappingURL=monetization-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monetization-service.d.ts","sourceRoot":"","sources":["../../src/managed-services/monetization-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,oDAAoD;AACpD,qBAAa,mBAAoB,SAAQ,mBAAmB;IAC1D,6DAA6D;YAC/C,gCAAgC;IAY9C,wDAAwD;YAC1C,2BAA2B;IAYzC,qDAAqD;YACvC,wBAAwB;IAUtC;;;;;;;OAOG;IACG,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBlD;;;;;;;OAOG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB1C;;;;;;;;;;OAUG;IACG,iCAAiC,CAAC,QAAQ,EAAE;QAChD,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjB;;;;;;;;;;OAUG;IACG,yBAAyB,CAAC,QAAQ,EAAE;QACxC,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBjB;;;;;;;;;OASG;IACG,sBAAsB,CAAC,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1E;;;;;;;;;OASG;IACG,kCAAkC,CAAC,uBAAuB,EAAE;QAChE,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjB;;;;;;;;;;OAUG;IACG,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxE;;;;;;;;;;OAUG;IACG,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB9C;;;;;;;;;;OAUG;IACG,iCAAiC,CAAC,UAAU,EAAE;QAClD,KAAK,EAAE,MAAM,CAAC;QACd,wBAAwB,EAAE,MAAM,CAAC;QACjC,oBAAoB,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;KACzD,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BjB;;;;;;;;;OASG;IACG,6BAA6B,CAAC,uBAAuB,EAAE;QAC3D,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjB;;;;;;;;;OASG;IACG,mBAAmB,CAAC,eAAe,EAAE;QACzC,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjB;;;;;;;;;OASG;IACG,cAAc,CAAC,UAAU,EAAE;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjB;;;;;;;;;;OAUG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3D;;;;;;;;;;OAUG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtC;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAuBrE"}