@@ -11,6 +11,7 @@ import {
11
11
activatePlugin ,
12
12
deactivatePlugin ,
13
13
deleteAllTemplates ,
14
+ setBrowserViewport ,
14
15
} from '@wordpress/e2e-test-utils' ;
15
16
16
17
const openSidebarPanelWithTitle = async ( title ) => {
@@ -56,7 +57,7 @@ const switchToTemplateMode = async () => {
56
57
57
58
// Check that we switched properly to edit mode.
58
59
await page . waitForXPath (
59
- '//*[contains(@class, "components-snackbar")]/*[ text()="Editing template. Changes made here affect all posts and pages that use the template."]'
60
+ '//*[text()="Editing template. Changes made here affect all posts and pages that use the template."]'
60
61
) ;
61
62
const title = await page . $eval (
62
63
'.edit-post-template-top-area' ,
@@ -119,7 +120,6 @@ describe( 'Post Editor Template mode', () => {
119
120
// there's a template resolution bug forcing us to do so.
120
121
await saveDraft ( ) ;
121
122
await page . reload ( ) ;
122
-
123
123
await switchToTemplateMode ( ) ;
124
124
125
125
// Edit the template
@@ -197,3 +197,180 @@ describe( 'Post Editor Template mode', () => {
197
197
expect ( content ) . toMatchSnapshot ( ) ;
198
198
} ) ;
199
199
} ) ;
200
+
201
+ describe ( 'Delete Post Template Confirmation Dialog' , ( ) => {
202
+ beforeAll ( async ( ) => {
203
+ await activatePlugin ( 'gutenberg-test-block-templates' ) ;
204
+ await deleteAllTemplates ( 'wp_template' ) ;
205
+ await deleteAllTemplates ( 'wp_template_part' ) ;
206
+ await activateTheme ( 'twentytwentyone' ) ;
207
+ await createNewPost ( ) ;
208
+ // Create a random post.
209
+ await page . type ( '.editor-post-title__input' , 'Just an FSE Post' ) ;
210
+ await page . keyboard . press ( 'Enter' ) ;
211
+ await page . keyboard . type ( 'Hello World' ) ;
212
+
213
+ // Save the post
214
+ // Saving shouldn't be necessary but unfortunately,
215
+ // there's a template resolution bug forcing us to do so.
216
+ await saveDraft ( ) ;
217
+ await page . reload ( ) ;
218
+ // Unselect the blocks.
219
+ await page . evaluate ( ( ) => {
220
+ wp . data . dispatch ( 'core/block-editor' ) . clearSelectedBlock ( ) ;
221
+ } ) ;
222
+ } ) ;
223
+
224
+ afterAll ( async ( ) => {
225
+ await activateTheme ( 'twentytwentyone' ) ;
226
+ await deactivatePlugin ( 'gutenberg-test-block-templates' ) ;
227
+ } ) ;
228
+
229
+ [ 'large' , 'small' ] . forEach ( ( viewport ) => {
230
+ it ( `should retain template if deletion is canceled when the viewport is ${ viewport } ` , async ( ) => {
231
+ await setBrowserViewport ( viewport ) ;
232
+
233
+ const isWelcomeGuideActive = await page . evaluate ( ( ) =>
234
+ wp . data
235
+ . select ( 'core/edit-post' )
236
+ . isFeatureActive ( 'welcomeGuide' )
237
+ ) ;
238
+ if ( isWelcomeGuideActive === true ) {
239
+ await page . evaluate ( ( ) =>
240
+ wp . data
241
+ . dispatch ( 'core/edit-post' )
242
+ . toggleFeature ( 'welcomeGuide' )
243
+ ) ;
244
+ await page . reload ( ) ;
245
+ await page . waitForSelector ( '.edit-post-layout' ) ;
246
+ }
247
+ if ( viewport === 'small' ) {
248
+ await page . waitForXPath ( '//button[@aria-label="Settings"]' ) ;
249
+ await openDocumentSettingsSidebar ( ) ;
250
+ }
251
+ const templateTitle = `${ viewport } Viewport Deletion Test` ;
252
+
253
+ await createNewTemplate ( templateTitle ) ;
254
+ // Edit the template
255
+ if ( viewport === 'small' ) {
256
+ await page . waitForXPath ( `//h2[text()="${ templateTitle } "]` ) ;
257
+ const closeDocumentSettingsButton = await page . waitForXPath (
258
+ '//button[@aria-label="Close settings"]'
259
+ ) ;
260
+ await closeDocumentSettingsButton . click ( ) ;
261
+ }
262
+ await insertBlock ( 'Paragraph' ) ;
263
+ await page . keyboard . type (
264
+ 'Just a random paragraph added to the template'
265
+ ) ;
266
+
267
+ // Save changes
268
+ const publishButton = await page . waitForXPath (
269
+ `//button[contains(text(), 'Publish')]`
270
+ ) ;
271
+ await publishButton . click ( ) ;
272
+ const saveButton = await page . waitForXPath (
273
+ `//div[contains(@class, "entities-saved-states__panel-header")]/button[contains(text(), 'Save')]`
274
+ ) ;
275
+ await saveButton . click ( ) ;
276
+ // Avoid publishing the post
277
+ // Select the cancel button via parent div's class, because the text `Cancel` is used on another button as well
278
+ const cancelButton = await page . waitForXPath (
279
+ `//div[contains(@class,"editor-post-publish-panel__header-cancel-button")]/button[not(@disabled)]`
280
+ ) ;
281
+ await cancelButton . click ( ) ;
282
+
283
+ const templateDropdown = await page . waitForXPath (
284
+ `//button[contains(text(), '${ templateTitle } ')]`
285
+ ) ;
286
+ await templateDropdown . click ( ) ;
287
+ const deleteTemplateButton = await page . waitForXPath (
288
+ '//button[@role="menuitem"][@aria-label="Delete template"]'
289
+ ) ;
290
+ await deleteTemplateButton . click ( ) ;
291
+
292
+ await page . waitForXPath (
293
+ `//*[text()="Are you sure you want to delete the ${ templateTitle } template? It may be used by other pages or posts."]`
294
+ ) ;
295
+ const dialogCancelButton = await page . waitForXPath (
296
+ '//*[@role="dialog"][not(@id="wp-link-wrap")]//button[text()="Cancel"]'
297
+ ) ;
298
+ await dialogCancelButton . click ( ) ;
299
+
300
+ const exitTemplateModeButton = await page . waitForXPath (
301
+ '//button[text()="Back"]'
302
+ ) ;
303
+ await exitTemplateModeButton . click ( ) ;
304
+
305
+ await page . waitForXPath (
306
+ '//button[@aria-label="Settings"][@aria-expanded="false"]'
307
+ ) ;
308
+ await openDocumentSettingsSidebar ( ) ;
309
+
310
+ const element = await page . waitForXPath (
311
+ '//h2/button[contains(text(), "Template")]/../..//select'
312
+ ) ;
313
+ const value = await element . getProperty ( 'value' ) ;
314
+ const currentTemplateSlug = await value . jsonValue ( ) ;
315
+
316
+ expect ( currentTemplateSlug ) . toBe (
317
+ `wp-custom-template-${ viewport } -viewport-deletion-test`
318
+ ) ;
319
+ } ) ;
320
+
321
+ it ( `should delete template if deletion is confirmed when the viewport is ${ viewport } ` , async ( ) => {
322
+ const templateTitle = `${ viewport } Viewport Deletion Test` ;
323
+
324
+ await setBrowserViewport ( viewport ) ;
325
+
326
+ await switchToTemplateMode ( ) ;
327
+ if ( viewport === 'small' ) {
328
+ const closeDocumentSettingsButton = await page . waitForXPath (
329
+ '//div[contains(@class,"interface-complementary-area-header__small")]/button[@aria-label="Close settings"]'
330
+ ) ;
331
+ await closeDocumentSettingsButton . click ( ) ;
332
+ }
333
+
334
+ const templateDropdown = await page . waitForXPath (
335
+ `//button[contains(text(), '${ templateTitle } ')]`
336
+ ) ;
337
+ await templateDropdown . click ( ) ;
338
+
339
+ const deleteTemplateButton = await page . waitForXPath (
340
+ '//button[@role="menuitem"][@aria-label="Delete template"]'
341
+ ) ;
342
+ await deleteTemplateButton . click ( ) ;
343
+
344
+ await page . waitForXPath (
345
+ `//*[text()="Are you sure you want to delete the ${ templateTitle } template? It may be used by other pages or posts."]`
346
+ ) ;
347
+ const dialogConfirmButton = await page . waitForXPath (
348
+ '//*[@role="dialog"][not(@id="wp-link-wrap")]//button[text()="OK"]'
349
+ ) ;
350
+
351
+ await dialogConfirmButton . click ( ) ;
352
+
353
+ // Saving isn't technically necessary, but for themes without any specified templates,
354
+ // the removal of the Templates dropdown is delayed. A save and reload allows for this
355
+ // delay and prevents flakiness
356
+ await saveDraft ( ) ;
357
+ await page . reload ( ) ;
358
+
359
+ const optionElementHandlers = await page . $x (
360
+ '//h2/button[contains(text(), "Template")]/../..//select/option'
361
+ ) ;
362
+ const availableTemplates = [ ] ;
363
+ for ( const elem of optionElementHandlers ) {
364
+ const elemName = await elem . getProperty ( 'textContent' ) ;
365
+ const templateName = await elemName . jsonValue ( ) ;
366
+ availableTemplates . push ( templateName ) ;
367
+ }
368
+
369
+ expect (
370
+ availableTemplates . includes (
371
+ `${ viewport } Viewport Deletion Test`
372
+ )
373
+ ) . toBe ( false ) ;
374
+ } ) ;
375
+ } ) ;
376
+ } ) ;
0 commit comments