From e6791246e49132c6af9d8acd9ff225ee9d8c0fab Mon Sep 17 00:00:00 2001 From: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:55:30 +0200 Subject: [PATCH] V16 QA Added acceptance tests for Webhook (#19545) * Added tests for webhook * Added tests for webhook trigger * Bumped version * Make all Webhook tests run in the pipeline * Fixed comment * Reverted npm command --- .../package-lock.json | 19 +- .../Umbraco.Tests.AcceptanceTest/package.json | 4 +- .../DefaultConfig/Webhook/Webhook.spec.ts | 188 ++++++++++++++ .../Webhook/WebhookTrigger.spec.ts | 242 ++++++++++++++++++ 4 files changed, 441 insertions(+), 12 deletions(-) create mode 100644 tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/Webhook.spec.ts create mode 100644 tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/WebhookTrigger.spec.ts diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index bc9cbdfc34..f2cabf43c3 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json @@ -7,8 +7,8 @@ "name": "acceptancetest", "hasInstallScript": true, "dependencies": { - "@umbraco/json-models-builders": "^2.0.35", - "@umbraco/playwright-testhelpers": "^16.0.23", + "@umbraco/json-models-builders": "^2.0.36", + "@umbraco/playwright-testhelpers": "^16.0.25", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" @@ -58,20 +58,19 @@ } }, "node_modules/@umbraco/json-models-builders": { - "version": "2.0.35", - "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.35.tgz", - "integrity": "sha512-9qHvp7j8Lhj2x4xxWYz+ovRyoSnJIl4eLbSAst4nODCNqXSTWOy3+mzho3SeYWeil00/r0zXExHoXklVYi4iKA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.36.tgz", + "integrity": "sha512-vQLL/y2ZIqrhCBe61W6YuA/C3KjGkva90WA09YfQuPL9HujOkJpVaP7KjJ0F8bBxwURy9tzMBFBLUz5fOdbkxQ==", "dependencies": { "camelize": "^1.0.1" } }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "16.0.23", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.23.tgz", - "integrity": "sha512-9By0jqdscFh5pRFCpBEvoOCOpEOUG9eoSGvyLPnWjiJtfTCSm2OHARX8QcP5vCU65TO59w7JwUcXBTExaRIFXg==", - "license": "MIT", + "version": "16.0.25", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.25.tgz", + "integrity": "sha512-IvRkkrTIxlXbg2dw0RhAUgkb7KSBJCyktK6zJynOORgZ5RXRae19hqKk7yEu2EwJpTstl6m9AzoVf1x4b94x5w==", "dependencies": { - "@umbraco/json-models-builders": "2.0.35", + "@umbraco/json-models-builders": "2.0.36", "node-fetch": "^2.6.7" } }, diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 5998bf61af..78c09e9719 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -20,8 +20,8 @@ "typescript": "^4.8.3" }, "dependencies": { - "@umbraco/json-models-builders": "^2.0.35", - "@umbraco/playwright-testhelpers": "^16.0.23", + "@umbraco/json-models-builders": "^2.0.36", + "@umbraco/playwright-testhelpers": "^16.0.25", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/Webhook.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/Webhook.spec.ts new file mode 100644 index 0000000000..7a42842d4b --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/Webhook.spec.ts @@ -0,0 +1,188 @@ +import {expect} from "@playwright/test"; +import {test} from '@umbraco/playwright-testhelpers'; + +const webhookName = 'Test Webhook'; +let webhookSiteToken = ''; + +test.beforeEach(async ({umbracoUi, umbracoApi}) => { + await umbracoApi.webhook.ensureNameNotExists(webhookName); + await umbracoUi.goToBackOffice(); + webhookSiteToken = await umbracoApi.webhook.generateWebhookSiteToken(); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.webhook.ensureNameNotExists(webhookName); +}); + +test('can create a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const event = 'Content Deleted'; + const webhookSiteUrl = umbracoApi.webhook.webhookSiteUrl + webhookSiteToken; + await umbracoUi.webhook.goToWebhooks(); + + // Act + await umbracoUi.webhook.clickWebhookCreateButton(); + await umbracoUi.webhook.enterWebhookName(webhookName); + await umbracoUi.webhook.enterUrl(webhookSiteUrl); + await umbracoUi.webhook.clickChooseEventButton(); + await umbracoUi.webhook.clickTextButtonWithName(event); + await umbracoUi.webhook.clickSubmitButton(); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeTruthy(); + expect(await umbracoApi.webhook.doesWebhookHaveUrl(webhookName, webhookSiteUrl)).toBeTruthy(); + expect(await umbracoApi.webhook.doesWebhookHaveEvent(webhookName, event)).toBeTruthy(); + await umbracoApi.webhook.isWebhookEnabled(webhookName); +}); + +test('can update webhook name', async ({umbracoApi, umbracoUi}) => { + // Arrange + const updatedName = 'Updated Webhook'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.enterWebhookName(updatedName); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesNameExist(updatedName)).toBeTruthy(); + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeFalsy(); +}); + +test('can delete a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken); + await umbracoUi.webhook.goToWebhooks(); + + // Act + await umbracoUi.webhook.clickDeleteWebhookWithName(webhookName); + await umbracoUi.webhook.clickConfirmToDeleteButton(); + + // Assert + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeFalsy(); +}); + +test('can add content type for a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const contentTypeName = 'Test Document Type For Webhook'; + const documentTypeId = await umbracoApi.documentType.createDefaultDocumentType(contentTypeName); + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickChooseContentTypeButton(); + await umbracoUi.webhook.clickModalMenuItemWithName(contentTypeName); + await umbracoUi.webhook.clickChooseModalButton(); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeTruthy(); + expect(await umbracoApi.webhook.doesWebhookHaveContentTypeId(webhookName, documentTypeId)).toBeTruthy(); + + // Clean + await umbracoApi.documentType.ensureNameNotExists(contentTypeName); +}); + +test('can add header for a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const headerName = 'test-header-name'; + const headerValue = 'test-header-value'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickAddHeadersButton(); + await umbracoUi.webhook.enterHeaderName(headerName); + await umbracoUi.webhook.enterHeaderValue(headerValue); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeTruthy(); + expect(await umbracoApi.webhook.doesWebhookHaveHeader(webhookName, headerName, headerValue)).toBeTruthy(); +}); + +test('can disable a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickEnabledToggleButton(); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesNameExist(webhookName)).toBeTruthy(); + await umbracoApi.webhook.isWebhookEnabled(webhookName, false); +}); + +test('cannot remove all events from a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const event = 'Content Deleted'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickRemoveButtonForName(event); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.content.isErrorNotificationVisible(); +}); + +test('can remove a content type from a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const event = 'Media Saved'; + const mediaTypeName = 'Audio'; + const mediaTypeData = await umbracoApi.mediaType.getByName(mediaTypeName); + await umbracoApi.webhook.createWebhookForSpecificContentType(webhookName, webhookSiteToken, event, mediaTypeName); + expect(await umbracoApi.webhook.doesWebhookHaveContentTypeId(webhookName, mediaTypeData.id)).toBeTruthy(); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickRemoveButtonForName(mediaTypeName); + await umbracoUi.webhook.clickConfirmRemoveButton(); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesWebhookHaveContentTypeId(webhookName, mediaTypeData.id)).toBeFalsy(); +}); + +test('can remove a header from a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const event = 'Content Published'; + const headerName = 'test-header-name'; + const headerValue = 'automation-test'; + await umbracoApi.webhook.createWebhookWithHeader(webhookName, webhookSiteToken, event, headerName, headerValue); + expect(await umbracoApi.webhook.doesWebhookHaveHeader(webhookName, headerName, headerValue)).toBeTruthy(); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickHeaderRemoveButton(); + await umbracoUi.webhook.clickSaveButton(); + + // Assert + await umbracoUi.webhook.isSuccessStateVisibleForSaveButton(); + expect(await umbracoApi.webhook.doesWebhookHaveHeader(webhookName, headerName, headerValue)).toBeFalsy(); +}); + +test('cannot add both content event and media event for a webhook', async ({umbracoApi, umbracoUi}) => { + // Arrange + const event = 'Content Published'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + await umbracoUi.webhook.goToWebhookWithName(webhookName); + + // Act + await umbracoUi.webhook.clickChooseEventButton(); + + // Assert + await umbracoUi.webhook.isModalMenuItemWithNameDisabled('Media Saved'); + await umbracoUi.webhook.isModalMenuItemWithNameDisabled('Media Deleted'); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/WebhookTrigger.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/WebhookTrigger.spec.ts new file mode 100644 index 0000000000..5b9f22d45a --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Webhook/WebhookTrigger.spec.ts @@ -0,0 +1,242 @@ +import {expect} from "@playwright/test"; +import {ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers'; + +// Webhook +const webhookName = 'Test Webhook'; +let webhookSiteToken = ''; + +// Content +const documentName = 'Test Webhook Content'; +const documentTypeName = 'TestDocumentTypeForWebhook'; +let documentTypeId = ''; + +// Media +const mediaName = 'Test Webhook Media'; +const mediaTypeName = 'Image'; + +test.beforeEach(async ({umbracoApi}) => { + await umbracoApi.webhook.ensureNameNotExists(webhookName); + webhookSiteToken = await umbracoApi.webhook.generateWebhookSiteToken(); + documentTypeId = await umbracoApi.documentType.createDefaultDocumentTypeWithAllowAsRoot(documentTypeName); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.webhook.ensureNameNotExists(webhookName); + await umbracoApi.documentType.ensureNameNotExists(documentTypeName); + await umbracoApi.document.ensureNameNotExists(documentName); + await umbracoApi.media.ensureNameNotExists(mediaName); +}); + +test('can trigger when content is published', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Published'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(documentName); + await umbracoUi.content.clickSaveAndPublishButton(); + + // Assert + await umbracoUi.content.isSuccessStateVisibleForSaveAndPublishButton(); + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(documentName); +}); + +test('can trigger when content is deleted', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Deleted'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + const contentId = await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + await umbracoApi.document.moveToRecycleBin(contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickEmptyRecycleBinButton(); + await umbracoUi.content.clickConfirmEmptyRecycleBinButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.emptiedRecycleBin); + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(contentId); +}); + +test('can trigger when content is unpublished', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Unpublished'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + const contentId = await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + await umbracoApi.document.publish(contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuForContent(documentName); + await umbracoUi.content.clickUnpublishActionMenuOption(); + await umbracoUi.content.clickConfirmToUnpublishButton(); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.unpublished); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(contentId); +}); + +test('can trigger when media is saved', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Media Saved'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + const mediaId = await umbracoApi.media.createDefaultMediaWithImage(mediaName); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.media); + + // Act + await umbracoUi.media.goToMediaWithName(mediaName); + await umbracoUi.media.clickSaveButton(); + await umbracoUi.content.isSuccessStateVisibleForSaveButton(); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(mediaName); + expect(webhookSiteData[0].content).toContain(mediaId); +}); + +test('can trigger when media is deleted', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Media Deleted'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event); + const mediaId = await umbracoApi.media.createDefaultMediaWithImage(mediaName); + await umbracoApi.media.trashMediaItem(mediaName); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.media); + + // Act + await umbracoUi.media.isItemVisibleInRecycleBin(mediaName); + await umbracoUi.media.deleteMediaItem(mediaName); + await umbracoUi.media.waitForMediaToBeTrashed(); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(mediaId); +}); + +test('can trigger the webhook for a specific media type', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Media Deleted'; + const secondMediaName = 'Test Second Media'; + await umbracoApi.webhook.createWebhookForSpecificContentType(webhookName, webhookSiteToken, event, mediaTypeName); + const mediaId = await umbracoApi.media.createDefaultMediaWithImage(mediaName); + const secondMediaId = await umbracoApi.media.createDefaultMediaWithArticle(secondMediaName); + await umbracoApi.media.trashMediaItem(mediaName); + await umbracoApi.media.trashMediaItem(secondMediaName); + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.media); + + // Act + await umbracoUi.media.isItemVisibleInRecycleBin(mediaName); + await umbracoUi.media.deleteMediaItem(mediaName); + await umbracoUi.media.deleteMediaItem(secondMediaName); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(mediaId); + expect(webhookSiteData[0].content).not.toContain(secondMediaId); + + // Clean + await umbracoApi.media.ensureNameNotExists(secondMediaName); +}); + +test('can trigger the webhook for a specific content type', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Published'; + const secondDocumentName = 'Second Test Webhook Content'; + const secondDocumentTypeName = 'SecondTestDocumentTypeForWebhook'; + const secondDocumentTypeId = await umbracoApi.documentType.createDefaultDocumentTypeWithAllowAsRoot(secondDocumentTypeName); + await umbracoApi.document.createDefaultDocument(secondDocumentName, secondDocumentTypeId); + await umbracoApi.webhook.createWebhookForSpecificContentType(webhookName, webhookSiteToken, event, documentTypeName); + await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuForContent(documentName); + await umbracoUi.content.clickPublishActionMenuOption(); + await umbracoUi.content.clickConfirmToPublishButton(); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + await umbracoUi.content.clickActionsMenuForContent(secondDocumentName); + await umbracoUi.content.clickPublishActionMenuOption(); + await umbracoUi.content.clickConfirmToPublishButton(); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].content).toContain(documentName); + expect(webhookSiteData[0].content).not.toContain(secondDocumentName); + + // Clean + await umbracoApi.documentType.ensureNameNotExists(secondDocumentTypeName); + await umbracoApi.document.ensureNameNotExists(secondDocumentName); +}); + +test('cannot trigger when the webhook is disabled', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Published'; + await umbracoApi.webhook.createDefaultWebhook(webhookName, webhookSiteToken, event, false); + await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuForContent(documentName); + await umbracoUi.content.clickPublishActionMenuOption(); + await umbracoUi.content.clickConfirmToPublishButton(); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken, 7000); + expect(webhookSiteData).toBeFalsy(); +}); + +test('can custom header for the webhook request', async ({umbracoApi, umbracoUi}) => { + test.slow(); + + // Arrange + const event = 'Content Published'; + const headerName = 'test-header-name'; + const headerValue = 'automation-test'; + await umbracoApi.webhook.createWebhookWithHeader(webhookName, webhookSiteToken, event, headerName, headerValue); + await umbracoApi.document.createDefaultDocument(documentName, documentTypeId); + + await umbracoUi.goToBackOffice(); + await umbracoUi.webhook.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuForContent(documentName); + await umbracoUi.content.clickPublishActionMenuOption(); + await umbracoUi.content.clickConfirmToPublishButton(); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + + // Assert + const webhookSiteData = await umbracoApi.webhook.getWebhookSiteRequestResponse(webhookSiteToken); + expect(webhookSiteData[0].headers[headerName]).toEqual([headerValue]); +}); \ No newline at end of file