testing/web-platform/tests/credential-management/credentialscontainer-create-basics.https.html
author Florian Quèze <florian@queze.net>
Tue, 08 Jul 2025 20:48:53 +0000 (12 hours ago)
changeset 795809 b01190f141a12f4b506acb1f4476561c4b0f2407
parent 761722 e6b8704f42fa4507d592980958b090b0797e1ccb
permissions -rw-r--r--
Bug 1960567 - remove the last C++ and scriptable APIs to accumulate data to legacy telemetry histograms, r=chutten. Differential Revision: https://phabricator.services.mozilla.com/D255582
<!DOCTYPE html>
<title>Credential Management API: create() basics.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
promise_test(function(t) {
    return promise_rejects_dom(t, "NotSupportedError",
            navigator.credentials.create());
}, "navigator.credentials.create() with no argument.");

promise_test(function(t) {
    return promise_rejects_dom(t, "NotSupportedError",
            navigator.credentials.create({}));
}, "navigator.credentials.create() with empty argument.");

promise_test(function(t) {
    var credential_data = {
        id: 'id',
        password: 'pencil',
    };

    return navigator.credentials.create({password: credential_data})
        .then(function(credential) {
            assert_equals(credential.id, 'id');
            assert_equals(credential.name, '');
            assert_equals(credential.iconURL, '');
            assert_equals(credential.type, 'password');
            assert_equals(credential.password, 'pencil');
        });
}, "navigator.credentials.create() with valid PasswordCredentialData");

promise_test(function(t) {
    var f = document.createElement('form');
    f.innerHTML = "<input type='text' name='theId' value='musterman' autocomplete='username'>"
        + "<input type='text' name='thePassword' value='sekrit' autocomplete='current-password'>"
        + "<input type='text' name='theIcon' value='https://example.com/photo' autocomplete='photo'>"
        + "<input type='text' name='theExtraField' value='extra'>"
        + "<input type='text' name='theName' value='friendly name' autocomplete='name'>";

    return navigator.credentials.create({password: f})
        .then(function(credential) {
            assert_equals(credential.id, 'musterman');
            assert_equals(credential.name, 'friendly name');
            assert_equals(credential.iconURL, 'https://example.com/photo');
            assert_equals(credential.type, 'password');
            assert_equals(credential.password, 'sekrit');
        });
}, "navigator.credentials.create() with valid HTMLFormElement");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({password: "bogus password data"}));
}, "navigator.credentials.create() with bogus password data");

promise_test(function(t) {
    var federated_data = {
        id: 'id',
        provider: 'https://example.com/',
    };

    return navigator.credentials.create({federated: federated_data})
        .then(function(credential) {
            assert_equals(credential.id, 'id');
            assert_equals(credential.name, '');
            assert_equals(credential.iconURL, '');
            assert_equals(credential.type, 'federated');
        });
}, "navigator.credentials.create() with valid FederatedCredentialData");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({federated: "bogus federated data"}));
}, "navigator.credentials.create() with bogus federated data");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({publicKey: "bogus publicKey data"}));
}, "navigator.credentials.create() with bogus publicKey data");

promise_test(function(t) {
    var credential_data = {
        id: 'id',
        password: 'pencil',
    };

    var federated_data = {
        id: 'id',
        provider: 'https://example.com/',
    };

    return promise_rejects_dom(t, "NotSupportedError",
            navigator.credentials.create({
                password: credential_data,
                federated: federated_data,
            }));
}, "navigator.credentials.create() with both PasswordCredentialData and FederatedCredentialData");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({
                password: "bogus password data",
                federated: "bogus federated data",
            }));
}, "navigator.credentials.create() with bogus password and federated data");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({
                federated: "bogus federated data",
                publicKey: "bogus publicKey data",
            }));
}, "navigator.credentials.create() with bogus federated and publicKey data");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({
                password: "bogus password data",
                publicKey: "bogus publicKey data",
            }));
}, "navigator.credentials.create() with bogus password and publicKey data");

promise_test(function(t) {
    return promise_rejects_js(t, TypeError,
            navigator.credentials.create({
                password: "bogus password data",
                federated: "bogus federated data",
                publicKey: "bogus publicKey data",
            }));
}, "navigator.credentials.create() with bogus password, federated, and publicKey data");

promise_test(function(t) {
    return promise_rejects_dom(t, "NotSupportedError",
            navigator.credentials.create({bogus_key: "bogus data"}));
}, "navigator.credentials.create() with bogus data");

promise_test(function(t) {
    const controller = new AbortController();
    controller.abort("custom reason");

    return promise_rejects_exactly(t, "custom reason",
        navigator.credentials.create({ signal: controller.signal }));
}, "navigator.credentials.create() aborted with custom reason");

promise_test(async function(t) {
    const reasons = [{}, [], new Error("custom error")];

    for (let reason of reasons) {
        const result = navigator.credentials.create({ signal: AbortSignal.abort(reason) });
        await promise_rejects_exactly(t, reason, result);
  }
}, "navigator.credentials.create() aborted with different objects");

promise_test(function(t) {
    const error = new Error("custom error");
    const controller = new AbortController();

    const result = navigator.credentials.create({ signal: controller.signal });
    controller.abort(error); // aborted after the promise is created

    return promise_rejects_exactly(t, error, result);
}, "navigator.credentials.create() rejects when aborted after the promise creation");
</script>