diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-requestclose.tentative.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-requestclose.tentative.html index ed52f78a8872..eb2270b861c7 100644 --- a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-requestclose.tentative.html +++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-requestclose.tentative.html @@ -41,31 +41,132 @@ assert_false(dialog.open,'Without user activation, requestClose can\'t be cancelled'); },`requestClose requires user activation in order to be cancelable`); +async function setup(t,closedby) { + t.add_cleanup(() => { + dialog.close(); + dialog.removeAttribute('closedby'); + dialog.returnValue = ''; + }); + assert_false(dialog.hasAttribute('closedby')); + if (closedby) { + dialog.setAttribute('closedby',closedby); + } + // Be sure any pending close events get fired. + await new Promise(resolve => requestAnimationFrame(resolve)); + return getSignal(t); +} + [false,true].forEach(modal => { - promise_test(async (t) => { - t.add_cleanup(() => dialog.close()); - openDialog(modal); - dialog.requestClose(); - assert_false(dialog.open); - },`${modal ? "Modal:" : "Non-modal:"} requestClose closes the dialog`); + [null,'any','closedrequest','none'].forEach(closedby => { + const testDescription = `for ${modal ? "modal" : "modeless"} dialog with closedby=${closedby}`; + promise_test(async (t) => { + await setup(t,closedby); + openDialog(modal); + if (dialog.closedBy != "none") { + dialog.requestClose(); + assert_false(dialog.open); + } else { + assert_throws_dom('InvalidStateError',() => dialog.requestClose()); + assert_true(dialog.open); + } + },`requestClose basic behavior ${testDescription}`); + + promise_test(async (t) => { + const signal = await setup(t,closedby); + let events = []; + dialog.addEventListener('cancel',() => events.push('cancel'),{signal}); + dialog.addEventListener('close',() => events.push('close'),{signal}); + openDialog(modal); + assert_array_equals(events,[]); + if (dialog.closedBy != "none") { + dialog.requestClose(); + assert_false(dialog.open); + assert_array_equals(events,['cancel'],'close is scheduled'); + await new Promise(resolve => requestAnimationFrame(resolve)); + assert_array_equals(events,['cancel','close']); + } else { + assert_throws_dom('InvalidStateError',() => dialog.requestClose()); + } + },`requestClose fires both cancel and close ${testDescription}`); - promise_test(async (t) => { - t.add_cleanup(() => dialog.close()); - const signal = getSignal(t); - let shouldPreventDefault = true; - dialog.addEventListener('cancel',(e) => { - if (shouldPreventDefault) { - e.preventDefault(); + promise_test(async (t) => { + const signal = await setup(t,'none'); + let events = []; + dialog.addEventListener('cancel',() => events.push('cancel'),{signal}); + dialog.addEventListener('close',() => events.push('close'),{signal}); + openDialog(modal); + dialog.setAttribute('closedby',closedby); + assert_array_equals(events,[]); + if (dialog.closedBy != "none") { + dialog.requestClose(); + assert_false(dialog.open); + } else { + assert_throws_dom('InvalidStateError',() => dialog.requestClose()); } - },{signal}); - openDialog(modal); - await clickOn(dialog); // User activation - dialog.requestClose(); - assert_true(dialog.open,'cancel event was cancelled - dialog shouldn\'t close'); - shouldPreventDefault = false; - await clickOn(dialog); // User activation - dialog.requestClose(); - assert_false(dialog.open,'cancel event was not cancelled - dialog should now close'); - },`${modal ? "Modal:" : "Non-modal:"} requestClose can be cancelled`); + },`changing closedby from 'none' to '${closedby}' for ${modal ? "modal" : "modeless"} dialog`); + + promise_test(async (t) => { + const signal = await setup(t,closedby); + let events = []; + dialog.addEventListener('cancel',() => events.push('cancel'),{signal}); + dialog.addEventListener('close',() => events.push('close'),{signal}); + openDialog(modal); + dialog.removeAttribute('closedby'); + assert_array_equals(events,[]); + if (dialog.closedBy != "none") { + dialog.requestClose(); + assert_false(dialog.open); + } else { + assert_throws_dom('InvalidStateError',() => dialog.requestClose()); + } + },`Removing closedby when closedby='${closedby}' for ${modal ? "modal" : "modeless"} dialog`); + + if (dialog.closedBy != "none") { + promise_test(async (t) => { + const signal = await setup(t,closedby); + let shouldPreventDefault = true; + dialog.addEventListener('cancel',(e) => { + if (shouldPreventDefault) { + e.preventDefault(); + } + },{signal}); + openDialog(modal); + await clickOn(dialog); // User activation + dialog.requestClose(); + assert_true(dialog.open,'cancel event was cancelled - dialog shouldn\'t close'); + shouldPreventDefault = false; + await clickOn(dialog); // User activation + dialog.requestClose(); + assert_false(dialog.open,'cancel event was not cancelled - dialog should now close'); + },`requestClose can be cancelled ${testDescription}`); + + promise_test(async (t) => { + await setup(t,closedby); + openDialog(modal); + assert_equals(dialog.returnValue,'','Return value starts out empty'); + const returnValue = 'The return value'; + dialog.requestClose(returnValue); + assert_false(dialog.open); + assert_equals(dialog.returnValue,returnValue,'Return value should be set'); + dialog.show(); + dialog.close(); + assert_equals(dialog.returnValue,returnValue,'Return value should not be changed by close()'); + dialog.show(); + dialog.close('another'); + assert_equals(dialog.returnValue,'another','Return value changes via close(value)'); + },`requestClose(returnValue) passes along the return value ${testDescription}`); + + promise_test(async (t) => { + await setup(t,closedby); + dialog.addEventListener('cancel',(e) => e.preventDefault(),{once:true}); + openDialog(modal); + dialog.returnValue = 'foo'; + assert_equals(dialog.returnValue,'foo'); + dialog.requestClose('This should not get saved'); + assert_true(dialog.open,'cancelled'); + assert_equals(dialog.returnValue,'foo','Return value should not be changed'); + },`requestClose(returnValue) doesn't change returnvalue when cancelled ${testDescription}`); + } + }); });