diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 4a143b243cc8..3f66cd3ba7f7 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -9,13 +9,13 @@ "testSqlite": "npx playwright test DefaultConfig --grep-invert \"Users\"", "all": "npx playwright test", "createTest": "node createTest.js", - "smokeTest": "npx playwright test DefaultConfig --grep \"@smoke\"", + "smokeTest": "npx playwright test DefaultConfig/Content/ScheduledPublishing --grep \"@smoke\"", "smokeTestSqlite": "npx playwright test DefaultConfig --grep \"@smoke\" --grep-invert \"Users\"" }, "devDependencies": { "@playwright/test": "^1.50", "@types/node": "^20.9.0", - "prompt": "^1.2.0", + "prompt": "^1.2.0", "tslib": "^2.4.0", "typescript": "^4.8.3" }, diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ScheduledPublishing.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ScheduledPublishing.spec.ts new file mode 100644 index 000000000000..b4724de6ac74 --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ScheduledPublishing.spec.ts @@ -0,0 +1,581 @@ +import {ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers'; +import {expect} from "@playwright/test"; + +let dataTypeId = ''; +const contentName = 'TestContent'; +const documentTypeName = 'TestDocumentTypeForContent'; +const childContentName = 'ChildContent'; +const childDocumentTypeName = 'ChildDocumentTypeForContent'; +const dataTypeName = 'Textstring'; +const contentText = 'This is test content text'; +const scheduleWaitTime = 180000; + +test.beforeEach(async ({umbracoApi}) => { + // Need to increase the timeout of the tests due to the time to wait for publishing + test.setTimeout(200000); + const dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); + dataTypeId = dataTypeData.id; + await umbracoApi.document.ensureNameNotExists(contentName); + await umbracoApi.documentType.ensureNameNotExists(documentTypeName); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.document.ensureNameNotExists(contentName); + await umbracoApi.documentType.ensureNameNotExists(documentTypeName); +}); + +test('can schedule the publishing of invariant unpublish content', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + console.log('Published at: ' + publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Unpublished + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + console.log('Current time after waiting: ' + await umbracoApi.getCurrentTimePlusMinute(0)); + //const contentData = await umbracoApi.document.getByName(contentName); + //expect(contentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of invariant published content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + const contentId = await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoApi.document.publish(contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.enterTextstring('Updated text'); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of variant unpublish content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithEnglishCultureAndTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Unpublished + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of variant published content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + const contentId = await umbracoApi.document.createDocumentWithEnglishCultureAndTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoApi.document.publishDocumentWithCulture(contentId, 'en-US'); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.enterTextstring('Updated text'); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of invariant unpublish child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + await umbracoApi.document.createDocumentWithTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Unpublished + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const childContentData = await umbracoApi.document.getByName(childContentName); + expect(childContentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of variant unpublish child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + await umbracoApi.document.createDocumentWithEnglishCultureAndTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Unpublished + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const childContentData = await umbracoApi.document.getByName(childContentName); + expect(childContentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of invariant published child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + const childContentId = await umbracoApi.document.createDocumentWithTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoApi.document.publish(childContentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const childContentData = await umbracoApi.document.getByName(childContentName); + expect(childContentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +test('can schedule the publishing of variant published child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + const childContentId = await umbracoApi.document.createDocumentWithEnglishCultureAndTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoApi.document.publish(childContentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const publishedTime = await umbracoApi.convertDateFormat(publishDateTime); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(publishedTime); + // verify the status of content after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + const childContentData = await umbracoApi.document.getByName(childContentName); + expect(childContentData.variants[0].state).toBe('Published'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Published'); + // verify the value of "Last published" + await umbracoUi.content.doesLastPublishedContainText(publishedTime.substring(0, publishedTime.length - 5)); +}); + +// Remove .fixme when the issue is fixed: https://github.com/umbraco/Umbraco-CMS/issues/18554 +test.fixme('cannot schedule the publishing of child content if parent not published', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + const childContentId = await umbracoApi.document.createDocumentWithTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoApi.document.publish(childContentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const publishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.isErrorNotificationVisible(); +}); + +test('can schedule the publishing of multiple culture variants content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const firstCulture = 'en-US'; + const secondCulture = 'da'; + await umbracoApi.language.createDanishLanguage(); + const documentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithTwoCulturesAndTextContent(contentName, documentTypeId, contentText, dataTypeName, firstCulture, secondCulture); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + await umbracoUi.content.clickSelectAllCheckbox(); + const firstPublishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const firstPublishedTime = await umbracoApi.convertDateFormat(firstPublishDateTime); + await umbracoUi.content.enterPublishTime(firstPublishDateTime); + const secondPublishDateTime = await umbracoApi.getCurrentTimePlusMinute(2); + await umbracoUi.content.enterPublishTime(secondPublishDateTime, 1); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before publishing is Unpublished + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); + // verify the value of "Publish At" + await umbracoUi.content.doesPublishAtContainText(firstPublishedTime); + // verify the status of first culture after the publish time is Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + let contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Published'); + expect(contentData.variants[1].state).toBe('Draft'); +// verify the status of both culture after the second publish time are Published + await umbracoUi.waitForTimeout(scheduleWaitTime); + contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Published'); + expect(contentData.variants[1].state).toBe('Published'); + + // Clean + await umbracoApi.language.ensureIsoCodeNotExists(secondCulture); +}); + +test('publish time cannot be in the past', async ({umbracoApi, umbracoUi}) => { + // Arrange + const warningMessage = 'The release date cannot be in the past'; + const pastDateTime = '2024-03-09T10:00'; + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + await umbracoUi.content.enterPublishTime(pastDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesPublishAtValidationMessageContainText(warningMessage); +}); + +test('unpublish time cannot be in the past', async ({umbracoApi, umbracoUi}) => { + // Arrange + const warningMessage = 'The expire date cannot be in the past'; + const pastDateTime = '2024-03-09T10:00'; + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + await umbracoUi.content.enterUnpublishTime(pastDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesUnpublishAtValidationMessageContainText(warningMessage); +}); + +test('unpublish time cannot be before publish time', async ({umbracoApi, umbracoUi}) => { + // Arrange + const warningMessage = 'The expire date cannot be before the release date'; + const publishDateTime = '2040-03-09T10:00'; + const unpublishDateTime = '2024-03-09T10:00'; + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + await umbracoUi.content.enterPublishTime(publishDateTime); + await umbracoUi.content.enterUnpublishTime(unpublishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesUnpublishAtValidationMessageContainText(warningMessage); +}); + +test('can schedule the unpublishing of invariant published content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + const contentId = await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoApi.document.publish(contentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const unpublishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const unpublishedTime = await umbracoApi.convertDateFormat(unpublishDateTime); + await umbracoUi.content.enterUnpublishTime(unpublishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before unpublishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Remove At" + await umbracoUi.content.doesRemoveAtContainText(unpublishedTime); + // verify the status of content after the unpublish time is Unpublished + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Draft'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); +}); + +test('can schedule the unpublishing of variant published content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const documentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(documentTypeName, dataTypeName, dataTypeId); + const contentId = await umbracoApi.document.createDocumentWithEnglishCultureAndTextContent(contentName, documentTypeId, contentText, dataTypeName); + await umbracoApi.document.publishDocumentWithCulture(contentId, 'en-US'); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + // Change content + await umbracoUi.content.enterTextstring('Updated text'); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const unpublishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const unpublishedTime = await umbracoApi.convertDateFormat(unpublishDateTime); + await umbracoUi.content.enterUnpublishTime(unpublishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before unpublishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Remove At" + await umbracoUi.content.doesRemoveAtContainText(unpublishedTime); + // verify the status of content after the unpublish time is Unpublished + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.variants[0].state).toBe('Draft'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); +}); + +test('can schedule the unpublishing of invariant published child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + const childContentId = await umbracoApi.document.createDocumentWithTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoApi.document.publish(childContentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const unpublishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const unpublishedTime = await umbracoApi.convertDateFormat(unpublishDateTime); + await umbracoUi.content.enterUnpublishTime(unpublishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before unpublishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Remove At" + await umbracoUi.content.doesRemoveAtContainText(unpublishedTime); + // verify the status of content after the unpublish time is Unpublished + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(childContentName); + expect(contentData.variants[0].state).toBe('Draft'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); +}); + +test('can schedule the unpublishing of variant published child content', async ({umbracoApi, umbracoUi}) => { + // Arrange + const childDocumentTypeId = await umbracoApi.documentType.createVariantDocumentTypeWithInvariantPropertyEditor(childDocumentTypeName, dataTypeName, dataTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithAllowedChildNode(documentTypeName, childDocumentTypeId); + const contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoApi.document.publish(contentId); + const childContentId = await umbracoApi.document.createDocumentWithEnglishCultureAndTextContentAndParent(childContentName, childDocumentTypeId, contentText, dataTypeName, contentId); + await umbracoApi.document.publish(childContentId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.goToContentWithName(childContentName); + await umbracoUi.content.clickViewMoreOptionsButton(); + await umbracoUi.content.clickSchedulePublishButton(); + const unpublishDateTime = await umbracoApi.getCurrentTimePlusMinute(); + const unpublishedTime = await umbracoApi.convertDateFormat(unpublishDateTime); + await umbracoUi.content.enterUnpublishTime(unpublishDateTime); + await umbracoUi.content.clickSchedulePublishModalButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.schedulePublishingUpdated); + // verify the status of content before unpublishing is Published (pending changes) + await umbracoUi.content.clickInfoTab(); + await umbracoUi.content.doesDocumentStateHaveText('Published (pending changes)'); + // verify the value of "Remove At" + await umbracoUi.content.doesRemoveAtContainText(unpublishedTime); + // verify the status of content after the unpublish time is Unpublished + await umbracoUi.waitForTimeout(scheduleWaitTime); + const contentData = await umbracoApi.document.getByName(childContentName); + expect(contentData.variants[0].state).toBe('Draft'); + await umbracoUi.reloadPage(); + await umbracoUi.content.doesDocumentStateHaveText('Unpublished'); +}); \ No newline at end of file