| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script src="../../http/tests/inspector/resources/protocol-test.js"></script> | |
| <link rel="stylesheet" href="resources/external.css"> | |
| <script> | |
| function test() { | |
| let suite = ProtocolTest.createAsyncSuite("CSS.setStyleTextRace"); | |
| suite.addTestCase({ | |
| name: "CSS.setStyleSheetText.CachedContents", | |
| description: "Replacing an external stylesheet should change its live rules after cached contents are copied for mutation.", | |
| async test() { | |
| await InspectorProtocol.awaitCommand({method: "Page.enable"}); | |
| let {headers} = await InspectorProtocol.awaitCommand({method: "CSS.getAllStyleSheets"}); | |
| let styleSheetId = headers.find((header) => header.sourceURL.endsWith("/resources/external.css"))?.styleSheetId; | |
| ProtocolTest.assert(styleSheetId, "The real external stylesheet should be available."); | |
| let {text: originalText} = await InspectorProtocol.awaitCommand({method: "CSS.getStyleSheetText", params: {styleSheetId}}); | |
| let initialComputed = await InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {expression: "getComputedStyle(document.body).color"}}); | |
| ProtocolTest.expectEqual(initialComputed.result.value, "rgb(255, 0, 0)", "The page should initially use the external stylesheet."); | |
| let revisedText = originalText.replace("red", "orange"); | |
| await InspectorProtocol.awaitCommand({method: "CSS.setStyleSheetText", params: {styleSheetId, text: revisedText}}); | |
| let {text: changedText} = await InspectorProtocol.awaitCommand({method: "CSS.getStyleSheetText", params: {styleSheetId}}); | |
| ProtocolTest.expectEqual(changedText, revisedText, "The backend should retain the requested stylesheet text."); | |
| let changedComputed = await InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {expression: "getComputedStyle(document.body).color"}}); | |
| ProtocolTest.expectEqual(changedComputed.result.value, "rgb(255, 165, 0)", "The whole stylesheet edit should change the page's rendered color."); | |
| let rule = await InspectorProtocol.awaitCommand({method: "Runtime.evaluate", params: {expression: "document.styleSheets[0].cssRules[0].style.color"}}); | |
| ProtocolTest.expectEqual(rule.result.value, "orange", "The live stylesheet should contain the new declaration."); | |
| await InspectorProtocol.awaitCommand({method: "CSS.setStyleSheetText", params: {styleSheetId, text: originalText}}); | |
| }, | |
| }); | |
| suite.addTestCase({ | |
| name: "CSS.setStyleTextAfterSetStylesheetText", | |
| description: "Ensure that editing the style of a CSS rule works after immediately updating the stylesheet text", | |
| test: async () => { | |
| let { root } = await InspectorProtocol.awaitCommand({ method: "DOM.getDocument" }); | |
| let body = await InspectorProtocol.awaitCommand({ | |
| method: "DOM.querySelector", | |
| params: { nodeId: root.nodeId, selector: "body" }, | |
| }); | |
| async function getAuthorStylesheetId() { | |
| let { headers } = await InspectorProtocol.awaitCommand({ method: "CSS.getAllStyleSheets" }); | |
| return headers.find((header) => header.origin === "author")?.styleSheetId; | |
| } | |
| let styleSheetId = await getAuthorStylesheetId(); | |
| if (!styleSheetId) | |
| ProtocolTest.log("FAIL: Missing author style sheet"); | |
| ProtocolTest.log("INFO: Get stylesheet text"); | |
| let { text } = await InspectorProtocol.awaitCommand({ | |
| method: "CSS.getStyleSheetText", | |
| params: { styleSheetId }, | |
| }); | |
| ProtocolTest.log(text); | |
| async function getAuthorStyleMatchingElementAndSelector(element, selector) { | |
| let { matchedCSSRules } = await InspectorProtocol.awaitCommand({ | |
| method: "CSS.getMatchedStylesForNode", | |
| params: { nodeId: element.nodeId }, | |
| }); | |
| let ruleMatchingSelector = matchedCSSRules | |
| .map(({ rule }) => rule) | |
| .find((rule) => { | |
| if (rule.origin !== "author") | |
| return false; | |
| return rule.selectorList.selectors.find(cssSelector => cssSelector.text === selector); | |
| }) | |
| return ruleMatchingSelector?.style; | |
| }; | |
| ProtocolTest.log("INFO: Get style for 'body' CSS rule"); | |
| let bodyStyle = await getAuthorStyleMatchingElementAndSelector(body, "body"); | |
| if (!bodyStyle) | |
| ProtocolTest.log("FAIL: Missing 'body' CSS rule"); | |
| ProtocolTest.log(bodyStyle.cssText); | |
| ProtocolTest.log("INFO: Set stylesheet text with identical contents"); | |
| InspectorProtocol.sendCommand({ | |
| method: "CSS.setStyleSheetText", | |
| params: { styleSheetId, text }, | |
| }); | |
| await InspectorProtocol.awaitEvent({event: "CSS.styleSheetChanged"}); | |
| ProtocolTest.log("INFO: 'styleSheetChanged' event fired"); | |
| ProtocolTest.log("INFO: Update style for 'body' CSS rule"); | |
| let updatedCSSText = "color: green;" | |
| let setStyleTextResult = await InspectorProtocol.awaitCommand({ | |
| method: "CSS.setStyleText", | |
| params: { styleId: bodyStyle.styleId, text: updatedCSSText }, | |
| }); | |
| ProtocolTest.expectEqual(setStyleTextResult.style.cssText, updatedCSSText, "CSS rule text was updated"); | |
| ProtocolTest.log("INFO: Get stylesheet text again"); | |
| let getStyleSheetTextResult = await InspectorProtocol.awaitCommand({ | |
| method: "CSS.getStyleSheetText", | |
| params: { styleSheetId }, | |
| }); | |
| ProtocolTest.log(getStyleSheetTextResult.text); | |
| ProtocolTest.expectNotEqual(text, getStyleSheetTextResult.text, "Stylsheet text reflects change to CSS rule"); | |
| } | |
| }); | |
| suite.runTestCasesAndFinish(); | |
| } | |
| </script> | |
| </head> | |
| <body onload="runTest()"> | |
| <p>Testing that calling CSS.setStyleText works immediately after CSS.setStyleSheetText without an intermediate call to CSS.getStyleSheetText.</p> | |
| </body> | |
| </html> |