Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: verify
- Manifest: netwerk/test/browser/browser.toml
"use strict";
Services.scriptloader.loadSubScript(
new URL("head_local_network_access.js", gTestPath).href,
this
);
add_setup(async function () {
await setupLnaPrefs();
await setupLnaServer();
});
requestLongerTimeout(4);
/**
* Test: Loopback-network temporary permission persists within expiry window
*
* Verifies that when a user grants loopback-network permission, subsequent
* requests within the expiry window do NOT trigger a new prompt and succeed
* automatically using the cached permission.
*
* Steps:
* 1. Make a request that triggers loopback-network permission prompt
* 2. User grants permission (clicks "Allow")
* 3. Make a second request within the expiry window (< 2 seconds)
* 4. Verify NO prompt appears and request succeeds
*
* This validates that temporary permissions work correctly and avoid
* repeatedly prompting users for the same permission.
*/
add_task(async function test_lna_temporary_permission_expiry_loopback_allow() {
info("Test loopback-network: Allow within expiry (no re-prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and grant permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_OK,
"First request should succeed after permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(popup, "First prompt should appear");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Make second request within expiry (should NOT prompt)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Second request within expiry should succeed without prompt"
);
await SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
await content.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`);
});
await promise;
// Verify no prompt appeared (permission was cached)
popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(!popup, "No prompt should appear within expiry window");
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
/**
* Test: Loopback-network temporary permission expires and re-prompts
*
* Verifies that after the temporary permission expires, a new request
* triggers a fresh permission prompt, ensuring permissions don't persist
* indefinitely.
*
* Steps:
* 1. Make a request that triggers loopback-network permission prompt
* 2. User grants permission (clicks "Allow")
* 3. Wait for permission to expire (2.5 seconds > 2 second timeout)
* 4. Make another request after expiry
* 5. Verify a NEW prompt appears (permission has expired)
*
* This validates that the custom LNA expiry time works correctly and
* expired permissions trigger new prompts as expected.
*/
add_task(
async function test_lna_temporary_permission_expiry_loopback_allow_after_expiry() {
info(
"Test loopback-network: Allow, then retry after expiry (should prompt)"
);
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and grant permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_OK,
"First request should succeed after permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Wait for permission to expire (2.5 seconds)");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 2500));
info("Step 3: Make request after expiry (should prompt again)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Request after expiry should succeed after new permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
// Verify prompt appears again after expiry
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(popup, "Prompt should appear again after expiry");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);
/**
* Test: Loopback-network temporary deny permission persists within expiry window
*
* Verifies that when a user denies loopback-network permission, subsequent
* requests within the expiry window do NOT trigger a new prompt and are
* automatically denied using the cached deny permission.
*
* Steps:
* 1. Make a request that triggers loopback-network permission prompt
* 2. User denies permission (clicks "Not Now")
* 3. Make a second request within the expiry window (< 2 seconds)
* 4. Verify NO prompt appears and request is denied
*
* This validates that temporary deny permissions work correctly and avoid
* repeatedly prompting users for permissions they've already denied.
*/
add_task(async function test_lna_temporary_permission_expiry_loopback_deny() {
info("Test loopback-network: Deny within expiry (no re-prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and deny permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"First request should be denied"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(popup, "First prompt should appear");
clickDoorhangerButton(
PROMPT_NOT_NOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Make second request within expiry (should NOT prompt)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"Second request within expiry should be denied without prompt"
);
await SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
await content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await promise;
// Verify no prompt appeared (deny permission was cached)
popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(!popup, "No prompt should appear within expiry window");
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
});
/**
* Test: Loopback-network temporary deny permission expires and re-prompts
*
* Verifies that after a temporary deny permission expires, a new request
* triggers a fresh permission prompt, giving the user another opportunity
* to grant access.
*
* Steps:
* 1. Make a request that triggers loopback-network permission prompt
* 2. User denies permission (clicks "Not Now")
* 3. Wait for deny permission to expire (2.5 seconds > 2 second timeout)
* 4. Make another request after expiry
* 5. Verify a NEW prompt appears (deny permission has expired)
* 6. User can now choose to allow (demonstrating prompt works after expiry)
*
* This validates that temporary deny permissions expire correctly and
* users get a second chance to grant permission after the timeout.
*/
add_task(
async function test_lna_temporary_permission_expiry_loopback_deny_after_expiry() {
info(
"Test loopback-network: Deny, then retry after expiry (should prompt)"
);
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and deny permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"First request should be denied"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
clickDoorhangerButton(
PROMPT_NOT_NOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Wait for permission to expire (2.5 seconds)");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 2500));
info("Step 3: Make request after expiry (should prompt again)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Request after expiry should succeed after new permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
// Verify prompt appears again after deny permission expired
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"loopback-network",
tab.linkedBrowser
);
ok(popup, "Prompt should appear again after expiry");
// This time allow to demonstrate the prompt works
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"loopback-network"
);
await promise;
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);
/**
* Test: Local-network temporary permission persists within expiry window
*
* Verifies that when a user grants local-network permission, subsequent
* requests within the expiry window do NOT trigger a new prompt and succeed
* automatically using the cached permission.
*
* Steps:
* 1. Make a request that triggers local-network permission prompt
* 2. User grants permission (clicks "Allow")
* 3. Make a second request within the expiry window (< 2 seconds)
* 4. Verify NO prompt appears and request succeeds
*
* This validates that temporary permissions work correctly for local-network
* (private IP addresses) in addition to loopback-network.
*/
add_task(
async function test_lna_temporary_permission_expiry_local_network_allow() {
info("Test local-network: Allow within expiry (no re-prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.address_space.private.override", "127.0.0.1:21555"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and grant permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_OK,
"First request should succeed after permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(popup, "First prompt should appear");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Make second request within expiry (should NOT prompt)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Second request within expiry should succeed without prompt"
);
await SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
await content.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`);
});
await promise;
// Verify no prompt appeared (permission was cached)
popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(!popup, "No prompt should appear within expiry window");
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);
/**
* Test: Local-network temporary permission expires and re-prompts
*
* Verifies that after the temporary local-network permission expires,
* a new request triggers a fresh permission prompt.
*
* Steps:
* 1. Make a request that triggers local-network permission prompt
* 2. User grants permission (clicks "Allow")
* 3. Wait for permission to expire (2.5 seconds > 2 second timeout)
* 4. Make another request after expiry
* 5. Verify a NEW prompt appears (permission has expired)
*
* This validates that the custom LNA expiry time works correctly for
* local-network permissions (private IP addresses) and expired permissions
* trigger new prompts as expected.
*/
add_task(
async function test_lna_temporary_permission_expiry_local_network_allow_after_expiry() {
info("Test local-network: Allow, then retry after expiry (should prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.address_space.private.override", "127.0.0.1:21555"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and grant permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_OK,
"First request should succeed after permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Wait for permission to expire (2.5 seconds)");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 2500));
info("Step 3: Make request after expiry (should prompt again)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Request after expiry should succeed after new permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
// Verify prompt appears again after expiry
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(popup, "Prompt should appear again after expiry");
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);
/**
* Test: Local-network temporary deny permission persists within expiry window
*
* Verifies that when a user denies local-network permission, subsequent
* requests within the expiry window do NOT trigger a new prompt and are
* automatically denied using the cached deny permission.
*
* Steps:
* 1. Make a request that triggers local-network permission prompt
* 2. User denies permission (clicks "Not Now")
* 3. Make a second request within the expiry window (< 2 seconds)
* 4. Verify NO prompt appears and request is denied
*
* This validates that temporary deny permissions work correctly for
* local-network (private IP addresses) and avoid repeatedly prompting
* users for permissions they've already denied.
*/
add_task(
async function test_lna_temporary_permission_expiry_local_network_deny() {
info("Test local-network: Deny within expiry (no re-prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.address_space.private.override", "127.0.0.1:21555"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and deny permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"First request should be denied"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(popup, "First prompt should appear");
clickDoorhangerButton(
PROMPT_NOT_NOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Make second request within expiry (should NOT prompt)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"Second request within expiry should be denied without prompt"
);
await SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
await content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await promise;
// Verify no prompt appeared (deny permission was cached)
popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(!popup, "No prompt should appear within expiry window");
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);
/**
* Test: Local-network temporary deny permission expires and re-prompts
*
* Verifies that after a temporary local-network deny permission expires,
* a new request triggers a fresh permission prompt, giving the user another
* opportunity to grant access.
*
* Steps:
* 1. Make a request that triggers local-network permission prompt
* 2. User denies permission (clicks "Not Now")
* 3. Wait for deny permission to expire (2.5 seconds > 2 second timeout)
* 4. Make another request after expiry
* 5. Verify a NEW prompt appears (deny permission has expired)
* 6. User can now choose to allow (demonstrating prompt works after expiry)
*
* This validates that temporary deny permissions expire correctly for
* local-network (private IP addresses) and users get a second chance to
* grant permission after the timeout.
*/
add_task(
async function test_lna_temporary_permission_expiry_local_network_deny_after_expiry() {
info("Test local-network: Deny, then retry after expiry (should prompt)");
await restorePermissions();
await SpecialPowers.pushPrefEnv({
set: [
["network.lna.address_space.public.override", "127.0.0.1:4443"],
["network.lna.address_space.private.override", "127.0.0.1:21555"],
["network.lna.temporary_permission_expire_time_ms", 2000], // 2 seconds for testing
],
});
const testURL = `${LNA_BASE_URL}page_with_non_trackers.html`;
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testURL);
info("Step 1: Make first request and deny permission");
const rand1 = Math.random();
let promise = observeAndCheck(
"fetch",
rand1,
Cr.NS_ERROR_LOCAL_NETWORK_ACCESS_DENIED,
"First request should be denied"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand1], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
clickDoorhangerButton(
PROMPT_NOT_NOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
// Wait for permission to be saved
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 300));
info("Step 2: Wait for permission to expire (2.5 seconds)");
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 2500));
info("Step 3: Make request after expiry (should prompt again)");
const rand2 = Math.random();
promise = observeAndCheck(
"fetch",
rand2,
Cr.NS_OK,
"Request after expiry should succeed after new permission granted"
);
SpecialPowers.spawn(tab.linkedBrowser, [rand2], async rand => {
content
.fetch(`http://localhost:21555/?type=fetch&rand=${rand}`)
.catch(() => {});
});
// Verify prompt appears again after deny permission expired
await BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
let popup = PopupNotifications.getNotification(
"local-network",
tab.linkedBrowser
);
ok(popup, "Prompt should appear again after expiry");
// This time allow to demonstrate the prompt works
clickDoorhangerButton(
PROMPT_ALLOW_BUTTON,
tab.linkedBrowser,
"local-network"
);
await promise;
gBrowser.removeTab(tab);
await SpecialPowers.popPrefEnv();
}
);