613 lines
17 KiB
JavaScript
613 lines
17 KiB
JavaScript
/* 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, {
|
|
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
|
|
});
|
|
|
|
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);
|
|
});
|