diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/client/application/test/browser | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/application/test/browser')
43 files changed, 1760 insertions, 0 deletions
diff --git a/devtools/client/application/test/browser/browser.ini b/devtools/client/application/test/browser/browser.ini new file mode 100644 index 0000000000..4150959be4 --- /dev/null +++ b/devtools/client/application/test/browser/browser.ini @@ -0,0 +1,80 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + head.js + resources/manifest/icon.svg + resources/manifest/load-fail.html + resources/manifest/load-no-manifest.html + resources/manifest/load-ok-icons.html + resources/manifest/load-ok-json-error.html + resources/manifest/load-ok-manifest-link.html + resources/manifest/load-ok-warnings.html + resources/manifest/load-ok.html + resources/manifest/manifest.json + resources/service-workers/controlled-install-sw.js + resources/service-workers/controlled-install.html + resources/service-workers/debug-sw.js + resources/service-workers/debug.html + resources/service-workers/dynamic-registration.html + resources/service-workers/empty.html + resources/service-workers/empty-sw.js + resources/service-workers/scope-page.html + resources/service-workers/simple.html + resources/service-workers/simple-unicode.html + !/devtools/client/debugger/test/mochitest/shared-head.js + !/devtools/client/shared/test/shared-head.js + !/devtools/client/shared/test/telemetry-test-helpers.js + +# Worker-related tests +[browser_application_panel_debug-service-worker.js] +skip-if = debug || asan || !serviceworker_e10s # Bug 1559591, 1575578, 1588154 +[browser_application_panel_list-domain-workers.js] +https_first_disabled = true +skip-if = debug # Bug 1559591 +[browser_application_panel_list-multiple-workers-same-registration.js] +https_first_disabled = true +skip-if = debug # Bug 1559591 +[browser_application_panel_list-several-workers.js] +https_first_disabled = true +skip-if = debug # Bug 1559591 +[browser_application_panel_list-single-worker.js] +https_first_disabled = true +skip-if = debug # Bug 1559591 +[browser_application_panel_start-service-worker.js] +skip-if = asan || debug || !serviceworker_e10s || tsan # Bug 1559487, 1559591, 1608640 +[browser_application_panel_list-workers-empty.js] +[browser_application_panel_list-unicode.js] +skip-if = debug # Bug 1559591 +[browser_application_panel_unregister-worker.js] +skip-if = debug # Bug 1559591 +[browser_application_panel_viewsource-service-worker.js] +https_first_disabled = true +skip-if = debug || asan || !serviceworker_e10s # Bug 1559591, 1575578, 1588154 +[browser_application_panel_worker-states.js] +skip-if = asan || debug || !serviceworker_e10s # Bug 1559487, 1559591, 1608640 +# Manifest-related tests +[browser_application_panel_manifest-display.js] +[browser_application_panel_manifest-load.js] +[browser_application_panel_manifest-open-json.js] +https_first_disabled = true +[browser_application_panel_manifest-reload.js] +https_first_disabled = true +# Telemetry tests +[browser_application_panel_telemetry-debug-worker.js] +https_first_disabled = true +skip-if = + asan || debug || !serviceworker_e10s # Bug 1559487, 1559591, 1608640 + os == 'linux' && bits == 64 && !debug # Bug 1654354 +[browser_application_panel_telemetry-select-page.js] +[browser_application_panel_telemetry-start-worker.js] +skip-if = ccov || asan || debug || !serviceworker_e10s || tsan # Bug 1559487, 1559591, 1608640, 1654468 +[browser_application_panel_telemetry-unregister-worker.js] +skip-if = asan || debug || !serviceworker_e10s # Bug 1559487, 1559591, 1608640 +# Misc tests +[browser_application_panel_open-links.js] +skip-if = true # Bug 1467256, 1559591 +[browser_application_panel_sidebar.js] +[browser_application_panel_target-switching.js] +https_first_disabled = true +skip-if = (os == 'win') || (os == 'linux') # Bug 1640234 diff --git a/devtools/client/application/test/browser/browser_application_panel_debug-service-worker.js b/devtools/client/application/test/browser/browser_application_panel_debug-service-worker.js new file mode 100644 index 0000000000..57dd000edb --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_debug-service-worker.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/shared-head.js", + this +); + +const TAB_URL = URL_ROOT + "resources/service-workers/debug.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab, toolbox, commands } = await openNewTabAndApplicationPanel( + TAB_URL + ); + + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const container = getWorkerContainers(doc)[0]; + info("Wait until the inspect link is displayed"); + await waitUntil(() => { + return container.querySelector(".js-inspect-link"); + }); + + info("Click on the inspect link and wait for debugger to be ready"); + const debugLink = container.querySelector(".js-inspect-link"); + debugLink.click(); + await waitFor(() => toolbox.getPanel("jsdebugger")); + + // add a breakpoint at line 11 + const debuggerContext = createDebuggerContext(toolbox); + await waitForLoadedSource(debuggerContext, "debug-sw.js"); + await addBreakpoint(debuggerContext, "debug-sw.js", 11); + + // force a pause at the breakpoint + info("Invoke fetch, expect the service worker script to pause on line 11"); + await ContentTask.spawn(tab.linkedBrowser, {}, async function () { + content.wrappedJSObject.fetchFromWorker(); + }); + await waitForPaused(debuggerContext); + const workerScript = findSource(debuggerContext, "debug-sw.js"); + assertPausedAtSourceAndLine(debuggerContext, workerScript.id, 11); + await resume(debuggerContext); + + // remove breakpoint + await removeBreakpoint(debuggerContext, workerScript.id, 11); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_list-domain-workers.js b/devtools/client/application/test/browser/browser_application_panel_list-domain-workers.js new file mode 100644 index 0000000000..ccb0884d0e --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-domain-workers.js @@ -0,0 +1,70 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel only displays service workers from the + * current domain. + */ + +const SIMPLE_URL = URL_ROOT + "resources/service-workers/simple.html"; +const OTHER_URL = SIMPLE_URL.replace("example.com", "test1.example.com"); +const EMPTY_URL = (URL_ROOT + "resources/service-workers/empty.html").replace( + "example.com", + "test2.example.com" +); + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, commands, tab } = await openNewTabAndApplicationPanel( + SIMPLE_URL + ); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + let scopeEl = getWorkerContainers(doc)[0].querySelector(".js-sw-scope"); + ok( + scopeEl.textContent.startsWith("example.com"), + "First service worker registration is displayed for the correct domain" + ); + + info( + "Navigate to another page for a different domain with no service worker" + ); + + await navigateTo(EMPTY_URL); + info("Wait until the service worker list is updated"); + await waitUntil( + () => doc.querySelector(".js-registration-list-empty") !== null + ); + ok( + true, + "No service workers are shown for an empty page in a different domain." + ); + + info( + "Navigate to another page for a different domain with another service worker" + ); + await navigateTo(OTHER_URL); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + scopeEl = getWorkerContainers(doc)[0].querySelector(".js-sw-scope"); + ok( + scopeEl.textContent.startsWith("test1.example.com"), + "Second service worker registration is displayed for the correct domain" + ); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_list-multiple-workers-same-registration.js b/devtools/client/application/test/browser/browser_application_panel_list-multiple-workers-same-registration.js new file mode 100644 index 0000000000..8e117927d1 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-multiple-workers-same-registration.js @@ -0,0 +1,64 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const WORKER1_URL = URL_ROOT + "resources/service-workers/simple.html"; +const WORKER2_URL = URL_ROOT + "resources/service-workers/debug.html"; + +add_task(async function () { + await enableApplicationPanel(); + + await openTabAndWaitForWorker(WORKER1_URL); + const { panel, tab, commands } = await openTabAndWaitForWorker(WORKER2_URL); + + const doc = panel.panelWin.document; + + let registrationContainer = getWorkerContainers(doc)[0]; + + info("Wait until the unregister button is displayed for the registration"); + await waitUntil(() => { + registrationContainer = getWorkerContainers(doc)[0]; + return registrationContainer.querySelector(".js-unregister-button"); + }); + + const scopeEl = registrationContainer.querySelector(".js-sw-scope"); + const expectedScope = + "example.com/browser/devtools/client/application/test/" + + "browser/resources/service-workers"; + ok( + scopeEl.textContent.startsWith(expectedScope), + "Registration has the expected scope" + ); + + // check the workers data + // note that the worker from WORKER2_URL will appear second in the list with + // the "installed" state + info("Check the workers data for this registration"); + const workers = registrationContainer.querySelectorAll(".js-sw-worker"); + is(workers.length, 2, "Registration has two workers"); + // check url for worker from WORKER1_URL + const url1El = workers[0].querySelector(".js-source-url"); + is(url1El.textContent, "empty-sw.js", "First worker has correct URL"); + // check url for worker from WORKER2_URL + const url2El = workers[1].querySelector(".js-source-url"); + is(url2El.textContent, "debug-sw.js", "Second worker has correct URL"); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +async function openTabAndWaitForWorker(url) { + const { panel, commands, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + return { panel, commands, tab }; +} diff --git a/devtools/client/application/test/browser/browser_application_panel_list-several-workers.js b/devtools/client/application/test/browser/browser_application_panel_list-several-workers.js new file mode 100644 index 0000000000..4e1295082e --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-several-workers.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel can display several service workers applying to the + * same domain. + */ + +const SIMPLE_URL = URL_ROOT + "resources/service-workers/simple.html"; +const OTHER_SCOPE_URL = URL_ROOT + "resources/service-workers/scope-page.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, commands, tab } = await openNewTabAndApplicationPanel( + SIMPLE_URL + ); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + info("Wait until the unregister button is displayed for the service worker"); + await waitUntil(() => + getWorkerContainers(doc)[0].querySelector(".js-unregister-button") + ); + + ok(true, "First service worker registration is displayed"); + + info( + "Navigate to another page for the same domain with another service worker" + ); + await navigateTo(OTHER_SCOPE_URL); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 2); + + info("Wait until the unregister button is displayed for the service worker"); + await waitUntil(() => + getWorkerContainers(doc)[1].querySelector(".js-unregister-button") + ); + + ok(true, "Second service worker registration is displayed"); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_list-single-worker.js b/devtools/client/application/test/browser/browser_application_panel_list-single-worker.js new file mode 100644 index 0000000000..74cab13bf6 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-single-worker.js @@ -0,0 +1,64 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = + URL_ROOT + "resources/service-workers/dynamic-registration.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Check for non-existing service worker"); + const isWorkerListEmpty = !!doc.querySelector(".js-registration-list-empty"); + ok(isWorkerListEmpty, "No Service Worker displayed"); + + info("Register a service worker in the page."); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + content.wrappedJSObject.registerServiceWorker(); + }); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => !!getWorkerContainers(doc).length); + + let workerContainer = getWorkerContainers(doc)[0]; + + info("Wait until the unregister button is displayed for the service worker"); + await waitUntil(() => { + workerContainer = getWorkerContainers(doc)[0]; + return workerContainer.querySelector(".js-unregister-button"); + }); + + const scopeEl = workerContainer.querySelector(".js-sw-scope"); + const expectedScope = + "example.com/browser/devtools/client/application/test/" + + "browser/resources/service-workers"; + ok( + scopeEl.textContent.startsWith(expectedScope), + "Service worker has the expected scope" + ); + + const updatedEl = workerContainer.querySelector(".js-sw-updated"); + ok( + updatedEl.textContent.includes(`${new Date().getFullYear()}`), + "Service worker has a last updated time" + ); + + info("Unregister the service worker"); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + const registration = await content.wrappedJSObject.sw; + registration.unregister(); + }); + + info("Wait until the service worker is removed from the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 0); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_list-unicode.js b/devtools/client/application/test/browser/browser_application_panel_list-unicode.js new file mode 100644 index 0000000000..c747fa9ae3 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-unicode.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = ( + URL_ROOT + "resources/service-workers/simple-unicode.html" +).replace("example.com", "xn--hxajbheg2az3al.xn--jxalpdlp"); + +/** + * Check that the application panel displays filenames and URL's in human-readable, + * Unicode characters, and not encoded URI's or punycode. + */ + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const workerContainer = getWorkerContainers(doc)[0]; + + const scopeEl = workerContainer.querySelector(".js-sw-scope"); + ok( + scopeEl.textContent.startsWith( + "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1." + + "\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE" + ), + "Service worker has the expected Unicode scope" + ); + const urlEl = workerContainer.querySelector(".js-source-url"); + ok( + urlEl.textContent.endsWith("\u65E5\u672C"), + "Service worker has the expected Unicode url" + ); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_list-workers-empty.js b/devtools/client/application/test/browser/browser_application_panel_list-workers-empty.js new file mode 100644 index 0000000000..1bb75d2999 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_list-workers-empty.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel only displays service workers from the + * current domain. + */ + +const EMPTY_URL = URL_ROOT + "resources/service-workers/empty.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab } = await openNewTabAndApplicationPanel(EMPTY_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + await waitUntil( + () => doc.querySelector(".js-registration-list-empty") !== null + ); + ok(true, "No service workers are shown for an empty page"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_manifest-display.js b/devtools/client/application/test/browser/browser_application_panel_manifest-display.js new file mode 100644 index 0000000000..714fcc276e --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_manifest-display.js @@ -0,0 +1,145 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the manifest is being properly shown + */ + +add_task(async function () { + info("Test that we are displaying correctly a valid manifest"); + const url = URL_ROOT + "resources/manifest/load-ok.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to be displayed"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest is being displayed"); + + // assert manifest members are being properly displayed + checkManifestMember(doc, "name", "Foo"); + checkManifestMember(doc, "background_color", "#ff0000"); + + ok( + doc.querySelector(".js-manifest-issues") === null, + "No validation issues are being displayed" + ); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info( + "Test that we are displaying correctly a manifest with validation warnings" + ); + const url = URL_ROOT + "resources/manifest/load-ok-warnings.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to be displayed"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest is being displayed"); + + // assert manifest members are being properly displayed + checkManifestMember(doc, "name", "Foo"); + checkManifestMember(doc, "background_color", ""); + + const issuesEl = doc.querySelector(".js-manifest-issues"); + ok(issuesEl !== null, "Validation issues are displayed"); + + const warningEl = [...issuesEl.querySelectorAll(".js-manifest-issue")].find( + x => x.textContent.includes("background_color") + ); + ok(warningEl !== null, "A warning about background_color is displayed"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info("Test that we are displaying correctly a manifest with JSON errors"); + const url = URL_ROOT + "resources/manifest/load-ok-json-error.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to be displayed"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest is being displayed"); + + const issuesEl = doc.querySelector(".js-manifest-issues"); + ok(issuesEl !== null, "Validation issues are displayed"); + + const errorEl = [...issuesEl.querySelectorAll(".js-manifest-issue")].find(x => + x.textContent.includes("JSON") + ); + ok(errorEl !== null, "An error about JSON parsing is displayed"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info("Test that we are displaying correctly a manifest with icons"); + const url = URL_ROOT + "resources/manifest/load-ok-icons.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to be displayed"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest is being displayed"); + + // assert manifest icon is being displayed + const iconEl = findMemberByLabel(doc, "128x128image/svg"); + ok(iconEl !== null, "Icon label is being displayed with size and image type"); + const imgEl = iconEl.querySelector(".js-manifest-item-content img"); + ok(imgEl !== null, "An image is displayed for the icon"); + is( + imgEl.src, + URL_ROOT + "resources/manifest/icon.svg", + "The icon image has the the icon url as source" + ); + const iconTextContent = iconEl.querySelector( + ".js-manifest-item-content" + ).textContent; + ok(iconTextContent.includes("any"), "Purpose is being displayed"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +function findMemberByLabel(doc, member) { + return [...doc.querySelectorAll(".js-manifest-item")].find(x => + x.querySelector(".js-manifest-item-label").textContent.startsWith(member) + ); +} + +function checkManifestMember(doc, member, expectedValue) { + const itemEl = findMemberByLabel(doc, member); + is( + itemEl.querySelector(".js-manifest-item-content").textContent, + expectedValue, + `Manifest member ${member} displays the correct value` + ); +} diff --git a/devtools/client/application/test/browser/browser_application_panel_manifest-load.js b/devtools/client/application/test/browser/browser_application_panel_manifest-load.js new file mode 100644 index 0000000000..dd89fbc1a6 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_manifest-load.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel fetches a manifest when in the Manifest Page + */ + +add_task(async function () { + info("Test that manifest page loads the manifest successfully"); + const url = URL_ROOT + "resources/manifest/load-ok.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to load"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest loaded successfully"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info("Test that manifest page shows an error when failing to load"); + const url = URL_ROOT + "resources/manifest/load-fail.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to fail to load"); + await waitUntil( + () => doc.querySelector(".js-manifest-loaded-error") !== null + ); + ok(true, "Manifest page displays loading error"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info("Test that manifest page shows a message when there is no manifest"); + const url = URL_ROOT + "resources/manifest/load-no-manifest.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the 'no manifest' message to appear"); + await waitUntil(() => doc.querySelector(".js-manifest-empty") !== null); + ok(true, "Manifest page displays a 'no manifest' message"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_manifest-open-json.js b/devtools/client/application/test/browser/browser_application_panel_manifest-open-json.js new file mode 100644 index 0000000000..7869502d4b --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_manifest-open-json.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel fetches a manifest when in the Manifest Page + */ + +add_task(async function () { + info("Test that manifest page has a link that opens the manifest JSON file"); + const url = URL_ROOT_SSL + "resources/manifest/load-ok-manifest-link.html"; + const manifestUrl = URL_ROOT_SSL + "resources/manifest/manifest.json"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest JSON link"); + await waitUntil(() => doc.querySelector(".js-manifest-json-link") !== null); + ok(true, "Link to JSON is displayed"); + + info("Click on link and wait till the JSON is opened in a new tab"); + // click on the link and wait for the new tab to open + const onTabLoaded = BrowserTestUtils.waitForNewTab( + gBrowser, + `${manifestUrl}` + ); + const link = doc.querySelector(".js-manifest-json-link"); + link.click(); + const jsonTab = await onTabLoaded; + ok(jsonTab, "The manifest JSON was opened in a new tab"); + + // close the tabs + info("Closing the page tab."); + await BrowserTestUtils.removeTab(tab); + info("Closing the manifest JSON tab."); + await BrowserTestUtils.removeTab(jsonTab); +}); + +add_task(async function () { + info( + "Test that manifest page does not show a link for manifests embedded in a data url" + ); + const url = URL_ROOT_SSL + "resources/manifest/load-ok.html"; + + await enableApplicationPanel(); + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to load"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest loaded successfully"); + is( + doc.querySelector(".js-manifest-json-link"), + null, + "No JSON link is shown" + ); + + // close tab + info("Closing the tab"); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_manifest-reload.js b/devtools/client/application/test/browser/browser_application_panel_manifest-reload.js new file mode 100644 index 0000000000..4b8ab50985 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_manifest-reload.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the application panel refetches the page manifest when reloading + * or navigating to a new page + */ + +add_task(async function () { + await enableApplicationPanel(); + + info("Loading a page with no manifest"); + let url = URL_ROOT_SSL + "resources/manifest/load-no-manifest.html"; + const { panel, tab } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the 'no manifest' message to appear"); + await waitFor(() => doc.querySelector(".js-manifest-empty") !== null); + ok(true, "Manifest page displays a 'no manifest' message"); + + info("Navigating to a page with a manifest"); + url = URL_ROOT_SSL + "resources/manifest/load-ok.html"; + await navigateTo(url); + + info("Waiting for the manifest to show up"); + await waitFor(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest displayed successfully"); + + info("Navigating to a page with a manifest that fails to load"); + url = URL_ROOT_SSL + "resources/manifest/load-fail.html"; + await navigateTo(url); + + info("Waiting for the manifest to fail to load"); + await waitFor(() => doc.querySelector(".js-manifest-loaded-error") !== null); + ok(true, "Manifest page displays loading error"); + + info("Reloading"); + await navigateTo(url); + + info("Waiting for the manifest to fail to load"); + await waitFor(() => doc.querySelector(".js-manifest-loaded-error") !== null); + ok(true, "Manifest page displays loading error"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_open-links.js b/devtools/client/application/test/browser/browser_application_panel_open-links.js new file mode 100644 index 0000000000..d654873827 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_open-links.js @@ -0,0 +1,48 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { Toolbox } = require("resource://devtools/client/framework/toolbox.js"); + +/** + * Check that links work when the devtools are detached in a separate window. + */ + +const TAB_URL = URL_ROOT + "resources/service-workers/empty.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, toolbox } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + // detach devtools in a separate window + await toolbox.switchHost(Toolbox.HostType.WINDOW); + + // click on the link and wait for the new tab to open + const onTabLoaded = BrowserTestUtils.waitForNewTab( + gBrowser, + "about:debugging#workers", + true + ); + doc.querySelector(".js-trusted-link").click(); + info("Opening link in a new tab."); + const newTab = await onTabLoaded; + + // We only need to check that newTab is truthy since + // BrowserTestUtils.waitForNewTab checks the URL. + ok(newTab, "The expected tab was opened."); + + info("Wait until the main about debugging container is available"); + await waitUntil(() => { + const aboutDebuggingDoc = newTab.linkedBrowser.contentDocument; + return aboutDebuggingDoc.querySelector(".app"); + }); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(newTab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_sidebar.js b/devtools/client/application/test/browser/browser_application_panel_sidebar.js new file mode 100644 index 0000000000..80b2fbfe09 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_sidebar.js @@ -0,0 +1,82 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that the manifest is being properly shown + */ + +add_task(async function () { + info("Test that we are displaying correctly the sidebar"); + + await enableApplicationPanel(); + const { panel, tab, commands } = await openNewTabAndApplicationPanel(); + const doc = panel.panelWin.document; + + info("Waiting for the sidebar to be displayed"); + await waitUntil(() => doc.querySelector(".js-sidebar") !== null); + ok(true, "Sidebar is being displayed"); + + await waitUntil(() => doc.querySelector(".js-service-workers-page") !== null); + ok(true, "Service Workers page was loaded per default."); + + // close the tab + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info("Test that we are displaying correctly the selected page - manifest"); + + await enableApplicationPanel(); + const { panel, tab, commands } = await openNewTabAndApplicationPanel(); + const doc = panel.panelWin.document; + + info("Select service worker page"); + selectPage(panel, "service-workers"); + await waitUntil(() => doc.querySelector(".js-service-workers-page") !== null); + await unregisterAllWorkers(commands.client, doc); + + info("Select manifest page in the sidebar"); + const link = doc.querySelector(".js-sidebar-manifest"); + link.click(); + + await waitUntil(() => doc.querySelector(".js-manifest-page") !== null); + ok(true, "Manifest page was selected."); + + // close the tab + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); + +add_task(async function () { + info( + "Test that we are displaying correctly the selected page - service workers" + ); + const url = URL_ROOT + "resources/manifest/load-ok.html"; + + await enableApplicationPanel(); + const { panel, tab, commands } = await openNewTabAndApplicationPanel(url); + const doc = panel.panelWin.document; + + selectPage(panel, "manifest"); + + info("Waiting for the manifest to load"); + await waitUntil(() => doc.querySelector(".js-manifest-page") !== null); + ok(true, "Manifest page was selected."); + + info("Select service worker page in the sidebar"); + const link = doc.querySelector(".js-sidebar-service-workers"); + link.click(); + + await waitUntil(() => doc.querySelector(".js-service-workers-page") !== null); + ok(true, "Service workers page was selected."); + + // close the tab + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_start-service-worker.js b/devtools/client/application/test/browser/browser_application_panel_start-service-worker.js new file mode 100644 index 0000000000..1070f0f5af --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_start-service-worker.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/simple.html"; + +/** + * Tests that the Start button works for service workers who can be debugged + */ +add_task(async function () { + await enableApplicationPanel(); // this also enables SW debugging + + // Setting a low idle_timeout and idle_extended_timeout will allow the service worker + // to reach the STOPPED state quickly, which will allow us to test the start button. + // The default value is 30000 milliseconds. + info("Set a low service worker idle timeout"); + await pushPref("dom.serviceWorkers.idle_timeout", 1000); + await pushPref("dom.serviceWorkers.idle_extended_timeout", 1000); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + await waitForWorkerRegistration(tab); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + info("Wait until the start button is displayed and enabled"); + const container = getWorkerContainers(doc)[0]; + await waitUntil(() => { + const button = container.querySelector(".js-start-button"); + return button && !button.disabled; + }); + + info("Click the button and wait for the worker to start"); + const button = container.querySelector(".js-start-button"); + button.click(); + + info("Wait until status 'Running' is displayed"); + await waitUntil(() => { + const statusEl = container.querySelector(".js-worker-status"); + return statusEl && statusEl.textContent === "Running"; + }); + ok(true, "Worker status is 'Running'"); + + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_target-switching.js b/devtools/client/application/test/browser/browser_application_panel_target-switching.js new file mode 100644 index 0000000000..ff8d521e30 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_target-switching.js @@ -0,0 +1,68 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test switching for the top-level target. + +// We use about:robots, because this page will run in the parent process. +// Navigating from about:robots to a regular content page will always trigger +// a target switch, with or without fission. +const PARENT_PROCESS_URI = "about:robots"; +const CONTENT_PROCESS_URI_WORKERS = + URL_ROOT + "resources/service-workers/simple.html"; +const CONTENT_PROCESS_URI_MANIFEST = + URL_ROOT + "resources/manifest/load-ok.html"; + +// test workers when target switching +add_task(async function () { + await enableApplicationPanel(); + + info("Open a page that runs in the parent process"); + const { panel, commands, tab } = await openNewTabAndApplicationPanel( + PARENT_PROCESS_URI + ); + const doc = panel.panelWin.document; + + info("Check for non-existing service worker"); + selectPage(panel, "service-workers"); + const isWorkerListEmpty = !!doc.querySelector(".js-registration-list-empty"); + ok(isWorkerListEmpty, "No Service Worker displayed"); + + info("Navigate to a page that runs in the child process"); + await navigateTo(CONTENT_PROCESS_URI_WORKERS); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + // close the tab + info("Closing the tab."); + await unregisterAllWorkers(commands.client, doc); + await BrowserTestUtils.removeTab(tab); +}); + +// test manifest when target switching +add_task(async function () { + await enableApplicationPanel(); + + info("Open a page that runs in the parent process"); + const { panel, tab } = await openNewTabAndApplicationPanel( + PARENT_PROCESS_URI + ); + const doc = panel.panelWin.document; + + info("Waiting for the 'no manifest' message to appear"); + selectPage(panel, "manifest"); + await waitUntil(() => doc.querySelector(".js-manifest-empty") !== null); + + info("Navigate to a page that runs in the child process"); + await navigateTo(CONTENT_PROCESS_URI_MANIFEST); + + info("Waiting for the manifest to load"); + selectPage(panel, "manifest"); + await waitUntil(() => doc.querySelector(".js-manifest") !== null); + ok(true, "Manifest loaded successfully"); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_telemetry-debug-worker.js b/devtools/client/application/test/browser/browser_application_panel_telemetry-debug-worker.js new file mode 100644 index 0000000000..fe95dabd5e --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_telemetry-debug-worker.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/simple.html"; + +// check telemetry for debugging a service worker +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab, toolbox, commands } = await openNewTabAndApplicationPanel( + TAB_URL + ); + + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + setupTelemetryTest(); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const container = getWorkerContainers(doc)[0]; + info("Wait until the debug link is displayed"); + await waitUntil(() => { + return container.querySelector(".js-inspect-link"); + }); + + info("Click on the debug link and wait for debugger to be ready"); + const debugLink = container.querySelector(".js-inspect-link"); + debugLink.click(); + await waitUntil(() => toolbox.getPanel("jsdebugger")); + + const events = getTelemetryEvents("jsdebugger"); + const openToolboxEvent = events.find(event => event.method == "enter"); + ok(openToolboxEvent.session_id > 0, "Event has a valid session id"); + is( + openToolboxEvent.start_state, + "application", + "Event has the 'application' start state" + ); + + // clean up and close the tab + await unregisterAllWorkers(commands.client, doc); + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_telemetry-select-page.js b/devtools/client/application/test/browser/browser_application_panel_telemetry-select-page.js new file mode 100644 index 0000000000..c200c38c17 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_telemetry-select-page.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function () { + await enableApplicationPanel(); + + const TAB_URL = URL_ROOT + "resources/service-workers/empty.html"; + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + setupTelemetryTest(); + + // make sure the default page is opened and then select a different one + await waitUntil(() => doc.querySelector(".js-service-workers-page") !== null); + ok(true, "Service Workers page was loaded per default."); + selectPage(panel, "manifest"); + + checkTelemetryEvent({ method: "select_page", page_type: "manifest" }); + + // close the tab + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_telemetry-start-worker.js b/devtools/client/application/test/browser/browser_application_panel_telemetry-start-worker.js new file mode 100644 index 0000000000..235ce3060d --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_telemetry-start-worker.js @@ -0,0 +1,45 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/simple.html"; + +// check telemetry for starting a service worker +add_task(async function () { + info("Set a low service worker idle timeout"); + await pushPref("dom.serviceWorkers.idle_timeout", 1000); + await pushPref("dom.serviceWorkers.idle_extended_timeout", 1000); + + await enableApplicationPanel(); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + await waitForWorkerRegistration(tab); + + setupTelemetryTest(); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + info("Wait until the start button is displayed and enabled"); + const container = getWorkerContainers(doc)[0]; + await waitUntil(() => { + const button = container.querySelector(".js-start-button"); + return button && !button.disabled; + }); + + info("Click the start button"); + const button = container.querySelector(".js-start-button"); + button.click(); + + checkTelemetryEvent({ method: "start_worker" }); + + // clean up and close the tab + await unregisterAllWorkers(commands.client, doc); + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_telemetry-unregister-worker.js b/devtools/client/application/test/browser/browser_application_panel_telemetry-unregister-worker.js new file mode 100644 index 0000000000..aa6d35f946 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_telemetry-unregister-worker.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/simple.html"; + +// check telemetry for unregistering a service worker +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + setupTelemetryTest(); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const workerContainer = getWorkerContainers(doc)[0]; + + info("Wait until the unregister button is displayed for the service worker"); + await waitUntil(() => workerContainer.querySelector(".js-unregister-button")); + info("Click the unregister button"); + const button = workerContainer.querySelector(".js-unregister-button"); + button.click(); + + checkTelemetryEvent({ method: "unregister_worker" }); + + // clean up and close the tab + await unregisterAllWorkers(commands.client, doc); + info("Closing the tab."); + await commands.client.waitForRequestsToSettle(); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_unregister-worker.js b/devtools/client/application/test/browser/browser_application_panel_unregister-worker.js new file mode 100644 index 0000000000..8f6c4a5793 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_unregister-worker.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/simple.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const workerContainer = getWorkerContainers(doc)[0]; + + info("Wait until the unregister button is displayed for the service worker"); + await waitUntil(() => workerContainer.querySelector(".js-unregister-button")); + info("Click the unregister button"); + const button = workerContainer.querySelector(".js-unregister-button"); + button.click(); + info("Wait until the service worker is removed from the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 0); + ok(true, "Service worker list is empty"); + + // just in case cleanup + await unregisterAllWorkers(commands.client, doc); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_viewsource-service-worker.js b/devtools/client/application/test/browser/browser_application_panel_viewsource-service-worker.js new file mode 100644 index 0000000000..fc6f0819b6 --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_viewsource-service-worker.js @@ -0,0 +1,50 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/debug.html"; +const SW_URL = URL_ROOT + "resources/service-workers/debug-sw.js"; + +add_task(async function () { + await enableApplicationPanel(); + + // disable service worker debugging + await pushPref( + "devtools.debugger.features.windowless-service-workers", + false + ); + + const { panel, tab, commands } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 1); + + const container = getWorkerContainers(doc)[0]; + info("Wait until the inspect link is displayed"); + await waitUntil(() => { + return container.querySelector(".js-inspect-link"); + }); + + info("Click on the inspect link and wait for a new view-source: tab open"); + // click on the link and wait for the new tab to open + const onTabLoaded = BrowserTestUtils.waitForNewTab( + gBrowser, + `view-source:${SW_URL}` + ); + const inspectLink = container.querySelector(".js-inspect-link"); + inspectLink.click(); + + const sourceTab = await onTabLoaded; + ok(sourceTab, "The service worker source was opened in a new tab"); + + // clean up + await unregisterAllWorkers(commands.client, doc); + // close the tabs + info("Closing the tabs."); + await BrowserTestUtils.removeTab(sourceTab); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/browser_application_panel_worker-states.js b/devtools/client/application/test/browser/browser_application_panel_worker-states.js new file mode 100644 index 0000000000..54446506fa --- /dev/null +++ b/devtools/client/application/test/browser/browser_application_panel_worker-states.js @@ -0,0 +1,62 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TAB_URL = URL_ROOT + "resources/service-workers/controlled-install.html"; + +add_task(async function () { + await enableApplicationPanel(); + + const { panel, tab } = await openNewTabAndApplicationPanel(TAB_URL); + const doc = panel.panelWin.document; + + selectPage(panel, "service-workers"); + + info("Check for non-existing service worker"); + const isWorkerListEmpty = !!doc.querySelector(".js-registration-list-empty"); + ok(isWorkerListEmpty, "No Service Worker displayed"); + + info("Register a service worker with a controlled install in the page."); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + content.wrappedJSObject.registerServiceWorker(); + }); + + info("Wait until the service worker appears in the application panel"); + await waitUntil(() => !!getWorkerContainers(doc).length); + info("Wait until the 'Installing' state is displayed"); + await waitUntil(() => { + const containers = getWorkerContainers(doc); + if (containers.length === 0) { + return false; + } + + const stateEl = containers[0].querySelector(".js-worker-status"); + return stateEl.textContent.toLowerCase() === "installing"; + }); + + info("Allow the service worker to complete installation"); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + content.wrappedJSObject.installServiceWorker(); + }); + + info("Wait until the 'running' state is displayed"); + await waitUntil(() => { + const workerContainer = getWorkerContainers(doc)[0]; + const stateEl = workerContainer.querySelector(".js-worker-status"); + return stateEl.textContent.toLowerCase() === "running"; + }); + + info("Unregister the service worker"); + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + const registration = await content.wrappedJSObject.sw; + registration.unregister(); + }); + + info("Wait until the service worker is removed from the application panel"); + await waitUntil(() => getWorkerContainers(doc).length === 0); + + // close the tab + info("Closing the tab."); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/devtools/client/application/test/browser/head.js b/devtools/client/application/test/browser/head.js new file mode 100644 index 0000000000..6b7e67ff8d --- /dev/null +++ b/devtools/client/application/test/browser/head.js @@ -0,0 +1,134 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* eslint-env browser */ +/* eslint no-unused-vars: [2, {"vars": "local"}] */ + +"use strict"; + +// Load the shared-head file first. +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js", + this +); + +/** + * Set all preferences needed to enable service worker debugging and testing. + */ +async function enableServiceWorkerDebugging() { + // Enable service workers. + await pushPref("dom.serviceWorkers.enabled", true); + // Accept workers from mochitest's http. + await pushPref("dom.serviceWorkers.testing.enabled", true); + // Force single content process, see Bug 1231208 for the SW refactor that should enable + // SW debugging in multi-e10s. + await pushPref("dom.ipc.processCount", 1); + + // Enable service workers in the debugger + await pushPref("devtools.debugger.features.windowless-service-workers", true); + // Disable randomly spawning processes during tests + await pushPref("dom.ipc.processPrelaunch.enabled", false); + + // Wait for dom.ipc.processCount to be updated before releasing processes. + Services.ppmm.releaseCachedProcesses(); +} + +async function enableApplicationPanel() { + // FIXME bug 1575427 this rejection is very common. + const { PromiseTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromiseTestUtils.sys.mjs" + ); + PromiseTestUtils.allowMatchingRejectionsGlobally( + /this._frontCreationListeners is null/ + ); + + // Enable all preferences related to service worker debugging. + await enableServiceWorkerDebugging(); + + // Enable web manifest processing. + Services.prefs.setBoolPref("dom.manifest.enabled", true); + + // Enable application panel in DevTools. + await pushPref("devtools.application.enabled", true); +} + +function setupTelemetryTest() { + // Reset all the counts + Services.telemetry.clearEvents(); + + // Ensure no events have been logged + const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS; + const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true); + ok(!snapshot.parent, "No events have been logged for the main process"); +} + +function getTelemetryEvents(objectName) { + // read the requested events only + const ALL_CHANNELS = Ci.nsITelemetry.DATASET_ALL_CHANNELS; + const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true); + // filter and transform the event data so the relevant info is in a single object: + // { method: "...", extraField: "...", anotherExtraField: "...", ... } + const events = snapshot.parent + .filter(event => event[1] === "devtools.main" && event[3] === objectName) + .map(event => ({ method: event[2], ...event[5] })); + + return events; +} + +function checkTelemetryEvent(expectedEvent, objectName = "application") { + info("Check telemetry event"); + const events = getTelemetryEvents(objectName); + + // assert we only got 1 event with a valid session ID + is(events.length, 1, "There was only 1 event logged"); + const [event] = events; + ok(event.session_id > 0, "There is a valid session_id in the event"); + + // assert expected data + Assert.deepEqual(event, { ...expectedEvent, session_id: event.session_id }); +} + +function getWorkerContainers(doc) { + return doc.querySelectorAll(".js-sw-container"); +} + +async function openNewTabAndApplicationPanel(url) { + const tab = await addTab(url); + + const toolbox = await gDevTools.showToolboxForTab(tab, { + toolId: "application", + }); + const panel = toolbox.getCurrentPanel(); + const target = toolbox.target; + const commands = toolbox.commands; + return { panel, tab, target, toolbox, commands }; +} + +async function unregisterAllWorkers(client, doc) { + // This method is declared in shared-head.js + await unregisterAllServiceWorkers(client); + + info("Wait for service workers to disappear from the UI"); + waitUntil(() => getWorkerContainers(doc).length === 0); +} + +async function waitForWorkerRegistration(swTab) { + info("Wait until the registration appears on the window"); + const swBrowser = swTab.linkedBrowser; + await asyncWaitUntil(async () => + SpecialPowers.spawn(swBrowser, [], function () { + return !!content.wrappedJSObject.getRegistration(); + }) + ); +} + +function selectPage(panel, page) { + /** + * Select a page by simulating a user click in the sidebar. + * @param {string} page The page we want to select (see `PAGE_TYPES`) + **/ + info(`Selecting application page: ${page}`); + const doc = panel.panelWin.document; + const navItem = doc.querySelector(`.js-sidebar-${page}`); + navItem.click(); +} diff --git a/devtools/client/application/test/browser/resources/manifest/icon.svg b/devtools/client/application/test/browser/resources/manifest/icon.svg new file mode 100644 index 0000000000..bfed2982bc --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/icon.svg @@ -0,0 +1,4 @@ +<!-- 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/. --> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 953.37 984"><defs><linearGradient id="linear-gradient" x1="-14706.28" y1="9250.14" x2="-14443.04" y2="9250.14" gradientTransform="matrix(0.76, 0.03, 0.05, -1.12, 11485.47, 11148)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0083ff"/><stop offset="0.1" stop-color="#0092f8"/><stop offset="0.31" stop-color="#00abeb"/><stop offset="0.52" stop-color="#00bee1"/><stop offset="0.75" stop-color="#00c8dc"/><stop offset="1" stop-color="#00ccda"/></linearGradient><radialGradient id="radial-gradient" cx="-7588.66" cy="8866.53" r="791.23" gradientTransform="matrix(1.23, 0, 0, -1.22, 9958.21, 11048.11)" gradientUnits="userSpaceOnUse"><stop offset="0.02" stop-color="#005fe7"/><stop offset="0.18" stop-color="#0042b4"/><stop offset="0.32" stop-color="#002989"/><stop offset="0.4" stop-color="#002079"/><stop offset="0.47" stop-color="#131d78"/><stop offset="0.66" stop-color="#3b1676"/><stop offset="0.75" stop-color="#4a1475"/></radialGradient><linearGradient id="linear-gradient-2" x1="539.64" y1="254.8" x2="348.2" y2="881.03" gradientTransform="matrix(1, 0, 0, -1, 1, 984)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#000f43" stop-opacity="0.4"/><stop offset="0.48" stop-color="#001962" stop-opacity="0.17"/><stop offset="1" stop-color="#002079" stop-opacity="0"/></linearGradient><linearGradient id="linear-gradient-3" x1="540.64" y1="254.8" x2="349.2" y2="881.03" gradientTransform="matrix(1, 0, 0, -1, 0, 984)" href="#linear-gradient-2"/><linearGradient id="linear-gradient-4" x1="-8367.12" y1="7348.87" x2="-8482.36" y2="7357.76" gradientTransform="matrix(1.22, 0.12, 0.12, -1.22, 10241.06, 10765.32)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#812cc9"/><stop offset="1" stop-color="#005fe7"/></linearGradient><linearGradient id="linear-gradient-5" x1="-8449.89" y1="7496.97" x2="-8341.94" y2="7609.09" gradientTransform="matrix(1.22, 0.12, 0.12, -1.22, 10241.06, 10765.32)" gradientUnits="userSpaceOnUse"><stop offset="0.05" stop-color="#005fe7"/><stop offset="0.18" stop-color="#065de6"/><stop offset="0.35" stop-color="#1856e1"/><stop offset="0.56" stop-color="#354adb"/><stop offset="0.78" stop-color="#5d3ad1"/><stop offset="0.95" stop-color="#812cc9"/></linearGradient><linearGradient id="linear-gradient-6" x1="-8653.41" y1="7245.3" x2="-8422.52" y2="7244.76" gradientTransform="matrix(1.22, 0.12, 0.12, -1.22, 10241.06, 10765.32)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#002079"/><stop offset="0.99" stop-color="#a238ff"/></linearGradient><radialGradient id="radial-gradient-2" cx="644.11" cy="599.83" fx="785.0454815336918" fy="470.6889181532662" r="793.95" gradientTransform="matrix(1, 0, 0, -1, 0, 984)" gradientUnits="userSpaceOnUse"><stop offset="0.2" stop-color="#00fdff"/><stop offset="0.26" stop-color="#0af1ff"/><stop offset="0.37" stop-color="#23d2ff"/><stop offset="0.52" stop-color="#4da0ff"/><stop offset="0.69" stop-color="#855bff"/><stop offset="0.77" stop-color="#a238ff"/><stop offset="0.81" stop-color="#a738fd"/><stop offset="0.86" stop-color="#b539f9"/><stop offset="0.9" stop-color="#cd39f1"/><stop offset="0.96" stop-color="#ee3ae6"/><stop offset="0.98" stop-color="#ff3be0"/></radialGradient><linearGradient id="linear-gradient-7" x1="-7458.97" y1="9093.17" x2="-7531.06" y2="8282.84" gradientTransform="matrix(1.23, 0, 0, -1.22, 9958.21, 11048.11)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00ec00"/><stop offset="0.1" stop-color="#00e244"/><stop offset="0.22" stop-color="#00d694"/><stop offset="0.31" stop-color="#00cfc7"/><stop offset="0.35" stop-color="#00ccda"/><stop offset="0.42" stop-color="#0bc2dd" stop-opacity="0.92"/><stop offset="0.57" stop-color="#29a7e4" stop-opacity="0.72"/><stop offset="0.77" stop-color="#597df0" stop-opacity="0.4"/><stop offset="1" stop-color="#9448ff" stop-opacity="0"/></linearGradient><linearGradient id="linear-gradient-8" x1="-8926.61" y1="7680.53" x2="-8790.14" y2="7680.53" gradientTransform="matrix(1.22, 0.12, 0.12, -1.22, 10241.06, 10765.32)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#005fe7"/><stop offset="0.46" stop-color="#0071f3" stop-opacity="0.51"/><stop offset="0.83" stop-color="#007efc" stop-opacity="0.14"/><stop offset="1" stop-color="#0083ff" stop-opacity="0"/></linearGradient><radialGradient id="radial-gradient-3" cx="-8914.62" cy="7721.05" r="165.97" gradientTransform="matrix(1.22, 0.12, 0.12, -1.22, 10241.06, 10765.32)" gradientUnits="userSpaceOnUse"><stop offset="0.63" stop-color="#ffe302" stop-opacity="0"/><stop offset="0.67" stop-color="#ffe302" stop-opacity="0.05"/><stop offset="0.75" stop-color="#ffe302" stop-opacity="0.19"/><stop offset="0.86" stop-color="#ffe302" stop-opacity="0.4"/><stop offset="0.99" stop-color="#ffe302" stop-opacity="0.7"/></radialGradient><linearGradient id="linear-gradient-9" x1="214.02" y1="2032.47" x2="96.19" y2="2284.31" gradientTransform="matrix(0.99, 0.1, 0.1, -0.99, -250.1, 2306.29)" gradientUnits="userSpaceOnUse"><stop offset="0.19" stop-color="#4a1475" stop-opacity="0.5"/><stop offset="0.62" stop-color="#2277ac" stop-opacity="0.23"/><stop offset="0.94" stop-color="#00ccda" stop-opacity="0"/></linearGradient><linearGradient id="linear-gradient-10" x1="-38.44" y1="278.18" x2="55.67" y2="171.29" gradientTransform="matrix(0.99, 0.1, 0.1, -0.99, 229.04, 745.87)" gradientUnits="userSpaceOnUse"><stop offset="0.01" stop-color="#002079" stop-opacity="0.5"/><stop offset="1" stop-color="#0083ff" stop-opacity="0"/></linearGradient><linearGradient id="linear-gradient-11" x1="142.45" y1="96.25" x2="142.5" y2="149.68" gradientTransform="matrix(0.99, 0.1, 0.1, -0.99, 229.04, 745.87)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4a1475" stop-opacity="0.9"/><stop offset="0.18" stop-color="#6720a2" stop-opacity="0.6"/><stop offset="0.38" stop-color="#812acb" stop-opacity="0.34"/><stop offset="0.57" stop-color="#9332e8" stop-opacity="0.15"/><stop offset="0.76" stop-color="#9e36f9" stop-opacity="0.04"/><stop offset="0.93" stop-color="#a238ff" stop-opacity="0"/></linearGradient><linearGradient id="linear-gradient-12" x1="620.52" y1="947.88" x2="926.18" y2="264.39" gradientTransform="matrix(1, 0, 0, -1, 0, 984)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00ec00" stop-opacity="0"/><stop offset="0.28" stop-color="#00dc6d" stop-opacity="0.5"/><stop offset="0.5" stop-color="#00d1bb" stop-opacity="0.86"/><stop offset="0.6" stop-color="#00ccda"/><stop offset="0.68" stop-color="#04c9db"/><stop offset="0.75" stop-color="#0fc1df"/><stop offset="0.83" stop-color="#23b2e6"/><stop offset="0.9" stop-color="#3e9ef0"/><stop offset="0.98" stop-color="#6184fc"/><stop offset="0.99" stop-color="#6680fe"/></linearGradient><linearGradient id="linear-gradient-13" x1="680.88" y1="554.79" x2="536.1" y2="166.04" gradientTransform="matrix(1, 0, 0, -1, 0, 984)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0083ff"/><stop offset="0.04" stop-color="#0083ff" stop-opacity="0.92"/><stop offset="0.14" stop-color="#0083ff" stop-opacity="0.71"/><stop offset="0.26" stop-color="#0083ff" stop-opacity="0.52"/><stop offset="0.37" stop-color="#0083ff" stop-opacity="0.36"/><stop offset="0.49" stop-color="#0083ff" stop-opacity="0.23"/><stop offset="0.61" stop-color="#0083ff" stop-opacity="0.13"/><stop offset="0.73" stop-color="#0083ff" stop-opacity="0.06"/><stop offset="0.86" stop-color="#0083ff" stop-opacity="0.01"/><stop offset="1" stop-color="#0083ff" stop-opacity="0"/></linearGradient></defs><title>firefox-logo-nightly</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Layer_2-2" data-name="Layer 2"><g id="Firefox"><path d="M770.28,91.56c-23.95,27.88-35.1,90.64-10.82,154.26s61.5,49.8,84.7,114.67c30.62,85.6,16.37,200.59,16.37,200.59s36.81,106.61,62.47-6.63C979.79,341.74,770.28,143.94,770.28,91.56Z" style="fill:url(#linear-gradient)"/><path id="_Path_" data-name=" Path " d="M476.92,972.83c245.24,0,443.9-199.74,443.9-446s-198.66-446-443.66-446S33.5,280.51,33.5,526.8C33,773.33,231.92,972.83,476.92,972.83Z" style="fill:url(#radial-gradient)"/><path d="M810.67,803.64a246.8,246.8,0,0,1-30.12,18.18,705.31,705.31,0,0,0,38.3-63c9.46-10.47,18.13-20.65,25.19-31.65,3.44-5.41,7.31-12.08,11.42-19.82,24.92-44.9,52.4-117.56,53.18-192.2v-5.66a257.25,257.25,0,0,0-5.71-55.75c.2,1.43.38,2.86.56,4.29-.22-1.1-.41-2.21-.64-3.31.37,2,.66,4,1,6,5.09,43.22,1.47,85.37-16.68,116.45-.29.45-.58.88-.87,1.32,9.41-47.23,12.56-99.39,2.09-151.6,0,0-4.19-25.38-35.38-102.44-18-44.35-49.83-80.72-78-107.21-24.69-30.55-47.11-51-59.47-64.06C689.72,126,678.9,105.61,674.45,92.31c-3.85-1.93-53.14-49.81-57.05-51.63-21.51,33.35-89.16,137.67-57,235.15,14.58,44.17,51.47,90,90.07,115.74,1.69,1.94,23,25,33.09,77.16,10.45,53.85,5,95.86-16.54,158C641.73,681.24,577,735.12,516.3,740.63c-129.67,11.78-177.15-65.11-177.15-65.11C385.49,694,436.72,690.17,467.87,671c31.4-19.43,50.39-33.83,65.81-28.15C548.86,648.43,561,632,550.1,615a78.5,78.5,0,0,0-79.4-34.57c-31.43,5.11-60.23,30-101.41,5.89a86.29,86.29,0,0,1-7.73-5.06c-2.71-1.79,8.83,2.72,6.13.69-8-4.35-22.2-13.84-25.88-17.22-.61-.56,6.22,2.18,5.61,1.62-38.51-31.71-33.7-53.13-32.49-66.57,1-10.75,8-24.52,19.75-30.11,5.69,3.11,9.24,5.48,9.24,5.48s-2.43-5-3.74-7.58c.46-.2.9-.15,1.36-.34,4.66,2.25,15,8.1,20.41,11.67,7.07,5,9.33,9.44,9.33,9.44s1.86-1,.48-5.37c-.5-1.78-2.65-7.45-9.65-13.17h.44A81.61,81.61,0,0,1,374.42,478c2-7.18,5.53-14.68,4.75-28.09-.48-9.43-.26-11.87-1.92-15.51-1.49-3.13.83-4.35,3.42-1.1a32.5,32.5,0,0,0-2.21-7.4v-.24c3.23-11.24,68.25-40.46,73-43.88A67.2,67.2,0,0,0,470.59,361c3.62-5.76,6.34-13.85,7-26.11.36-8.84-3.76-14.73-69.51-21.62-18-1.77-28.53-14.8-34.53-26.82-1.09-2.59-2.21-4.94-3.33-7.28a57.68,57.68,0,0,1-2.56-8.43c10.75-30.87,28.81-57,55.37-76.7,1.45-1.32-5.78.34-4.34-1,1.69-1.54,12.71-6,14.79-7,2.54-1.2-10.88-6.9-22.73-5.51-12.07,1.36-14.63,2.8-21.07,5.53,2.67-2.66,11.17-6.15,9.18-6.13-13,2-29.18,9.56-43,18.12a10.66,10.66,0,0,1,.83-4.35c-6.44,2.73-22.26,13.79-26.87,23.14a44.29,44.29,0,0,0,.27-5.4,84.17,84.17,0,0,0-13.19,13.82l-.24.22c-37.36-15-70.23-16-98.05-9.28-6.09-6.11-9.06-1.64-22.91-32.07-.94-1.83.72,1.81,0,0-2.28-5.9,1.39,7.87,0,0-23.28,18.37-53.92,39.19-68.63,53.89-.18.59,17.16-4.9,0,0-6,1.72-5.6,5.28-6.51,37.5-.22,2.44,0,5.18-.22,7.38-11.75,15-19.75,27.64-22.78,34.21-15.19,26.18-31.93,67-48.15,131.55A334.82,334.82,0,0,1,75.2,398.36C61.71,432.63,48.67,486.44,46.07,569.3A482.08,482.08,0,0,1,58.6,518.64,473,473,0,0,0,93.33,719.71c9.33,22.82,24.76,57.46,51,95.4C226.9,902,343.31,956,472.21,956,606.79,956,727.64,897.13,810.67,803.64Z" style="fill:url(#linear-gradient-2)"/><path d="M810.67,803.64a246.8,246.8,0,0,1-30.12,18.18,705.31,705.31,0,0,0,38.3-63c9.46-10.47,18.13-20.65,25.19-31.65,3.44-5.41,7.31-12.08,11.42-19.82,24.92-44.9,52.4-117.56,53.18-192.2v-5.66a257.25,257.25,0,0,0-5.71-55.75c.2,1.43.38,2.86.56,4.29-.22-1.1-.41-2.21-.64-3.31.37,2,.66,4,1,6,5.09,43.22,1.47,85.37-16.68,116.45-.29.45-.58.88-.87,1.32,9.41-47.23,12.56-99.39,2.09-151.6,0,0-4.19-25.38-35.38-102.44-18-44.35-49.83-80.72-78-107.21-24.69-30.55-47.11-51-59.47-64.06C689.72,126,678.9,105.61,674.45,92.31c-3.85-1.93-53.14-49.81-57.05-51.63-21.51,33.35-89.16,137.67-57,235.15,14.58,44.17,51.47,90,90.07,115.74,1.69,1.94,23,25,33.09,77.16,10.45,53.85,5,95.86-16.54,158C641.73,681.24,577,735.12,516.3,740.63c-129.67,11.78-177.15-65.11-177.15-65.11C385.49,694,436.72,690.17,467.87,671c31.4-19.43,50.39-33.83,65.81-28.15C548.86,648.43,561,632,550.1,615a78.5,78.5,0,0,0-79.4-34.57c-31.43,5.11-60.23,30-101.41,5.89a86.29,86.29,0,0,1-7.73-5.06c-2.71-1.79,8.83,2.72,6.13.69-8-4.35-22.2-13.84-25.88-17.22-.61-.56,6.22,2.18,5.61,1.62-38.51-31.71-33.7-53.13-32.49-66.57,1-10.75,8-24.52,19.75-30.11,5.69,3.11,9.24,5.48,9.24,5.48s-2.43-5-3.74-7.58c.46-.2.9-.15,1.36-.34,4.66,2.25,15,8.1,20.41,11.67,7.07,5,9.33,9.44,9.33,9.44s1.86-1,.48-5.37c-.5-1.78-2.65-7.45-9.65-13.17h.44A81.61,81.61,0,0,1,374.42,478c2-7.18,5.53-14.68,4.75-28.09-.48-9.43-.26-11.87-1.92-15.51-1.49-3.13.83-4.35,3.42-1.1a32.5,32.5,0,0,0-2.21-7.4v-.24c3.23-11.24,68.25-40.46,73-43.88A67.2,67.2,0,0,0,470.59,361c3.62-5.76,6.34-13.85,7-26.11.36-8.84-3.76-14.73-69.51-21.62-18-1.77-28.53-14.8-34.53-26.82-1.09-2.59-2.21-4.94-3.33-7.28a57.68,57.68,0,0,1-2.56-8.43c10.75-30.87,28.81-57,55.37-76.7,1.45-1.32-5.78.34-4.34-1,1.69-1.54,12.71-6,14.79-7,2.54-1.2-10.88-6.9-22.73-5.51-12.07,1.36-14.63,2.8-21.07,5.53,2.67-2.66,11.17-6.15,9.18-6.13-13,2-29.18,9.56-43,18.12a10.66,10.66,0,0,1,.83-4.35c-6.44,2.73-22.26,13.79-26.87,23.14a44.29,44.29,0,0,0,.27-5.4,84.17,84.17,0,0,0-13.19,13.82l-.24.22c-37.36-15-70.23-16-98.05-9.28-6.09-6.11-9.06-1.64-22.91-32.07-.94-1.83.72,1.81,0,0-2.28-5.9,1.39,7.87,0,0-23.28,18.37-53.92,39.19-68.63,53.89-.18.59,17.16-4.9,0,0-6,1.72-5.6,5.28-6.51,37.5-.22,2.44,0,5.18-.22,7.38-11.75,15-19.75,27.64-22.78,34.21-15.19,26.18-31.93,67-48.15,131.55A334.82,334.82,0,0,1,75.2,398.36C61.71,432.63,48.67,486.44,46.07,569.3A482.08,482.08,0,0,1,58.6,518.64,473,473,0,0,0,93.33,719.71c9.33,22.82,24.76,57.46,51,95.4C226.9,902,343.31,956,472.21,956,606.79,956,727.64,897.13,810.67,803.64Z" style="fill:url(#linear-gradient-3)"/><path d="M711.1,866.71c162.87-18.86,235-186.7,142.38-190C769.85,674,634,875.61,711.1,866.71Z" style="fill:url(#linear-gradient-4)"/><path d="M865.21,642.42C977.26,577.21,948,436.34,948,436.34s-43.25,50.24-72.62,130.32C846.4,646,797.84,681.81,865.21,642.42Z" style="fill:url(#linear-gradient-5)"/><path d="M509.47,950.06C665.7,999.91,800,876.84,717.21,835.74,642,798.68,435.32,926.49,509.47,950.06Z" style="fill:url(#linear-gradient-6)"/><path d="M638.58,21.42l.53-.57A1.7,1.7,0,0,0,638.58,21.42ZM876.85,702.23c3.8-5.36,8.94-22.53,13.48-30.21,27.58-44.52,27.78-80,27.78-80.84,16.66-83.22,15.15-117.2,4.9-180-8.25-50.6-44.32-123.09-75.57-158-32.2-36-9.51-24.25-40.69-50.52-27.33-30.29-53.82-60.29-68.25-72.36C634.22,43.09,636.57,24.58,638.58,21.42c-.34.37-.84.92-1.47,1.64C635.87,18.14,635,14,635,14s-57,57-69,152c-7.83,62,15.38,126.68,49,168a381.62,381.62,0,0,0,59,58h0c25.4,36.48,39.38,81.49,39.38,129.91,0,121.24-98.34,219.53-219.65,219.53a220.14,220.14,0,0,1-49.13-5.52c-57.24-10.92-90.3-39.8-106.78-59.41-9.45-11.23-13.46-19.42-13.46-19.42,51.28,18.37,108,14.53,142.47-4.52,34.75-19.26,55.77-33.55,72.84-27.92,16.82,5.61,30.21-10.67,18.2-27.54-11.77-16.85-42.4-41-87.88-34.29-34.79,5.07-66.66,29.76-112.24,5.84a97.34,97.34,0,0,1-8.55-5c-3-1.77,9.77,2.69,6.79.68-8.87-4.32-24.57-13.73-28.64-17.07-.68-.56,6.88,2.16,6.2,1.6-42.62-31.45-37.3-52.69-36-66,1.07-10.66,8.81-24.32,21.86-29.86,6.3,3.08,10.23,5.43,10.23,5.43s-2.69-4.92-4.14-7.51c.51-.19,1-.15,1.5-.34,5.16,2.23,16.58,8,22.59,11.57,7.83,4.95,10.32,9.36,10.32,9.36s2.06-1,.54-5.33c-.56-1.77-2.93-7.39-10.68-13.07h.48a91.65,91.65,0,0,1,13.13,8.17c2.19-7.12,6.12-14.56,5.25-27.86-.53-9.35-.28-11.78-2.12-15.39-1.65-3.1.92-4.31,3.78-1.09a29.73,29.73,0,0,0-2.44-7.34v-.24c3.57-11.14,75.53-40.12,80.77-43.51a70.24,70.24,0,0,0,21.17-20.63c4-5.72,7-13.73,7.75-25.89.25-5.48-1.44-9.82-20.5-14-11.44-2.49-29.14-4.91-56.43-7.47-19.9-1.76-31.58-14.68-38.21-26.6-1.21-2.57-2.45-4.9-3.68-7.22a53.41,53.41,0,0,1-2.83-8.36,158.47,158.47,0,0,1,61.28-76.06c1.6-1.31-6.4.33-4.8-1,1.87-1.52,14.06-5.93,16.37-6.92,2.81-1.19-12-6.84-25.16-5.47-13.36,1.35-16.19,2.78-23.32,5.49,3-2.64,12.37-6.1,10.16-6.08-14.4,2-32.3,9.48-47.6,18a9.72,9.72,0,0,1,.92-4.31c-7.13,2.71-24.64,13.67-29.73,23a39.79,39.79,0,0,0,.29-5.35,88.55,88.55,0,0,0-14.6,13.7l-.27.22C258.14,196,221.75,195,191,201.72c-6.74-6.06-17.57-15.23-32.89-45.4-1-1.82-1.6,3.75-2.4,2-6-13.81-9.55-36.44-9-52,0,0-12.32,5.61-22.51,29.06-1.89,4.21-3.11,6.54-4.32,8.87-.56.68,1.27-7.7,1-7.24-1.77,3-6.36,7.19-8.37,12.62-1.38,4-3.32,6.27-4.56,11.29l-.29.46c-.1-1.48.37-6.08,0-5.14A235.4,235.4,0,0,0,95.34,186c-5.49,18-11.88,42.61-12.89,74.57-.24,2.42,0,5.14-.25,7.32-13,14.83-21.86,27.39-25.2,33.91-16.81,26-35.33,66.44-53.29,130.46a319.35,319.35,0,0,1,28.54-50C17.32,416.25,2.89,469.62,0,551.8a436.92,436.92,0,0,1,13.87-50.24C11.29,556.36,17.68,624.3,52.32,701c20.57,45,67.92,136.6,183.62,208h0s39.36,29.3,107,51.26c5,1.81,10.06,3.6,15.23,5.33q-2.43-1-4.71-2A484.9,484.9,0,0,0,492.27,984c175.18.15,226.85-70.2,226.85-70.2l-.51.38q3.71-3.49,7.14-7.26c-27.64,26.08-90.75,27.84-114.3,26,40.22-11.81,66.69-21.81,118.17-41.52q9-3.36,18.48-7.64l2-.94c1.25-.58,2.49-1.13,3.75-1.74a349.3,349.3,0,0,0,70.26-44c51.7-41.3,63-81.56,68.83-108.1-.82,2.54-3.37,8.47-5.17,12.32-13.31,28.48-42.84,46-74.91,61a689.05,689.05,0,0,0,42.38-62.44C865.77,729.39,869,713.15,876.85,702.23Z" style="fill:url(#radial-gradient-2)"/><path d="M813.92,801c21.08-23.24,40-49.82,54.35-80,36.9-77.58,94-206.58,49-341.31C881.77,273.22,833,215,771.11,158.12,670.56,65.76,642.48,24.52,642.48,0c0,0-116.09,129.41-65.74,264.38s153.46,130,221.68,270.87c80.27,165.74-64.95,346.61-185,397.24,7.35-1.63,267-60.38,280.61-208.88C893.68,726.34,887.83,767.41,813.92,801Z" style="fill:url(#linear-gradient-7)"/><path d="M477.59,319.37c.39-8.77-4.16-14.66-76.68-21.46-29.84-2.76-41.26-30.33-44.75-41.94-10.61,27.56-15,56.49-12.64,91.48,1.61,22.92,17,47.52,24.37,62,0,0,1.64-2.13,2.39-2.91,13.86-14.43,71.94-36.42,77.39-39.54C453.69,363.16,476.58,346.44,477.59,319.37Z" style="fill:url(#linear-gradient-8)"/><path d="M477.59,319.37c.39-8.77-4.16-14.66-76.68-21.46-29.84-2.76-41.26-30.33-44.75-41.94-10.61,27.56-15,56.49-12.64,91.48,1.61,22.92,17,47.52,24.37,62,0,0,1.64-2.13,2.39-2.91,13.86-14.43,71.94-36.42,77.39-39.54C453.69,363.16,476.58,346.44,477.59,319.37Z" style="opacity:0.5;isolation:isolate;fill:url(#radial-gradient-3)"/><path d="M158.31,156.47c-1-1.82-1.6,3.75-2.4,2-6-13.81-9.58-36.2-8.72-52,0,0-12.32,5.61-22.51,29.06-1.89,4.21-3.11,6.54-4.32,8.86-.56.68,1.27-7.7,1-7.24-1.77,3-6.36,7.19-8.35,12.38-1.65,4.24-3.35,6.52-4.61,11.77-.39,1.43.39-6.32,0-5.38C84.72,201.68,80.19,271,82.69,268,133.17,214.14,191,201.36,191,201.36c-6.15-4.53-19.53-17.63-32.7-44.89Z" style="fill:url(#linear-gradient-9)"/><path d="M349.84,720.1c-69.72-29.77-149-71.75-146-167.14C207.92,427.35,321,452.18,321,452.18c-4.27,1-15.68,9.16-19.72,17.82-4.27,10.83-12.07,35.28,11.55,60.9,37.09,40.19-76.2,95.36,98.66,199.57,4.41,2.4-41-1.43-61.64-10.36Z" style="fill:url(#linear-gradient-10)"/><path d="M325.07,657.5c49.44,17.21,107,14.19,141.52-4.86,23.09-12.85,52.7-33.43,70.92-28.35-15.78-6.24-27.73-9.15-42.1-9.86-2.45,0-5.38,0-8-.32a136,136,0,0,0-15.76.86c-8.9.82-18.77,6.43-27.74,5.53-.48,0,8.7-3.77,8-3.61-4.75,1-9.92,1.21-15.37,1.88-3.47.39-6.45.82-9.89,1-103,8.73-190-55.81-190-55.81-7.41,25,33.17,74.3,88.52,93.57Z" style="opacity:0.5;isolation:isolate;fill:url(#linear-gradient-11)"/><path d="M813.74,801.65c104.16-102.27,156.86-226.58,134.58-366,0,0,8.9,71.5-24.85,144.63,16.21-71.39,18.1-160.11-25-252C841,205.64,746.45,141.11,710.35,114.19,655.66,73.4,633,31.87,632.57,23.3c-16.34,33.48-65.77,148.2-5.31,247,56.64,92.56,145.86,120,208.33,205C950.67,631.67,813.74,801.65,813.74,801.65Z" style="fill:url(#linear-gradient-12)"/><path d="M798.81,535.55C762.41,460.35,717,427.55,674,392c5,7,6.23,9.47,9,14,37.83,40.32,93.61,138.66,53.11,262.11C659.88,900.48,355,791.06,323,760.32,335.93,894.81,561,959.16,707.6,872,791,793,858.47,658.79,798.81,535.55Z" style="fill:url(#linear-gradient-13)"/></g></g></g></g></svg> diff --git a/devtools/client/application/test/browser/resources/manifest/load-fail.html b/devtools/client/application/test/browser/resources/manifest/load-fail.html new file mode 100644 index 0000000000..180c42a7b5 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-fail.html @@ -0,0 +1,9 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Manifest 404 not found</title> + <link rel="manifest" href='nowhere.json'> +</head> +<body> +<h1>Manifest error 404 not found</h1> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-no-manifest.html b/devtools/client/application/test/browser/resources/manifest/load-no-manifest.html new file mode 100644 index 0000000000..aeabc8a0cb --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-no-manifest.html @@ -0,0 +1,8 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>No manifest link</title> +</head> +<body> +<h1>No manifest <code>link</code> tag.</h1> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-ok-icons.html b/devtools/client/application/test/browser/resources/manifest/load-ok-icons.html new file mode 100644 index 0000000000..539e5d2247 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-ok-icons.html @@ -0,0 +1,9 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Manifest successful load (with icons)</title> + <link rel="manifest" href='data:application/manifest+json,{"name": "Foo", "background_color": "%23ff0000", "icons": [{ "sizes": "128x128", "src": "http://example.com/browser/devtools/client/application/test/browser/resources/manifest/icon.svg", "type": "image/svg"}]}'> +</head> +<body> +<h1>Manifest OK (with icons)</h1> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-ok-json-error.html b/devtools/client/application/test/browser/resources/manifest/load-ok-json-error.html new file mode 100644 index 0000000000..95ad22b609 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-ok-json-error.html @@ -0,0 +1,10 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Manifest successful load with a warning</title> + <link rel="manifest" href='data:application/manifest+json,{"name": "Foo}'> +</head> +<body> +<h1>Manifest OK with validation errors</h1> +<p>The manifest has invalid JSON</p> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-ok-manifest-link.html b/devtools/client/application/test/browser/resources/manifest/load-ok-manifest-link.html new file mode 100644 index 0000000000..f336f409e3 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-ok-manifest-link.html @@ -0,0 +1,9 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Successful load for a linked manifest</title> + <link rel="manifest" href='manifest.json'> +</head> +<body> +<h1>Manifest OK (linked manifest)</h1> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-ok-warnings.html b/devtools/client/application/test/browser/resources/manifest/load-ok-warnings.html new file mode 100644 index 0000000000..467d6c3e70 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-ok-warnings.html @@ -0,0 +1,10 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Manifest successful load with a warning</title> + <link rel="manifest" href='data:application/manifest+json,{"name": "Foo", "background_color": 42}'> +</head> +<body> +<h1>Manifest OK with validation warnings</h1> +<p><code>background_color</code> does not contain a valid CSS color.</p> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/load-ok.html b/devtools/client/application/test/browser/resources/manifest/load-ok.html new file mode 100644 index 0000000000..1e6f5de59e --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/load-ok.html @@ -0,0 +1,9 @@ +<!doctype html> +<head> + <meta charset="utf-8"> + <title>Manifest successful load</title> + <link rel="manifest" href='data:application/manifest+json,{"name": "Foo", "background_color": "%23ff0000"}'> +</head> +<body> +<h1>Manifest OK</h1> +</body> diff --git a/devtools/client/application/test/browser/resources/manifest/manifest.json b/devtools/client/application/test/browser/resources/manifest/manifest.json new file mode 100644 index 0000000000..0bc7bb50a3 --- /dev/null +++ b/devtools/client/application/test/browser/resources/manifest/manifest.json @@ -0,0 +1,3 @@ +{ + "name": "Foo" +} diff --git a/devtools/client/application/test/browser/resources/service-workers/controlled-install-sw.js b/devtools/client/application/test/browser/resources/service-workers/controlled-install-sw.js new file mode 100644 index 0000000000..d0a70a5312 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/controlled-install-sw.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Copied from shared-head.js +function waitUntil(predicate, interval = 10) { + if (predicate()) { + return Promise.resolve(true); + } + return new Promise(resolve => { + setTimeout(function () { + waitUntil(predicate, interval).then(() => resolve(true)); + }, interval); + }); +} + +// this flag will be flipped externally from controlled-install.html +// by sending a message event to the worker +let canInstall = false; +self.addEventListener("message", event => { + if (event.data === "install-service-worker") { + canInstall = true; + } +}); + +self.addEventListener("install", event => { + event.waitUntil(waitUntil(() => canInstall)); +}); diff --git a/devtools/client/application/test/browser/resources/service-workers/controlled-install.html b/devtools/client/application/test/browser/resources/service-workers/controlled-install.html new file mode 100644 index 0000000000..300ee1fde7 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/controlled-install.html @@ -0,0 +1,27 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +let registration; + +window.registerServiceWorker = async function() { + registration = await navigator.serviceWorker.register( + "controlled-install-sw.js" + ); + window.sw = registration; +}; + +window.installServiceWorker = function() { + registration.installing.postMessage("install-service-worker"); +}; +</script> +</body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/debug-sw.js b/devtools/client/application/test/browser/resources/service-workers/debug-sw.js new file mode 100644 index 0000000000..31f0b1bdd2 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/debug-sw.js @@ -0,0 +1,18 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +self.addEventListener("activate", event => { + event.waitUntil(self.clients.claim()); +}); + +self.onfetch = function (event) { + const url = event.request.url; + + const response = url.endsWith("test") + ? new Response("lorem ipsum", { statusText: "OK" }) + : fetch(event.request); + + event.respondWith(response); +}; diff --git a/devtools/client/application/test/browser/resources/service-workers/debug.html b/devtools/client/application/test/browser/resources/service-workers/debug.html new file mode 100644 index 0000000000..f0f16858fd --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/debug.html @@ -0,0 +1,25 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> + +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; +window.sw = navigator.serviceWorker.register("debug-sw.js"); + +/* exported fetchFromWorker */ +async function fetchFromWorker() { + const response = await fetch("test"); + const text = await response.text(); + console.log(`Response from worker: ${text}`); +} +</script> + +<p>This page has a <code>fetchFromWorker()</code> function.</p> +</body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/dynamic-registration.html b/devtools/client/application/test/browser/resources/service-workers/dynamic-registration.html new file mode 100644 index 0000000000..def300da65 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/dynamic-registration.html @@ -0,0 +1,19 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +window.registerServiceWorker = function() { + window.sw = navigator.serviceWorker.register("empty-sw.js"); +}; + +</script> +</body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/empty-sw.js b/devtools/client/application/test/browser/resources/service-workers/empty-sw.js new file mode 100644 index 0000000000..5d33297056 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/empty-sw.js @@ -0,0 +1,4 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Empty, just test registering. diff --git a/devtools/client/application/test/browser/resources/service-workers/empty.html b/devtools/client/application/test/browser/resources/service-workers/empty.html new file mode 100644 index 0000000000..02373ca02e --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/empty.html @@ -0,0 +1,11 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> + +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test (no worker, empty page)</title> +</head> +<body></body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/scope-page.html b/devtools/client/application/test/browser/resources/service-workers/scope-page.html new file mode 100644 index 0000000000..eed5bc82ed --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/scope-page.html @@ -0,0 +1,19 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +window.sw = navigator.serviceWorker.register("empty-sw.js", { + scope: "./scope-page.html", +}); + +</script> +</body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/simple-unicode.html b/devtools/client/application/test/browser/resources/service-workers/simple-unicode.html new file mode 100644 index 0000000000..51e17b7fec --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/simple-unicode.html @@ -0,0 +1,15 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; +window.sw = navigator.serviceWorker.register("empty-sw.js?q=日本"); +</script> +</body> +</html> diff --git a/devtools/client/application/test/browser/resources/service-workers/simple.html b/devtools/client/application/test/browser/resources/service-workers/simple.html new file mode 100644 index 0000000000..88dc00aff0 --- /dev/null +++ b/devtools/client/application/test/browser/resources/service-workers/simple.html @@ -0,0 +1,32 @@ +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <meta charset="UTF-8"> + <title>Service worker test</title> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +let registration; + +const registerServiceWorker = async function() { + try { + registration = await navigator.serviceWorker.register("empty-sw.js"); + dump("Empty service worker registered\n"); + } catch (e) { + dump("Empty service worker not registered: " + e + "\n"); + } +}; + +// Helper called from head.js to unregister the service worker. +window.getRegistration = function() { + return registration; +}; +// Register the service worker. +registerServiceWorker(); +</script> +</body> +</html> |