browser_styleeditor_sync.js (3567B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 "use strict"; 4 5 // Test that changes in the style inspector are synchronized into the 6 // style editor. 7 8 const TESTCASE_URI = TEST_BASE_HTTP + "sync.html"; 9 10 const expectedText = ` 11 body { 12 border-width: 15px; 13 /*! color: red; */ 14 } 15 16 #testid { 17 /*! font-size: 4em; */ 18 } 19 `; 20 21 async function closeAndReopenToolbox() { 22 await gDevTools.closeToolboxForTab(gBrowser.selectedTab); 23 const { ui: newui } = await openStyleEditor(); 24 return newui; 25 } 26 27 /** 28 * In this test, we are modifying rules via the inspector, which doesn't use STYLESHEET's onResourceUpdated event, 29 * but the style editor do listen for these events. The issue is that the style editor triggers asynchronous updates 30 * and new RDP requests which only happens randomly when the update notification happens late. 31 * In order to prevent that, ensure waiting for all the updates notifications while doing the action in the inspector, 32 * so that the style editor only gets STYLESHEET's available notification while opening. 33 */ 34 async function waitForNextStyleSheetResourceUpdate(inspector) { 35 const { resourceCommand } = inspector.commands; 36 37 const { promise, resolve } = Promise.withResolvers(); 38 const onAvailable = () => {}; 39 const onUpdated = () => { 40 resourceCommand.unwatchResources([resourceCommand.TYPES.STYLESHEET], { 41 onAvailable, 42 onUpdated, 43 }); 44 resolve(); 45 }; 46 await resourceCommand.watchResources([resourceCommand.TYPES.STYLESHEET], { 47 onAvailable, 48 onUpdated, 49 }); 50 return { onResourceUpdated: promise }; 51 } 52 53 add_task(async function () { 54 await addTab(TESTCASE_URI); 55 const { inspector, view } = await openRuleView(); 56 await selectNode("#testid", inspector); 57 let ruleEditor = getRuleViewRuleEditor(view, 1); 58 59 // Disable the "font-size" property. 60 let { onResourceUpdated } = 61 await waitForNextStyleSheetResourceUpdate(inspector); 62 let propEditor = ruleEditor.rule.textProps[0].editor; 63 let onModification = view.once("ruleview-changed"); 64 propEditor.enable.click(); 65 await onModification; 66 await onResourceUpdated; 67 68 // Disable the "color" property. Note that this property is in a 69 // rule that also contains a non-inherited property -- so this test 70 // is also testing that property editing works properly in this 71 // situation. 72 ({ onResourceUpdated } = 73 await waitForNextStyleSheetResourceUpdate(inspector)); 74 ruleEditor = getRuleViewRuleEditor(view, 3); 75 propEditor = ruleEditor.rule.textProps[1].editor; 76 onModification = view.once("ruleview-changed"); 77 propEditor.enable.click(); 78 await onModification; 79 await onResourceUpdated; 80 81 let { ui } = await openStyleEditor(); 82 83 let editor = await ui.editors[0].getSourceEditor(); 84 let text = editor.sourceEditor.getText(); 85 is(text, expectedText, "style inspector changes are synced"); 86 87 // Close and reopen the toolbox, to see that the edited text remains 88 // available. 89 ui = await closeAndReopenToolbox(); 90 editor = await ui.editors[0].getSourceEditor(); 91 text = editor.sourceEditor.getText(); 92 is(text, expectedText, "changes remain after close and reopen"); 93 94 // For the time being, the actor does not update the style's owning 95 // node's textContent. See bug 1205380. 96 const textContent = await SpecialPowers.spawn( 97 gBrowser.selectedBrowser, 98 [], 99 async function () { 100 return content.document.querySelector("style").textContent; 101 } 102 ); 103 104 isnot(textContent, expectedText, "changes not written back to style node"); 105 });