@axinom/mosaic-e2e-page-model 0.2.5-rc.8 → 0.3.0-rc.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 (36) hide show
  1. package/dist/managed-services/channel-service.d.ts +113 -0
  2. package/dist/managed-services/channel-service.d.ts.map +1 -0
  3. package/dist/managed-services/channel-service.js +184 -0
  4. package/dist/managed-services/channel-service.js.map +1 -0
  5. package/dist/managed-services/index.d.ts +1 -0
  6. package/dist/managed-services/index.d.ts.map +1 -1
  7. package/dist/managed-services/index.js +1 -0
  8. package/dist/managed-services/index.js.map +1 -1
  9. package/dist/page-model.d.ts +3 -1
  10. package/dist/page-model.d.ts.map +1 -1
  11. package/dist/page-model.js +2 -0
  12. package/dist/page-model.js.map +1 -1
  13. package/package.json +5 -4
  14. package/src/index.ts +5 -0
  15. package/src/managed-services/channel-service.ts +231 -0
  16. package/src/managed-services/image-service/image-selection-explorer.ts +40 -0
  17. package/src/managed-services/image-service/image-service.ts +142 -0
  18. package/src/managed-services/image-service/index.ts +2 -0
  19. package/src/managed-services/index.ts +4 -0
  20. package/src/managed-services/managed-service-model.ts +31 -0
  21. package/src/managed-services/monetization-service/claim-set-control.ts +84 -0
  22. package/src/managed-services/monetization-service/index.ts +3 -0
  23. package/src/managed-services/monetization-service/monetization-service.ts +560 -0
  24. package/src/managed-services/monetization-service/payment-plan-recurrence-period-field.ts +43 -0
  25. package/src/managed-services/monetization-service/payment-provider-settings-field.ts +76 -0
  26. package/src/managed-services/video-service.ts +211 -0
  27. package/src/page-model.ts +86 -0
  28. package/src/service-model.ts +29 -0
  29. package/src/sign-in/index.ts +4 -0
  30. package/src/sign-in/sign-in-page.ts +40 -0
  31. package/src/sign-in/sign-in-with-ax-auth-form.ts +58 -0
  32. package/src/sign-in/sign-in-with-google-form.ts +55 -0
  33. package/src/sign-in/sign-in-with-microsoft-form.ts +66 -0
  34. package/src/ui-selectors/breadcrumbs.ts +48 -0
  35. package/src/ui-selectors/index.ts +2 -0
  36. package/src/ui-selectors/ui-shell-model.ts +177 -0
@@ -0,0 +1,40 @@
1
+ import { SelectionExplorer } from '@axinom/mosaic-e2e-ui-selectors';
2
+
3
+ /** A mod*e*l for the mod*a*l image explorer component used to select images. */
4
+ export class ImageSelectionExplorer extends SelectionExplorer {
5
+ /**
6
+ * Select an image by title.
7
+ * If the image explorer modal is not showing or the selected title does not exist then an exception will be raised.
8
+ *
9
+ * The following steps will be taken:
10
+ * - Verify that the page header title is 'Select Image'
11
+ * - Filter by title and verify that at least one result is shown
12
+ * - Select the first result by row action
13
+ * - Wait for the modal to be closed
14
+ */
15
+ async selectImageByTitle(imageTitle: string): Promise<void> {
16
+ // verify the modal header
17
+ await this.pageHeader.title.waitFor({ state: 'visible' });
18
+ if ((await this.pageHeader.title.textContent()) !== 'Select Image') {
19
+ throw new Error('Image explorer modal must be showing.');
20
+ }
21
+ await this.waitToOpen();
22
+ await this.list.waitForData();
23
+
24
+ await this.filters
25
+ .getFilterByName('title')
26
+ .asFreeTextFilter()
27
+ .setValue(imageTitle);
28
+ await this.list.waitForData();
29
+
30
+ // verify that one result is showing
31
+ if ((await this.list.allVisibleRows.count()) === 0) {
32
+ throw new Error('An image with the specified title was not found.');
33
+ }
34
+
35
+ await this.list.getRow(1).selectButton.click();
36
+
37
+ // wait for the modal to close
38
+ await this.waitToClose();
39
+ }
40
+ }
@@ -0,0 +1,142 @@
1
+ import { ActionLabel } from '@axinom/mosaic-e2e-ui-selectors';
2
+ import { ManagedServiceModel } from '../managed-service-model';
3
+ import { ImageSelectionExplorer } from './image-selection-explorer';
4
+
5
+ /** A model for the managed image service. */
6
+ export class ImageService extends ManagedServiceModel {
7
+ /**
8
+ * This method navigates to an image details station by title.
9
+ * The management system must be loaded & signed in before using this method.
10
+ * If there is not exactly one matching image an exception will be raised.
11
+ *
12
+ * The following steps will be taken:
13
+ * - Navigate to the home breadcrumb then the 'Images' tile
14
+ * - Filter by title and click the image row action
15
+ * - Wait for the image details station to load
16
+ */
17
+ async navigateToImageDetails(args: {
18
+ /** A unique image title. */
19
+ title: string;
20
+ }): Promise<void> {
21
+ const { uiShell, uiManagedWorkflows } = this;
22
+ await uiShell.navigateToLandingPageTile('Images');
23
+ await uiManagedWorkflows.list.waitForData();
24
+
25
+ // filter to the item
26
+ await uiManagedWorkflows.filters
27
+ .getFilterByName('title')
28
+ .asFreeTextFilter()
29
+ .setValue(args.title);
30
+ await uiManagedWorkflows.list.waitForData();
31
+
32
+ // Verify that there is exactly one matching row
33
+ if ((await uiManagedWorkflows.list.allVisibleRows.count()) !== 1) {
34
+ throw new Error(
35
+ `Failed to find exactly one non-archived image with title '${args.title}'.`,
36
+ );
37
+ }
38
+
39
+ // navigate
40
+ await uiShell.waitForPageTransition(
41
+ uiManagedWorkflows.list.getRow(1).actionButton.click(),
42
+ );
43
+ await uiManagedWorkflows.form.waitForData();
44
+ }
45
+
46
+ /**
47
+ * This method uploads an image file from the local file system.
48
+ * The management system must be loaded & signed in before using this method.
49
+ * A unique image title and a valid image type must be provided.
50
+ *
51
+ * The following steps will be taken:
52
+ * - Navigate to the home breadcrumb then the 'Images' tile
53
+ * - Click the 'Upload' action
54
+ * - Enter file and image type inputs then click 'Proceed'
55
+ * - Edit the image title
56
+ * - Click the 'refresh' breadcrumb and wait for the image details station to reload
57
+ */
58
+ async uploadImage(properties: {
59
+ /** Path to a local image file. */
60
+ sourceFile: string;
61
+ /** A unique image title. */
62
+ title: string;
63
+ /** An existing image type (display value). */
64
+ imageType: string;
65
+ }): Promise<void> {
66
+ const { uiShell, uiManagedWorkflows } = this;
67
+ await uiShell.navigateToLandingPageTile('Images');
68
+ await uiShell.waitForPageTransition(
69
+ uiManagedWorkflows.pageHeader.actions.getActionByLabel('Upload').click(),
70
+ );
71
+
72
+ // Setting image upload input
73
+ await uiManagedWorkflows.form
74
+ .getFieldByName('file')
75
+ .asFileUploadField()
76
+ .setValue(properties.sourceFile);
77
+
78
+ // Set image type.
79
+ await uiManagedWorkflows.form
80
+ .getFieldByName('imageType')
81
+ .asSelectField()
82
+ .setValueByLabel(properties.imageType);
83
+
84
+ // Submitting the upload
85
+ await uiShell.waitForPageTransition(
86
+ uiManagedWorkflows.actions.getActionByLabel(ActionLabel.Proceed).click(),
87
+ );
88
+ await uiManagedWorkflows.form.waitForData();
89
+
90
+ // Set image title.
91
+ await uiManagedWorkflows.form
92
+ .getFieldByName('title')
93
+ .asSingleLineTextField()
94
+ .setValue(properties.title);
95
+
96
+ // Refresh to save
97
+ await uiShell.navigateToBreadcrumbRefresh();
98
+ await uiManagedWorkflows.form.waitForData();
99
+ }
100
+
101
+ /**
102
+ * This method archives an image by title.
103
+ * The management system must be loaded & signed in before using this method.
104
+ * If a single matching, non-archived image is not found then an exception will be raised.
105
+ *
106
+ * The following steps will be taken:
107
+ * - Navigate to the home breadcrumb then the 'Images' tile
108
+ * - Filter by title and click the image row action
109
+ * - Click 'Archive' and confirm
110
+ * - Wait for the image explorer station to load
111
+ */
112
+ async archiveImage(args: {
113
+ /** A unique image title. */
114
+ title: string;
115
+ }): Promise<void> {
116
+ const { uiShell, uiManagedWorkflows } = this;
117
+ await this.navigateToImageDetails(args);
118
+ try {
119
+ await uiManagedWorkflows.actions
120
+ .getActionByLabel('Archive')
121
+ .waitFor({ state: 'visible' });
122
+ } catch {
123
+ throw new Error(`The image archive button is not visible.`);
124
+ }
125
+ await uiManagedWorkflows.actions.getActionByLabel('Archive').click();
126
+ await uiShell.waitForPageTransition(
127
+ uiManagedWorkflows.actions.confirmButton.click(),
128
+ );
129
+ await uiManagedWorkflows.list.waitForData();
130
+ }
131
+
132
+ /**
133
+ * A reference to the ImageSelectionExplorer component mod*e*l which can be used
134
+ * to select images in a mod*a*l. e.g.
135
+ * ```
136
+ * await app.ui.form.modal
137
+ * .as(app.imageService.ImageSelectionExplorer)
138
+ * .selectImage('My image title');
139
+ * ```
140
+ */
141
+ readonly ImageSelectionExplorer = ImageSelectionExplorer;
142
+ }
@@ -0,0 +1,2 @@
1
+ export * from './image-selection-explorer';
2
+ export * from './image-service';
@@ -0,0 +1,4 @@
1
+ export * from './channel-service';
2
+ export * from './image-service';
3
+ export * from './monetization-service';
4
+ export * from './video-service';
@@ -0,0 +1,31 @@
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
+ /**
6
+ * An abstract model representing a Mosaic managed service.
7
+ */
8
+ export abstract class ManagedServiceModel {
9
+ constructor(
10
+ /** The playwright page object. */
11
+ protected readonly page: Page,
12
+
13
+ /**
14
+ * A model representing the Mosaic UI shell including methods for navigation.
15
+ *
16
+ * Use this model to interact with:
17
+ * - The breadcrumbs bar (on any page)
18
+ * - The landing page
19
+ * - The settings hub page
20
+ */
21
+ protected readonly uiShell: UiShellModel,
22
+
23
+ /**
24
+ * A model representing Mosaic UI workflows.
25
+ *
26
+ * Use this model to interact with workflows or mod*a*ls of any managed
27
+ * service (Image, Video, Monetization, etc).
28
+ */
29
+ protected readonly uiManagedWorkflows: UiWorkflowsModel,
30
+ ) {}
31
+ }
@@ -0,0 +1,84 @@
1
+ import {
2
+ Accordion,
3
+ AccordionItem,
4
+ ComponentModel,
5
+ DynamicDataList,
6
+ Modal,
7
+ } from '@axinom/mosaic-e2e-ui-selectors';
8
+ import { FrameLocator, Locator, Page } from 'playwright-core';
9
+
10
+ /**
11
+ * A model for the a claim row in the claims editor station. This model should not be used directly.
12
+ * It is used internally by methods of the `MonetizationService` model.
13
+ */
14
+ export class ClaimRow extends ComponentModel {
15
+ /** Get a locator to the appropriate input element to select this claim. */
16
+ async getInput(): Promise<Locator> {
17
+ const radioLabel = this.getLocator('//label', -1);
18
+ const checkBox = this.getLocator('//input', -1);
19
+ return (await radioLabel.isVisible()) ? radioLabel : checkBox;
20
+ }
21
+
22
+ /** This method toggles the claim selection. */
23
+ async toggle(): Promise<void> {
24
+ const input = await this.getInput();
25
+ await input.check();
26
+ }
27
+ }
28
+
29
+ /**
30
+ * A model for the a claim group in the claims editor station. This model should not be used directly.
31
+ * It is used internally by methods of the `MonetizationService` model.
32
+ */
33
+ export class ClaimGroup extends AccordionItem {
34
+ /** A model for the dynamic data list used to for claim multiple select. */
35
+ readonly dataList = new DynamicDataList(this);
36
+
37
+ /** A model for the modal opened by the dynamic data list. */
38
+ readonly explorerModal = new Modal(this).asSelectionExplorer();
39
+
40
+ /**
41
+ * This method will determine whether the claim group uses modal input.
42
+ * If this returns true, then claims should be selected with the `dataList` and `explorerModal` properties.
43
+ * If it returns false then the `getClaimRowByLabel` method should be used.
44
+ */
45
+ async isDataListEntry(): Promise<boolean> {
46
+ return this.dataList.getLocator().isVisible();
47
+ }
48
+
49
+ /** This method gets a claim row by label. */
50
+ getClaimRowByLabel(claimLabel: string): ClaimRow {
51
+ return new ClaimRow(
52
+ this,
53
+ `//*[contains(@data-test-id, "claim:") and .//*[@data-test-id="claim-label" and text()="${claimLabel}"]]`,
54
+ );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * A model for the claims editor station. This model should not be used directly.
60
+ * It is used internally by methods of the `MonetizationService` model.
61
+ */
62
+ export class ClaimsEditor extends ComponentModel {
63
+ /**
64
+ * A model for an accordion component.
65
+ * @param parent The parent playwright page, frame or component model.
66
+ * @param xpath A relative xpath selector to this element from the parent.
67
+ */
68
+ constructor(parent: Page | FrameLocator | ComponentModel, xpath = '//form') {
69
+ super(parent, xpath);
70
+ }
71
+
72
+ private accordion = new Accordion(this.root, this.xpath);
73
+
74
+ /** This method gets a claim row by claim value. */
75
+ getClaimRow(claim: string): ClaimRow {
76
+ return new ClaimRow(this.accordion, `//*[@data-test-id="claim:${claim}"]`);
77
+ }
78
+
79
+ /** This method gets a claim group by label. */
80
+ getClaimGroup(claimGroupLabel: string): ClaimGroup {
81
+ const accordionItem = this.accordion.getItemContainingText(claimGroupLabel);
82
+ return new ClaimGroup(this.root, accordionItem.xpath);
83
+ }
84
+ }
@@ -0,0 +1,3 @@
1
+ export * from './monetization-service';
2
+ export * from './payment-plan-recurrence-period-field';
3
+ export * from './payment-provider-settings-field';