diff --git a/lib/helpers/ApiHelpers.ts b/lib/helpers/ApiHelpers.ts index fce41df..de8d4a1 100644 --- a/lib/helpers/ApiHelpers.ts +++ b/lib/helpers/ApiHelpers.ts @@ -35,6 +35,7 @@ import {LoginApiHelper} from "./LoginApiHelper"; import {WebhookApiHelper} from "./WebhookApiHelper"; import {MediaDeliveryApiHelper} from './differentAppSettingsHelpers/MediaDeliveryApiHelper'; import {ContentDeliveryApiHelper} from "./differentAppSettingsHelpers/ContentDeliveryApiHelper"; +import {SmtpApiHelper} from './SmtpApiHelper'; export class ApiHelpers { baseUrl: string = umbracoConfig.environment.baseUrl; @@ -73,6 +74,7 @@ export class ApiHelpers { webhook: WebhookApiHelper; mediaDeliveryApi: MediaDeliveryApiHelper; contentDeliveryApi: ContentDeliveryApiHelper; + smtp: SmtpApiHelper; constructor(page: Page) { this.page = page; @@ -110,6 +112,7 @@ export class ApiHelpers { this.webhook = new WebhookApiHelper(this, this.page); this.mediaDeliveryApi = new MediaDeliveryApiHelper(this); this.contentDeliveryApi = new ContentDeliveryApiHelper(this); + this.smtp = new SmtpApiHelper(this); } async getAccessToken() { diff --git a/lib/helpers/ContentUiHelper.ts b/lib/helpers/ContentUiHelper.ts index ba4afc8..a66b5b2 100644 --- a/lib/helpers/ContentUiHelper.ts +++ b/lib/helpers/ContentUiHelper.ts @@ -1794,4 +1794,10 @@ export class ContentUiHelper extends UiBaseLocators { async isChooseButtonVisible(isVisible: boolean = true) { await expect(this.chooseBtn).toBeVisible({visible: isVisible}); } + + async clickDocumentNotificationOptionWithName(name: string) { + const notificationOptionLocator = this.page.locator('umb-document-notifications-modal [id$="' + name + '"]').locator('#toggle'); + await expect(notificationOptionLocator).toBeVisible(); + await notificationOptionLocator.click(); + } } \ No newline at end of file diff --git a/lib/helpers/DocumentApiHelper.ts b/lib/helpers/DocumentApiHelper.ts index 39b2c60..c080dcd 100644 --- a/lib/helpers/DocumentApiHelper.ts +++ b/lib/helpers/DocumentApiHelper.ts @@ -1637,5 +1637,22 @@ export class DocumentApiHelper { entityType: 'document-property-value' }); return await this.update(documentId, documentData); - } + } + + async getNotifications(id: string) { + const response = await this.api.get(this.api.baseUrl + '/umbraco/management/api/v1/document/' + id + '/notifications'); + return await response.json(); + } + + async updatetNotifications(id: string, subscribedActionIds: string[] = []) { + const updateData = { + "subscribedActionIds": subscribedActionIds + }; + return await this.api.put(this.api.baseUrl + '/umbraco/management/api/v1/document/' + id + '/notifications', updateData); + } + + async doesNotificationExist(id: string, actionId: string) { + const notifications = await this.getNotifications(id); + return notifications.some((notification) => notification.actionId === actionId && notification.subscribed === true); + } } \ No newline at end of file diff --git a/lib/helpers/MediaUiHelper.ts b/lib/helpers/MediaUiHelper.ts index b076a3d..62d3886 100644 --- a/lib/helpers/MediaUiHelper.ts +++ b/lib/helpers/MediaUiHelper.ts @@ -8,7 +8,6 @@ export class MediaUiHelper extends UiBaseLocators { private readonly mediaSearchTxt: Locator; private readonly trashBtn: Locator; private readonly restoreThreeDotsBtn: Locator; - private readonly restoreBtn: Locator; private readonly confirmEmptyRecycleBinBtn: Locator; private readonly mediaCreateBtn: Locator; private readonly mediaListHeader: Locator; @@ -33,7 +32,6 @@ export class MediaUiHelper extends UiBaseLocators { this.mediaSearchTxt = page.getByLabel('Search', {exact: true}); this.trashBtn = page.getByLabel(/^Trash(…)?$/); this.restoreThreeDotsBtn = page.getByRole('button', {name: 'Restore…'}); - this.restoreBtn = page.getByLabel('Restore', {exact: true}); this.confirmEmptyRecycleBinBtn = page.locator('#confirm').getByLabel('Empty Recycle Bin', {exact: true}); this.mediaCreateBtn = this.page.locator('umb-collection-toolbar').getByLabel('Create'); this.mediaListView = this.page.locator('umb-media-table-collection-view'); @@ -87,7 +85,7 @@ export class MediaUiHelper extends UiBaseLocators { await this.clickActionsMenuForName(name); await this.restoreThreeDotsBtn.click(); await this.page.waitForTimeout(1000); - await this.restoreBtn.click(); + await this.clickRestoreButton(); } async waitForMediaToBeTrashed() { diff --git a/lib/helpers/SmtpApiHelper.ts b/lib/helpers/SmtpApiHelper.ts new file mode 100644 index 0000000..ac705a8 --- /dev/null +++ b/lib/helpers/SmtpApiHelper.ts @@ -0,0 +1,37 @@ +import {ApiHelpers} from "./ApiHelpers"; + +export class SmtpApiHelper { + api: ApiHelpers; + private smtpBaseUrl = 'http://localhost:5000'; // Default smtp4dev URL, can be configured + + constructor(api: ApiHelpers) { + this.api = api; + } + + async getAllEmails() { + const response = await this.api.page.request.get(this.smtpBaseUrl + '/api/messages', { + ignoreHTTPSErrors: true + }); + return await response.json(); + } + + async deleteAllEmails() { + const response = await this.api.page.request.delete(this.smtpBaseUrl + '/api/messages/*', { + ignoreHTTPSErrors: true + }); + return response.status(); + } + + async findEmailBySubject(subject: string) { + const emails = await this.getAllEmails(); + const foundEmail = emails.results.find((email: any) => + email.subject && email.subject.toLowerCase().includes(subject.toLowerCase()) + ); + return foundEmail || null; + } + + async doesNotificationEmailWithSubjectExist(actionName: string, contentName: string) { + const expectedSubject = `Notification about ${actionName} performed on ${contentName}` + return this.findEmailBySubject(expectedSubject); + } +} \ No newline at end of file diff --git a/lib/helpers/UiBaseLocators.ts b/lib/helpers/UiBaseLocators.ts index c7e944a..08adc29 100644 --- a/lib/helpers/UiBaseLocators.ts +++ b/lib/helpers/UiBaseLocators.ts @@ -158,6 +158,7 @@ export class UiBaseLocators { public readonly inputUploadField: Locator; public readonly entityItem: Locator; public readonly sectionLinks: Locator; + public readonly restoreBtn: Locator; public readonly backOfficeMain: Locator; constructor(page: Page) { @@ -320,6 +321,7 @@ export class UiBaseLocators { this.imageCropperField = page.locator('umb-image-cropper-field'); this.inputUploadField = page.locator('umb-input-upload-field').locator('#wrapperInner'); this.entityItem = page.locator('umb-entity-item-ref'); + this.restoreBtn = page.getByLabel('Restore', {exact: true}); this.backOfficeMain = page.locator('umb-backoffice-main'); } @@ -1455,6 +1457,11 @@ export class UiBaseLocators { await expect(this.page.getByTestId('workspace:view-link:' + alias)).toBeVisible({visible: isVisible}); } + async clickRestoreButton() { + await expect(this.restoreBtn).toBeVisible(); + await this.restoreBtn.click(); + } + async isInputDropzoneVisible(isVisible: boolean = true) { await expect(this.inputDropzone).toBeVisible({visible: isVisible}); } diff --git a/package-lock.json b/package-lock.json index c4e7947..eb0783c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@umbraco/playwright-testhelpers", - "version": "17.0.10", + "version": "17.0.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@umbraco/playwright-testhelpers", - "version": "17.0.10", + "version": "17.0.11", "license": "MIT", "dependencies": { "@umbraco/json-models-builders": "2.0.42", diff --git a/package.json b/package.json index e6a28a6..d65ff78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@umbraco/playwright-testhelpers", - "version": "17.0.10", + "version": "17.0.11", "description": "Test helpers for making playwright tests for Umbraco solutions", "main": "dist/lib/index.js", "files": [