fune/devtools/shared/commands/resource/tests/browser_resources_css_messages.js

210 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test the ResourceCommand API around CSS_MESSAGE
// Reproduces the CSS message assertions from devtools/shared/webconsole/test/chrome/test_page_errors.html
const { MESSAGE_CATEGORY } = require("resource://devtools/shared/constants.js");
// Create a simple server so we have a nice sourceName in the resources packets.
const httpServer = createTestHTTPServer();
httpServer.registerPathHandler(`/test_css_messages.html`, (req, res) => {
res.setStatusLine(req.httpVersion, 200, "OK");
res.write(`<meta charset=utf8>
<style>
html {
color: bloup;
}
</style>Test CSS Messages`);
});
const TEST_URI = `http://localhost:${httpServer.identity.primaryPort}/test_css_messages.html`;
add_task(async function() {
await testWatchingCssMessages();
await testWatchingCachedCssMessages();
});
async function testWatchingCssMessages() {
// Disable the preloaded process as it creates processes intermittently
// which forces the emission of RDP requests we aren't correctly waiting for.
await pushPref("dom.ipc.processPrelaunch.enabled", false);
// Open a test tab
const tab = await addTab(TEST_URI);
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
const receivedMessages = [];
const { onAvailable, onAllMessagesReceived } = setupOnAvailableFunction(
targetCommand,
receivedMessages,
false
);
await resourceCommand.watchResources([resourceCommand.TYPES.CSS_MESSAGE], {
onAvailable,
});
info(
"Now log CSS warning *after* the call to ResourceCommand.watchResources and after " +
"having received the existing message"
);
// We need to wait for the first CSS Warning as it is not a cached message; when we
// start watching, the `cssErrorReportingEnabled` is checked on the target docShell, and
// if it is false, we re-parse the stylesheets to get the messages.
await BrowserTestUtils.waitForCondition(() => receivedMessages.length === 1);
info("Trigger a CSS Warning");
triggerCSSWarning(tab);
info("Waiting for all expected CSS messages to be received");
await onAllMessagesReceived;
ok(true, "All the expected CSS messages were received");
Services.console.reset();
targetCommand.destroy();
await client.close();
}
async function testWatchingCachedCssMessages() {
// Disable the preloaded process as it creates processes intermittently
// which forces the emission of RDP requests we aren't correctly waiting for.
await pushPref("dom.ipc.processPrelaunch.enabled", false);
// Open a test tab
const tab = await addTab(TEST_URI);
// By default, the CSS Parser does not emit warnings at all, for performance matter.
// Since we actually want the Parser to emit those messages _before_ we start listening
// for CSS messages, we need to set the cssErrorReportingEnabled flag on the docShell.
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
content.docShell.cssErrorReportingEnabled = true;
});
// Setting the docShell flag only indicates to the Parser that from now on, it should
// emit warnings. But it does not automatically emit warnings for the existing CSS
// errors in the stylesheets. So here we reload the tab, which will make the Parser
// parse the stylesheets again, this time emitting warnings.
await reloadBrowser();
// and trigger more CSS warnings
await triggerCSSWarning(tab);
// At this point, all messages should be in the ConsoleService cache, and we can begin
// to watch and check that we do retrieve those messages.
const { client, resourceCommand, targetCommand } = await initResourceCommand(
tab
);
const receivedMessages = [];
const { onAvailable } = setupOnAvailableFunction(
targetCommand,
receivedMessages,
true
);
await resourceCommand.watchResources([resourceCommand.TYPES.CSS_MESSAGE], {
onAvailable,
});
is(receivedMessages.length, 3, "Cached messages were retrieved as expected");
Services.console.reset();
targetCommand.destroy();
await client.close();
}
function setupOnAvailableFunction(
targetCommand,
receivedMessages,
isAlreadyExistingResource
) {
// timeStamp are the result of a number in microsecond divided by 1000.
// so we can't expect a precise number of decimals, or even if there would
// be decimals at all.
const FRACTIONAL_NUMBER_REGEX = /^\d+(\.\d{1,3})?$/;
// The expected messages are the CSS warnings:
// - one for the rule in the style element
// - two for the JS modified style we're doing in the test.
const expectedMessages = [
{
pageError: {
errorMessage: /Expected color but found bloup/,
sourceName: /test_css_messages/,
category: MESSAGE_CATEGORY.CSS_PARSER,
timeStamp: FRACTIONAL_NUMBER_REGEX,
error: false,
warning: true,
},
cssSelectors: "html",
isAlreadyExistingResource,
},
{
pageError: {
errorMessage: /Error in parsing value for width/,
sourceName: /test_css_messages/,
category: MESSAGE_CATEGORY.CSS_PARSER,
timeStamp: FRACTIONAL_NUMBER_REGEX,
error: false,
warning: true,
},
isAlreadyExistingResource,
},
{
pageError: {
errorMessage: /Error in parsing value for height/,
sourceName: /test_css_messages/,
category: MESSAGE_CATEGORY.CSS_PARSER,
timeStamp: FRACTIONAL_NUMBER_REGEX,
error: false,
warning: true,
},
isAlreadyExistingResource,
},
];
let done;
const onAllMessagesReceived = new Promise(resolve => (done = resolve));
const onAvailable = resources => {
for (const resource of resources) {
const { pageError } = resource;
is(
resource.targetFront,
targetCommand.targetFront,
"The targetFront property is the expected one"
);
if (!pageError.sourceName.includes("test_css_messages")) {
info(`Ignore error from unknown source: "${pageError.sourceName}"`);
continue;
}
const index = receivedMessages.length;
receivedMessages.push(resource);
info(
`checking received css message #${index}: ${pageError.errorMessage}`
);
ok(pageError, "The resource has a pageError attribute");
checkObject(resource, expectedMessages[index]);
if (receivedMessages.length == expectedMessages.length) {
done();
}
}
};
return { onAvailable, onAllMessagesReceived };
}
/**
* Sets invalid values for width and height on the document's body style attribute.
*/
function triggerCSSWarning(tab) {
return ContentTask.spawn(tab.linkedBrowser, null, function frameScript() {
content.document.body.style.width = "red";
content.document.body.style.height = "blue";
});
}