diff --git a/src/js/_enqueues/wp/dashboard.js b/src/js/_enqueues/wp/dashboard.js index 5216611d5dc3c..aea2dc4c5da25 100644 --- a/src/js/_enqueues/wp/dashboard.js +++ b/src/js/_enqueues/wp/dashboard.js @@ -137,14 +137,33 @@ jQuery( function($) { * @return {void} */ window.quickPressLoad = function() { - var act = $('#quickpost-action'), t; + var act = $( '#quickpost-action' ), t = $( '#quick-press' ), titleInput, contentInput; // Enable the submit buttons. $( '#quick-press .submit input[type="submit"], #quick-press .submit input[type="reset"]' ).prop( 'disabled' , false ); - t = $('#quick-press').on( 'submit', function( e ) { + titleInput = t.find( '#title' ); + contentInput = t.find( '#content' ); + + function validateAtLeastOne() { + var isFilled = titleInput.val().trim() || contentInput.val().trim(), + message = isFilled ? '' : wp.i18n.__( 'Please provide at least the title or the content.' ); + titleInput[0].setCustomValidity( message ); + contentInput[0].setCustomValidity( message ); + } + + t.on( 'input', validateAtLeastOne ); + + t.on( 'submit', function( e ) { e.preventDefault(); + // Don't submit if both the title and content are empty. + validateAtLeastOne(); + if ( ! e.target.checkValidity() ) { + e.target.reportValidity(); + return; + } + // Show a spinner. $('#dashboard_quick_press #publishing-action .spinner').show(); @@ -180,7 +199,7 @@ jQuery( function($) { // Change the QuickPost action to the publish value. $('#publish').on( 'click', function() { act.val( 'post-quickpress-publish' ); } ); - $('#quick-press').on( 'click focusin', function() { + t.on( 'click focusin', function() { wpActiveEditor = 'content'; }); diff --git a/tests/e2e/specs/dashboard.test.js b/tests/e2e/specs/dashboard.test.js index 90459ac83ae6f..45de845533e78 100644 --- a/tests/e2e/specs/dashboard.test.js +++ b/tests/e2e/specs/dashboard.test.js @@ -45,19 +45,25 @@ test.describe( 'Quick Draft', () => { ).toContainText( 'Test Draft Title' ); } ); - test( 'Allows draft to be created without Title or Content', async ( { + test( 'Allows draft to be created with Content but without Title', async ( { admin, page } ) => { await admin.visitAdminPage( '/' ); - // Wait for Save Draft button to appear and click it - const saveDraftButton = page.locator( + // Wait for Quick Draft content field to appear. + const draftContentField = page.locator( '#quick-press' - ).getByRole( 'button', { name: 'Save Draft' } ); + ).getByRole( 'textbox', { name: 'Content' } ); - await expect( saveDraftButton ).toBeVisible(); - await saveDraftButton.click(); + await expect( draftContentField ).toBeVisible(); + + // Focus and fill in a title. + await draftContentField.fill( 'Test Draft Content' ); + + // Navigate to Save Draft button and press it. + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Enter' ); // Check that new draft appears in Your Recent Drafts section await expect( @@ -71,4 +77,38 @@ test.describe( 'Quick Draft', () => { page.locator( '.type-post.status-draft .title' ).first() ).toContainText( 'Untitled' ); } ); + + test( 'Allows draft to be created with Title but without Content', async ( { + admin, + page + } ) => { + await admin.visitAdminPage( '/' ); + + // Wait for Quick Draft title field to appear. + const draftTitleField = page.locator( + '#quick-press' + ).getByRole( 'textbox', { name: 'Title' } ); + + await expect( draftTitleField ).toBeVisible(); + + // Focus and fill in a title. + await draftTitleField.fill( 'Test Draft Title' ); + + // Navigate to Save Draft button and press it. + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Enter' ); + + // Check that new draft appears in Your Recent Drafts section + await expect( + page.locator( '.drafts .draft-title' ).first().getByRole( 'link' ) + ).toHaveText( 'Test Draft Title' ); + + // Check that new draft appears in Posts page + await admin.visitAdminPage( '/edit.php' ); + + await expect( + page.locator( '.type-post.status-draft .title' ).first() + ).toContainText( 'Test Draft Title' ); + } ); } );