Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

ChromeUtils.defineESModuleGetters(this, {
});
let testURL =
"uriloader/exthandler/tests/mochitest/protocolHandler.html";
add_task(async function () {
await SpecialPowers.pushPrefEnv({
set: [["security.external_protocol_requires_permission", false]],
});
// Load a page registering a protocol handler.
let browser = gBrowser.selectedBrowser;
BrowserTestUtils.startLoadingURIString(browser, testURL);
await BrowserTestUtils.browserLoaded(browser, false, testURL);
// Register the protocol handler by clicking the notificationbar button.
let notificationValue = "Protocol Registration: web+testprotocol";
let getNotification = () =>
gBrowser.getNotificationBox().getNotificationWithValue(notificationValue);
await BrowserTestUtils.waitForCondition(getNotification);
let notification = getNotification();
let button = notification.buttonContainer.querySelector("button");
ok(button, "got registration button");
button.click();
// Set the new handler as default.
const protoSvc = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
let protoInfo = protoSvc.getProtocolHandlerInfo("web+testprotocol");
is(
protoInfo.preferredAction,
protoInfo.useHelperApp,
"using a helper application is the preferred action"
);
ok(!protoInfo.preferredApplicationHandler, "no preferred handler is set");
let handlers = protoInfo.possibleApplicationHandlers;
is(1, handlers.length, "only one handler registered for web+testprotocol");
let handler = handlers.queryElementAt(0, Ci.nsIHandlerApp);
ok(handler instanceof Ci.nsIWebHandlerApp, "the handler is a web handler");
is(
handler.uriTemplate,
"correct url template"
);
protoInfo.preferredApplicationHandler = handler;
protoInfo.alwaysAskBeforeHandling = false;
const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
Ci.nsIHandlerService
);
handlerSvc.store(protoInfo);
const expectedURL =
// Create a framed link:
await SpecialPowers.spawn(browser, [], async function () {
let iframe = content.document.createElement("iframe");
iframe.src = `data:text/html,<a href="web+testprotocol:test">Click me</a>`;
content.document.body.append(iframe);
// Can't return this promise because it resolves to the event object.
await ContentTaskUtils.waitForEvent(iframe, "load");
iframe.contentDocument.querySelector("a").click();
});
let kidContext = browser.browsingContext.children[0];
await TestUtils.waitForCondition(() => {
let spec = kidContext.currentWindowGlobal?.documentURI?.spec || "";
return spec == expectedURL;
});
is(
kidContext.currentWindowGlobal.documentURI.spec,
expectedURL,
"Should load in frame."
);
// Middle-click a testprotocol link and check the new tab is correct
let link = "#link";
let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser, expectedURL);
await BrowserTestUtils.synthesizeMouseAtCenter(link, { button: 1 }, browser);
let tab = await promiseTabOpened;
gBrowser.selectedTab = tab;
is(
gURLBar.value,
UrlbarTestUtils.trimURL(expectedURL),
"the expected URL is displayed in the location bar"
);
BrowserTestUtils.removeTab(tab);
// Shift-click the testprotocol link and check the new window.
let newWindowPromise = BrowserTestUtils.waitForNewWindow({
url: expectedURL,
});
await BrowserTestUtils.synthesizeMouseAtCenter(
link,
{ shiftKey: true },
browser
);
let win = await newWindowPromise;
await BrowserTestUtils.waitForCondition(
() => win.gBrowser.currentURI.spec == expectedURL
);
is(
win.gURLBar.value,
UrlbarTestUtils.trimURL(expectedURL),
"the expected URL is displayed in the location bar"
);
await BrowserTestUtils.closeWindow(win);
// Click the testprotocol link and check the url in the current tab.
let loadPromise = BrowserTestUtils.browserLoaded(browser);
await BrowserTestUtils.synthesizeMouseAtCenter(link, {}, browser);
await loadPromise;
await BrowserTestUtils.waitForCondition(
() => gURLBar.value != UrlbarTestUtils.trimURL(testURL)
);
is(
gURLBar.value,
UrlbarTestUtils.trimURL(expectedURL),
"the expected URL is displayed in the location bar"
);
// Cleanup.
protoInfo.preferredApplicationHandler = null;
handlers.removeElementAt(0);
handlerSvc.store(protoInfo);
});