/* 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 . */
// Tests pretty-printing of HTML file and its inner scripts.
"use strict";
const TEST_FILENAME = `doc-pretty-print-inline-scripts.html`;
const PRETTY_PRINTED_FILENAME = `${TEST_FILENAME}:formatted`;
const BREAKABLE_LINE_HINT_CHAR = `➤`;
// Import helpers for the inspector
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js",
this
);
add_task(async function () {
const dbg = await initDebugger(TEST_FILENAME);
await selectSource(dbg, TEST_FILENAME);
clickElement(dbg, "prettyPrintButton");
await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME);
const prettyPrintedSource = findSourceContent(dbg, PRETTY_PRINTED_FILENAME);
ok(prettyPrintedSource, "Pretty-printed source exists");
info("Check that the HTML file was pretty-printed as expected");
const expectedPrettyHtml = getExpectedPrettyPrintedHtml();
is(
prettyPrintedSource.value,
// ➤ is used to indicate breakable lines, we remove them to assert the actual
// content of the editor.
expectedPrettyHtml.replaceAll(BREAKABLE_LINE_HINT_CHAR, ""),
"HTML file is pretty printed as expected"
);
info("Check breakable lines");
const htmlLines = expectedPrettyHtml.split("\n");
const expectedBreakableLines = [];
htmlLines.forEach((line, index) => {
if (line.startsWith(BREAKABLE_LINE_HINT_CHAR)) {
// Lines in the debugger are 1-based
expectedBreakableLines.push(index + 1);
}
});
await assertBreakableLines(
dbg,
PRETTY_PRINTED_FILENAME,
htmlLines.length,
expectedBreakableLines
);
info("Check that console messages are pointing to pretty-printed file");
const { toolbox } = dbg;
await toolbox.selectTool("webconsole");
const { hud } = await dbg.toolbox.getPanel("webconsole");
info("Wait until messages are sourcemapped");
await waitFor(
() => !!findMessageByType(hud, PRETTY_PRINTED_FILENAME, ".log")
);
const firstMessage = await waitFor(() =>
findMessageByType(hud, "User information", ".log")
);
const firstMessageLink = firstMessage.querySelector(".frame-link-source");
is(
firstMessageLink.innerText,
`${PRETTY_PRINTED_FILENAME}:18:8`,
"first console message has expected location"
);
info(
"Click on the link of the first message to open the file in the debugger"
);
firstMessageLink.click();
await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME);
ok(true, "pretty printed file was selected in debugger…");
await waitForSelectedLocation(dbg, 18);
ok(true, "…at the expected location");
info("Go back to the console to check an other message");
await toolbox.selectTool("webconsole");
const secondMessage = await waitFor(() =>
findMessageByType(hud, "42 yay", ".log")
);
const secondMessageLink = secondMessage.querySelector(".frame-link-source");
is(
secondMessageLink.innerText,
`${PRETTY_PRINTED_FILENAME}:41:12`,
"second console message has expected location"
);
info(
"Click on the link of the second message to open the file in the debugger"
);
secondMessageLink.click();
await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME);
ok(true, "pretty printed file was selected in debugger…");
await waitForSelectedLocation(dbg, 41);
ok(true, "…at the expected location");
info("Check that event listener popup is pointing to pretty-printed file");
const inspector = await toolbox.selectTool("inspector");
const nodeFront = await getNodeFront("h1", inspector);
const markupContainer = inspector.markup.getContainer(nodeFront);
const evHolder = markupContainer.elt.querySelector(
".inspector-badge.interactive[data-event]"
);
const eventTooltip = inspector.markup.eventDetailsTooltip;
info("Open event tooltip.");
EventUtils.synthesizeMouseAtCenter(
evHolder,
{},
inspector.markup.doc.defaultView
);
await eventTooltip.once("shown");
ok(true, "event tooltip opened");
// wait for filename to be sourcemapped
await waitFor(() =>
eventTooltip.panel
.querySelector(".event-header")
?.innerText.includes(PRETTY_PRINTED_FILENAME)
);
const header = eventTooltip.panel.querySelector(".event-header");
const headerFilename = header.querySelector(
".event-tooltip-filename"
).innerText;
ok(
headerFilename.endsWith(`${PRETTY_PRINTED_FILENAME}:51`),
`Location in event tooltip is the pretty printed one (${headerFilename})`
);
info(
"Check that clicking on open debugger icon selects the pretty printed file"
);
header.querySelector(".event-tooltip-debugger-icon").click();
await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME);
ok(true, "pretty printed file was selected in debugger…");
await waitForSelectedLocation(dbg, 51);
ok(true, "…at the expected location");
});
add_task(async function prettyPrintSingleLineDataUrl() {
const TEST_URL = `data:text/html,`;
const PRETTY_PRINTED_URL = `${TEST_URL}:formatted`;
const dbg = await initDebuggerWithAbsoluteURL(TEST_URL);
await selectSource(dbg, TEST_URL);
clickElement(dbg, "prettyPrintButton");
const prettySource = await waitForSource(dbg, PRETTY_PRINTED_URL);
await waitForSelectedSource(dbg, prettySource);
const prettyPrintedSource = findSourceContent(dbg, PRETTY_PRINTED_URL);
ok(prettyPrintedSource, "Pretty-printed source exists");
info("Check that the HTML file was pretty-printed as expected");
const expectedPrettyHtml = ``;
is(
prettyPrintedSource.value,
expectedPrettyHtml,
"HTML file is pretty printed as expected"
);
});
/**
* Return the expected pretty-printed HTML. Lines starting with ➤ indicate breakable
* lines for easier maintenance.
*
* @returns {String}
*/
function getExpectedPrettyPrintedHtml() {
return `
Debugger test page
Minified
`;
}