234 lines
7.5 KiB
HTML
234 lines
7.5 KiB
HTML
<!DOCTYPE html>
|
|
<title>Digital Credential tests.</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" allow="digital-credentials-get"></iframe>
|
|
</body>
|
|
<script type="module">
|
|
import { makeGetOptions, sendMessage, loadIframe } from "./support/helper.js";
|
|
|
|
const iframeSameOrigin = document.querySelector("iframe#same-origin");
|
|
const iframeCrossOrigin = document.querySelector("iframe#cross-origin");
|
|
|
|
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) => {
|
|
const invalidData = [null, undefined, "", 123, true, false];
|
|
for (const data of invalidData) {
|
|
const options = {
|
|
digital: {
|
|
requests: [
|
|
{
|
|
data,
|
|
protocol: "openid4vp",
|
|
},
|
|
],
|
|
},
|
|
};
|
|
await promise_rejects_js(
|
|
t,
|
|
TypeError,
|
|
navigator.credentials.get(options)
|
|
);
|
|
}
|
|
}, "Type conversion happens on the data member of the DigitalCredentialGetRequest object.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeSameOrigin.focus();
|
|
for (const global of [window, iframeSameOrigin.contentWindow]) {
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get()
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({})
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({ x: "y" })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({ x: "y", y: "z" })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({ mediation: "required" })
|
|
);
|
|
|
|
const abortController = new AbortController();
|
|
const { signal } = abortController;
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({ signal })
|
|
);
|
|
|
|
await promise_rejects_dom(
|
|
t,
|
|
"NotSupportedError",
|
|
global.DOMException,
|
|
global.navigator.credentials.get({ signal, mediation: "required" })
|
|
);
|
|
}
|
|
}, "Calling navigator.credentials.get() without a digital member same origin.");
|
|
|
|
promise_test(async (t) => {
|
|
for (const request of [undefined, []]) {
|
|
const options = makeGetOptions(request);
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_js(
|
|
t,
|
|
TypeError,
|
|
navigator.credentials.get(options)
|
|
);
|
|
}
|
|
}, "navigator.credentials.get() 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 = makeGetOptions(request);
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_js(
|
|
t,
|
|
iframeWindow.TypeError,
|
|
iframeWindow.navigator.credentials.get(options)
|
|
);
|
|
}
|
|
}, "navigator.credentials.get() 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 = makeGetOptions(request);
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
action: "get",
|
|
options,
|
|
});
|
|
assert_equals(result.constructor, "TypeError");
|
|
}
|
|
}, "navigator.credentials.get() 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, ...makeGetOptions([]) }]) {
|
|
await promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
navigator.credentials.get(options)
|
|
);
|
|
}
|
|
}, "navigator.credentials.get() 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, ...makeGetOptions([]) }]) {
|
|
await test_driver.bless("user activation");
|
|
await promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
iframeWindow.DOMException,
|
|
iframeWindow.navigator.credentials.get(options)
|
|
);
|
|
assert_true(
|
|
navigator.userActivation.isActive,
|
|
"User activation is still active."
|
|
);
|
|
}
|
|
}, "navigator.credentials.get() promise is rejected if called with an aborted controller in same-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
iframeCrossOrigin.focus();
|
|
for (const options of [undefined, {}, makeGetOptions([])]) {
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
abort: "before",
|
|
action: "get",
|
|
options,
|
|
});
|
|
assert_equals(result.constructor, "DOMException");
|
|
assert_equals(result.name, "AbortError");
|
|
}
|
|
}, "navigator.credentials.get() 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 = makeGetOptions("openid4vp");
|
|
options.signal = signal;
|
|
await test_driver.bless("user activation");
|
|
const promise = promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
DOMException,
|
|
navigator.credentials.get(options)
|
|
);
|
|
abortController.abort();
|
|
await promise;
|
|
}, "navigator.credentials.get() promise is rejected if abort controller is aborted after call to get().");
|
|
|
|
promise_test(async (t) => {
|
|
iframeCrossOrigin.focus();
|
|
const result = await sendMessage(iframeCrossOrigin, {
|
|
abort: "after",
|
|
action: "get",
|
|
needsActivation: true,
|
|
options: makeGetOptions("openid4vp"),
|
|
});
|
|
assert_equals(result.constructor, "DOMException");
|
|
assert_equals(result.name, "AbortError");
|
|
}, "navigator.credentials.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe.");
|
|
|
|
promise_test(async (t) => {
|
|
/** @type sequence<CredentialMediationRequirement> */
|
|
const disallowedMediations = ["conditional", "optional", "silent"];
|
|
for (const mediation of disallowedMediations) {
|
|
const options = makeGetOptions("default", mediation);
|
|
await promise_rejects_js(
|
|
t,
|
|
TypeError,
|
|
navigator.credentials.get(options)
|
|
);
|
|
}
|
|
}, "Mediation is required to get a DigitalCredential.");
|
|
</script>
|