summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js')
-rw-r--r--devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js200
1 files changed, 200 insertions, 0 deletions
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js b/devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js
new file mode 100644
index 0000000000..780a1b3ec1
--- /dev/null
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_custom_formatters_errors.js
@@ -0,0 +1,200 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Check display of custom formatters.
+const TEST_URI =
+ "https://example.com/browser/devtools/client/webconsole/" +
+ "test/browser/test-console-custom-formatters-errors.html";
+
+add_task(async function () {
+ await pushPref("devtools.custom-formatters.enabled", true);
+
+ const hud = await openNewTabAndConsole(TEST_URI);
+
+ // Reload the browser to ensure the custom formatters are picked up
+ await reloadBrowser();
+
+ await testHeaderNotAFunction(hud);
+ await testHeaderNotReturningJsonMl(hud);
+ await testHeaderNotReturningElementType(hud);
+ await testHeaderThrowing(hud);
+ await testHasBodyNotAFunction(hud);
+ await testHasBodyThrowing(hud);
+ await testBodyNotAFunction(hud);
+ await testBodyReturningNull(hud);
+ await testBodyNotReturningJsonMl(hud);
+ await testBodyNotReturningElementType(hud);
+ await testBodyThrowing(hud);
+ await testIncorrectObjectTag(hud);
+ await testInvalidTagname(hud);
+ await testNoPrivilegedAccess(hud);
+ await testErrorsLoggedOnce(hud);
+});
+
+async function testHeaderNotAFunction(hud) {
+ info(`Test for "header" not being a function`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[0].header should be a function, got number`,
+ });
+}
+
+async function testHeaderNotReturningJsonMl(hud) {
+ info(`Test for "header" not returning JsonML`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[1].header should return an array, got number`,
+ source: "test-console-custom-formatters-errors.html:19:19",
+ });
+}
+
+async function testHeaderNotReturningElementType(hud) {
+ info(`Test for "header" function returning array without element type`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[2].header returned an empty array`,
+ });
+}
+
+async function testHeaderThrowing(hud) {
+ info(`Test for "header" function throwing`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[3].header threw: ERROR`,
+ });
+}
+
+async function testHasBodyNotAFunction(hud) {
+ info(`Test for "hasBody" not being a function`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[4].hasBody should be a function, got number`,
+ });
+}
+
+async function testHasBodyThrowing(hud) {
+ info(`Test for "hasBody" function throwing`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[5].hasBody threw: ERROR`,
+ });
+}
+
+async function testBodyNotAFunction(hud) {
+ info(`Test for "body" not being a function`);
+ await testCustomFormatting(hud, {
+ messageText: "body not a function",
+ bodyText: `Custom formatter failed: devtoolsFormatters[6].body should be a function, got number`,
+ });
+}
+
+async function testBodyReturningNull(hud) {
+ info(`Test for "body" returning null`);
+ await testCustomFormatting(hud, {
+ messageText: "body returns null",
+ bodyText: `Custom formatter failed: devtoolsFormatters[7].body should return an array, got null`,
+ });
+}
+
+async function testBodyNotReturningJsonMl(hud) {
+ info(`Test for "body" not returning JsonML`);
+ await testCustomFormatting(hud, {
+ messageText: "body doesn't return JsonML",
+ bodyText: `Custom formatter failed: devtoolsFormatters[8].body should return an array, got number`,
+ });
+}
+
+async function testBodyNotReturningElementType(hud) {
+ info(`Test for "body" function returning array without element type`);
+ await testCustomFormatting(hud, {
+ messageText: "body array misses element type",
+ bodyText: `Custom formatter failed: devtoolsFormatters[9].body returned an empty array`,
+ });
+}
+
+async function testBodyThrowing(hud) {
+ info(`Test for "body" function throwing`);
+ await testCustomFormatting(hud, {
+ messageText: "body throws",
+ bodyText: `Custom formatter failed: devtoolsFormatters[10].body threw: ERROR`,
+ });
+}
+
+async function testErrorsLoggedOnce(hud) {
+ const messages = findMessagesByType(hud, "custom formatter failed", ".error");
+
+ messages.forEach(async message => {
+ await checkUniqueMessageExists(hud, message.textContent, ".error");
+ });
+}
+
+async function testIncorrectObjectTag(hud) {
+ info(`Test for "object" tag without attribute`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[11] couldn't be run: "object" tag should have attributes`,
+ });
+
+ info(`Test for "object" tag without "object" attribute`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[12] couldn't be run: attribute of "object" tag should have an "object" property`,
+ });
+
+ info(`Test for infinite "object" tag`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: Too deep hierarchy of inlined custom previews`,
+ });
+}
+
+async function testInvalidTagname(hud) {
+ info(`Test invalid tagname in the returned JsonML`);
+ await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[14] couldn't be run: tagName should be a string, got number`,
+ });
+}
+
+async function testNoPrivilegedAccess(hud) {
+ info(`Test for denied access to windowUtils from hook`);
+ const node = await testCustomFormatting(hud, {
+ messageText: `Custom formatter failed: devtoolsFormatters[17].header threw`,
+ });
+ ok(
+ node.textContent.includes("window.windowUtils is undefined"),
+ "Access to windowUtils triggered expected error"
+ );
+}
+
+async function testCustomFormatting(hud, { messageText, source, bodyText }) {
+ const headerNode = bodyText
+ ? await waitFor(() => {
+ return findConsoleAPIMessage(hud, messageText);
+ })
+ : await waitFor(() => {
+ return findErrorMessage(hud, messageText);
+ });
+
+ ok(true, `Got expected message: ${messageText}`);
+
+ if (source) {
+ const sourceLink = headerNode.querySelector(".message-location");
+ is(sourceLink?.textContent, source, "Source location is correct");
+ }
+
+ if (bodyText) {
+ const arrow = headerNode.querySelector(".collapse-button");
+
+ ok(arrow, "There must be a toggle arrow for the header");
+
+ info("Expanding the Object");
+ const bodyErrorNode = waitFor(() => {
+ return findErrorMessage(hud, bodyText);
+ });
+
+ arrow.click();
+ await bodyErrorNode;
+
+ ok(
+ headerNode
+ .querySelector(".collapse-button")
+ .classList.contains("expanded"),
+ "The arrow of the node has the expected class after clicking on it"
+ );
+ }
+
+ return headerNode;
+}