| <!DOCTYPE html> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script> |
| |
| // Copied from resources/bluetooth/bluetooth-helpers.js. |
| function callWithKeyDown(functionCalledOnKeyPress) { |
| return new Promise((resolve, reject) => { |
| function onKeyPress() { |
| document.removeEventListener('keypress', onKeyPress, false); |
| try { |
| resolve(functionCalledOnKeyPress()); |
| } catch (e) { |
| reject(e); |
| } |
| } |
| document.addEventListener('keypress', onKeyPress, false); |
| |
| eventSender.keyDown(' ', []); |
| }); |
| } |
| |
| var prompt_test_cases = [ |
| { |
| name: 'prompt-accept-access-userchoice-first', |
| cancel: true, |
| late: false, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: true |
| }, { |
| name: 'prompt-accept-no-access-userchoice-first', |
| cancel: true, |
| late: false, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: false |
| }, { |
| name: 'prompt-dismiss-access-userchoice-first', |
| cancel: true, |
| late: false, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: true |
| }, { |
| name: 'prompt-dismiss-no-access-userchoice-first', |
| cancel: true, |
| late: false, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: false |
| }, { |
| name: 'prompt-before-preventDefault-access-userchoice-first', |
| cancel: false, |
| late: false, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: true |
| }, { |
| name: 'prompt-before-preventDefault-no-access-userchoice-first', |
| cancel: false, |
| late: false, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: false |
| }, { |
| name: 'prompt-late-accept-access-userchoice-first', |
| cancel: true, |
| late: true, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: false |
| }, { |
| name: 'prompt-late-accept-no-access-userchoice-first', |
| cancel: true, |
| late: true, |
| platform: 'foo', |
| outcome: 'accepted', |
| userChoice: false |
| }, { |
| name: 'prompt-late-dismiss-access-userchoice-first', |
| cancel: true, |
| late: true, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: true |
| }, { |
| name: 'prompt-late-dismiss-no-access-userchoice-first', |
| cancel: true, |
| late: true, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: false |
| }, { |
| name: 'prompt-late-without-preventDefault-access-userchoice-first', |
| cancel: false, |
| late: true, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: true |
| }, { |
| name: 'prompt-late-without-preventDefault-no-access-userchoice-first', |
| cancel: false, |
| late: true, |
| platform: '', |
| outcome: 'dismissed', |
| userChoice: false |
| } |
| ]; |
| |
| function verify_prompt_resolve(e, t) { |
| callWithKeyDown(() => e.prompt().then( |
| function() { }, t.unreached_func("prompt() promise should resolve."))); |
| } |
| |
| function verify_prompt_reject(e, t) { |
| e.prompt().then(t.unreached_func("prompt() promise should reject."), |
| t.step_func(function(error) { |
| assert_true( |
| error instanceof DOMException, |
| "Rejected promise should throw a DOMException." |
| ); |
| assert_equals( |
| error.message, |
| "The prompt() method must be called with a user gesture", |
| "Rejected promise does not provide expected message." |
| ); |
| }) |
| ); |
| } |
| |
| function verify_userChoice(e, t, test_case, index) { |
| e.userChoice.then(t.step_func(function(result) { |
| assert_equals(result.platform, test_case.platform, 'Resolved platform'); |
| assert_equals(result.outcome, test_case.outcome, 'Outcome'); |
| })).then(t.step_func(function() { |
| prompt_test(index + 1); |
| t.done(); |
| }), t.unreached_func("userChoice promise should resolve.")); |
| } |
| |
| function prompt_test(index) { |
| if (index >= prompt_test_cases.length) |
| return; |
| |
| var test_case = prompt_test_cases[index]; |
| async_test(function(t) { |
| var event = null; |
| var event_handler = t.step_func(function(e) { |
| // Remove the event handler to prevent it being used in subsequent |
| // invocations of prompt_test(). Save event object for call outside handler. |
| window.removeEventListener('beforeinstallprompt', event_handler); |
| event = e; |
| |
| assert_equals(e.platforms.length, 2, 'Number of platforms'); |
| assert_equals(e.platforms[0], 'foo', 'First platform'); |
| assert_equals(e.platforms[1], 'bar', 'Second platform'); |
| |
| if (test_case.userChoice) { |
| // Access userChoice to ensure it is independent of prompt. |
| e.userChoice; |
| } |
| |
| if (test_case.cancel) { |
| e.preventDefault(); |
| } |
| |
| if (test_case.late) { |
| window.setTimeout(function() { |
| assert_false(event == null, "event is null outside handler"); |
| |
| // Test that firing prompt() outside of the handler resolves or rejects correctly. |
| verify_prompt_resolve(event, t); |
| // Check userChoice and call the next test. |
| verify_userChoice(event, t, test_case, index); |
| }, 0); |
| return; |
| } |
| |
| // Ensure prompt rejects without a user gesture. |
| verify_prompt_reject(e, t); |
| |
| // Call prompt() to restart the pipeline. |
| verify_prompt_resolve(e, t); |
| |
| // prompt() has been fired, so check the userChoice promise and call the next test. |
| verify_userChoice(e, t, test_case, index); |
| }); |
| window.addEventListener('beforeinstallprompt', event_handler); |
| |
| testRunner.dispatchBeforeInstallPromptEvent(['foo', 'bar'], t.step_func(function(result) { |
| testRunner.resolveBeforeInstallPromptPromise(test_case.platform); |
| })); |
| }, test_case.name); |
| } |
| |
| prompt_test(0); |
| </script> |