<!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 onKeyUp() {
document.removeEventListener('keyup', onKeyUp, false);
try {
resolve(functionCalledOnKeyPress());
} catch (e) {
reject(e);
}
}
document.addEventListener('keyup', onKeyUp, false);
eventSender.keyDown('Enter', []);
});
}
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, test_case) {
callWithKeyDown(() => e.prompt().then(t.step_func(function(result) {
assert_equals(result.platform, test_case.platform, 'Resolved platform');
assert_equals(result.outcome, test_case.outcome, 'Outcome');
}), 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,
"Failed to execute 'prompt' on 'BeforeInstallPromptEvent': " +
"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, test_case);
// 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, test_case);
// 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>