220 lines
7.5 KiB
HTML
220 lines
7.5 KiB
HTML
<!DOCTYPE html>
|
|
<title>Digital Credential API tests for create.</title>
|
|
<link rel="help" href="https://wicg.github.io/digital-credentials/" />
|
|
<script src="/common/get-host-info.sub.js"></script>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/testdriver.js"></script>
|
|
<script src="/resources/testdriver-vendor.js"></script>
|
|
|
|
<body>
|
|
<iframe id="same-origin"></iframe>
|
|
<iframe id="cross-origin"></iframe>
|
|
</body>
|
|
|
|
<script type="module">
|
|
import { makeCreateOptions, sendMessage, loadIframe } from "./support/helper.js";
|
|
|
|
const iframeSameOrigin = document.querySelector("iframe#same-origin");
|
|
const iframeCrossOrigin = document.querySelector("iframe#cross-origin");
|
|
const mediations = ["silent", "optional", "conditional", "required"];
|
|
|
|
promise_setup(async () => {
|
|
const hostInfo = get_host_info();
|
|
await Promise.all([
|
|
loadIframe(
|
|
iframeCrossOrigin,
|
|
`${hostInfo.HTTPS_REMOTE_ORIGIN}/digital-credentials/support/iframe.html`
|
|
),
|
|
loadIframe(iframeSameOrigin, "/digital-credentials/support/iframe.html"),
|
|
]);
|
|
});
|
|
|
|
promise_test(async (t) => {
|
|
iframeSameOrigin.focus();
|
|
for (const global of [window, iframeSameOrigin.contentWindow]) {
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create()
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({})
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({ x: "y" })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({ x: "y", y: "z" })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({ mediation: "required" })
|
|
);
|
|
|
|
const abortController = new AbortController();
|
|
const { signal } = abortController;
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({ signal })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.create({ signal, mediation: "required" })
|
|
);
|
|
}
|
|
}, "Calling navigator.credentials.create() without a digital member same origin.");
|
|
|
|
promise_test(async (t) => {
|
|
for (const request of [undefined, []]) {
|
|
const options = makeCreateOptions(request);
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_js(t, TypeError, navigator.credentials.create(options));
|
|
}
|
|
}, "navigator.credentials.create() API rejects if there are no credential request.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeSameOrigin.focus();
|
|
const { contentWindow: iframeWindow } = iframeSameOrigin;
|
|
for (const request of [undefined, []]) {
|
|
const options = makeCreateOptions(request);
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_js(
|
|
t,
|
|
iframeWindow.TypeError,
|
|
iframeWindow.navigator.credentials.create(options)
|
|
);
|
|
}
|
|
}, "navigator.credentials.create() API rejects if there are no credential request for same-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeCrossOrigin.focus();
|
|
for (const request of [undefined, []]) {
|
|
const options = makeCreateOptions(request);
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
action: "create",
|
|
options,
|
|
});
|
|
assert_equals(result.constructor, "TypeError");
|
|
}
|
|
}, "navigator.credentials.create() API rejects if there are no credential request in cross-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
const abortController = new AbortController();
|
|
const { signal } = abortController;
|
|
abortController.abort();
|
|
for (const options of [{ signal }, { signal, ...makeCreateOptions([]) }]) {
|
|
await promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
navigator.credentials.create(options)
|
|
);
|
|
}
|
|
}, "navigator.credentials.create() promise is rejected if called with an aborted controller.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeSameOrigin.focus();
|
|
const { contentWindow: iframeWindow } = iframeSameOrigin;
|
|
const abortController = new iframeWindow.AbortController();
|
|
const { signal } = abortController;
|
|
abortController.abort();
|
|
for (const options of [{ signal }, { signal, ...makeCreateOptions([]) }]) {
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
iframeWindow.DOMException,
|
|
iframeWindow.navigator.credentials.create(options)
|
|
);
|
|
assert_true(
|
|
navigator.userActivation.isActive,
|
|
"User activation is still active."
|
|
);
|
|
}
|
|
}, "navigator.credentials.create() promise is rejected if called with an aborted controller in same-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeCrossOrigin.focus();
|
|
for (const options of [undefined, {}, makeCreateOptions([])]) {
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
abort: "before",
|
|
action: "create",
|
|
options,
|
|
});
|
|
assert_equals(result.constructor, "DOMException");
|
|
assert_equals(result.name, "AbortError");
|
|
}
|
|
}, "navigator.credentials.create() promise is rejected if called with an aborted signal in cross-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
const abortController = new AbortController();
|
|
const { signal } = abortController;
|
|
const options = makeCreateOptions("openid4vci");
|
|
options.signal = signal;
|
|
await test_driver.bless("user activation");
|
|
const promise = promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
DOMException,
|
|
navigator.credentials.create(options)
|
|
);
|
|
abortController.abort();
|
|
await promise;
|
|
}, "navigator.credentials.create() promise is rejected if abort controller is aborted after call to create().");
|
|
|
|
promise_test(async (t) => {
|
|
iframeCrossOrigin.focus();
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
abort: "after",
|
|
action: "create",
|
|
needsActivation: true,
|
|
options: makeCreateOptions("openid4vci"),
|
|
});
|
|
assert_equals(result.constructor, "DOMException");
|
|
assert_equals(result.name, "AbortError");
|
|
}, "navigator.credentials.create() promise is rejected if abort controller is aborted after call to create() in cross-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
const abortController = new AbortController();
|
|
const { signal } = abortController;
|
|
abortController.abort();
|
|
for (const mediation of mediations) {
|
|
const requestPromise = navigator.credentials.create({
|
|
mediation,
|
|
signal,
|
|
});
|
|
await promise_rejects_dom(t, "AbortError", requestPromise);
|
|
}
|
|
}, "Adding mediations together with abort signal respects the abort signal.");
|
|
|
|
promise_test(async (t) => {
|
|
/** @type sequence<CredentialMediationRequirement> */
|
|
const disallowedMediations = [ "conditional", "optional", "silent"];
|
|
for (const mediation of disallowedMediations) {
|
|
const options = makeCreateOptions("default", mediation);
|
|
await promise_rejects_js(t, TypeError, navigator.credentials.create(options));
|
|
}
|
|
}, "Mediation is required to create a DigitalCredential.");
|
|
</script>
|