1+ import { ConstantHelper , NotificationConstantHelper , test } from '@umbraco/playwright-testhelpers' ;
2+ import { expect } from "@playwright/test" ;
3+
4+ const contentName = 'TestContent' ;
5+ const documentTypeName = 'TestDocumentTypeForContent' ;
6+ const customDataTypeName = 'Test RTE Tiptap' ;
7+
8+ test . beforeEach ( async ( { umbracoApi} ) => {
9+ await umbracoApi . documentType . ensureNameNotExists ( documentTypeName ) ;
10+ await umbracoApi . document . ensureNameNotExists ( contentName ) ;
11+ } ) ;
12+
13+ test . afterEach ( async ( { umbracoApi} ) => {
14+ await umbracoApi . document . ensureNameNotExists ( contentName ) ;
15+ await umbracoApi . documentType . ensureNameNotExists ( documentTypeName ) ;
16+ await umbracoApi . dataType . ensureNameNotExists ( customDataTypeName ) ;
17+ } ) ;
18+
19+ test ( 'can add a media in RTE Tiptap property editor' , async ( { umbracoApi, umbracoUi} ) => {
20+ // Arrange
21+ const iconTitle = 'Media Picker' ;
22+ const imageName = 'Test Image For Content' ;
23+ await umbracoApi . media . ensureNameNotExists ( imageName ) ;
24+ await umbracoApi . media . createDefaultMediaWithImage ( imageName ) ;
25+ const customDataTypeId = await umbracoApi . dataType . createDefaultTiptapDataType ( customDataTypeName ) ;
26+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
27+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
28+ await umbracoUi . goToBackOffice ( ) ;
29+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
30+
31+ // Act
32+ await umbracoUi . content . goToContentWithName ( contentName ) ;
33+ await umbracoUi . content . clickTipTapToolbarIconWithTitle ( iconTitle ) ;
34+ await umbracoUi . content . selectMediaWithName ( imageName ) ;
35+ await umbracoUi . content . clickChooseModalButton ( ) ;
36+ await umbracoUi . content . clickMediaCaptionAltTextModalSubmitButton ( ) ;
37+ await umbracoUi . content . clickSaveAndPublishButton ( ) ;
38+
39+ // Assert
40+ await umbracoUi . content . doesSuccessNotificationHaveText ( NotificationConstantHelper . success . saved ) ;
41+ await umbracoUi . content . doesSuccessNotificationHaveText ( NotificationConstantHelper . success . published ) ;
42+ expect ( await umbracoApi . document . doesNameExist ( contentName ) ) . toBeTruthy ( ) ;
43+ const contentData = await umbracoApi . document . getByName ( contentName ) ;
44+ expect ( contentData . values [ 0 ] . value . markup ) . toContain ( '<img' ) ;
45+ expect ( contentData . values [ 0 ] . value . markup ) . toContain ( imageName ) ;
46+
47+ // Clean
48+ await umbracoApi . media . ensureNameNotExists ( imageName ) ;
49+ } ) ;
50+
51+ test ( 'can embed a video into RTE Tiptap property editor' , async ( { umbracoApi, umbracoUi} ) => {
52+ // Arrange
53+ const iconTitle = 'Embed' ;
54+ const videoURL = 'https://www.youtube.com/watch?v=Yu29dE-0OoI' ;
55+ const customDataTypeId = await umbracoApi . dataType . createDefaultTiptapDataType ( customDataTypeName ) ;
56+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
57+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
58+ await umbracoUi . goToBackOffice ( ) ;
59+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
60+
61+ // Act
62+ await umbracoUi . content . goToContentWithName ( contentName ) ;
63+ await umbracoUi . content . clickTipTapToolbarIconWithTitle ( iconTitle ) ;
64+ await umbracoUi . content . enterEmbeddedURL ( videoURL ) ;
65+ await umbracoUi . content . clickEmbeddedRetrieveButton ( ) ;
66+ await umbracoUi . content . waitForEmbeddedPreviewVisible ( ) ;
67+ await umbracoUi . content . clickEmbeddedMediaModalConfirmButton ( ) ;
68+ await umbracoUi . content . clickSaveButton ( ) ;
69+
70+ // Assert
71+ await umbracoUi . content . doesSuccessNotificationHaveText ( NotificationConstantHelper . success . saved ) ;
72+ expect ( await umbracoApi . document . doesNameExist ( contentName ) ) . toBeTruthy ( ) ;
73+ const contentData = await umbracoApi . document . getByName ( contentName ) ;
74+ expect ( contentData . values [ 0 ] . value . markup ) . toContain ( 'data-embed-url' ) ;
75+ expect ( contentData . values [ 0 ] . value . markup ) . toContain ( videoURL ) ;
76+ } ) ;
77+
78+ test ( 'cannot submit an empty link in RTE Tiptap property editor' , async ( { umbracoApi, umbracoUi} ) => {
79+ // Arrange
80+ const iconTitle = 'Link' ;
81+ const customDataTypeId = await umbracoApi . dataType . createDefaultTiptapDataType ( customDataTypeName ) ;
82+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
83+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
84+ await umbracoUi . goToBackOffice ( ) ;
85+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
86+
87+ // Act
88+ await umbracoUi . content . goToContentWithName ( contentName ) ;
89+ await umbracoUi . content . clickTipTapToolbarIconWithTitle ( iconTitle ) ;
90+ await umbracoUi . content . clickManualLinkButton ( ) ;
91+ await umbracoUi . content . enterLink ( '' ) ;
92+ await umbracoUi . content . enterAnchorOrQuerystring ( '' ) ;
93+ await umbracoUi . content . enterLinkTitle ( '' ) ;
94+ await umbracoUi . content . clickAddButton ( ) ;
95+
96+ // Assert
97+ await umbracoUi . content . isTextWithMessageVisible ( ConstantHelper . validationMessages . emptyLinkPicker ) ;
98+ } ) ;
99+
100+ // TODO: Remove skip when the front-end ready. Currently it still accept the empty link with an anchor or querystring
101+ // Issue link: https://github.com/umbraco/Umbraco-CMS/issues/17411
102+ test . skip ( 'cannot submit an empty URL with an anchor or querystring in RTE Tiptap property editor' , async ( { umbracoApi, umbracoUi} ) => {
103+ // Arrange
104+ const iconTitle = 'Link' ;
105+ const customDataTypeId = await umbracoApi . dataType . createDefaultTiptapDataType ( customDataTypeName ) ;
106+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
107+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
108+ await umbracoUi . goToBackOffice ( ) ;
109+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
110+
111+ // Act
112+ await umbracoUi . content . goToContentWithName ( contentName ) ;
113+ await umbracoUi . content . clickTipTapToolbarIconWithTitle ( iconTitle ) ;
114+ await umbracoUi . content . clickManualLinkButton ( ) ;
115+ await umbracoUi . content . enterLink ( '' ) ;
116+ await umbracoUi . content . enterAnchorOrQuerystring ( '#value' ) ;
117+ await umbracoUi . content . clickAddButton ( ) ;
118+
119+ // Assert
120+ await umbracoUi . content . isTextWithMessageVisible ( ConstantHelper . validationMessages . emptyLinkPicker ) ;
121+ } ) ;
122+
123+ // TODO: Remove skip when the front-end ready. Currently it is impossible to link to unpublished document
124+ // Issue link: https://github.com/umbraco/Umbraco-CMS/issues/17974
125+ test . skip ( 'can insert a link to an unpublished document in RTE Tiptap property editor' , async ( { umbracoApi, umbracoUi} ) => {
126+ // Arrange
127+ const iconTitle = 'Link' ;
128+ const customDataTypeId = await umbracoApi . dataType . createDefaultTiptapDataType ( customDataTypeName ) ;
129+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
130+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
131+ // Create a document to link
132+ const documentTypeForLinkedDocumentName = 'TestDocumentType' ;
133+ const documentTypeForLinkedDocumentId = await umbracoApi . documentType . createDefaultDocumentTypeWithAllowAsRoot ( documentTypeForLinkedDocumentName ) ;
134+ const linkedDocumentName = 'LinkedDocument' ;
135+ await umbracoApi . document . createDefaultDocument ( linkedDocumentName , documentTypeForLinkedDocumentId ) ;
136+ await umbracoUi . goToBackOffice ( ) ;
137+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
138+
139+ // Act
140+ await umbracoUi . content . goToContentWithName ( contentName ) ;
141+ await umbracoUi . content . clickTipTapToolbarIconWithTitle ( iconTitle ) ;
142+ await umbracoUi . content . clickDocumentLinkButton ( ) ;
143+ await umbracoUi . content . selectLinkByName ( linkedDocumentName ) ;
144+ await umbracoUi . content . clickButtonWithName ( 'Choose' ) ;
145+ await umbracoUi . content . clickAddButton ( ) ;
146+ await umbracoUi . content . clickSaveButton ( ) ;
147+
148+ // Assert
149+ await umbracoUi . content . isSuccessNotificationVisible ( ) ;
150+
151+ // Clean
152+ await umbracoApi . documentType . ensureNameNotExists ( documentTypeForLinkedDocumentName ) ;
153+ await umbracoApi . document . ensureNameNotExists ( linkedDocumentName ) ;
154+ } ) ;
155+
156+ test ( 'can view word count' , async ( { umbracoApi, umbracoUi} ) => {
157+ // Arrange
158+ const inputText = 'Test Tiptap <b>here</b>!!!' ;
159+ const expectedWordCount = 3 ;
160+ const customDataTypeId = await umbracoApi . dataType . createTiptapDataTypeWithWordCountStatusbar ( customDataTypeName ) ;
161+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
162+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
163+ await umbracoUi . goToBackOffice ( ) ;
164+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
165+
166+ // Act
167+ await umbracoUi . content . goToContentWithName ( contentName ) ;
168+ await umbracoUi . content . enterRTETipTapEditor ( inputText ) ;
169+
170+ // Assert
171+ await umbracoUi . content . doesTiptapHaveWordCount ( expectedWordCount ) ;
172+ } ) ;
173+
174+ test ( 'can view element path' , async ( { umbracoApi, umbracoUi} ) => {
175+ // Arrange
176+ const inputText = 'This is Tiptap test' ;
177+ const expectedElementPath = 'p' ;
178+ const customDataTypeId = await umbracoApi . dataType . createTiptapDataTypeWithElementPathStatusbar ( customDataTypeName ) ;
179+ const documentTypeId = await umbracoApi . documentType . createDocumentTypeWithPropertyEditor ( documentTypeName , customDataTypeName , customDataTypeId ) ;
180+ await umbracoApi . document . createDefaultDocument ( contentName , documentTypeId ) ;
181+ await umbracoUi . goToBackOffice ( ) ;
182+ await umbracoUi . content . goToSection ( ConstantHelper . sections . content ) ;
183+
184+ // Act
185+ await umbracoUi . content . goToContentWithName ( contentName ) ;
186+ await umbracoUi . content . enterRTETipTapEditor ( inputText ) ;
187+
188+ // Assert
189+ await umbracoUi . content . doesElementPathHaveText ( expectedElementPath ) ;
190+ } ) ;
0 commit comments