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