summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js')
-rw-r--r--devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js250
1 files changed, 250 insertions, 0 deletions
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
new file mode 100644
index 0000000000..0c55538a49
--- /dev/null
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js
@@ -0,0 +1,250 @@
+/* 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/>. */
+
+// Verify that we hit breakpoints on popups
+
+"use strict";
+
+const TEST_URI = "https://example.org/document-builder.sjs?html=main page";
+const POPUP_URL = `https://example.com/document-builder.sjs?html=${escape(`popup for breakpoints
+ <script>
+ var paused = true;
+ console.log('popup');
+ paused = false;
+ </script>
+`)}`;
+const POPUP_DEBUGGER_STATEMENT_URL = `https://example.com/document-builder.sjs?html=${escape(`popup with debugger;
+ <script>
+ var paused = true;
+ debugger;
+ paused = false;
+ </script>
+`)}`;
+
+function isPopupPaused(popupBrowsingContext) {
+ return SpecialPowers.spawn(popupBrowsingContext, [], function (url) {
+ return content.wrappedJSObject.paused;
+ });
+}
+
+async function openPopup(popupUrl, browser = gBrowser.selectedBrowser) {
+ const onPopupTabSelected = BrowserTestUtils.waitForEvent(
+ gBrowser.tabContainer,
+ "TabSelect"
+ );
+ const popupBrowsingContext = await SpecialPowers.spawn(
+ browser,
+ [popupUrl],
+ function (url) {
+ const popup = content.open(url);
+ return popup.browsingContext;
+ }
+ );
+ await onPopupTabSelected;
+ is(
+ gBrowser.selectedBrowser.browsingContext,
+ popupBrowsingContext,
+ "The popup is the selected tab"
+ );
+ return popupBrowsingContext;
+}
+
+async function closePopup(browsingContext) {
+ const onPreviousTabSelected = BrowserTestUtils.waitForEvent(
+ gBrowser.tabContainer,
+ "TabSelect"
+ );
+ await SpecialPowers.spawn(browsingContext, [], function () {
+ content.close();
+ });
+ await onPreviousTabSelected;
+}
+
+add_task(async function testPausedByBreakpoint() {
+ await pushPref("devtools.popups.debug", true);
+
+ info("Test breakpoints set in popup scripts");
+ const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
+
+ info("Open the popup in order to be able to set a breakpoint");
+ const firstPopupBrowsingContext = await openPopup(POPUP_URL);
+
+ await waitForSource(dbg, POPUP_URL);
+ const source = findSource(dbg, POPUP_URL);
+
+ await selectSource(dbg, source);
+ await addBreakpoint(dbg, source, 4);
+
+ info("Now close and reopen the popup");
+ await closePopup(firstPopupBrowsingContext);
+
+ info("Re-open the popup");
+ const popupBrowsingContext = await openPopup(POPUP_URL);
+ await waitForPaused(dbg);
+ is(
+ await isPopupPaused(popupBrowsingContext),
+ true,
+ "The popup is really paused"
+ );
+
+ await waitForSource(dbg, POPUP_URL);
+ assertPausedAtSourceAndLine(dbg, source.id, 4);
+
+ await resume(dbg);
+ is(
+ await isPopupPaused(popupBrowsingContext),
+ false,
+ "The popup resumed its execution"
+ );
+});
+
+add_task(async function testPausedByDebuggerStatement() {
+ info("Test debugger statements in popup scripts");
+ const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
+
+ info("Open a popup with a debugger statement");
+ const popupBrowsingContext = await openPopup(POPUP_DEBUGGER_STATEMENT_URL);
+ await waitForPaused(dbg);
+ is(
+ await isPopupPaused(popupBrowsingContext),
+ true,
+ "The popup is really paused"
+ );
+
+ const source = findSource(dbg, POPUP_DEBUGGER_STATEMENT_URL);
+ assertPausedAtSourceAndLine(dbg, source.id, 4);
+
+ await resume(dbg);
+ is(
+ await isPopupPaused(popupBrowsingContext),
+ false,
+ "The popup resumed its execution"
+ );
+});
+
+add_task(async function testPausedInTwoPopups() {
+ info("Test being paused in two popup at the same time");
+ const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
+
+ info("Open the popup in order to be able to set a breakpoint");
+ const browser = gBrowser.selectedBrowser;
+ const popupBrowsingContext = await openPopup(POPUP_URL);
+
+ await waitForSource(dbg, POPUP_URL);
+ const source = findSource(dbg, POPUP_URL);
+
+ await selectSource(dbg, source);
+ await addBreakpoint(dbg, source, 4);
+
+ info("Now close and reopen the popup");
+ await closePopup(popupBrowsingContext);
+
+ info("Open a first popup which will hit the breakpoint");
+ const firstPopupBrowsingContext = await openPopup(POPUP_URL);
+ await waitForPaused(dbg);
+ const { targetCommand } = dbg.commands;
+ const firstTarget = targetCommand
+ .getAllTargets([targetCommand.TYPES.FRAME])
+ .find(targetFront => targetFront.url == POPUP_URL);
+ is(
+ firstTarget.browsingContextID,
+ firstPopupBrowsingContext.id,
+ "The popup target matches the popup BrowsingContext"
+ );
+ const firstThread = (await firstTarget.getFront("thread")).actorID;
+ is(
+ dbg.selectors.getCurrentThread(),
+ firstThread,
+ "The popup thread is automatically selected on pause"
+ );
+ is(
+ await isPopupPaused(firstPopupBrowsingContext),
+ true,
+ "The first popup is really paused"
+ );
+
+ info("Open a second popup which will also hit the breakpoint");
+ let onAvailable;
+ const onNewTarget = new Promise(resolve => {
+ onAvailable = ({ targetFront }) => {
+ if (
+ targetFront.url == POPUP_URL &&
+ targetFront.browsingContextID != firstPopupBrowsingContext.id
+ ) {
+ targetCommand.unwatchTargets({
+ types: [targetCommand.TYPES.FRAME],
+ onAvailable,
+ });
+ resolve(targetFront);
+ }
+ };
+ });
+ await targetCommand.watchTargets({
+ types: [targetCommand.TYPES.FRAME],
+ onAvailable,
+ });
+ const secondPopupBrowsingContext = await openPopup(POPUP_URL, browser);
+ info("Wait for second popup's target");
+ const popupTarget = await onNewTarget;
+ is(
+ popupTarget.browsingContextID,
+ secondPopupBrowsingContext.id,
+ "The new target matches the popup WindowGlobal"
+ );
+ const secondThread = (await popupTarget.getFront("thread")).actorID;
+ await waitForPausedThread(dbg, secondThread);
+ is(
+ dbg.selectors.getCurrentThread(),
+ secondThread,
+ "The second popup thread is automatically selected on pause"
+ );
+ is(
+ await isPopupPaused(secondPopupBrowsingContext),
+ true,
+ "The second popup is really paused"
+ );
+
+ info("Resume the execution of the second popup");
+ await resume(dbg);
+ is(
+ await isPopupPaused(secondPopupBrowsingContext),
+ false,
+ "The second popup resumed its execution"
+ );
+ is(
+ await isPopupPaused(firstPopupBrowsingContext),
+ true,
+ "The first popup is still paused"
+ );
+
+ info("Resume the execution of the first popup");
+ await dbg.actions.selectThread(getContext(dbg), firstThread);
+ await resume(dbg);
+ is(
+ await isPopupPaused(firstPopupBrowsingContext),
+ false,
+ "The first popup resumed its execution"
+ );
+});
+
+add_task(async function testClosingOriginalTab() {
+ info(
+ "Test closing the toolbox on the original tab while the popup is kept open"
+ );
+ const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
+ await dbg.toolbox.selectTool("webconsole");
+
+ info("Open a popup");
+ const originalTab = gBrowser.selectedTab;
+ await openPopup("about:blank");
+ await wait(1000);
+ const popupTab = gBrowser.selectedTab;
+ gBrowser.selectedTab = originalTab;
+ info("Close the toolbox from the original tab");
+ await dbg.toolbox.closeToolbox();
+ await wait(1000);
+ info("Re-select the popup");
+ gBrowser.selectedTab = popupTab;
+ await wait(1000);
+});