diff options
Diffstat (limited to '')
-rw-r--r-- | devtools/client/inspector/rules/test/browser_rules_copy_styles.js | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/devtools/client/inspector/rules/test/browser_rules_copy_styles.js b/devtools/client/inspector/rules/test/browser_rules_copy_styles.js new file mode 100644 index 0000000000..01fe365841 --- /dev/null +++ b/devtools/client/inspector/rules/test/browser_rules_copy_styles.js @@ -0,0 +1,359 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests the behaviour of the copy styles context menu items in the rule + * view. + */ + +const osString = Services.appinfo.OS; + +const TEST_URI = URL_ROOT_SSL + "doc_copystyles.html"; + +add_task(async function () { + await addTab(TEST_URI); + const { inspector, view } = await openRuleView(); + await selectNode("#testid", inspector); + + const ruleEditor = getRuleViewRuleEditor(view, 1); + + const data = [ + { + desc: "Test Copy Property Name", + node: ruleEditor.rule.textProps[0].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyPropertyName", + expectedPattern: "color", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Property Value", + node: ruleEditor.rule.textProps[2].editor.valueSpan, + menuItemLabel: "styleinspector.contextmenu.copyPropertyValue", + expectedPattern: "12px", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: false, + copyPropertyValue: true, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Property Value with Priority", + node: ruleEditor.rule.textProps[3].editor.valueSpan, + menuItemLabel: "styleinspector.contextmenu.copyPropertyValue", + expectedPattern: "#00F !important", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: false, + copyPropertyValue: true, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Property Declaration", + node: ruleEditor.rule.textProps[2].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyDeclaration", + expectedPattern: "font-size: 12px;", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Property Declaration with Priority", + node: ruleEditor.rule.textProps[3].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyDeclaration", + expectedPattern: "border-color: #00F !important;", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Rule", + node: ruleEditor.rule.textProps[2].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyRule", + expectedPattern: + "#testid {[\\r\\n]+" + + "\tcolor: #F00;[\\r\\n]+" + + "\tbackground-color: #00F;[\\r\\n]+" + + "\tfont-size: 12px;[\\r\\n]+" + + "\tborder-color: #00F !important;[\\r\\n]+" + + '\t--var: "\\*/";[\\r\\n]+' + + "}", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Selector", + node: ruleEditor.selectorText, + menuItemLabel: "styleinspector.contextmenu.copySelector", + expectedPattern: "html, body, #testid", + visible: { + copyLocation: false, + copyDeclaration: false, + copyPropertyName: false, + copyPropertyValue: false, + copySelector: true, + copyRule: true, + }, + }, + { + desc: "Test Copy Location", + node: ruleEditor.source, + menuItemLabel: "styleinspector.contextmenu.copyLocation", + expectedPattern: + "https://example.com/browser/devtools/client/" + + "inspector/rules/test/doc_copystyles.css", + visible: { + copyLocation: true, + copyDeclaration: false, + copyPropertyName: false, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + async setup() { + await disableProperty(view, 0); + }, + desc: "Test Copy Rule with Disabled Property", + node: ruleEditor.rule.textProps[2].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyRule", + expectedPattern: + "#testid {[\\r\\n]+" + + "\t/\\* color: #F00; \\*/[\\r\\n]+" + + "\tbackground-color: #00F;[\\r\\n]+" + + "\tfont-size: 12px;[\\r\\n]+" + + "\tborder-color: #00F !important;[\\r\\n]+" + + '\t--var: "\\*/";[\\r\\n]+' + + "}", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + async setup() { + await disableProperty(view, 4); + }, + desc: "Test Copy Rule with Disabled Property with Comment", + node: ruleEditor.rule.textProps[2].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyRule", + expectedPattern: + "#testid {[\\r\\n]+" + + "\t/\\* color: #F00; \\*/[\\r\\n]+" + + "\tbackground-color: #00F;[\\r\\n]+" + + "\tfont-size: 12px;[\\r\\n]+" + + "\tborder-color: #00F !important;[\\r\\n]+" + + '\t/\\* --var: "\\*\\\\/"; \\*/[\\r\\n]+' + + "}", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + { + desc: "Test Copy Property Declaration with Disabled Property", + node: ruleEditor.rule.textProps[0].editor.nameSpan, + menuItemLabel: "styleinspector.contextmenu.copyDeclaration", + expectedPattern: "/\\* color: #F00; \\*/", + visible: { + copyLocation: false, + copyDeclaration: true, + copyPropertyName: true, + copyPropertyValue: false, + copySelector: false, + copyRule: true, + }, + }, + ]; + + for (const { + setup, + desc, + node, + menuItemLabel, + expectedPattern, + visible, + } of data) { + if (setup) { + await setup(); + } + + info(desc); + await checkCopyStyle(view, node, menuItemLabel, expectedPattern, visible); + } +}); + +async function checkCopyStyle( + view, + node, + menuItemLabel, + expectedPattern, + visible +) { + const allMenuItems = openStyleContextMenuAndGetAllItems(view, node); + const menuItem = allMenuItems.find( + item => item.label === STYLE_INSPECTOR_L10N.getStr(menuItemLabel) + ); + const menuitemCopy = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy") + ); + const menuitemCopyLocation = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyLocation") + ); + const menuitemCopyDeclaration = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyDeclaration") + ); + const menuitemCopyPropertyName = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyName") + ); + const menuitemCopyPropertyValue = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr( + "styleinspector.contextmenu.copyPropertyValue" + ) + ); + const menuitemCopySelector = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copySelector") + ); + const menuitemCopyRule = allMenuItems.find( + item => + item.label === + STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyRule") + ); + + ok(menuitemCopy.disabled, "Copy disabled is as expected: true"); + ok(menuitemCopy.visible, "Copy visible is as expected: true"); + + is( + menuitemCopyLocation.visible, + visible.copyLocation, + "Copy Location visible attribute is as expected: " + visible.copyLocation + ); + + is( + menuitemCopyDeclaration.visible, + visible.copyDeclaration, + "Copy Property Declaration visible attribute is as expected: " + + visible.copyDeclaration + ); + + is( + menuitemCopyPropertyName.visible, + visible.copyPropertyName, + "Copy Property Name visible attribute is as expected: " + + visible.copyPropertyName + ); + + is( + menuitemCopyPropertyValue.visible, + visible.copyPropertyValue, + "Copy Property Value visible attribute is as expected: " + + visible.copyPropertyValue + ); + + is( + menuitemCopySelector.visible, + visible.copySelector, + "Copy Selector visible attribute is as expected: " + visible.copySelector + ); + + is( + menuitemCopyRule.visible, + visible.copyRule, + "Copy Rule visible attribute is as expected: " + visible.copyRule + ); + + try { + await waitForClipboardPromise( + () => menuItem.click(), + () => checkClipboardData(expectedPattern) + ); + } catch (e) { + failedClipboard(expectedPattern); + } +} + +async function disableProperty(view, index) { + const ruleEditor = getRuleViewRuleEditor(view, 1); + const textProp = ruleEditor.rule.textProps[index]; + await togglePropStatus(view, textProp); +} + +function checkClipboardData(expectedPattern) { + const actual = SpecialPowers.getClipboardData("text/plain"); + const expectedRegExp = new RegExp(expectedPattern, "g"); + return expectedRegExp.test(actual); +} + +function failedClipboard(expectedPattern) { + // Format expected text for comparison + const terminator = osString == "WINNT" ? "\r\n" : "\n"; + expectedPattern = expectedPattern.replace(/\[\\r\\n\][+*]/g, terminator); + expectedPattern = expectedPattern.replace(/\\\(/g, "("); + expectedPattern = expectedPattern.replace(/\\\)/g, ")"); + + let actual = SpecialPowers.getClipboardData("text/plain"); + + // Trim the right hand side of our strings. This is because expectedPattern + // accounts for windows sometimes adding a newline to our copied data. + expectedPattern = expectedPattern.trimRight(); + actual = actual.trimRight(); + + ok( + false, + "Clipboard text does not match expected " + + "results (escaped for accurate comparison):\n" + ); + info("Actual: " + escape(actual)); + info("Expected: " + escape(expectedPattern)); +} |