diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index 5116f8e67b..09eb8bd02d 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.25", - "@umbraco/playwright-testhelpers": "^15.0.3", + "@umbraco/json-models-builders": "^2.0.26", + "@umbraco/playwright-testhelpers": "^15.0.4", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" @@ -55,20 +55,19 @@ } }, "node_modules/@umbraco/json-models-builders": { - "version": "2.0.25", - "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.25.tgz", - "integrity": "sha512-bFO4AuXUlkyRtBolqOnAvlW12B7Zh/cee3DHShAb+KaXdAC9LzvHYCSH33yJRk2Qc9KvK6ECAMamhiBcT1cMWw==", - "license": "MIT", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.26.tgz", + "integrity": "sha512-fsIcIcLjT52avK9u+sod6UIR2WlyWMJdlXw+OAePsqLwAXiSuXIEFvLmjfTHzmnw+qOtvKe3olML7e6LPnv/hw==", "dependencies": { "camelize": "^1.0.1" } }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.3.tgz", - "integrity": "sha512-gwkUM8ztRHY6PjixfQIthOWIbarItZPKqijLYReO/AaVrdn9XkDNA0LYAlPFDjv/vj4LNOnJ9uA+sEw1ZzJvow==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.4.tgz", + "integrity": "sha512-NT+tGBS19PBbZn/jjdyUKfFLi91hFfy0DrMhvKzb4I8O5D96Pbs1lX4mGlKvfqa2IPisMYCmsKoEKO8VimTvTg==", "dependencies": { - "@umbraco/json-models-builders": "2.0.25", + "@umbraco/json-models-builders": "2.0.26", "node-fetch": "^2.6.7" } }, diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 102e525f1b..a848f29cff 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.25", - "@umbraco/playwright-testhelpers": "^15.0.3", + "@umbraco/json-models-builders": "^2.0.26", + "@umbraco/playwright-testhelpers": "^15.0.4", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/RichTextEditor.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/RichTextEditor.spec.ts index fce5f31444..7d03341929 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/RichTextEditor.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/RichTextEditor.spec.ts @@ -1,235 +1,23 @@ import {test} from '@umbraco/playwright-testhelpers'; import {expect} from "@playwright/test"; -const dataTypeName = 'Richtext editor'; -let dataTypeDefaultData = null; -let dataTypeData = null; - -// Create tests for TinyMCE and TipTap - -test.beforeEach(async ({umbracoUi, umbracoApi}) => { +test('tiptap is the default property editor in rich text editor', async ({umbracoApi, umbracoUi}) => { + // Arrange + const dataTypeName = 'Richtext editor'; + const tipTapPropertyEditorName = 'Rich Text Editor [Tiptap] Property Editor UI'; + const tipTapAlias = 'Umbraco.RichText'; + const tipTapUiAlias = 'Umb.PropertyEditorUi.Tiptap'; await umbracoUi.goToBackOffice(); await umbracoUi.dataType.goToSettingsTreeItem('Data Types'); - dataTypeDefaultData = await umbracoApi.dataType.getByName(dataTypeName); -}); - -test.afterEach(async ({umbracoApi}) => { - if (dataTypeDefaultData !== null) { - await umbracoApi.dataType.update(dataTypeDefaultData.id, dataTypeDefaultData); - } -}); - -test('can enable ignore user start nodes', async ({umbracoApi, umbracoUi}) => { - // Arrange - const expectedDataTypeValues = { - "alias": "ignoreUserStartNodes", - "value": true - }; - await umbracoUi.dataType.goToDataType(dataTypeName); // Act - await umbracoUi.dataType.clickIgnoreUserStartNodesSlider(); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -// TODO: Remove skip when the front-end is ready. Currently it is impossible to uncheck all the toolbar options. -test.skip('can enable all toolbar options', async ({umbracoApi, umbracoUi}) => { - // Arrange - const toolbarValues: string[] = ["undo", "redo", "cut", "copy"]; - const expectedDataTypeValues = [ - { - "alias": "toolbar", - "value": toolbarValues - } - ]; - - // Remove all existing values - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - dataTypeData.values = []; - await umbracoApi.dataType.update(dataTypeData.id, dataTypeData); - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); await umbracoUi.dataType.goToDataType(dataTypeName); - // Act - await umbracoUi.dataType.pickTheToolbarOptionByValue(toolbarValues); - await umbracoUi.dataType.clickSaveButton(); - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toEqual(expectedDataTypeValues); -}); - -// TODO: Remove skip when the front-end is ready -test.skip('can add stylesheet', async ({umbracoApi, umbracoUi}) => { - // Arrange - const stylesheetName = 'StylesheetForDataType.css'; - await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName); - const stylesheetPath = await umbracoApi.stylesheet.createDefaultStylesheet(stylesheetName); - - const expectedDataTypeValues = { - "alias": "stylesheets", - "value": [stylesheetPath] - }; - - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.addStylesheet(stylesheetName); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); - - // Clean - await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName); -}); - -test('can add dimensions', async ({umbracoApi, umbracoUi}) => { - // Arrange - const width = 100; - const height = 10; - const expectedDataTypeValues = { - "alias": "dimensions", - "value": { - "width": width, - "height": height - } - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.enterDimensionsValue(width.toString(), height.toString()); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -test('can add maximum size for inserted images', async ({umbracoApi, umbracoUi}) => { - // Arrange - const maxImageSize = 300; - const expectedDataTypeValues = { - "alias": "maxImageSize", - "value": maxImageSize - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.enterMaximumSizeForImages(maxImageSize.toString()); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -test('can select overlay size', async ({umbracoApi, umbracoUi}) => { - // Arrange - const overlaySizeValue = 'large'; - const expectedDataTypeValues = { - "alias": "overlaySize", - "value": overlaySizeValue - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.chooseOverlaySizeByValue(overlaySizeValue); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -// No hide label for TipTap -test.skip('can enable hide label', async ({umbracoApi, umbracoUi}) => { - // Arrange - const expectedDataTypeValues = { - "alias": "hideLabel", - "value": true - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.clickHideLabelSlider(); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -test('can add image upload folder', async ({umbracoApi, umbracoUi}) => { - // Arrange - const mediaFolderName = 'TestMediaFolder'; - await umbracoApi.media.ensureNameNotExists(mediaFolderName); - const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName); - const expectedDataTypeValues = { - "alias": "mediaParentId", - "value": mediaFolderId - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.addImageUploadFolder(mediaFolderName); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); - - // Clean - await umbracoApi.media.ensureNameNotExists(mediaFolderName); -}); - -// There is no inline editing mode for TipTap -test.skip('can enable inline editing mode', async ({umbracoApi, umbracoUi}) => { - // Arrange - const mode = 'Inline'; - const expectedDataTypeValues = { - "alias": "mode", - "value": mode - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.clickInlineRadioButton(); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); -}); - -test('can add an available block', async ({umbracoApi, umbracoUi}) => { - // Arrange - const elementTypeName = 'TestElementType'; - await umbracoApi.documentType.ensureNameNotExists(elementTypeName); - const elementTypeId = await umbracoApi.documentType.createEmptyElementType(elementTypeName); - const expectedDataTypeValues = { - alias: "blocks", - value: [ - { - contentElementTypeKey: elementTypeId, - } - ] - }; - await umbracoUi.dataType.goToDataType(dataTypeName); - - // Act - await umbracoUi.dataType.addAvailableBlocks(elementTypeName); - await umbracoUi.dataType.clickSaveButton(); - - // Assert - dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); - expect(dataTypeData.values).toContainEqual(expectedDataTypeValues); - - // Clean - await umbracoApi.documentType.delete(elementTypeId); -}); + await umbracoUi.dataType.doesPropertyEditorHaveName(tipTapPropertyEditorName); + await umbracoUi.dataType.doesPropertyEditorHaveSchemaAlias(tipTapAlias); + await umbracoUi.dataType.doesPropertyEditorHaveAlias(tipTapUiAlias); + const dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); + expect(dataTypeData.editorAlias).toBe(tipTapAlias); + expect(dataTypeData.editorUiAlias).toBe(tipTapUiAlias); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/TinyMCE.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/TinyMCE.spec.ts new file mode 100644 index 0000000000..dc2fd0f372 --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/TinyMCE.spec.ts @@ -0,0 +1,288 @@ +import {NotificationConstantHelper, test} from "@umbraco/playwright-testhelpers"; +import {expect} from "@playwright/test"; + +const tinyMCEName = 'TestTinyMCE'; + +test.beforeEach(async ({umbracoUi, umbracoApi}) => { + await umbracoApi.dataType.ensureNameNotExists(tinyMCEName); + await umbracoUi.goToBackOffice(); + await umbracoUi.dataType.goToSettingsTreeItem('Data Types'); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.dataType.ensureNameNotExists(tinyMCEName); +}); + +test('can create a rich text editor with tinyMCE', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const tinyMCELocatorName = 'Rich Text Editor [TinyMCE]'; + const tinyMCEFilterKeyword = 'Rich Text Editor'; + const tinyMCEAlias = 'Umbraco.RichText'; + const tinyMCEUiAlias = 'Umb.PropertyEditorUi.TinyMCE'; + + // Act + await umbracoUi.dataType.clickActionsMenuAtRoot(); + await umbracoUi.dataType.clickCreateButton(); + await umbracoUi.dataType.clickNewDataTypeThreeDotsButton(); + await umbracoUi.dataType.enterDataTypeName(tinyMCEName); + await umbracoUi.dataType.clickSelectAPropertyEditorButton(); + await umbracoUi.dataType.selectAPropertyEditor(tinyMCELocatorName, tinyMCEFilterKeyword); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.created); + expect(await umbracoApi.dataType.doesNameExist(tinyMCEName)).toBeTruthy(); + const dataTypeData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(dataTypeData.editorAlias).toBe(tinyMCEAlias); + expect(dataTypeData.editorUiAlias).toBe(tinyMCEUiAlias); +}); + +test('can rename a rich text editor with tinyMCE', async ({umbracoApi, umbracoUi}) => { + // Arrange + const wrongName = 'tinyMCETest'; + await umbracoApi.dataType.createDefaultTinyMCEDataType(wrongName); + + // Act + await umbracoUi.dataType.goToDataType(wrongName); + await umbracoUi.dataType.enterDataTypeName(tinyMCEName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + expect(await umbracoApi.dataType.doesNameExist(tinyMCEName)).toBeTruthy(); + expect(await umbracoApi.dataType.doesNameExist(wrongName)).toBeFalsy(); +}); + +test('can delete a rich text editor with tinyMCE', async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.clickRootFolderCaretButton(); + await umbracoUi.dataType.clickActionsMenuForDataType(tinyMCEName); + await umbracoUi.dataType.clickDeleteAndConfirmButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.deleted); + expect(await umbracoApi.dataType.doesNameExist(tinyMCEName)).toBeFalsy(); + await umbracoUi.dataType.isTreeItemVisible(tinyMCEName, false); +}); + +test('can enable toolbar options', async ({umbracoApi, umbracoUi}) => { + // Arrange + const toolbarValues = ["undo", "redo", "cut"]; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + const toolbarItemCount = await umbracoApi.dataType.getTinyMCEToolbarItemsCount(tinyMCEName); + + // Act + await umbracoUi.dataType.clickToolbarOptionByValue(toolbarValues); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const expectedToolbarItems = toolbarItemCount + toolbarValues.length; + expect(await umbracoApi.dataType.doesTinyMCEToolbarItemsMatchCount(tinyMCEName, expectedToolbarItems)).toBeTruthy(); + expect(await umbracoApi.dataType.doesTinyMCEToolbarHaveItems(tinyMCEName, toolbarValues)).toBeTruthy(); +}); + +test('can add stylesheet', async ({umbracoApi, umbracoUi}) => { + // Arrange + const stylesheetName = 'StylesheetForDataType.css'; + await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName); + const stylesheetPath = await umbracoApi.stylesheet.createDefaultStylesheet(stylesheetName); + const expectedTinyMCEValues = { + "alias": "stylesheets", + "value": [stylesheetPath] + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.addStylesheet(stylesheetName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); + + // Clean + await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName); +}); + +test('can add dimensions', async ({umbracoApi, umbracoUi}) => { + // Arrange + const width = 100; + const height = 10; + const expectedTinyMCEValues = { + "alias": "dimensions", + "value": { + "width": width, + "height": height + } + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.enterDimensionsValue(width.toString(), height.toString()); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); + +test('can update maximum size for inserted images', async ({umbracoApi, umbracoUi}) => { + // Arrange + const maximumSize = 300; + const expectedTinyMCEValues = { + "alias": "maxImageSize", + "value": maximumSize + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.enterMaximumSizeForImages(maximumSize.toString()); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); + +test('can enable inline editing mode', async ({umbracoApi, umbracoUi}) => { + // Arrange + const mode = 'Inline'; + const expectedTinyMCEValues = { + "alias": "mode", + "value": mode + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.clickInlineRadioButton(); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); + +test('can add an available block', async ({umbracoApi, umbracoUi}) => { + // Arrange + const elementTypeName = 'TestElementType'; + await umbracoApi.documentType.ensureNameNotExists(elementTypeName); + const elementTypeId = await umbracoApi.documentType.createEmptyElementType(elementTypeName); + const expectedTinyMCEValues = { + alias: "blocks", + value: [ + { + contentElementTypeKey: elementTypeId, + } + ] + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.addAvailableBlocks(elementTypeName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); + + // Clean + await umbracoApi.documentType.ensureNameNotExists(elementTypeName); +}); + +test('can select overlay size', async ({umbracoApi, umbracoUi}) => { + // Arrange + const overlaySizeValue = 'large'; + const expectedTinyMCEValues = { + "alias": "overlaySize", + "value": overlaySizeValue + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.chooseOverlaySizeByValue(overlaySizeValue); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); + +test('can enable hide label', async ({umbracoApi, umbracoUi}) => { + // Arrange + const expectedTinyMCEValues = { + "alias": "hideLabel", + "value": true + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.clickHideLabelSlider(); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); + +test('can add image upload folder', async ({umbracoApi, umbracoUi}) => { + // Arrange + const mediaFolderName = 'TestMediaFolder'; + await umbracoApi.media.ensureNameNotExists(mediaFolderName); + const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName); + const expectedTinyMCEValues = { + "alias": "mediaParentId", + "value": mediaFolderId + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.addImageUploadFolder(mediaFolderName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); + + // Clean + await umbracoApi.media.ensureNameNotExists(mediaFolderName); +}); + +test('can enable ignore user start nodes', async ({umbracoApi, umbracoUi}) => { + // Arrange + const expectedTinyMCEValues = { + "alias": "ignoreUserStartNodes", + "value": true + }; + await umbracoApi.dataType.createDefaultTinyMCEDataType(tinyMCEName); + await umbracoUi.dataType.goToDataType(tinyMCEName); + + // Act + await umbracoUi.dataType.clickIgnoreUserStartNodesSlider(); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tinyMCEData = await umbracoApi.dataType.getByName(tinyMCEName); + expect(tinyMCEData.values).toContainEqual(expectedTinyMCEValues); +}); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Tiptap.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Tiptap.spec.ts new file mode 100644 index 0000000000..a00c1a67fb --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/Tiptap.spec.ts @@ -0,0 +1,267 @@ +import {NotificationConstantHelper, test} from "@umbraco/playwright-testhelpers"; +import {expect} from "@playwright/test"; + +const tipTapName = 'TestTiptap'; + +test.beforeEach(async ({umbracoUi, umbracoApi}) => { + await umbracoApi.dataType.ensureNameNotExists(tipTapName); + await umbracoUi.goToBackOffice(); + await umbracoUi.dataType.goToSettingsTreeItem('Data Types'); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.dataType.ensureNameNotExists(tipTapName); +}); + +test('can create a rich text editor with tiptap', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const tipTapLocatorName = 'Rich Text Editor [Tiptap]'; + const tipTapAlias = 'Umbraco.RichText'; + const tipTapUiAlias = 'Umb.PropertyEditorUi.Tiptap'; + + // Act + await umbracoUi.dataType.clickActionsMenuAtRoot(); + await umbracoUi.dataType.clickCreateButton(); + await umbracoUi.dataType.clickNewDataTypeThreeDotsButton(); + await umbracoUi.dataType.enterDataTypeName(tipTapName); + await umbracoUi.dataType.clickSelectAPropertyEditorButton(); + await umbracoUi.dataType.selectAPropertyEditor(tipTapLocatorName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.created); + expect(await umbracoApi.dataType.doesNameExist(tipTapName)).toBeTruthy(); + const dataTypeData = await umbracoApi.dataType.getByName(tipTapName); + expect(dataTypeData.editorAlias).toBe(tipTapAlias); + expect(dataTypeData.editorUiAlias).toBe(tipTapUiAlias); +}); + +test('can rename a rich text editor with tiptap', async ({umbracoApi, umbracoUi}) => { + // Arrange + const wrongName = 'TiptapTest'; + await umbracoApi.dataType.createDefaultTiptapDataType(wrongName); + + // Act + await umbracoUi.dataType.goToDataType(wrongName); + await umbracoUi.dataType.enterDataTypeName(tipTapName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + expect(await umbracoApi.dataType.doesNameExist(tipTapName)).toBeTruthy(); + expect(await umbracoApi.dataType.doesNameExist(wrongName)).toBeFalsy(); +}); + +test('can delete a rich text editor with tiptap', async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + + // Act + await umbracoUi.dataType.clickRootFolderCaretButton(); + await umbracoUi.dataType.clickActionsMenuForDataType(tipTapName); + await umbracoUi.dataType.clickDeleteAndConfirmButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.deleted); + expect(await umbracoApi.dataType.doesNameExist(tipTapName)).toBeFalsy(); + await umbracoUi.dataType.isTreeItemVisible(tipTapName, false); +}); + +test('can add dimensions', async ({umbracoApi, umbracoUi}) => { + // Arrange + const width = 100; + const height = 10; + const expectedTiptapValues = { + "alias": "dimensions", + "value": { + "width": width, + "height": height + } + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.enterDimensionsValue(width.toString(), height.toString()); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); +}); + +test('can update maximum size for inserted images', async ({umbracoApi, umbracoUi}) => { + // Arrange + const maximumSize = 300; + const expectedTiptapValues = { + "alias": "maxImageSize", + "value": maximumSize + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.enterMaximumSizeForImages(maximumSize.toString()); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); +}); + +test('can select overlay size', async ({umbracoApi, umbracoUi}) => { + // Arrange + const overlaySizeValue = 'large'; + const expectedTiptapValues = { + "alias": "overlaySize", + "value": overlaySizeValue + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.chooseOverlaySizeByValue(overlaySizeValue); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); +}); + +test('can add an available block', async ({umbracoApi, umbracoUi}) => { + // Arrange + const elementTypeName = 'TestElementType'; + await umbracoApi.documentType.ensureNameNotExists(elementTypeName); + const elementTypeId = await umbracoApi.documentType.createEmptyElementType(elementTypeName); + const expectedTiptapValues = { + alias: "blocks", + value: [ + { + contentElementTypeKey: elementTypeId, + } + ] + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.addAvailableBlocks(elementTypeName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); + + // Clean + await umbracoApi.documentType.ensureNameNotExists(elementTypeName); +}); + +test('can add image upload folder', async ({umbracoApi, umbracoUi}) => { + // Arrange + const mediaFolderName = 'TestMediaFolder'; + await umbracoApi.media.ensureNameNotExists(mediaFolderName); + const mediaFolderId = await umbracoApi.media.createDefaultMediaFolder(mediaFolderName); + const expectedTiptapValues = { + "alias": "mediaParentId", + "value": mediaFolderId + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.addImageUploadFolder(mediaFolderName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); + + // Clean + await umbracoApi.media.ensureNameNotExists(mediaFolderName); +}); + +test('can enable ignore user start nodes', async ({umbracoApi, umbracoUi}) => { + // Arrange + const expectedTiptapValues = { + "alias": "ignoreUserStartNodes", + "value": true + }; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + + // Act + await umbracoUi.dataType.clickIgnoreUserStartNodesSlider(); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tiptapData = await umbracoApi.dataType.getByName(tipTapName); + expect(tiptapData.values).toContainEqual(expectedTiptapValues); +}); + +test('can delete toolbar group', async ({umbracoApi, umbracoUi}) => { + // Arrange + const deletedGroupIndex = 2; + const rowIndex = 0; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + const groupCount = await umbracoApi.dataType.getTiptapToolbarGroupInRowCount(tipTapName, rowIndex); + const groupValue = await umbracoApi.dataType.getTiptapToolbarGroupValueInRow(tipTapName, deletedGroupIndex, rowIndex); + + // Act + await umbracoUi.dataType.deleteToolbarGroup(deletedGroupIndex, rowIndex); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tipTapData = await umbracoApi.dataType.getByName(tipTapName); + const toolbarValue = tipTapData.values.find(value => value.alias === 'toolbar'); + expect(toolbarValue.value[rowIndex].length).toBe(groupCount - 1); + expect(toolbarValue.value[rowIndex]).not.toContain(groupValue); +}); + +test('can delete toolbar row', async ({umbracoApi, umbracoUi}) => { + // Arrange + const deletedRowIndex = 1; + await umbracoApi.dataType.createTiptapDataTypeWithTwoToolbarRows(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + const rowCount = await umbracoApi.dataType.getTiptapToolbarRowCount(tipTapName); + + // Act + await umbracoUi.dataType.deleteToolbarRow(deletedRowIndex); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tipTapData = await umbracoApi.dataType.getByName(tipTapName); + const toolbarValue = tipTapData.values.find(value => value.alias === 'toolbar'); + if (rowCount - 1 === 0) { + expect(toolbarValue).toBeFalsy(); + } else { + expect(toolbarValue.value.length).toBe(rowCount - 1); + } +}); + +test('can disable extensions item', async ({umbracoApi, umbracoUi}) => { + // Arrange + const extensionItemName = 'Text Align'; + await umbracoApi.dataType.createDefaultTiptapDataType(tipTapName); + await umbracoUi.dataType.goToDataType(tipTapName); + const extensionsCount = await umbracoApi.dataType.getTiptapExtensionsCount(tipTapName); + + // Act + await umbracoUi.dataType.clickExtensionItemWithName(extensionItemName); + await umbracoUi.dataType.clickSaveButton(); + + // Assert + await umbracoUi.dataType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + const tipTapData = await umbracoApi.dataType.getByName(tipTapName); + const extensionsValue = tipTapData.values.find(value => value.alias === 'extensions'); + expect(extensionsValue.value.length).toBe(extensionsCount - 1); + expect(extensionsValue.value).not.toContain(extensionItemName); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithRichTextEditor.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithTinyMCERichTextEditor.spec.ts similarity index 95% rename from tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithRichTextEditor.spec.ts rename to tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithTinyMCERichTextEditor.spec.ts index df9655388a..dfabaf39ef 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithRichTextEditor.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentWithTinyMCERichTextEditor.spec.ts @@ -15,7 +15,7 @@ test.beforeEach(async ({umbracoApi}) => { await umbracoApi.user.ensureNameNotExists(testUser.name); await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName); const stylesheetPath = await umbracoApi.stylesheet.createStylesheetWithHeaderContent(stylesheetName); - const dataTypeId = await umbracoApi.dataType.createRichTextEditorDataTypeWithStylesheet(richTextEditorName, stylesheetPath); + const dataTypeId = await umbracoApi.dataType.createTinyMCEDataTypeWithStylesheet(richTextEditorName, stylesheetPath); await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, richTextEditorName, dataTypeId); const userGroup = await umbracoApi.userGroup.getByName('Editors'); userGroupId = userGroup.id;