diff options
Diffstat (limited to '')
-rw-r--r-- | devtools/shared/commands/resource/tests/browser_resources_css_messages.js | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/devtools/shared/commands/resource/tests/browser_resources_css_messages.js b/devtools/shared/commands/resource/tests/browser_resources_css_messages.js new file mode 100644 index 0000000000..2146904bb0 --- /dev/null +++ b/devtools/shared/commands/resource/tests/browser_resources_css_messages.js @@ -0,0 +1,210 @@ +/* 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"; + }); +} |