Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
XPCOMUtils.defineLazyServiceGetter(
this,
"CredentialChooserService",
"@mozilla.org/browser/credentialchooserservice;1",
"nsICredentialChooserService"
);
ChromeUtils.defineESModuleGetters(this, {
});
const TEST_URL = "https://www.example.com/";
const TEST_URL_2 = "https://example.com/";
const TEST_CREDENTIAL_URL = "https://www.example.net/";
const TEST_IMAGE_DATA =
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgICAgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiB2aWV3Qm94PSIwIDAgMzIgMzIiPgogIDxjaXJjbGUgZmlsbD0iY29udGV4dC1maWxsIiBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiLz4KPC9zdmc+";
// A single credential shows up in a dialog and is chosen when "continue" is clicked
add_task(async function test_single_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = { id: "foo", type: "identity", origin: TEST_CREDENTIAL_URL };
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
is(inputs.length, 1, "One account expected");
let label = inputs[0].getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes("www.example.net"),
"Label includes the credential's origin without UI hints"
);
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
let icon = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item-icon")[0];
is(
icon.src,
"chrome://global/skin/icons/defaultFavicon.svg",
"The icon matches the default favicon."
);
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, "foo", "must have the correct credential chosen");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// A null id is selected when "cancel" is clicked
add_task(async function test_dialog_cancel() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = { id: "foo", type: "identity", origin: TEST_CREDENTIAL_URL };
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-secondary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, null, "Cancel should give a null choice");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// Dismissing the prompt resolves the callback with null
add_task(async function test_dialog_dismiss() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = { id: "foo", type: "identity", origin: TEST_CREDENTIAL_URL };
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Press escape
EventUtils.synthesizeKey("KEY_Escape");
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, null, "Escape should give a null choice");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// Three credentials are in the dialog and are rendered and interact correctly
add_task(async function test_three_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credentials = [
{ id: "foo", type: "identity", origin: "https://www.example.net/" },
{ id: "bar", type: "identity", origin: "https://example.net/" },
{ id: "baz", type: "identity", origin: "https://example.com/" },
];
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
credentials,
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
is(inputs.length, 3, "Three accounts expected");
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
const LABELS = ["www.example.net", "example.net", "example.com"];
for (let index = 0; index < inputs.length; index++) {
let input = inputs[index];
let label = input.getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes(LABELS[index]),
"Label includes the credential's origin without UI hints"
);
let radio = input.getElementsByClassName(
"identity-credential-list-item-radio"
)[0];
is(radio.checked, index == 0, "Initial radio state correct");
EventUtils.synthesizeMouseAtCenter(input, {});
ok(radio.checked, "Radio state selected after click");
}
// Click ok.
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(
choice,
"baz",
"must have the correct credential chosen (the last of the list)"
);
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// A credential shows up with UI hints when they never expire
add_task(async function test_uihint_nonexpiring_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = {
id: "foo",
type: "identity",
origin: TEST_CREDENTIAL_URL,
uiHints: {
iconURL: TEST_IMAGE_DATA,
name: "user readable",
},
};
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
is(inputs.length, 1, "One account expected");
let label = inputs[0].getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes("www.example.net"),
"Label still includes the credential's origin with UI hints"
);
ok(
label.textContent.includes("user readable"),
"Label includes the credential's name with UI hints"
);
let icon = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item-icon")[0];
is(icon.src, TEST_IMAGE_DATA, "The icon matches the custom.svg");
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, "foo", "must have the correct credential chosen");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// A credential shows up with UI hints when they expire in the future
add_task(async function test_uihint_nonexpiring_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = {
id: "foo",
type: "identity",
origin: TEST_CREDENTIAL_URL,
uiHints: {
iconURL: TEST_IMAGE_DATA,
name: "user readable",
expiresAfter: 1000,
},
};
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
is(inputs.length, 1, "One account expected");
let label = inputs[0].getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes("www.example.net"),
"Label still includes the credential's origin with UI hints"
);
ok(
label.textContent.includes("user readable"),
"Label includes the credential's name with UI hints"
);
let icon = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item-icon")[0];
is(icon.src, TEST_IMAGE_DATA, "The icon matches the custom.svg");
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, "foo", "must have the correct credential chosen");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// A credential shows up with UI hints when they never expire
add_task(async function test_uihint_not_yet_expiring_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = {
id: "foo",
type: "identity",
origin: TEST_CREDENTIAL_URL,
uiHints: {
iconURL: TEST_IMAGE_DATA,
name: "user readable",
},
};
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
is(inputs.length, 1, "One account expected");
let label = inputs[0].getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes("www.example.net"),
"Label still includes the credential's origin with UI hints"
);
ok(
label.textContent.includes("user readable"),
"Label includes the credential's name with UI hints"
);
let icon = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item-icon")[0];
is(icon.src, TEST_IMAGE_DATA, "The icon matches the custom.svg");
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, "foo", "must have the correct credential chosen");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// A credential shows up without UI hints when they are expired
add_task(async function test_uihint_expired_credential_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let popupShown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
// Construct our credential to choose from
let credential = {
id: "foo",
type: "identity",
origin: TEST_CREDENTIAL_URL,
uiHints: {
iconURL: TEST_IMAGE_DATA,
name: "user readable",
expiresAfter: 0,
},
};
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(
tab.linkedBrowser.browsingContext,
[credential],
{
notify: resolve,
}
);
});
// Wait for the popup to appear
await popupShown;
let popupHiding = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popuphiding"
);
// Validate the popup contents
let inputs = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item");
let title = document.getElementById("credential-chooser-header-text");
ok(
title.textContent.includes("www.example.com"),
"Popup title includes the visited hostname"
);
is(inputs.length, 1, "One account expected");
let label = inputs[0].getElementsByClassName(
"identity-credential-list-item-label-stack"
)[0];
ok(
label.textContent.includes("www.example.net"),
"Label still includes the credential's origin"
);
ok(
!label.textContent.includes("user readable"),
"Label does not include the credential's name without UI hints"
);
let icon = document
.getElementById("credential-chooser-entry")
.getElementsByClassName("identity-credential-list-item-icon")[0];
Assert.notEqual(icon.src, TEST_IMAGE_DATA, "We don't use the hint icon");
// Click
EventUtils.synthesizeMouseAtCenter(
document.getElementsByClassName("popup-notification-primary-button")[0],
{}
);
// Wait for the pop to go away
await popupHiding;
let choice = await credentialChoice;
is(choice, "foo", "must have the correct credential chosen");
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});
// Inactive documents should not have a popup.
add_task(async function test_inavtive_document_doesnt_show_dialog() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let oldBC = tab.linkedBrowser.browsingContext;
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, TEST_URL_2);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, TEST_URL_2);
// Construct our credential to choose from
let credential = { id: "foo", type: "identity", origin: TEST_CREDENTIAL_URL };
// Show the single account
let credentialChoice = new Promise(resolve => {
CredentialChooserService.showCredentialChooser(oldBC, [credential], {
notify: resolve,
});
});
let choice = await credentialChoice;
is(
choice,
null,
"An inactive should give a null choice without showing a popup"
);
// Clear the tab
await BrowserTestUtils.removeTab(tab);
});