From 6c17e99d3621b051cdd4b68c4b9346e20fefde4a Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Thu, 1 Dec 2016 08:29:43 +0100 Subject: [PATCH 01/34] Bug 1318796 - Open the appropriate tool when clicking on a location in the new console; r=jdescottes We were always opening the debugger when clicking on the location link, which could be wrong since we can have CSS warnings, or logs coming from Scratchpad. So we add the function to open in StyleEditor and Scratchpad, and copy some mochitests that where testing the interaction with those links. MozReview-Commit-ID: 73mQNfy199m --HG-- rename : devtools/client/webconsole/test/browser_webconsole_bug_766001_JS_Console_in_Debugger.js => devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_debugger_link.js rename : devtools/client/webconsole/test/browser_webconsole_scratchpad_panel_link.js => devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_scratchpad_link.js rename : devtools/client/webconsole/test/browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js => devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_styleeditor_link.js rename : devtools/client/webconsole/test/test-bug-766001-console-log.js => devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-console-log.js rename : devtools/client/webconsole/test/test-bug-766001-js-errors.js => devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-errors.js rename : devtools/client/webconsole/test/test-bug-766001-js-console-links.html => devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link.html rename : devtools/client/webconsole/test/test-bug-782653-css-errors-1.css => devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-1.css rename : devtools/client/webconsole/test/test-bug-782653-css-errors-2.css => devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-2.css rename : devtools/client/webconsole/test/test-bug-782653-css-errors.html => devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html extra : rebase_source : a8494acb5e450f86fa9cddd34515265fc3494d17 --- .../client/shared/components/stack-trace.js | 16 +++- .../test/mochitest/test_stack-trace.html | 3 +- .../new-console-output/components/message.js | 21 ++++- .../new-console-output-wrapper.js | 16 +++- .../test/fixtures/serviceContainer.js | 2 + .../test/mochitest/browser.ini | 12 +++ ...owser_webconsole_location_debugger_link.js | 74 ++++++++++++++++ ...ser_webconsole_location_scratchpad_link.js | 55 ++++++++++++ ...er_webconsole_location_styleeditor_link.js | 86 +++++++++++++++++++ ...nsole_stacktrace_location_debugger_link.js | 63 ++++++++++++++ ...ole_stacktrace_location_scratchpad_link.js | 62 +++++++++++++ ...test-location-debugger-link-console-log.js | 12 +++ .../test-location-debugger-link-errors.js | 10 +++ .../test-location-debugger-link.html | 14 +++ .../test-location-styleeditor-link-1.css | 10 +++ .../test-location-styleeditor-link-2.css | 10 +++ .../test-location-styleeditor-link.html | 14 +++ ...est-stacktrace-location-debugger-link.html | 25 ++++++ 18 files changed, 497 insertions(+), 8 deletions(-) create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_debugger_link.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_scratchpad_link.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_styleeditor_link.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_debugger_link.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_scratchpad_link.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-console-log.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-errors.js create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link.html create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-1.css create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-2.css create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html create mode 100644 devtools/client/webconsole/new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html diff --git a/devtools/client/shared/components/stack-trace.js b/devtools/client/shared/components/stack-trace.js index 43d0b871619e..28ab692c13c9 100644 --- a/devtools/client/shared/components/stack-trace.js +++ b/devtools/client/shared/components/stack-trace.js @@ -33,11 +33,16 @@ const StackTrace = createClass({ PropTypes: { stacktrace: PropTypes.array.isRequired, - onViewSourceInDebugger: PropTypes.func.isRequired + onViewSourceInDebugger: PropTypes.func.isRequired, + onViewSourceInScratchpad: PropTypes.func.isRequired, }, render() { - let { stacktrace, onViewSourceInDebugger } = this.props; + let { + stacktrace, + onViewSourceInDebugger, + onViewSourceInScratchpad + } = this.props; let frames = []; stacktrace.forEach(s => { @@ -47,17 +52,20 @@ const StackTrace = createClass({ }), "\n"); } + let source = s.filename.split(" -> ").pop(); frames.push("\t", Frame({ frame: { functionDisplayName: s.functionName, - source: s.filename.split(" -> ").pop(), + source, line: s.lineNumber, column: s.columnNumber, }, showFunctionName: true, showAnonymousFunctionName: true, showFullSourceUrl: true, - onClick: onViewSourceInDebugger + onClick: (/^Scratchpad\/\d+$/.test(source)) + ? onViewSourceInScratchpad + : onViewSourceInDebugger }), "\n"); }); diff --git a/devtools/client/shared/components/test/mochitest/test_stack-trace.html b/devtools/client/shared/components/test/mochitest/test_stack-trace.html index 53c71b3dce7a..5be6961c4fca 100644 --- a/devtools/client/shared/components/test/mochitest/test_stack-trace.html +++ b/devtools/client/shared/components/test/mochitest/test_stack-trace.html @@ -44,7 +44,8 @@ window.onload = function () { let props = { stacktrace, - onViewSourceInDebugger: () => {} + onViewSourceInDebugger: () => {}, + onViewSourceInScratchpad: () => {}, }; let trace = ReactDOM.render(StackTrace(props), window.document.body); diff --git a/devtools/client/webconsole/new-console-output/components/message.js b/devtools/client/webconsole/new-console-output/components/message.js index 95fc54950117..c1a793e94f6d 100644 --- a/devtools/client/webconsole/new-console-output/components/message.js +++ b/devtools/client/webconsole/new-console-output/components/message.js @@ -15,6 +15,7 @@ const { } = require("devtools/client/shared/vendor/react"); const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages"); const actions = require("devtools/client/webconsole/new-console-output/actions/index"); +const {MESSAGE_SOURCE} = require("devtools/client/webconsole/new-console-output/constants"); const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button")); const MessageIndent = createFactory(require("devtools/client/webconsole/new-console-output/components/message-indent").MessageIndent); const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon")); @@ -45,6 +46,8 @@ const Message = createClass({ serviceContainer: PropTypes.shape({ emitNewMessage: PropTypes.func.isRequired, onViewSourceInDebugger: PropTypes.func.isRequired, + onViewSourceInScratchpad: PropTypes.func.isRequired, + onViewSourceInStyleEditor: PropTypes.func.isRequired, sourceMapService: PropTypes.any, }), }, @@ -112,7 +115,8 @@ const Message = createClass({ } else if (stacktrace) { const child = open ? StackTrace({ stacktrace: stacktrace, - onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger + onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger, + onViewSourceInScratchpad: serviceContainer.onViewSourceInScratchpad, }) : null; attachment = dom.div({ className: "stacktrace devtools-monospace" }, child); } @@ -135,11 +139,24 @@ const Message = createClass({ const repeat = this.props.repeat ? MessageRepeat({repeat: this.props.repeat}) : null; + let onFrameClick; + if (serviceContainer && frame) { + if (source === MESSAGE_SOURCE.CSS) { + onFrameClick = serviceContainer.onViewSourceInStyleEditor; + } else if (/^Scratchpad\/\d+$/.test(frame.source)) { + onFrameClick = serviceContainer.onViewSourceInScratchpad; + } else { + // Point everything else to debugger, if source not available, + // it will fall back to view-source. + onFrameClick = serviceContainer.onViewSourceInDebugger; + } + } + // Configure the location. const location = dom.span({ className: "message-location devtools-monospace" }, frame ? FrameView({ frame, - onClick: serviceContainer ? serviceContainer.onViewSourceInDebugger : undefined, + onClick: onFrameClick, showEmptyPathAsHost: true, sourceMapService: serviceContainer ? serviceContainer.sourceMapService : undefined }) : null diff --git a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js index 2104046a2d31..c6f2e408f6ef 100644 --- a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js +++ b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js @@ -44,7 +44,21 @@ NewConsoleOutputWrapper.prototype = { }])); }, hudProxyClient: this.jsterm.hud.proxy.client, - onViewSourceInDebugger: frame => this.toolbox.viewSourceInDebugger.call( + onViewSourceInDebugger: frame => { + this.toolbox.viewSourceInDebugger.call( + this.toolbox, + frame.url, + frame.line + ).then(() => + this.jsterm.hud.emit("source-in-debugger-opened") + ); + }, + onViewSourceInScratchpad: frame => this.toolbox.viewSourceInScratchpad.call( + this.toolbox, + frame.url, + frame.line + ), + onViewSourceInStyleEditor: frame => this.toolbox.viewSourceInStyleEditor.call( this.toolbox, frame.url, frame.line diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js b/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js index 3c117cf96808..c29d1b1f8964 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js @@ -8,6 +8,8 @@ module.exports = { emitNewMessage: () => {}, hudProxyClient: {}, onViewSourceInDebugger: () => {}, + onViewSourceInStyleEditor: () => {}, + onViewSourceInScratchpad: () => {}, openNetworkPanel: () => {}, sourceMapService: { subscribe: () => {}, diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini index f68057562590..78ff1214e27d 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini @@ -8,6 +8,13 @@ support-files = test-console-filters.html test-console-group.html test-console-table.html + test-location-debugger-link-console-log.js + test-location-debugger-link-errors.js + test-location-debugger-link.html + test-location-styleeditor-link-1.css + test-location-styleeditor-link-2.css + test-location-styleeditor-link.html + test-stacktrace-location-debugger-link.html !/devtools/client/framework/test/shared-head.js [browser_webconsole_batching.js] @@ -17,7 +24,12 @@ support-files = [browser_webconsole_init.js] [browser_webconsole_input_focus.js] [browser_webconsole_keyboard_accessibility.js] +[browser_webconsole_location_debugger_link.js] +[browser_webconsole_location_scratchpad_link.js] +[browser_webconsole_location_styleeditor_link.js] [browser_webconsole_nodes_highlight.js] [browser_webconsole_observer_notifications.js] +[browser_webconsole_stacktrace_location_debugger_link.js] +[browser_webconsole_stacktrace_location_scratchpad_link.js] [browser_webconsole_timestamps.js] [browser_webconsole_vview_close_on_esc_key.js] diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_debugger_link.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_debugger_link.js new file mode 100644 index 000000000000..9ce4c64adc9d --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_debugger_link.js @@ -0,0 +1,74 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test that message source links for js errors and console API calls open in +// the jsdebugger when clicked. + +"use strict"; +requestLongerTimeout(2); + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" + + "new-console-output/test/mochitest/test-location-debugger-link.html"; + +add_task(function* () { + // Force the new debugger UI, in case this gets uplifted with the old + // debugger still turned on + yield pushPref("devtools.debugger.new-debugger-frontend", true); + yield pushPref("devtools.webconsole.filter.error", true); + yield pushPref("devtools.webconsole.filter.log", true); + + // On e10s, the exception thrown in test-location-debugger-link-errors.js + // is triggered in child process and is ignored by test harness + if (!Services.appinfo.browserTabsRemoteAutostart) { + expectUncaughtException(); + } + + let hud = yield openNewTabAndConsole(TEST_URI); + let target = TargetFactory.forTab(gBrowser.selectedTab); + let toolbox = gDevTools.getToolbox(target); + + yield testOpenInDebugger(hud, toolbox, "document.bar"); + + info("Selecting the console again"); + yield toolbox.selectTool("webconsole"); + yield testOpenInDebugger(hud, toolbox, "Blah Blah"); + + // // check again the first node. + info("Selecting the console again"); + yield toolbox.selectTool("webconsole"); + yield testOpenInDebugger(hud, toolbox, "document.bar"); +}); + +function* testOpenInDebugger(hud, toolbox, text) { + info(`Testing message with text "${text}"`); + let messageNode = yield waitFor(() => findMessage(hud, text)); + let frameLinkNode = messageNode.querySelector(".message-location .frame-link"); + ok(frameLinkNode, "The message does have a location link"); + yield checkClickOnNode(hud, toolbox, frameLinkNode); +} + +function* checkClickOnNode(hud, toolbox, frameLinkNode) { + info("checking click on node location"); + + let url = frameLinkNode.getAttribute("data-url"); + ok(url, `source url found ("${url}")`); + + let line = frameLinkNode.getAttribute("data-line"); + ok(line, `source line found ("${line}")`); + + let onSourceInDebuggerOpened = once(hud.ui, "source-in-debugger-opened"); + + EventUtils.sendMouseEvent({ type: "click" }, + frameLinkNode.querySelector(".frame-link-filename")); + + yield onSourceInDebuggerOpened; + + let dbg = toolbox.getPanel("jsdebugger"); + is( + dbg._selectors().getSelectedSource(dbg._getState()).get("url"), + url, + "expected source url" + ); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_scratchpad_link.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_scratchpad_link.js new file mode 100644 index 000000000000..ff0bc4c8b6fd --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_scratchpad_link.js @@ -0,0 +1,55 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URI = "data:text/html;charset=utf8,

test Scratchpad panel linking

"; + +add_task(function* () { + yield pushPref("devtools.scratchpad.enabled", true); + yield openNewTabAndToolbox(TEST_URI); + + info("Opening toolbox with Scratchpad panel"); + + let target = TargetFactory.forTab(gBrowser.selectedTab); + let toolbox = yield gDevTools.showToolbox(target, "scratchpad", "window"); + + let scratchpadPanel = toolbox.getPanel("scratchpad"); + let { scratchpad } = scratchpadPanel; + is(toolbox.getCurrentPanel(), scratchpadPanel, + "Scratchpad is currently selected panel"); + + info("Switching to webconsole panel"); + + let webconsolePanel = yield toolbox.selectTool("webconsole"); + let { hud } = webconsolePanel; + is(toolbox.getCurrentPanel(), webconsolePanel, + "Webconsole is currently selected panel"); + + info("console.log()ing from Scratchpad"); + + let messageText = "foobar-from-scratchpad"; + scratchpad.setText(`console.log('${messageText}')`); + scratchpad.run(); + let message = yield waitFor(() => findMessage(hud, messageText)); + + info("Clicking link to switch to and focus Scratchpad"); + + ok(message, "Found logged message from Scratchpad"); + let anchor = message.querySelector(".message-location .frame-link-filename"); + + let onScratchpadSelected = new Promise((resolve) => { + toolbox.once("scratchpad-selected", resolve); + }); + + EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow); + yield onScratchpadSelected; + + is(toolbox.getCurrentPanel(), scratchpadPanel, + "Clicking link switches to Scratchpad panel"); + + is(Services.ww.activeWindow, toolbox.win.parent, + "Scratchpad's toolbox is focused"); +}); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_styleeditor_link.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_styleeditor_link.js new file mode 100644 index 000000000000..d0ee81991336 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_location_styleeditor_link.js @@ -0,0 +1,86 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html"; + +add_task(function* () { + yield pushPref("devtools.webconsole.filter.css", true); + let hud = yield openNewTabAndConsole(TEST_URI); + let target = TargetFactory.forTab(gBrowser.selectedTab); + let toolbox = gDevTools.getToolbox(target); + + yield testViewSource(hud, toolbox, "\u2018font-weight\u2019"); + + info("Selecting the console again"); + yield toolbox.selectTool("webconsole"); + yield testViewSource(hud, toolbox, "\u2018color\u2019"); +}); + +function* testViewSource(hud, toolbox, text) { + info(`Testing message with text "${text}"`); + let messageNode = yield waitFor(() => findMessage(hud, text)); + let frameLinkNode = messageNode.querySelector(".message-location .frame-link"); + ok(frameLinkNode, "The message does have a location link"); + + let onStyleEditorSelected = new Promise((resolve) => { + toolbox.once("styleeditor-selected", (event, panel) => { + resolve(panel); + }); + }); + + EventUtils.sendMouseEvent({ type: "click" }, + messageNode.querySelector(".frame-link-filename")); + + let panel = yield onStyleEditorSelected; + ok(true, "The style editor is selected when clicking on the location element"); + + yield onStyleEditorReady(panel); + + info("style editor window focused"); + let href = frameLinkNode.getAttribute("data-url"); + let line = frameLinkNode.getAttribute("data-line"); + ok(line, "found source line"); + + let editor = getEditorForHref(panel.UI, href); + ok(editor, "found style editor for " + href); + yield performLineCheck(panel.UI, editor, line - 1); +} + +function* onStyleEditorReady(panel) { + let win = panel.panelWindow; + ok(win, "Style Editor Window is defined"); + ok(panel.UI, "Style Editor UI is defined"); + + info("Waiting the style editor to be focused"); + return new Promise(resolve => { + waitForFocus(function () { + resolve(); + }, win); + }); +} + +function getEditorForHref(styleEditorUI, href) { + let foundEditor = null; + for (let editor of styleEditorUI.editors) { + if (editor.styleSheet.href == href) { + foundEditor = editor; + break; + } + } + return foundEditor; +} + +function* performLineCheck(styleEditorUI, editor, line) { + info("wait for source editor to load"); + // Get out of the styleeditor-selected event loop. + yield waitForTick(); + + is(editor.sourceEditor.getCursor().line, line, + "correct line is selected"); + is(styleEditorUI.selectedStyleSheetIndex, editor.styleSheet.styleSheetIndex, + "correct stylesheet is selected in the editor"); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_debugger_link.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_debugger_link.js new file mode 100644 index 000000000000..2e8572c7f12a --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_debugger_link.js @@ -0,0 +1,63 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test that message source links for js errors and console API calls open in +// the jsdebugger when clicked. + +"use strict"; + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" + + "new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html"; + +add_task(function* () { + // Force the new debugger UI, in case this gets uplifted with the old + // debugger still turned on + Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true); + Services.prefs.setBoolPref("devtools.webconsole.filter.log", true); + registerCleanupFunction(function* () { + Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend"); + Services.prefs.clearUserPref("devtools.webconsole.filter.log"); + }); + + let hud = yield openNewTabAndConsole(TEST_URI); + let target = TargetFactory.forTab(gBrowser.selectedTab); + let toolbox = gDevTools.getToolbox(target); + + yield testOpenInDebugger(hud, toolbox, "console.trace()"); +}); + +function* testOpenInDebugger(hud, toolbox, text) { + info(`Testing message with text "${text}"`); + let messageNode = yield waitFor(() => findMessage(hud, text)); + let frameLinksNode = messageNode.querySelectorAll(".stack-trace .frame-link"); + is(frameLinksNode.length, 3, + "The message does have the expected number of frames in the stacktrace"); + + for (let frameLinkNode of frameLinksNode) { + yield checkClickOnNode(hud, toolbox, frameLinkNode); + + info("Selecting the console again"); + yield toolbox.selectTool("webconsole"); + } +} + +function* checkClickOnNode(hud, toolbox, frameLinkNode) { + info("checking click on node location"); + + let onSourceInDebuggerOpened = once(hud.ui, "source-in-debugger-opened"); + + EventUtils.sendMouseEvent({ type: "click" }, + frameLinkNode.querySelector(".frame-link-source")); + + yield onSourceInDebuggerOpened; + + let url = frameLinkNode.getAttribute("data-url"); + let dbg = toolbox.getPanel("jsdebugger"); + is( + dbg._selectors().getSelectedSource(dbg._getState()).get("url"), + url, + `Debugger is opened at expected source url (${url})` + ); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_scratchpad_link.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_scratchpad_link.js new file mode 100644 index 000000000000..60bb1d006614 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_stacktrace_location_scratchpad_link.js @@ -0,0 +1,62 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URI = "data:text/html;charset=utf8,

test stacktrace scratchpad linking

"; + +add_task(function* () { + yield pushPref("devtools.scratchpad.enabled", true); + yield openNewTabAndToolbox(TEST_URI); + + info("Opening toolbox with Scratchpad panel"); + + let target = TargetFactory.forTab(gBrowser.selectedTab); + let toolbox = yield gDevTools.showToolbox(target, "scratchpad", "window"); + + let scratchpadPanel = toolbox.getPanel("scratchpad"); + let { scratchpad } = scratchpadPanel; + is(toolbox.getCurrentPanel(), scratchpadPanel, + "Scratchpad is currently selected panel"); + + info("Switching to webconsole panel"); + + let webconsolePanel = yield toolbox.selectTool("webconsole"); + let { hud } = webconsolePanel; + is(toolbox.getCurrentPanel(), webconsolePanel, + "Webconsole is currently selected panel"); + + info("console.trace()ing from Scratchpad"); + + scratchpad.setText(` + function foo() { + bar(); + } + + function bar() { + console.trace(); + } + + foo(); + `); + scratchpad.run(); + let message = yield waitFor(() => findMessage(hud, "console.trace()")); + + info("Clicking link to switch to and focus Scratchpad"); + + ok(message, "Found console.trace message from Scratchpad"); + let anchor = message.querySelector(".stack-trace .frame-link .frame-link-filename"); + + let onScratchpadSelected = toolbox.once("scratchpad-selected"); + + EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow); + yield onScratchpadSelected; + + is(toolbox.getCurrentPanel(), scratchpadPanel, + "Clicking link in stacktrace switches to Scratchpad panel"); + + is(Services.ww.activeWindow, toolbox.win.parent, + "Scratchpad's toolbox is focused"); +}); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-console-log.js b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-console-log.js new file mode 100644 index 000000000000..eb4abbf639b4 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-console-log.js @@ -0,0 +1,12 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +function onLoad123() { + console.log("Blah Blah"); +} + +window.addEventListener("load", onLoad123, false); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-errors.js b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-errors.js new file mode 100644 index 000000000000..f488b7ffbe55 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link-errors.js @@ -0,0 +1,10 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +window.addEventListener("load", function () { + document.bar(); +}, false); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link.html new file mode 100644 index 000000000000..02aa90a12b12 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-debugger-link.html @@ -0,0 +1,14 @@ + + + + + Web Console test for opening JS/Console call Links in Debugger + + + + + +

Web Console test for opening JS/Console call Links in Debugger.

+ + diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-1.css b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-1.css new file mode 100644 index 000000000000..ad7fd1999542 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-1.css @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +body { + color: #0f0; + font-weight: green; +} + diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-2.css b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-2.css new file mode 100644 index 000000000000..91b14137a273 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link-2.css @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +body { + color: #0fl; + font-weight: bold; +} + diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html new file mode 100644 index 000000000000..61c3f4fa9850 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-location-styleeditor-link.html @@ -0,0 +1,14 @@ + + + + + Web Console test for opening CSS Links in Style Editor + + + + + +

Web Console test for opening CSS Links in Style Editor.

+ + diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html new file mode 100644 index 000000000000..a780771003d0 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-stacktrace-location-debugger-link.html @@ -0,0 +1,25 @@ + + + + + Web Console test for opening console call stacktrace links in Debugger + + + +

Web Console test for opening console call stacktrace links in Debugger.

+ + + From 7a44b94e0ed28c653b1d03d150168637c04f4593 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 22 Dec 2016 11:45:10 -0500 Subject: [PATCH 02/34] Bug 1325398 - Make the check for duplicate Treeherder symbols, happen during `full` graph not `target` graph stage. r=dustin MozReview-Commit-ID: GfwAgERKdsL --HG-- extra : rebase_source : 49a6375df512bc90252c7e165bbe0a06c6500307 extra : source : 3fe8f44c7af63e6b85b181e6c1116cc44d1f0975 --- taskcluster/taskgraph/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskcluster/taskgraph/generator.py b/taskcluster/taskgraph/generator.py index d4711f54149b..68268e54e4e7 100644 --- a/taskcluster/taskgraph/generator.py +++ b/taskcluster/taskgraph/generator.py @@ -196,6 +196,7 @@ class TaskGraphGenerator(object): full_task_graph = TaskGraph(all_tasks, Graph(full_task_set.graph.nodes, edges)) + full_task_graph.for_each_task(verify_task_graph_symbol, scratch_pad={}) logger.info("Full task graph contains %d tasks and %d dependencies" % ( len(full_task_set.graph.nodes), len(edges))) yield 'full_task_graph', full_task_graph @@ -221,7 +222,6 @@ class TaskGraphGenerator(object): target_task_graph = TaskGraph( {l: all_tasks[l] for l in target_graph.nodes}, target_graph) - target_task_graph.for_each_task(verify_task_graph_symbol, scratch_pad={}) target_task_graph.for_each_task(verify_gecko_v2_routes, scratch_pad={}) yield 'target_task_graph', target_task_graph From 3878d6e75290fb851ca97b63a21be43571155fac Mon Sep 17 00:00:00 2001 From: "gtatum@mozilla.com" Date: Tue, 11 Oct 2016 20:30:24 +0000 Subject: [PATCH 03/34] Bug 1309065 - Be smarter about filling in the client-side css properties db; r=tromey MozReview-Commit-ID: BOYwveTH1Hy --HG-- rename : devtools/server/tests/mochitest/test_css-properties_01.html => devtools/server/tests/mochitest/test_css-properties.html extra : rebase_source : 11ceb980e2d1039b0120e761ee59e9760ee57b00 --- devtools/server/actors/css-properties.js | 7 +- devtools/server/tests/mochitest/chrome.ini | 3 +- ...rties_01.html => test_css-properties.html} | 0 .../mochitest/test_css-properties_02.html | 86 --- .../shared/css/generated/mach_commands.py | 35 ++ .../shared/css/generated/properties-db.js | 543 ++++++++++++++++++ .../shared/css/generated/properties-db.js.in | 6 + devtools/shared/fronts/css-properties.js | 17 +- .../tests/unit/test_css-properties-db.js | 52 +- 9 files changed, 631 insertions(+), 118 deletions(-) rename devtools/server/tests/mochitest/{test_css-properties_01.html => test_css-properties.html} (100%) delete mode 100644 devtools/server/tests/mochitest/test_css-properties_02.html diff --git a/devtools/server/actors/css-properties.js b/devtools/server/actors/css-properties.js index 928922934461..2a4538378584 100644 --- a/devtools/server/actors/css-properties.js +++ b/devtools/server/actors/css-properties.js @@ -68,17 +68,12 @@ function generateCssProperties() { let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name); - // In order to maintain any backwards compatible changes when debugging older - // clients, take the definition from the static CSS properties database, and fill it - // in with the most recent property definition from the server. - const clientDefinition = CSS_PROPERTIES[name] || {}; - const serverDefinition = { + properties[name] = { isInherited: DOMUtils.isInheritedProperty(name), values, supports, subproperties, }; - properties[name] = Object.assign(clientDefinition, serverDefinition); }); return properties; diff --git a/devtools/server/tests/mochitest/chrome.ini b/devtools/server/tests/mochitest/chrome.ini index ae69d163e202..85cc75611b9c 100644 --- a/devtools/server/tests/mochitest/chrome.ini +++ b/devtools/server/tests/mochitest/chrome.ini @@ -30,8 +30,7 @@ support-files = [test_css-logic.html] [test_css-logic-media-queries.html] [test_css-logic-specificity.html] -[test_css-properties_01.html] -[test_css-properties_02.html] +[test_css-properties.html] [test_Debugger.Source.prototype.introductionScript.html] [test_Debugger.Source.prototype.introductionType.html] [test_Debugger.Source.prototype.element.html] diff --git a/devtools/server/tests/mochitest/test_css-properties_01.html b/devtools/server/tests/mochitest/test_css-properties.html similarity index 100% rename from devtools/server/tests/mochitest/test_css-properties_01.html rename to devtools/server/tests/mochitest/test_css-properties.html diff --git a/devtools/server/tests/mochitest/test_css-properties_02.html b/devtools/server/tests/mochitest/test_css-properties_02.html deleted file mode 100644 index 1a5d99d721f5..000000000000 --- a/devtools/server/tests/mochitest/test_css-properties_02.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - Test CSS Properties Actor - - - - - - - Mozilla Bug 1265798 - Test Document - - diff --git a/devtools/shared/css/generated/mach_commands.py b/devtools/shared/css/generated/mach_commands.py index 4d6016276aa7..fb002c3c4001 100644 --- a/devtools/shared/css/generated/mach_commands.py +++ b/devtools/shared/css/generated/mach_commands.py @@ -13,6 +13,7 @@ import os import sys import string import subprocess +from mozbuild import shellutil from mozbuild.base import ( MozbuildObject, MachCommandBase, @@ -39,12 +40,46 @@ class MachCommands(MachCommandBase): """Generate the static css properties database for devtools and write it to file.""" print("Re-generating the css properties database...") + preferences = self.get_preferences() db = self.get_properties_db_from_xpcshell() self.output_template({ + 'preferences': stringify(preferences), 'cssProperties': stringify(db['cssProperties']), 'pseudoElements': stringify(db['pseudoElements'])}) + def get_preferences(self): + """Get all of the preferences associated with enabling and disabling a property.""" + # Build the command to run the preprocessor on PythonCSSProps.h + headerPath = resolve_path(self.topsrcdir, 'layout/style/PythonCSSProps.h') + + cpp = self.substs['CPP'] + + if not cpp: + print("Unable to find the cpp program. Please do a full, nonartifact") + print("build and try this again.") + sys.exit(1) + + if type(cpp) is list: + cmd = cpp + else: + cmd = shellutil.split(cpp) + cmd += shellutil.split(self.substs['ACDEFINES']) + cmd.append(headerPath) + + # The preprocessed list takes the following form: + # [ (name, prop, id, flags, pref, proptype), ... ] + preprocessed = eval(subprocess.check_output(cmd)) + + # Map this list + # (name, prop, id, flags, pref, proptype) => (name, pref) + preferences = [ + (name, pref) + for name, prop, id, flags, pref, proptype in preprocessed + if 'CSS_PROPERTY_INTERNAL' not in flags and pref] + + return preferences + def get_properties_db_from_xpcshell(self): """Generate the static css properties db for devtools from an xpcshell script.""" build = MozbuildObject.from_environment() diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 0e2853499ced..b85ac7e72496 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -9377,3 +9377,546 @@ exports.PSEUDO_ELEMENTS = [ ":placeholder", ":-moz-color-swatch" ]; + +/** + * A list of the preferences keys for whether a CSS property is enabled or not. This is + * exposed for testing purposes. + */ +exports.PREFERENCES = [ + [ + "all", + "layout.css.all-shorthand.enabled" + ], + [ + "background-blend-mode", + "layout.css.background-blend-mode.enabled" + ], + [ + "box-decoration-break", + "layout.css.box-decoration-break.enabled" + ], + [ + "color-adjust", + "layout.css.color-adjust.enabled" + ], + [ + "contain", + "layout.css.contain.enabled" + ], + [ + "grid", + "layout.css.grid.enabled" + ], + [ + "grid-area", + "layout.css.grid.enabled" + ], + [ + "grid-auto-columns", + "layout.css.grid.enabled" + ], + [ + "grid-auto-flow", + "layout.css.grid.enabled" + ], + [ + "grid-auto-rows", + "layout.css.grid.enabled" + ], + [ + "grid-column", + "layout.css.grid.enabled" + ], + [ + "grid-column-end", + "layout.css.grid.enabled" + ], + [ + "grid-column-gap", + "layout.css.grid.enabled" + ], + [ + "grid-column-start", + "layout.css.grid.enabled" + ], + [ + "grid-gap", + "layout.css.grid.enabled" + ], + [ + "grid-row", + "layout.css.grid.enabled" + ], + [ + "grid-row-end", + "layout.css.grid.enabled" + ], + [ + "grid-row-gap", + "layout.css.grid.enabled" + ], + [ + "grid-row-start", + "layout.css.grid.enabled" + ], + [ + "grid-template", + "layout.css.grid.enabled" + ], + [ + "grid-template-areas", + "layout.css.grid.enabled" + ], + [ + "grid-template-columns", + "layout.css.grid.enabled" + ], + [ + "grid-template-rows", + "layout.css.grid.enabled" + ], + [ + "initial-letter", + "layout.css.initial-letter.enabled" + ], + [ + "image-orientation", + "layout.css.image-orientation.enabled" + ], + [ + "isolation", + "layout.css.isolation.enabled" + ], + [ + "mix-blend-mode", + "layout.css.mix-blend-mode.enabled" + ], + [ + "object-fit", + "layout.css.object-fit-and-position.enabled" + ], + [ + "object-position", + "layout.css.object-fit-and-position.enabled" + ], + [ + "-moz-osx-font-smoothing", + "layout.css.osx-font-smoothing.enabled" + ], + [ + "overflow-clip-box", + "layout.css.overflow-clip-box.enabled" + ], + [ + "paint-order", + "svg.paint-order.enabled" + ], + [ + "scroll-behavior", + "layout.css.scroll-behavior.property-enabled" + ], + [ + "scroll-snap-coordinate", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-destination", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-points-x", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-points-y", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type-x", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type-y", + "layout.css.scroll-snap.enabled" + ], + [ + "shape-outside", + "layout.css.shape-outside.enabled" + ], + [ + "text-combine-upright", + "layout.css.text-combine-upright.enabled" + ], + [ + "-webkit-text-fill-color", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke-color", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke-width", + "layout.css.prefixes.webkit" + ], + [ + "touch-action", + "layout.css.touch_action.enabled" + ], + [ + "-moz-transform", + "layout.css.prefixes.transforms" + ], + [ + "transform-box", + "svg.transform-box.enabled" + ], + [ + "-moz-transform-origin", + "layout.css.prefixes.transforms" + ], + [ + "-moz-perspective-origin", + "layout.css.prefixes.transforms" + ], + [ + "-moz-perspective", + "layout.css.prefixes.transforms" + ], + [ + "-moz-transform-style", + "layout.css.prefixes.transforms" + ], + [ + "-moz-backface-visibility", + "layout.css.prefixes.transforms" + ], + [ + "-moz-border-image", + "layout.css.prefixes.border-image" + ], + [ + "-moz-transition", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-delay", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-duration", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-property", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-timing-function", + "layout.css.prefixes.transitions" + ], + [ + "-moz-animation", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-delay", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-direction", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-duration", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-fill-mode", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-iteration-count", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-name", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-play-state", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-timing-function", + "layout.css.prefixes.animations" + ], + [ + "-moz-box-sizing", + "layout.css.prefixes.box-sizing" + ], + [ + "-moz-font-feature-settings", + "layout.css.prefixes.font-features" + ], + [ + "-moz-font-language-override", + "layout.css.prefixes.font-features" + ], + [ + "-webkit-animation", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-delay", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-duration", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-fill-mode", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-iteration-count", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-name", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-play-state", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-timing-function", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-filter", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-size-adjust", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform-style", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-backface-visibility", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-perspective", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-perspective-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-delay", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-duration", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-property", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-timing-function", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-top-left-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-top-right-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-bottom-left-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-bottom-right-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-clip", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-size", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-image", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-shadow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-sizing", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-flex", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-ordinal-group", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-orient", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-align", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-pack", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-wrap", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-flow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-order", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-grow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-shrink", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-basis", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-justify-content", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-items", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-self", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-content", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-user-select", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-clip", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-composite", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-image", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position-x", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position-y", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-repeat", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-size", + "layout.css.prefixes.webkit" + ] +]; diff --git a/devtools/shared/css/generated/properties-db.js.in b/devtools/shared/css/generated/properties-db.js.in index 370c9199a02d..372e525e9776 100644 --- a/devtools/shared/css/generated/properties-db.js.in +++ b/devtools/shared/css/generated/properties-db.js.in @@ -18,3 +18,9 @@ exports.CSS_PROPERTIES = ${cssProperties}; * A list of the pseudo elements. */ exports.PSEUDO_ELEMENTS = ${pseudoElements}; + +/** + * A list of the preferences keys for whether a CSS property is enabled or not. This is + * exposed for testing purposes. + */ +exports.PREFERENCES = ${preferences}; diff --git a/devtools/shared/fronts/css-properties.js b/devtools/shared/fronts/css-properties.js index 4bf0fa88e086..655687232e46 100644 --- a/devtools/shared/fronts/css-properties.js +++ b/devtools/shared/fronts/css-properties.js @@ -234,15 +234,7 @@ const initCssProperties = Task.async(function* (toolbox) { // Get the list dynamically if the cssProperties actor exists. if (toolbox.target.hasActor("cssProperties")) { front = CssPropertiesFront(client, toolbox.target.form); - const serverDB = yield front.getCSSDatabase(); - - // Ensure the database was returned in a format that is understood. - // Older versions of the protocol could return a blank database. - if (!serverDB.properties && !serverDB.margin) { - db = CSS_PROPERTIES_DB; - } else { - db = serverDB; - } + db = yield front.getCSSDatabase(); } else { // The target does not support this actor, so require a static list of supported // properties. @@ -294,9 +286,6 @@ function normalizeCssData(db) { db = { properties: db }; } - // Fill in any missing DB information from the static database. - db = Object.assign({}, CSS_PROPERTIES_DB, db); - let missingSupports = !db.properties.color.supports; let missingValues = !db.properties.color.values; let missingSubproperties = !db.properties.background.subproperties; @@ -320,6 +309,10 @@ function normalizeCssData(db) { db.properties[name].subproperties = CSS_PROPERTIES_DB.properties[name].subproperties; } + // Add "isInherited" information to the css properties if it's missing. + if (db.properties.font.isInherited) { + db.properties[name].isInherited = CSS_PROPERTIES_DB.properties[name].isInherited; + } } } diff --git a/devtools/shared/tests/unit/test_css-properties-db.js b/devtools/shared/tests/unit/test_css-properties-db.js index 108650a3ed49..ec14a99a6683 100644 --- a/devtools/shared/tests/unit/test_css-properties-db.js +++ b/devtools/shared/tests/unit/test_css-properties-db.js @@ -22,8 +22,9 @@ const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); -const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db"); +const {PSEUDO_ELEMENTS, CSS_PROPERTIES, PREFERENCES} = require("devtools/shared/css/generated/properties-db"); const {generateCssProperties} = require("devtools/server/actors/css-properties"); +const {Preferences} = require("resource://gre/modules/Preferences.jsm"); function run_test() { const propertiesErrorMessage = "If this assertion fails, then the client side CSS " + @@ -38,7 +39,9 @@ function run_test() { /** * Check that the platform and client match for the details on their CSS properties. - * Enumerate each property to aid in debugging. + * Enumerate each property to aid in debugging. Sometimes these properties don't + * completely agree due to differences in preferences. Check the currently set + * preference for that property to see if it's enabled. */ const platformProperties = generateCssProperties(); @@ -47,17 +50,18 @@ function run_test() { const clientProperty = CSS_PROPERTIES[propertyName]; const deepEqual = isJsonDeepEqual(platformProperty, clientProperty); + // The "all" property can contain information that can be turned on and off by + // preferences. These values can be different between OSes, so ignore the equality + // check for this property, since this is likely to fail. + if (propertyName === "all") { + continue; + } + if (deepEqual) { ok(true, `The static database and platform match for "${propertyName}".`); } else { - const prefMessage = `The static database and platform do not match ` + - `for "${propertyName}".`; - if (getPreference(propertyName) === false) { - ok(true, `${prefMessage} However, there is a preference for disabling this ` + - `property on the current build.`); - } else { - ok(false, `${prefMessage} ${propertiesErrorMessage}`); - } + ok(false, `The static database and platform do not match for ` + ` + "${propertyName}". ${propertiesErrorMessage}`); } } @@ -75,8 +79,14 @@ function run_test() { } mismatches.forEach(propertyName => { - ok(false, `The static database and platform do not agree on the property ` + - `"${propertyName}" ${propertiesErrorMessage}`); + if (getPreference(propertyName) === false) { + ok(true, `The static database and platform do not agree on the property ` + + `"${propertyName}" This is ok because it is currently disabled through ` + + `a preference.`); + } else { + ok(false, `The static database and platform do not agree on the property ` + + `"${propertyName}" ${propertiesErrorMessage}`); + } }); } @@ -134,3 +144,21 @@ function getKeyMismatches(a, b) { return aMismatches.concat(bMismatches); } + +/** + * Get the preference value of whether this property is enabled. Returns an empty string + * if no preference exists. + * + * @param {String} propertyName + * @return {Boolean|undefined} + */ +function getPreference(propertyName) { + const preference = PREFERENCES.find(([prefPropertyName, preferenceKey]) => { + return prefPropertyName === propertyName && !!preferenceKey; + }); + + if (preference) { + return Preferences.get(preference[1]); + } + return undefined; +} From 058d4352892b9a03225ac4c3aeea3743bb5e7b8c Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 11:19:36 +0100 Subject: [PATCH 04/34] Bug 1323770 - Moztest should forward correct test result. r=ahal Registered callback handlers for tests should receive the correct test status when the test has been finished, and not always "Error". This change allows those callbacks to run specific code for individual test results, eg. only do screenshots for failures. MozReview-Commit-ID: FfbCRR0Jvjb --HG-- extra : rebase_source : 98c69eea450f35312fd43bb7237a9d00e90636c4 --- testing/mozbase/moztest/moztest/adapters/unit.py | 13 ++++++++----- testing/mozbase/moztest/setup.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/testing/mozbase/moztest/moztest/adapters/unit.py b/testing/mozbase/moztest/moztest/adapters/unit.py index c31a6c3b37d1..cee0e05e92a0 100644 --- a/testing/mozbase/moztest/moztest/adapters/unit.py +++ b/testing/mozbase/moztest/moztest/adapters/unit.py @@ -134,7 +134,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addFailure(self, test, err): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "FAIL") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -145,10 +145,13 @@ class StructuredTestResult(TextTestResult): def addSuccess(self, test): extra = self._get_class_method_name(test) - self.logger.test_end(test.id(), "PASS", expected="PASS", extra=extra) + self.logger.test_end(test.id(), + "PASS", + expected="PASS", + extra=extra) def addExpectedFailure(self, test, err): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "FAIL") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -158,7 +161,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addUnexpectedSuccess(self, test): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "PASS") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "PASS", @@ -166,7 +169,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addSkip(self, test, reason): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "SKIP") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "SKIP", diff --git a/testing/mozbase/moztest/setup.py b/testing/mozbase/moztest/setup.py index 24455c285b71..9c7c11789842 100644 --- a/testing/mozbase/moztest/setup.py +++ b/testing/mozbase/moztest/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages -PACKAGE_VERSION = '0.7' +PACKAGE_VERSION = '0.8' # dependencies deps = ['mozinfo'] From ce0f46c7310fca8844a96d2d35b5171be477df68 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 15:19:40 +0100 Subject: [PATCH 05/34] Bug 1323770 - Marionette should not take screenshots for skipped tests. r=maja_zf Taking screenshots for skipped tests is useless and should be avoided to reduce the size of the test logs. MozReview-Commit-ID: 9HPH7pSXTj9 --HG-- extra : rebase_source : 43eef3c0d95aca3938e378b9f1029e361758bdff --- testing/marionette/harness/marionette_harness/runner/base.py | 4 ++++ testing/marionette/harness/requirements.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/marionette/harness/marionette_harness/runner/base.py b/testing/marionette/harness/marionette_harness/runner/base.py index 9527ea59142c..679efb87711b 100644 --- a/testing/marionette/harness/marionette_harness/runner/base.py +++ b/testing/marionette/harness/marionette_harness/runner/base.py @@ -552,6 +552,10 @@ class BaseMarionetteTestRunner(object): self.e10s = e10s def gather_debug(test, status): + # No screenshots and page source for skipped tests + if status == "SKIP": + return + rv = {} marionette = test._marionette_weakref() diff --git a/testing/marionette/harness/requirements.txt b/testing/marionette/harness/requirements.txt index 3fab7c2d1bda..75ab9ce92b2a 100644 --- a/testing/marionette/harness/requirements.txt +++ b/testing/marionette/harness/requirements.txt @@ -9,6 +9,6 @@ moznetwork >= 0.21 mozprocess >= 0.9 mozprofile >= 0.7 mozrunner >= 6.13 -moztest >= 0.7 +moztest >= 0.8 mozversion >= 1.1 wptserve >= 1.3.0 From ebbc95b0d4b82dae61c40b71d2aba7148f718f01 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 28 Dec 2016 16:49:44 +0100 Subject: [PATCH 06/34] Bug 1323770 - Fix skip decorators for unit tests. r=maja_zf Marionette's skip decorators are currently not conform with the ones from the Python's unittest module, which require a reason as parameter. As such Marionette should behave the same and should also require a reason for more detailed skip messages. This is done by wrapping the actual decorator with another enclosing method. With the changes we also ensure that the wrapper has the same attributes as the wrapped function by using functools.wraps(). This hasn't used so far and makes debugging harder. Further a couple of skip methods and classes were copied from the unittest module, which should be better imported instead to reduce code duplication. MozReview-Commit-ID: 6XT6M6cbCFW --HG-- extra : rebase_source : 08d9a0fda941448e601142bdde0409e574cbaa89 --- .../security/test_ssl_status_after_restart.py | 2 +- .../marionette_test/__init__.py | 12 +- .../marionette_test/decorators.py | 188 ++++++++++-------- .../marionette_test/errors.py | 32 --- .../marionette_test/testcases.py | 12 +- .../tests/unit/test_about_pages.py | 12 +- .../tests/unit/test_click_scrolling.py | 2 +- .../tests/unit/test_crash.py | 2 +- .../tests/unit/test_import_script.py | 9 +- .../tests/unit/test_modal_dialogs.py | 2 +- .../tests/unit/test_screen_orientation.py | 20 +- .../tests/unit/test_transport.py | 4 +- 12 files changed, 142 insertions(+), 155 deletions(-) delete mode 100644 testing/marionette/harness/marionette_harness/marionette_test/errors.py diff --git a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py index d5c99dd8de29..f274d8f2fd28 100644 --- a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py +++ b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py @@ -46,7 +46,7 @@ class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase): finally: super(TestSSLStatusAfterRestart, self).tearDown() - @skip_if_e10s + @skip_if_e10s("Bug 1325047") def test_ssl_status_after_restart(self): for item in self.test_data: with self.marionette.using_context('content'): diff --git a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py index 2de79c91273a..f9baf737dff4 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py @@ -5,11 +5,15 @@ __version__ = '3.1.0' -from .decorators import ( +from unittest.case import ( expectedFailure, + skip, + SkipTest, +) + +from .decorators import ( parameterized, run_if_e10s, - skip, skip_if_chrome, skip_if_desktop, skip_if_e10s, @@ -19,10 +23,6 @@ from .decorators import ( with_parameters, ) -from .errors import ( - SkipTest, -) - from .testcases import ( CommonTestCase, MarionetteTestCase, diff --git a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py index 8764532d660b..3a49868990a2 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py @@ -3,28 +3,13 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import functools -import sys import types -from .errors import ( - _ExpectedFailure, - _UnexpectedSuccess, +from unittest.case import ( SkipTest, ) -def expectedFailure(func): - """Decorator which marks a test as expected fail.""" - @functools.wraps(func) - def wrapper(*args, **kwargs): - try: - func(*args, **kwargs) - except Exception: - raise _ExpectedFailure(sys.exc_info()) - raise _UnexpectedSuccess - return wrapper - - def parameterized(func_suffix, *args, **kwargs): r"""Decorator which generates methods given a base method and some data. @@ -61,85 +46,101 @@ def parameterized(func_suffix, *args, **kwargs): return wrapped -def run_if_e10s(target): +def run_if_e10s(reason): """Decorator which runs a test if e10s mode is active.""" - def wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - }""") - - if not multi_process_browser: - raise SkipTest('skipping due to e10s is disabled') - return target(self, *args, **kwargs) - return wrapper - - -def skip(reason): - """Decorator which unconditionally skips a test.""" def decorator(test_item): - if not isinstance(test_item, (type, types.ClassType)): - @functools.wraps(test_item) - def skip_wrapper(*args, **kwargs): - raise SkipTest(reason) - test_item = skip_wrapper + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') - test_item.__unittest_skip__ = True - test_item.__unittest_skip_why__ = reason - return test_item + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = not self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + } + """) + if multi_process_browser: + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper return decorator -def skip_if_chrome(target): +def skip_if_chrome(reason): """Decorator which skips a test if chrome context is active.""" - def wrapper(self, *args, **kwargs): - if self.marionette._send_message("getContext", key="value") == "chrome": - raise SkipTest("skipping test in chrome context") - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette._send_message('getContext', key='value') == 'chrome': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_desktop(target): +def skip_if_desktop(reason): """Decorator which skips a test if run on desktop.""" - def wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'firefox': - raise SkipTest('skipping due to desktop') - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'firefox': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_e10s(target): +def skip_if_e10s(reason): """Decorator which skips a test if e10s mode is active.""" - def wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - }""") + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') - if multi_process_browser: - raise SkipTest('skipping due to e10s') - return target(self, *args, **kwargs) - return wrapper + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + } + """) + if multi_process_browser: + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_mobile(target): +def skip_if_mobile(reason): """Decorator which skips a test if run on mobile.""" - def wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'fennec': - raise SkipTest('skipping due to fennec') - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'fennec': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_unless_browser_pref(pref, predicate=bool): +def skip_unless_browser_pref(reason, pref, predicate=bool): """Decorator which skips a test based on the value of a browser preference. + :param reason: Message describing why the test need to be skipped. :param pref: the preference name :param predicate: a function that should return false to skip the test. The function takes one parameter, the preference value. @@ -150,33 +151,46 @@ def skip_unless_browser_pref(pref, predicate=bool): Example: :: class TestSomething(MarionetteTestCase): - @skip_unless_browser_pref("accessibility.tabfocus", - lambda value: value >= 7) + @skip_unless_browser_pref("Sessionstore needs to be enabled for crashes", + "browser.sessionstore.resume_from_crash", + lambda value: value is True, + ) def test_foo(self): pass # test implementation here + """ - def wrapper(target): - @functools.wraps(target) - def wrapped(self, *args, **kwargs): + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + if not callable(predicate): + raise ValueError('predicate must be callable') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): value = self.marionette.get_pref(pref) if value is None: self.fail("No such browser preference: {0!r}".format(pref)) if not predicate(value): - raise SkipTest("browser preference {0!r}: {1!r}".format((pref, value))) - return target(self, *args, **kwargs) - return wrapped - return wrapper + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_unless_protocol(predicate): +def skip_unless_protocol(reason, predicate): """Decorator which skips a test if the predicate does not match the current protocol level.""" def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + if not callable(predicate): + raise ValueError('predicate must be callable') + @functools.wraps(test_item) - def skip_wrapper(self): + def skip_wrapper(self, *args, **kwargs): level = self.marionette.client.protocol if not predicate(level): - raise SkipTest('skipping because protocol level is {}'.format(level)) - return test_item(self) + raise SkipTest(reason) + return test_item(self, *args, **kwargs) return skip_wrapper return decorator diff --git a/testing/marionette/harness/marionette_harness/marionette_test/errors.py b/testing/marionette/harness/marionette_harness/marionette_test/errors.py deleted file mode 100644 index 301cac82c7de..000000000000 --- a/testing/marionette/harness/marionette_harness/marionette_test/errors.py +++ /dev/null @@ -1,32 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -class SkipTest(Exception): - """ - Raise this exception in a test to skip it. - - Usually you can use TestResult.skip() or one of the skipping decorators - instead of raising this directly. - """ - - pass - - -class _ExpectedFailure(Exception): - """ - Raise this when a test is expected to fail. - - This is an implementation detail. - """ - - def __init__(self, exc_info): - super(_ExpectedFailure, self).__init__() - self.exc_info = exc_info - - -class _UnexpectedSuccess(Exception): - """The test was supposed to fail, but it didn't.""" - - pass diff --git a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py index 4c20e7eda221..5051e3351eeb 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py @@ -12,6 +12,12 @@ import unittest import warnings import weakref +from unittest.case import ( + _ExpectedFailure, + _UnexpectedSuccess, + SkipTest, +) + from marionette_driver.errors import ( MarionetteException, ScriptTimeoutException, @@ -19,12 +25,6 @@ from marionette_driver.errors import ( ) from mozlog import get_default_logger -from .errors import ( - _ExpectedFailure, - _UnexpectedSuccess, - SkipTest, -) - def _wraps_parameterized(func, func_suffix, args, kwargs): """Internal: Decorator used in class MetaParameterized.""" diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py index 493c813ec1f9..f0365f470a4f 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py @@ -26,7 +26,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): super(TestAboutPages, self).tearDown() - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_back_forward(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -46,7 +46,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_navigate_non_remote_about_pages(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -61,7 +61,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # On Android no shortcuts are available + @skip_if_mobile("On Android no shortcuts are available") def test_navigate_shortcut_key(self): def open_with_shortcut(): with self.marionette.using_context("chrome"): @@ -76,7 +76,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_type_to_non_remote_tab(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -93,7 +93,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Interacting with chrome elements not available for Fennec + @skip_if_mobile("Interacting with chrome elements not available for Fennec") def test_type_to_remote_tab(self): # about:blank keeps remoteness from remote_uri self.marionette.navigate("about:blank") @@ -103,7 +103,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.wait_for_condition(lambda mn: mn.get_url() == self.remote_uri) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_hang(self): # Open a new tab and close the first one new_tab = self.open_tab(trigger="menu") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py index 8c4b140a6657..5543126782a6 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py @@ -43,7 +43,7 @@ class TestClickScrolling(MarionetteTestCase): except MoveTargetOutOfBoundsException: self.fail("Should not be out of bounds") - @skip("Bug 1003682") + @skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll") def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self): test_html = self.marionette.absolute_url("scroll.html") self.marionette.navigate(test_html) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py index 3f7bd0a3ed31..7e74f0857a12 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py @@ -104,7 +104,7 @@ class TestCrash(BaseCrashTestCase): # chrome and frame script. # self.marionette.get_url() - @run_if_e10s + @run_if_e10s("Content crashes only exist in e10s mode") def test_crash_content_process(self): # If e10s is disabled the chrome process crashes self.marionette.navigate(self.remote_uri) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py index 21a37e941784..e86de2bd579d 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py @@ -31,6 +31,11 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.marionette.clear_imported_scripts() self.reset_context() + def tearDown(self): + self.close_all_windows() + + super(TestImportScriptContent, self).tearDown() + def reset_context(self): self.marionette.set_context("content") @@ -109,8 +114,8 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.assert_defined("testFunc") self.assert_defined("testAnotherFunc") - @skip_if_chrome - @skip_if_mobile # New windows not supported in Fennec + @skip_if_chrome("Needs content scope") + @skip_if_mobile("New windows not supported in Fennec") def test_imports_apply_globally(self): self.marionette.navigate( self.marionette.absolute_url("test_windows.html")) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py index 151dccd56219..cfc402d6819a 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py @@ -157,7 +157,7 @@ class TestTabModals(MarionetteTestCase): alert.accept() self.wait_for_condition(lambda mn: mn.get_url() == "about:blank") - @skip_if_e10s + @skip_if_e10s("Bug 1325044") def test_unrelated_command_when_alert_present(self): click_handler = self.marionette.find_element(By.ID, 'click-handler') text = self.marionette.find_element(By.ID, 'click-result').text diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py index 7dfafc1750c3..830795a1ec62 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py @@ -23,31 +23,31 @@ class TestScreenOrientation(MarionetteTestCase): self.assertEqual(self.marionette.orientation, default_orientation, "invalid state") MarionetteTestCase.tearDown(self) - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_portrait_primary(self): self.marionette.set_orientation("portrait-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_landscape_primary(self): self.marionette.set_orientation("landscape-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_portrait_secondary(self): self.marionette.set_orientation("portrait-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-secondary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_landscape_secondary(self): self.marionette.set_orientation("landscape-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-secondary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_shorthand_portrait(self): # Set orientation to something other than portrait-primary first, since the default is # portrait-primary. @@ -58,29 +58,29 @@ class TestScreenOrientation(MarionetteTestCase): new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_shorthand_landscape(self): self.marionette.set_orientation("landscape") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_with_mixed_casing(self): self.marionette.set_orientation("lAnDsCaPe") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_invalid_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")): self.marionette.set_orientation("cheese") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_null_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")): self.marionette.set_orientation(None) - @skip_if_mobile + @skip_if_mobile("Specific test for Firefox") def test_unsupported_operation_on_desktop(self): with self.assertRaises(errors.UnsupportedOperationException): self.marionette.set_orientation("landscape-primary") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py index 2d2d7a4e42ba..39e36a9b224c 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py @@ -33,14 +33,14 @@ class TestMessageSequencing(MarionetteTestCase): self.marionette.client.send(cmd) return self.last_id - @skip_unless_protocol(lambda level: level >= 3) + @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) def test_discard_older_messages(self): first = self.send(*get_current_url) second = self.send(*execute_script) resp = self.marionette.client.receive() self.assertEqual(second, resp.id) - @skip_unless_protocol(lambda level: level >= 3) + @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) def test_last_id_incremented(self): before = self.last_id self.send(*get_current_url) From 4e4be46188bb689b4504d0ae0d3b0c21f1903871 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 17:34:59 +0100 Subject: [PATCH 07/34] Bug 1323770 - Fix inappropriatelly skipped/disabled tests. r=maja_zf Commenting out test methods is not the way how we should mark tests as being skipped. The correct skip methods have to be used instead so that the final results also show the correct skip count. MozReview-Commit-ID: LKL4YQCyFko --HG-- extra : rebase_source : e9df5f27011b800bf36392a6aa245f001b4abdf0 --- .../tests/unit/test_certificates.py | 8 +++--- .../tests/unit/test_element_state_chrome.py | 7 ++--- .../tests/unit/test_navigation.py | 14 +++++----- .../tests/unit/test_single_finger_desktop.py | 26 ++++++++++--------- .../tests/unit/test_text_chrome.py | 5 ++-- .../tests/unit/test_typing.py | 18 +++++-------- .../tests/unit/unit-tests.ini | 1 + 7 files changed, 39 insertions(+), 40 deletions(-) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py index a19a433d3469..fb4c5c38b4d0 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py @@ -4,10 +4,12 @@ from marionette_driver.errors import UnknownException -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip class TestCertificates(MarionetteTestCase): + + @skip("Bug 1325079") def test_block_insecure_sites(self): self.marionette.delete_session() self.marionette.start_session() @@ -17,16 +19,16 @@ class TestCertificates(MarionetteTestCase): with self.assertRaises(UnknownException): self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) + @skip("Bug 1325079") def test_accept_all_insecure(self): self.marionette.delete_session() self.marionette.start_session({"desiredCapability": {"acceptSslCerts": ["*"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) - """ + @skip("Bug 1325079") def test_accept_some_insecure(self): self.marionette.delete_session() self.marionette.start_session({"requiredCapabilities": {"acceptSslCerts": ["127.0.0.1"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) - """ \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py index e2433dc6c6d7..01ed355c48a2 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py @@ -4,7 +4,7 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip class TestIsElementEnabledChrome(MarionetteTestCase): @@ -36,9 +36,7 @@ class TestIsElementEnabledChrome(MarionetteTestCase): self.assertTrue(rect['y'] > 0) -# Switched off in bug 896043, -# and to be turned on in bug 896046 -""" +@skip("Switched off in bug 896043, and to be turned on in bug 896046") class TestIsElementDisplayed(MarionetteTestCase): def test_isDisplayed(self): l = self.marionette.find_element(By.ID, "textInput") @@ -46,7 +44,6 @@ class TestIsElementDisplayed(MarionetteTestCase): self.marionette.execute_script("arguments[0].hidden = true;", [l]) self.assertFalse(l.is_displayed()) self.marionette.execute_script("arguments[0].hidden = false;", [l]) -""" class TestGetElementAttributeChrome(MarionetteTestCase): diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py index 3d2821b46e3f..fdb18814b7be 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py @@ -2,15 +2,17 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from unittest import skip - import contextlib import time import urllib from marionette_driver import errors, By, Wait - -from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin +from marionette_harness import ( + MarionetteTestCase, + skip, + skip_if_mobile, + WindowManagerMixin, +) def inline(doc): @@ -112,7 +114,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.marionette.switch_to_frame() self.assertTrue('test_iframe.html' in self.marionette.get_url()) - @skip_if_mobile # Bug 1323755 - Socket timeout + @skip_if_mobile("Bug 1323755 - Socket timeout") def test_invalid_protocol(self): with self.assertRaises(errors.MarionetteException): self.marionette.navigate("thisprotocoldoesnotexist://") @@ -150,7 +152,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.assertTrue(self.marionette.execute_script( "return window.visited", sandbox=None)) - @skip_if_mobile # Fennec doesn't support other chrome windows + @skip_if_mobile("Fennec doesn't support other chrome windows") def test_about_blank_for_new_docshell(self): """ Bug 1312674 - Hang when loading about:blank for a new docshell.""" # Open a window to get a new docshell created for the first tab diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py index 019531efcfc3..8ac80c3c547c 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py @@ -6,9 +6,9 @@ import os import sys from marionette_driver.errors import MarionetteException -from marionette_driver.by import By +from marionette_driver import Actions, By -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip # add this directory to the path sys.path.append(os.path.dirname(__file__)) @@ -85,28 +85,30 @@ prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]); def test_wait_with_value(self): wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click") - """ - // Skipping due to Bug 1191066 + @skip("Bug 1191066") def test_context_menu(self): - context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click") + context_menu(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu", + "button1-mousemove-mousedown-contextmenu-mouseup-click") + @skip("Bug 1191066") def test_long_press_action(self): - long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") + long_press_action(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu-mouseup-click") + @skip("Bug 1191066") def test_long_press_on_xy_action(self): - long_press_on_xy_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") - """ + long_press_on_xy_action(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu-mouseup-click") - """ - //Skipping due to Bug 865334 + @skip("Bug 865334") def test_long_press_fail(self): testAction = self.marionette.absolute_url("testAction.html") self.marionette.navigate(testAction) button = self.marionette.find_element(By.ID, "button1Copy") action = Actions(self.marionette) action.press(button).long_press(button, 5) - assertRaises(MarionetteException, action.perform) - """ + self.assertRaises(MarionetteException, action.perform) def test_chain(self): chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py index 065e10c9729b..e0b63de16f58 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py @@ -4,10 +4,10 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase, WindowManagerMixin +from marionette_harness import MarionetteTestCase, skip, WindowManagerMixin -''' Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046 +@skip("Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046") class TestTextChrome(WindowManagerMixin, MarionetteTestCase): def setUp(self): @@ -42,4 +42,3 @@ class TestTextChrome(WindowManagerMixin, MarionetteTestCase): self.assertEqual("test", box.text) box.send_keys("at") self.assertEqual("attest", box.text) -''' diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py index bb7b2ff41c31..53d2bb4f1d67 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py @@ -8,7 +8,7 @@ from marionette_driver.by import By from marionette_driver.errors import ElementNotVisibleException from marionette_driver.keys import Keys -from marionette_harness import MarionetteTestCase, skip_if_mobile +from marionette_harness import MarionetteTestCase, skip, skip_if_mobile def inline(doc): @@ -32,7 +32,7 @@ class TestTypingChrome(TypingTestCase): super(TestTypingChrome, self).setUp() self.marionette.set_context("chrome") - @skip_if_mobile # Interacting with chrome elements not available for Fennec + @skip_if_mobile("Interacting with chrome elements not available for Fennec") def test_cut_and_paste_shortcuts(self): with self.marionette.using_context("content"): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -213,7 +213,7 @@ class TestTypingContent(TypingTestCase): # filled, we're a letter short here self.assertEqual(result.text, "I like chees") - @skip_if_mobile # Bug 1324752 - Arrow keys cannot be sent in Fennec + @skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec") def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -241,7 +241,7 @@ class TestTypingContent(TypingTestCase): # And leave no rubbish/printable keys in the "keyReporter" self.assertEqual("", element.get_property("value")) - """Disabled. Reenable in Bug 1068728 + @skip("Reenable in Bug 1068728") def testNumericShiftKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -252,7 +252,6 @@ class TestTypingContent(TypingTestCase): element.send_keys(numericShiftsEtc) self.assertEqual(numericShiftsEtc, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ def testLowerCaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -263,7 +262,7 @@ class TestTypingContent(TypingTestCase): element.send_keys(lowerAlphas) self.assertEqual(lowerAlphas, element.get_property("value")) - """Disabled. Reenable in Bug 1068735 + @skip("Reenable in Bug 1068735") def testUppercaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -274,9 +273,8 @@ class TestTypingContent(TypingTestCase): element.send_keys(upperAlphas) self.assertEqual(upperAlphas, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ - """Disabled. Reenable in Bug 1068726 + @skip("Reenable in Bug 1068726") def testAllPrintableKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -288,9 +286,8 @@ class TestTypingContent(TypingTestCase): self.assertTrue(allPrintable, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ - """Disabled. Reenable in Bug 1068733 + @skip("Reenable in Bug 1068733") def testSpecialSpaceKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -298,7 +295,6 @@ class TestTypingContent(TypingTestCase): element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij") self.assertEqual("abcd fgh ij", element.get_property("value")) - """ def testShouldTypeAnInteger(self): test_html = self.marionette.absolute_url("javascriptPage.html") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini index bb4fe03ececd..868cab610984 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini +++ b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini @@ -7,6 +7,7 @@ [test_expectedfail.py] expected = fail [test_import_script.py] +[test_certificates.py] [test_click.py] [test_click_chrome.py] skip-if = appname == 'fennec' From d1a5db810e2cc7905ada8ec546894401172e028d Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 28 Dec 2016 13:42:19 -0800 Subject: [PATCH 08/34] Backed out changeset 2aef437d23b7 (bug 1309065) for failures in test_css-properties-db.js a=backout --HG-- rename : devtools/server/tests/mochitest/test_css-properties.html => devtools/server/tests/mochitest/test_css-properties_01.html --- devtools/server/actors/css-properties.js | 7 +- devtools/server/tests/mochitest/chrome.ini | 3 +- ...rties.html => test_css-properties_01.html} | 0 .../mochitest/test_css-properties_02.html | 86 +++ .../shared/css/generated/mach_commands.py | 35 -- .../shared/css/generated/properties-db.js | 543 ------------------ .../shared/css/generated/properties-db.js.in | 6 - devtools/shared/fronts/css-properties.js | 17 +- .../tests/unit/test_css-properties-db.js | 52 +- 9 files changed, 118 insertions(+), 631 deletions(-) rename devtools/server/tests/mochitest/{test_css-properties.html => test_css-properties_01.html} (100%) create mode 100644 devtools/server/tests/mochitest/test_css-properties_02.html diff --git a/devtools/server/actors/css-properties.js b/devtools/server/actors/css-properties.js index 2a4538378584..928922934461 100644 --- a/devtools/server/actors/css-properties.js +++ b/devtools/server/actors/css-properties.js @@ -68,12 +68,17 @@ function generateCssProperties() { let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name); - properties[name] = { + // In order to maintain any backwards compatible changes when debugging older + // clients, take the definition from the static CSS properties database, and fill it + // in with the most recent property definition from the server. + const clientDefinition = CSS_PROPERTIES[name] || {}; + const serverDefinition = { isInherited: DOMUtils.isInheritedProperty(name), values, supports, subproperties, }; + properties[name] = Object.assign(clientDefinition, serverDefinition); }); return properties; diff --git a/devtools/server/tests/mochitest/chrome.ini b/devtools/server/tests/mochitest/chrome.ini index 85cc75611b9c..ae69d163e202 100644 --- a/devtools/server/tests/mochitest/chrome.ini +++ b/devtools/server/tests/mochitest/chrome.ini @@ -30,7 +30,8 @@ support-files = [test_css-logic.html] [test_css-logic-media-queries.html] [test_css-logic-specificity.html] -[test_css-properties.html] +[test_css-properties_01.html] +[test_css-properties_02.html] [test_Debugger.Source.prototype.introductionScript.html] [test_Debugger.Source.prototype.introductionType.html] [test_Debugger.Source.prototype.element.html] diff --git a/devtools/server/tests/mochitest/test_css-properties.html b/devtools/server/tests/mochitest/test_css-properties_01.html similarity index 100% rename from devtools/server/tests/mochitest/test_css-properties.html rename to devtools/server/tests/mochitest/test_css-properties_01.html diff --git a/devtools/server/tests/mochitest/test_css-properties_02.html b/devtools/server/tests/mochitest/test_css-properties_02.html new file mode 100644 index 000000000000..1a5d99d721f5 --- /dev/null +++ b/devtools/server/tests/mochitest/test_css-properties_02.html @@ -0,0 +1,86 @@ + + + + + + Test CSS Properties Actor + + + + + + + Mozilla Bug 1265798 + Test Document + + diff --git a/devtools/shared/css/generated/mach_commands.py b/devtools/shared/css/generated/mach_commands.py index fb002c3c4001..4d6016276aa7 100644 --- a/devtools/shared/css/generated/mach_commands.py +++ b/devtools/shared/css/generated/mach_commands.py @@ -13,7 +13,6 @@ import os import sys import string import subprocess -from mozbuild import shellutil from mozbuild.base import ( MozbuildObject, MachCommandBase, @@ -40,46 +39,12 @@ class MachCommands(MachCommandBase): """Generate the static css properties database for devtools and write it to file.""" print("Re-generating the css properties database...") - preferences = self.get_preferences() db = self.get_properties_db_from_xpcshell() self.output_template({ - 'preferences': stringify(preferences), 'cssProperties': stringify(db['cssProperties']), 'pseudoElements': stringify(db['pseudoElements'])}) - def get_preferences(self): - """Get all of the preferences associated with enabling and disabling a property.""" - # Build the command to run the preprocessor on PythonCSSProps.h - headerPath = resolve_path(self.topsrcdir, 'layout/style/PythonCSSProps.h') - - cpp = self.substs['CPP'] - - if not cpp: - print("Unable to find the cpp program. Please do a full, nonartifact") - print("build and try this again.") - sys.exit(1) - - if type(cpp) is list: - cmd = cpp - else: - cmd = shellutil.split(cpp) - cmd += shellutil.split(self.substs['ACDEFINES']) - cmd.append(headerPath) - - # The preprocessed list takes the following form: - # [ (name, prop, id, flags, pref, proptype), ... ] - preprocessed = eval(subprocess.check_output(cmd)) - - # Map this list - # (name, prop, id, flags, pref, proptype) => (name, pref) - preferences = [ - (name, pref) - for name, prop, id, flags, pref, proptype in preprocessed - if 'CSS_PROPERTY_INTERNAL' not in flags and pref] - - return preferences - def get_properties_db_from_xpcshell(self): """Generate the static css properties db for devtools from an xpcshell script.""" build = MozbuildObject.from_environment() diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index b85ac7e72496..0e2853499ced 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -9377,546 +9377,3 @@ exports.PSEUDO_ELEMENTS = [ ":placeholder", ":-moz-color-swatch" ]; - -/** - * A list of the preferences keys for whether a CSS property is enabled or not. This is - * exposed for testing purposes. - */ -exports.PREFERENCES = [ - [ - "all", - "layout.css.all-shorthand.enabled" - ], - [ - "background-blend-mode", - "layout.css.background-blend-mode.enabled" - ], - [ - "box-decoration-break", - "layout.css.box-decoration-break.enabled" - ], - [ - "color-adjust", - "layout.css.color-adjust.enabled" - ], - [ - "contain", - "layout.css.contain.enabled" - ], - [ - "grid", - "layout.css.grid.enabled" - ], - [ - "grid-area", - "layout.css.grid.enabled" - ], - [ - "grid-auto-columns", - "layout.css.grid.enabled" - ], - [ - "grid-auto-flow", - "layout.css.grid.enabled" - ], - [ - "grid-auto-rows", - "layout.css.grid.enabled" - ], - [ - "grid-column", - "layout.css.grid.enabled" - ], - [ - "grid-column-end", - "layout.css.grid.enabled" - ], - [ - "grid-column-gap", - "layout.css.grid.enabled" - ], - [ - "grid-column-start", - "layout.css.grid.enabled" - ], - [ - "grid-gap", - "layout.css.grid.enabled" - ], - [ - "grid-row", - "layout.css.grid.enabled" - ], - [ - "grid-row-end", - "layout.css.grid.enabled" - ], - [ - "grid-row-gap", - "layout.css.grid.enabled" - ], - [ - "grid-row-start", - "layout.css.grid.enabled" - ], - [ - "grid-template", - "layout.css.grid.enabled" - ], - [ - "grid-template-areas", - "layout.css.grid.enabled" - ], - [ - "grid-template-columns", - "layout.css.grid.enabled" - ], - [ - "grid-template-rows", - "layout.css.grid.enabled" - ], - [ - "initial-letter", - "layout.css.initial-letter.enabled" - ], - [ - "image-orientation", - "layout.css.image-orientation.enabled" - ], - [ - "isolation", - "layout.css.isolation.enabled" - ], - [ - "mix-blend-mode", - "layout.css.mix-blend-mode.enabled" - ], - [ - "object-fit", - "layout.css.object-fit-and-position.enabled" - ], - [ - "object-position", - "layout.css.object-fit-and-position.enabled" - ], - [ - "-moz-osx-font-smoothing", - "layout.css.osx-font-smoothing.enabled" - ], - [ - "overflow-clip-box", - "layout.css.overflow-clip-box.enabled" - ], - [ - "paint-order", - "svg.paint-order.enabled" - ], - [ - "scroll-behavior", - "layout.css.scroll-behavior.property-enabled" - ], - [ - "scroll-snap-coordinate", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-destination", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-points-x", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-points-y", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-type", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-type-x", - "layout.css.scroll-snap.enabled" - ], - [ - "scroll-snap-type-y", - "layout.css.scroll-snap.enabled" - ], - [ - "shape-outside", - "layout.css.shape-outside.enabled" - ], - [ - "text-combine-upright", - "layout.css.text-combine-upright.enabled" - ], - [ - "-webkit-text-fill-color", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-text-stroke", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-text-stroke-color", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-text-stroke-width", - "layout.css.prefixes.webkit" - ], - [ - "touch-action", - "layout.css.touch_action.enabled" - ], - [ - "-moz-transform", - "layout.css.prefixes.transforms" - ], - [ - "transform-box", - "svg.transform-box.enabled" - ], - [ - "-moz-transform-origin", - "layout.css.prefixes.transforms" - ], - [ - "-moz-perspective-origin", - "layout.css.prefixes.transforms" - ], - [ - "-moz-perspective", - "layout.css.prefixes.transforms" - ], - [ - "-moz-transform-style", - "layout.css.prefixes.transforms" - ], - [ - "-moz-backface-visibility", - "layout.css.prefixes.transforms" - ], - [ - "-moz-border-image", - "layout.css.prefixes.border-image" - ], - [ - "-moz-transition", - "layout.css.prefixes.transitions" - ], - [ - "-moz-transition-delay", - "layout.css.prefixes.transitions" - ], - [ - "-moz-transition-duration", - "layout.css.prefixes.transitions" - ], - [ - "-moz-transition-property", - "layout.css.prefixes.transitions" - ], - [ - "-moz-transition-timing-function", - "layout.css.prefixes.transitions" - ], - [ - "-moz-animation", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-delay", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-direction", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-duration", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-fill-mode", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-iteration-count", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-name", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-play-state", - "layout.css.prefixes.animations" - ], - [ - "-moz-animation-timing-function", - "layout.css.prefixes.animations" - ], - [ - "-moz-box-sizing", - "layout.css.prefixes.box-sizing" - ], - [ - "-moz-font-feature-settings", - "layout.css.prefixes.font-features" - ], - [ - "-moz-font-language-override", - "layout.css.prefixes.font-features" - ], - [ - "-webkit-animation", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-delay", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-direction", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-duration", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-fill-mode", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-iteration-count", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-name", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-play-state", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-animation-timing-function", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-filter", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-text-size-adjust", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transform", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transform-origin", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transform-style", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-backface-visibility", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-perspective", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-perspective-origin", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transition", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transition-delay", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transition-duration", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transition-property", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-transition-timing-function", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-radius", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-top-left-radius", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-top-right-radius", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-bottom-left-radius", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-bottom-right-radius", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-background-clip", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-background-origin", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-background-size", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-border-image", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-shadow", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-sizing", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-flex", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-ordinal-group", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-orient", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-direction", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-align", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-box-pack", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-direction", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-wrap", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-flow", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-order", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-grow", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-shrink", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-flex-basis", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-justify-content", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-align-items", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-align-self", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-align-content", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-user-select", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-clip", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-composite", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-image", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-origin", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-position", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-position-x", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-position-y", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-repeat", - "layout.css.prefixes.webkit" - ], - [ - "-webkit-mask-size", - "layout.css.prefixes.webkit" - ] -]; diff --git a/devtools/shared/css/generated/properties-db.js.in b/devtools/shared/css/generated/properties-db.js.in index 372e525e9776..370c9199a02d 100644 --- a/devtools/shared/css/generated/properties-db.js.in +++ b/devtools/shared/css/generated/properties-db.js.in @@ -18,9 +18,3 @@ exports.CSS_PROPERTIES = ${cssProperties}; * A list of the pseudo elements. */ exports.PSEUDO_ELEMENTS = ${pseudoElements}; - -/** - * A list of the preferences keys for whether a CSS property is enabled or not. This is - * exposed for testing purposes. - */ -exports.PREFERENCES = ${preferences}; diff --git a/devtools/shared/fronts/css-properties.js b/devtools/shared/fronts/css-properties.js index 655687232e46..4bf0fa88e086 100644 --- a/devtools/shared/fronts/css-properties.js +++ b/devtools/shared/fronts/css-properties.js @@ -234,7 +234,15 @@ const initCssProperties = Task.async(function* (toolbox) { // Get the list dynamically if the cssProperties actor exists. if (toolbox.target.hasActor("cssProperties")) { front = CssPropertiesFront(client, toolbox.target.form); - db = yield front.getCSSDatabase(); + const serverDB = yield front.getCSSDatabase(); + + // Ensure the database was returned in a format that is understood. + // Older versions of the protocol could return a blank database. + if (!serverDB.properties && !serverDB.margin) { + db = CSS_PROPERTIES_DB; + } else { + db = serverDB; + } } else { // The target does not support this actor, so require a static list of supported // properties. @@ -286,6 +294,9 @@ function normalizeCssData(db) { db = { properties: db }; } + // Fill in any missing DB information from the static database. + db = Object.assign({}, CSS_PROPERTIES_DB, db); + let missingSupports = !db.properties.color.supports; let missingValues = !db.properties.color.values; let missingSubproperties = !db.properties.background.subproperties; @@ -309,10 +320,6 @@ function normalizeCssData(db) { db.properties[name].subproperties = CSS_PROPERTIES_DB.properties[name].subproperties; } - // Add "isInherited" information to the css properties if it's missing. - if (db.properties.font.isInherited) { - db.properties[name].isInherited = CSS_PROPERTIES_DB.properties[name].isInherited; - } } } diff --git a/devtools/shared/tests/unit/test_css-properties-db.js b/devtools/shared/tests/unit/test_css-properties-db.js index ec14a99a6683..108650a3ed49 100644 --- a/devtools/shared/tests/unit/test_css-properties-db.js +++ b/devtools/shared/tests/unit/test_css-properties-db.js @@ -22,9 +22,8 @@ const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); -const {PSEUDO_ELEMENTS, CSS_PROPERTIES, PREFERENCES} = require("devtools/shared/css/generated/properties-db"); +const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db"); const {generateCssProperties} = require("devtools/server/actors/css-properties"); -const {Preferences} = require("resource://gre/modules/Preferences.jsm"); function run_test() { const propertiesErrorMessage = "If this assertion fails, then the client side CSS " + @@ -39,9 +38,7 @@ function run_test() { /** * Check that the platform and client match for the details on their CSS properties. - * Enumerate each property to aid in debugging. Sometimes these properties don't - * completely agree due to differences in preferences. Check the currently set - * preference for that property to see if it's enabled. + * Enumerate each property to aid in debugging. */ const platformProperties = generateCssProperties(); @@ -50,18 +47,17 @@ function run_test() { const clientProperty = CSS_PROPERTIES[propertyName]; const deepEqual = isJsonDeepEqual(platformProperty, clientProperty); - // The "all" property can contain information that can be turned on and off by - // preferences. These values can be different between OSes, so ignore the equality - // check for this property, since this is likely to fail. - if (propertyName === "all") { - continue; - } - if (deepEqual) { ok(true, `The static database and platform match for "${propertyName}".`); } else { - ok(false, `The static database and platform do not match for ` + ` - "${propertyName}". ${propertiesErrorMessage}`); + const prefMessage = `The static database and platform do not match ` + + `for "${propertyName}".`; + if (getPreference(propertyName) === false) { + ok(true, `${prefMessage} However, there is a preference for disabling this ` + + `property on the current build.`); + } else { + ok(false, `${prefMessage} ${propertiesErrorMessage}`); + } } } @@ -79,14 +75,8 @@ function run_test() { } mismatches.forEach(propertyName => { - if (getPreference(propertyName) === false) { - ok(true, `The static database and platform do not agree on the property ` + - `"${propertyName}" This is ok because it is currently disabled through ` + - `a preference.`); - } else { - ok(false, `The static database and platform do not agree on the property ` + - `"${propertyName}" ${propertiesErrorMessage}`); - } + ok(false, `The static database and platform do not agree on the property ` + + `"${propertyName}" ${propertiesErrorMessage}`); }); } @@ -144,21 +134,3 @@ function getKeyMismatches(a, b) { return aMismatches.concat(bMismatches); } - -/** - * Get the preference value of whether this property is enabled. Returns an empty string - * if no preference exists. - * - * @param {String} propertyName - * @return {Boolean|undefined} - */ -function getPreference(propertyName) { - const preference = PREFERENCES.find(([prefPropertyName, preferenceKey]) => { - return prefPropertyName === propertyName && !!preferenceKey; - }); - - if (preference) { - return Preferences.get(preference[1]); - } - return undefined; -} From 4bed5ca05c37afa1f81bc861d86fb98c39f9a7aa Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 28 Dec 2016 14:09:26 -0800 Subject: [PATCH 09/34] Backed out 4 changesets (bug 1323770) for marionette bustage a=backout Backed out changeset bb8ccabdbe27 (bug 1323770) Backed out changeset f1fbf0853e4f (bug 1323770) Backed out changeset d0e5cb3af786 (bug 1323770) Backed out changeset 71e82343afb9 (bug 1323770) --- .../security/test_ssl_status_after_restart.py | 2 +- .../marionette_test/__init__.py | 12 +- .../marionette_test/decorators.py | 190 ++++++++---------- .../marionette_test/errors.py | 32 +++ .../marionette_test/testcases.py | 12 +- .../harness/marionette_harness/runner/base.py | 4 - .../tests/unit/test_about_pages.py | 12 +- .../tests/unit/test_certificates.py | 8 +- .../tests/unit/test_click_scrolling.py | 2 +- .../tests/unit/test_crash.py | 2 +- .../tests/unit/test_element_state_chrome.py | 7 +- .../tests/unit/test_import_script.py | 9 +- .../tests/unit/test_modal_dialogs.py | 2 +- .../tests/unit/test_navigation.py | 14 +- .../tests/unit/test_screen_orientation.py | 20 +- .../tests/unit/test_single_finger_desktop.py | 26 ++- .../tests/unit/test_text_chrome.py | 5 +- .../tests/unit/test_transport.py | 4 +- .../tests/unit/test_typing.py | 18 +- .../tests/unit/unit-tests.ini | 1 - testing/marionette/harness/requirements.txt | 2 +- .../mozbase/moztest/moztest/adapters/unit.py | 13 +- testing/mozbase/moztest/setup.py | 2 +- 23 files changed, 203 insertions(+), 196 deletions(-) create mode 100644 testing/marionette/harness/marionette_harness/marionette_test/errors.py diff --git a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py index f274d8f2fd28..d5c99dd8de29 100644 --- a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py +++ b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py @@ -46,7 +46,7 @@ class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase): finally: super(TestSSLStatusAfterRestart, self).tearDown() - @skip_if_e10s("Bug 1325047") + @skip_if_e10s def test_ssl_status_after_restart(self): for item in self.test_data: with self.marionette.using_context('content'): diff --git a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py index f9baf737dff4..2de79c91273a 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py @@ -5,15 +5,11 @@ __version__ = '3.1.0' -from unittest.case import ( - expectedFailure, - skip, - SkipTest, -) - from .decorators import ( + expectedFailure, parameterized, run_if_e10s, + skip, skip_if_chrome, skip_if_desktop, skip_if_e10s, @@ -23,6 +19,10 @@ from .decorators import ( with_parameters, ) +from .errors import ( + SkipTest, +) + from .testcases import ( CommonTestCase, MarionetteTestCase, diff --git a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py index 3a49868990a2..8764532d660b 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py @@ -3,13 +3,28 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import functools +import sys import types -from unittest.case import ( +from .errors import ( + _ExpectedFailure, + _UnexpectedSuccess, SkipTest, ) +def expectedFailure(func): + """Decorator which marks a test as expected fail.""" + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + except Exception: + raise _ExpectedFailure(sys.exc_info()) + raise _UnexpectedSuccess + return wrapper + + def parameterized(func_suffix, *args, **kwargs): r"""Decorator which generates methods given a base method and some data. @@ -46,101 +61,85 @@ def parameterized(func_suffix, *args, **kwargs): return wrapped -def run_if_e10s(reason): +def run_if_e10s(target): """Decorator which runs a test if e10s mode is active.""" - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') + def wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + }""") - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = not self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - } - """) - if multi_process_browser: - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper + if not multi_process_browser: + raise SkipTest('skipping due to e10s is disabled') + return target(self, *args, **kwargs) + return wrapper + + +def skip(reason): + """Decorator which unconditionally skips a test.""" + def decorator(test_item): + if not isinstance(test_item, (type, types.ClassType)): + @functools.wraps(test_item) + def skip_wrapper(*args, **kwargs): + raise SkipTest(reason) + test_item = skip_wrapper + + test_item.__unittest_skip__ = True + test_item.__unittest_skip_why__ = reason + return test_item return decorator -def skip_if_chrome(reason): +def skip_if_chrome(target): """Decorator which skips a test if chrome context is active.""" - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') - - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): - if self.marionette._send_message('getContext', key='value') == 'chrome': - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper - return decorator + def wrapper(self, *args, **kwargs): + if self.marionette._send_message("getContext", key="value") == "chrome": + raise SkipTest("skipping test in chrome context") + return target(self, *args, **kwargs) + return wrapper -def skip_if_desktop(reason): +def skip_if_desktop(target): """Decorator which skips a test if run on desktop.""" - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') - - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'firefox': - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper - return decorator + def wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'firefox': + raise SkipTest('skipping due to desktop') + return target(self, *args, **kwargs) + return wrapper -def skip_if_e10s(reason): +def skip_if_e10s(target): """Decorator which skips a test if e10s mode is active.""" - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') + def wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + }""") - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - } - """) - if multi_process_browser: - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper - return decorator + if multi_process_browser: + raise SkipTest('skipping due to e10s') + return target(self, *args, **kwargs) + return wrapper -def skip_if_mobile(reason): +def skip_if_mobile(target): """Decorator which skips a test if run on mobile.""" - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') - - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'fennec': - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper - return decorator + def wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'fennec': + raise SkipTest('skipping due to fennec') + return target(self, *args, **kwargs) + return wrapper -def skip_unless_browser_pref(reason, pref, predicate=bool): +def skip_unless_browser_pref(pref, predicate=bool): """Decorator which skips a test based on the value of a browser preference. - :param reason: Message describing why the test need to be skipped. :param pref: the preference name :param predicate: a function that should return false to skip the test. The function takes one parameter, the preference value. @@ -151,46 +150,33 @@ def skip_unless_browser_pref(reason, pref, predicate=bool): Example: :: class TestSomething(MarionetteTestCase): - @skip_unless_browser_pref("Sessionstore needs to be enabled for crashes", - "browser.sessionstore.resume_from_crash", - lambda value: value is True, - ) + @skip_unless_browser_pref("accessibility.tabfocus", + lambda value: value >= 7) def test_foo(self): pass # test implementation here - """ - def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') - if not callable(predicate): - raise ValueError('predicate must be callable') - - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): + def wrapper(target): + @functools.wraps(target) + def wrapped(self, *args, **kwargs): value = self.marionette.get_pref(pref) if value is None: self.fail("No such browser preference: {0!r}".format(pref)) if not predicate(value): - raise SkipTest(reason) - return test_item(self, *args, **kwargs) - return skip_wrapper - return decorator + raise SkipTest("browser preference {0!r}: {1!r}".format((pref, value))) + return target(self, *args, **kwargs) + return wrapped + return wrapper -def skip_unless_protocol(reason, predicate): +def skip_unless_protocol(predicate): """Decorator which skips a test if the predicate does not match the current protocol level.""" def decorator(test_item): - if not isinstance(test_item, types.FunctionType): - raise Exception('Decorator only supported for functions') - if not callable(predicate): - raise ValueError('predicate must be callable') - @functools.wraps(test_item) - def skip_wrapper(self, *args, **kwargs): + def skip_wrapper(self): level = self.marionette.client.protocol if not predicate(level): - raise SkipTest(reason) - return test_item(self, *args, **kwargs) + raise SkipTest('skipping because protocol level is {}'.format(level)) + return test_item(self) return skip_wrapper return decorator diff --git a/testing/marionette/harness/marionette_harness/marionette_test/errors.py b/testing/marionette/harness/marionette_harness/marionette_test/errors.py new file mode 100644 index 000000000000..301cac82c7de --- /dev/null +++ b/testing/marionette/harness/marionette_harness/marionette_test/errors.py @@ -0,0 +1,32 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +class SkipTest(Exception): + """ + Raise this exception in a test to skip it. + + Usually you can use TestResult.skip() or one of the skipping decorators + instead of raising this directly. + """ + + pass + + +class _ExpectedFailure(Exception): + """ + Raise this when a test is expected to fail. + + This is an implementation detail. + """ + + def __init__(self, exc_info): + super(_ExpectedFailure, self).__init__() + self.exc_info = exc_info + + +class _UnexpectedSuccess(Exception): + """The test was supposed to fail, but it didn't.""" + + pass diff --git a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py index 5051e3351eeb..4c20e7eda221 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py @@ -12,12 +12,6 @@ import unittest import warnings import weakref -from unittest.case import ( - _ExpectedFailure, - _UnexpectedSuccess, - SkipTest, -) - from marionette_driver.errors import ( MarionetteException, ScriptTimeoutException, @@ -25,6 +19,12 @@ from marionette_driver.errors import ( ) from mozlog import get_default_logger +from .errors import ( + _ExpectedFailure, + _UnexpectedSuccess, + SkipTest, +) + def _wraps_parameterized(func, func_suffix, args, kwargs): """Internal: Decorator used in class MetaParameterized.""" diff --git a/testing/marionette/harness/marionette_harness/runner/base.py b/testing/marionette/harness/marionette_harness/runner/base.py index 679efb87711b..9527ea59142c 100644 --- a/testing/marionette/harness/marionette_harness/runner/base.py +++ b/testing/marionette/harness/marionette_harness/runner/base.py @@ -552,10 +552,6 @@ class BaseMarionetteTestRunner(object): self.e10s = e10s def gather_debug(test, status): - # No screenshots and page source for skipped tests - if status == "SKIP": - return - rv = {} marionette = test._marionette_weakref() diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py index f0365f470a4f..493c813ec1f9 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py @@ -26,7 +26,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): super(TestAboutPages, self).tearDown() - @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") + @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles def test_back_forward(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -46,7 +46,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") + @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles def test_navigate_non_remote_about_pages(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -61,7 +61,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile("On Android no shortcuts are available") + @skip_if_mobile # On Android no shortcuts are available def test_navigate_shortcut_key(self): def open_with_shortcut(): with self.marionette.using_context("chrome"): @@ -76,7 +76,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") + @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles def test_type_to_non_remote_tab(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -93,7 +93,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile("Interacting with chrome elements not available for Fennec") + @skip_if_mobile # Interacting with chrome elements not available for Fennec def test_type_to_remote_tab(self): # about:blank keeps remoteness from remote_uri self.marionette.navigate("about:blank") @@ -103,7 +103,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.wait_for_condition(lambda mn: mn.get_url() == self.remote_uri) - @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") + @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles def test_hang(self): # Open a new tab and close the first one new_tab = self.open_tab(trigger="menu") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py index fb4c5c38b4d0..a19a433d3469 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py @@ -4,12 +4,10 @@ from marionette_driver.errors import UnknownException -from marionette_harness import MarionetteTestCase, skip +from marionette_harness import MarionetteTestCase class TestCertificates(MarionetteTestCase): - - @skip("Bug 1325079") def test_block_insecure_sites(self): self.marionette.delete_session() self.marionette.start_session() @@ -19,16 +17,16 @@ class TestCertificates(MarionetteTestCase): with self.assertRaises(UnknownException): self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) - @skip("Bug 1325079") def test_accept_all_insecure(self): self.marionette.delete_session() self.marionette.start_session({"desiredCapability": {"acceptSslCerts": ["*"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) - @skip("Bug 1325079") + """ def test_accept_some_insecure(self): self.marionette.delete_session() self.marionette.start_session({"requiredCapabilities": {"acceptSslCerts": ["127.0.0.1"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) + """ \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py index 5543126782a6..8c4b140a6657 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py @@ -43,7 +43,7 @@ class TestClickScrolling(MarionetteTestCase): except MoveTargetOutOfBoundsException: self.fail("Should not be out of bounds") - @skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll") + @skip("Bug 1003682") def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self): test_html = self.marionette.absolute_url("scroll.html") self.marionette.navigate(test_html) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py index 7e74f0857a12..3f7bd0a3ed31 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py @@ -104,7 +104,7 @@ class TestCrash(BaseCrashTestCase): # chrome and frame script. # self.marionette.get_url() - @run_if_e10s("Content crashes only exist in e10s mode") + @run_if_e10s def test_crash_content_process(self): # If e10s is disabled the chrome process crashes self.marionette.navigate(self.remote_uri) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py index 01ed355c48a2..e2433dc6c6d7 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py @@ -4,7 +4,7 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase, skip +from marionette_harness import MarionetteTestCase class TestIsElementEnabledChrome(MarionetteTestCase): @@ -36,7 +36,9 @@ class TestIsElementEnabledChrome(MarionetteTestCase): self.assertTrue(rect['y'] > 0) -@skip("Switched off in bug 896043, and to be turned on in bug 896046") +# Switched off in bug 896043, +# and to be turned on in bug 896046 +""" class TestIsElementDisplayed(MarionetteTestCase): def test_isDisplayed(self): l = self.marionette.find_element(By.ID, "textInput") @@ -44,6 +46,7 @@ class TestIsElementDisplayed(MarionetteTestCase): self.marionette.execute_script("arguments[0].hidden = true;", [l]) self.assertFalse(l.is_displayed()) self.marionette.execute_script("arguments[0].hidden = false;", [l]) +""" class TestGetElementAttributeChrome(MarionetteTestCase): diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py index e86de2bd579d..21a37e941784 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py @@ -31,11 +31,6 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.marionette.clear_imported_scripts() self.reset_context() - def tearDown(self): - self.close_all_windows() - - super(TestImportScriptContent, self).tearDown() - def reset_context(self): self.marionette.set_context("content") @@ -114,8 +109,8 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.assert_defined("testFunc") self.assert_defined("testAnotherFunc") - @skip_if_chrome("Needs content scope") - @skip_if_mobile("New windows not supported in Fennec") + @skip_if_chrome + @skip_if_mobile # New windows not supported in Fennec def test_imports_apply_globally(self): self.marionette.navigate( self.marionette.absolute_url("test_windows.html")) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py index cfc402d6819a..151dccd56219 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py @@ -157,7 +157,7 @@ class TestTabModals(MarionetteTestCase): alert.accept() self.wait_for_condition(lambda mn: mn.get_url() == "about:blank") - @skip_if_e10s("Bug 1325044") + @skip_if_e10s def test_unrelated_command_when_alert_present(self): click_handler = self.marionette.find_element(By.ID, 'click-handler') text = self.marionette.find_element(By.ID, 'click-result').text diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py index fdb18814b7be..3d2821b46e3f 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py @@ -2,17 +2,15 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +from unittest import skip + import contextlib import time import urllib from marionette_driver import errors, By, Wait -from marionette_harness import ( - MarionetteTestCase, - skip, - skip_if_mobile, - WindowManagerMixin, -) + +from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin def inline(doc): @@ -114,7 +112,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.marionette.switch_to_frame() self.assertTrue('test_iframe.html' in self.marionette.get_url()) - @skip_if_mobile("Bug 1323755 - Socket timeout") + @skip_if_mobile # Bug 1323755 - Socket timeout def test_invalid_protocol(self): with self.assertRaises(errors.MarionetteException): self.marionette.navigate("thisprotocoldoesnotexist://") @@ -152,7 +150,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.assertTrue(self.marionette.execute_script( "return window.visited", sandbox=None)) - @skip_if_mobile("Fennec doesn't support other chrome windows") + @skip_if_mobile # Fennec doesn't support other chrome windows def test_about_blank_for_new_docshell(self): """ Bug 1312674 - Hang when loading about:blank for a new docshell.""" # Open a window to get a new docshell created for the first tab diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py index 830795a1ec62..7dfafc1750c3 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py @@ -23,31 +23,31 @@ class TestScreenOrientation(MarionetteTestCase): self.assertEqual(self.marionette.orientation, default_orientation, "invalid state") MarionetteTestCase.tearDown(self) - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_portrait_primary(self): self.marionette.set_orientation("portrait-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_landscape_primary(self): self.marionette.set_orientation("landscape-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_portrait_secondary(self): self.marionette.set_orientation("portrait-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-secondary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_landscape_secondary(self): self.marionette.set_orientation("landscape-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-secondary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_shorthand_portrait(self): # Set orientation to something other than portrait-primary first, since the default is # portrait-primary. @@ -58,29 +58,29 @@ class TestScreenOrientation(MarionetteTestCase): new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_to_shorthand_landscape(self): self.marionette.set_orientation("landscape") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_orientation_with_mixed_casing(self): self.marionette.set_orientation("lAnDsCaPe") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_invalid_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")): self.marionette.set_orientation("cheese") - @skip_if_desktop("Not supported in Firefox") + @skip_if_desktop def test_set_null_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")): self.marionette.set_orientation(None) - @skip_if_mobile("Specific test for Firefox") + @skip_if_mobile def test_unsupported_operation_on_desktop(self): with self.assertRaises(errors.UnsupportedOperationException): self.marionette.set_orientation("landscape-primary") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py index 8ac80c3c547c..019531efcfc3 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py @@ -6,9 +6,9 @@ import os import sys from marionette_driver.errors import MarionetteException -from marionette_driver import Actions, By +from marionette_driver.by import By -from marionette_harness import MarionetteTestCase, skip +from marionette_harness import MarionetteTestCase # add this directory to the path sys.path.append(os.path.dirname(__file__)) @@ -85,30 +85,28 @@ prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]); def test_wait_with_value(self): wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click") - @skip("Bug 1191066") + """ + // Skipping due to Bug 1191066 def test_context_menu(self): - context_menu(self.marionette, self.wait_for_condition, - "button1-mousemove-mousedown-contextmenu", - "button1-mousemove-mousedown-contextmenu-mouseup-click") + context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click") - @skip("Bug 1191066") def test_long_press_action(self): - long_press_action(self.marionette, self.wait_for_condition, - "button1-mousemove-mousedown-contextmenu-mouseup-click") + long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") - @skip("Bug 1191066") def test_long_press_on_xy_action(self): - long_press_on_xy_action(self.marionette, self.wait_for_condition, - "button1-mousemove-mousedown-contextmenu-mouseup-click") + long_press_on_xy_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") + """ - @skip("Bug 865334") + """ + //Skipping due to Bug 865334 def test_long_press_fail(self): testAction = self.marionette.absolute_url("testAction.html") self.marionette.navigate(testAction) button = self.marionette.find_element(By.ID, "button1Copy") action = Actions(self.marionette) action.press(button).long_press(button, 5) - self.assertRaises(MarionetteException, action.perform) + assertRaises(MarionetteException, action.perform) + """ def test_chain(self): chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py index e0b63de16f58..065e10c9729b 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py @@ -4,10 +4,10 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase, skip, WindowManagerMixin +from marionette_harness import MarionetteTestCase, WindowManagerMixin -@skip("Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046") +''' Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046 class TestTextChrome(WindowManagerMixin, MarionetteTestCase): def setUp(self): @@ -42,3 +42,4 @@ class TestTextChrome(WindowManagerMixin, MarionetteTestCase): self.assertEqual("test", box.text) box.send_keys("at") self.assertEqual("attest", box.text) +''' diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py index 39e36a9b224c..2d2d7a4e42ba 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py @@ -33,14 +33,14 @@ class TestMessageSequencing(MarionetteTestCase): self.marionette.client.send(cmd) return self.last_id - @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) + @skip_unless_protocol(lambda level: level >= 3) def test_discard_older_messages(self): first = self.send(*get_current_url) second = self.send(*execute_script) resp = self.marionette.client.receive() self.assertEqual(second, resp.id) - @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) + @skip_unless_protocol(lambda level: level >= 3) def test_last_id_incremented(self): before = self.last_id self.send(*get_current_url) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py index 53d2bb4f1d67..bb7b2ff41c31 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py @@ -8,7 +8,7 @@ from marionette_driver.by import By from marionette_driver.errors import ElementNotVisibleException from marionette_driver.keys import Keys -from marionette_harness import MarionetteTestCase, skip, skip_if_mobile +from marionette_harness import MarionetteTestCase, skip_if_mobile def inline(doc): @@ -32,7 +32,7 @@ class TestTypingChrome(TypingTestCase): super(TestTypingChrome, self).setUp() self.marionette.set_context("chrome") - @skip_if_mobile("Interacting with chrome elements not available for Fennec") + @skip_if_mobile # Interacting with chrome elements not available for Fennec def test_cut_and_paste_shortcuts(self): with self.marionette.using_context("content"): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -213,7 +213,7 @@ class TestTypingContent(TypingTestCase): # filled, we're a letter short here self.assertEqual(result.text, "I like chees") - @skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec") + @skip_if_mobile # Bug 1324752 - Arrow keys cannot be sent in Fennec def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -241,7 +241,7 @@ class TestTypingContent(TypingTestCase): # And leave no rubbish/printable keys in the "keyReporter" self.assertEqual("", element.get_property("value")) - @skip("Reenable in Bug 1068728") + """Disabled. Reenable in Bug 1068728 def testNumericShiftKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -252,6 +252,7 @@ class TestTypingContent(TypingTestCase): element.send_keys(numericShiftsEtc) self.assertEqual(numericShiftsEtc, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) + """ def testLowerCaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -262,7 +263,7 @@ class TestTypingContent(TypingTestCase): element.send_keys(lowerAlphas) self.assertEqual(lowerAlphas, element.get_property("value")) - @skip("Reenable in Bug 1068735") + """Disabled. Reenable in Bug 1068735 def testUppercaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -273,8 +274,9 @@ class TestTypingContent(TypingTestCase): element.send_keys(upperAlphas) self.assertEqual(upperAlphas, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) + """ - @skip("Reenable in Bug 1068726") + """Disabled. Reenable in Bug 1068726 def testAllPrintableKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -286,8 +288,9 @@ class TestTypingContent(TypingTestCase): self.assertTrue(allPrintable, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) + """ - @skip("Reenable in Bug 1068733") + """Disabled. Reenable in Bug 1068733 def testSpecialSpaceKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -295,6 +298,7 @@ class TestTypingContent(TypingTestCase): element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij") self.assertEqual("abcd fgh ij", element.get_property("value")) + """ def testShouldTypeAnInteger(self): test_html = self.marionette.absolute_url("javascriptPage.html") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini index 868cab610984..bb4fe03ececd 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini +++ b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini @@ -7,7 +7,6 @@ [test_expectedfail.py] expected = fail [test_import_script.py] -[test_certificates.py] [test_click.py] [test_click_chrome.py] skip-if = appname == 'fennec' diff --git a/testing/marionette/harness/requirements.txt b/testing/marionette/harness/requirements.txt index 75ab9ce92b2a..3fab7c2d1bda 100644 --- a/testing/marionette/harness/requirements.txt +++ b/testing/marionette/harness/requirements.txt @@ -9,6 +9,6 @@ moznetwork >= 0.21 mozprocess >= 0.9 mozprofile >= 0.7 mozrunner >= 6.13 -moztest >= 0.8 +moztest >= 0.7 mozversion >= 1.1 wptserve >= 1.3.0 diff --git a/testing/mozbase/moztest/moztest/adapters/unit.py b/testing/mozbase/moztest/moztest/adapters/unit.py index cee0e05e92a0..c31a6c3b37d1 100644 --- a/testing/mozbase/moztest/moztest/adapters/unit.py +++ b/testing/mozbase/moztest/moztest/adapters/unit.py @@ -134,7 +134,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addFailure(self, test, err): - extra = self.call_callbacks(test, "FAIL") + extra = self.call_callbacks(test, "ERROR") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -145,13 +145,10 @@ class StructuredTestResult(TextTestResult): def addSuccess(self, test): extra = self._get_class_method_name(test) - self.logger.test_end(test.id(), - "PASS", - expected="PASS", - extra=extra) + self.logger.test_end(test.id(), "PASS", expected="PASS", extra=extra) def addExpectedFailure(self, test, err): - extra = self.call_callbacks(test, "FAIL") + extra = self.call_callbacks(test, "ERROR") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -161,7 +158,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addUnexpectedSuccess(self, test): - extra = self.call_callbacks(test, "PASS") + extra = self.call_callbacks(test, "ERROR") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "PASS", @@ -169,7 +166,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addSkip(self, test, reason): - extra = self.call_callbacks(test, "SKIP") + extra = self.call_callbacks(test, "ERROR") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "SKIP", diff --git a/testing/mozbase/moztest/setup.py b/testing/mozbase/moztest/setup.py index 9c7c11789842..24455c285b71 100644 --- a/testing/mozbase/moztest/setup.py +++ b/testing/mozbase/moztest/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages -PACKAGE_VERSION = '0.8' +PACKAGE_VERSION = '0.7' # dependencies deps = ['mozinfo'] From 5aabeea3381dc460f8d4910010fbf1a36f15f1f0 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Thu, 22 Dec 2016 07:17:30 +0900 Subject: [PATCH 10/34] Bug 1325217 - Remove Windows Vista from manifest. r=jimm MozReview-Commit-ID: BoZo3XKCgv0 --HG-- extra : rebase_source : 8ad6fa7d6fcc3741e308287a57471f61dd62f97b --- browser/app/firefox.exe.manifest | 1 - dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest | 1 - ipc/app/plugin-container.exe.manifest | 1 - js/xpconnect/shell/xpcshell.exe.manifest | 1 - .../maintenanceservice/maintenanceservice.exe.manifest | 1 - toolkit/crashreporter/client/crashreporter.exe.manifest | 1 - toolkit/mozapps/update/updater/updater.exe.comctl32.manifest | 1 - toolkit/mozapps/update/updater/updater.exe.manifest | 1 - 8 files changed, 8 deletions(-) diff --git a/browser/app/firefox.exe.manifest b/browser/app/firefox.exe.manifest index b23c2a4c0972..8b8db4b7bcac 100644 --- a/browser/app/firefox.exe.manifest +++ b/browser/app/firefox.exe.manifest @@ -37,7 +37,6 @@ - diff --git a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest index 8d6149c5857b..f5b7345f992e 100644 --- a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest +++ b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest @@ -32,7 +32,6 @@ - diff --git a/ipc/app/plugin-container.exe.manifest b/ipc/app/plugin-container.exe.manifest index d61ddec1a8ce..303109523dd3 100644 --- a/ipc/app/plugin-container.exe.manifest +++ b/ipc/app/plugin-container.exe.manifest @@ -37,7 +37,6 @@ - diff --git a/js/xpconnect/shell/xpcshell.exe.manifest b/js/xpconnect/shell/xpcshell.exe.manifest index db2aa0861309..c35b77af4360 100644 --- a/js/xpconnect/shell/xpcshell.exe.manifest +++ b/js/xpconnect/shell/xpcshell.exe.manifest @@ -25,7 +25,6 @@ - diff --git a/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest b/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest index cb317c47db4d..e6bfba8ca5c4 100644 --- a/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest +++ b/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest @@ -20,7 +20,6 @@ - diff --git a/toolkit/crashreporter/client/crashreporter.exe.manifest b/toolkit/crashreporter/client/crashreporter.exe.manifest index f8587bfada91..e6b2ceefbce6 100644 --- a/toolkit/crashreporter/client/crashreporter.exe.manifest +++ b/toolkit/crashreporter/client/crashreporter.exe.manifest @@ -32,7 +32,6 @@ - diff --git a/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest b/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest index 9a6cdb565fe1..6bb850199b05 100644 --- a/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest +++ b/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest @@ -32,7 +32,6 @@ - diff --git a/toolkit/mozapps/update/updater/updater.exe.manifest b/toolkit/mozapps/update/updater/updater.exe.manifest index cd229c954109..619b4abfe185 100644 --- a/toolkit/mozapps/update/updater/updater.exe.manifest +++ b/toolkit/mozapps/update/updater/updater.exe.manifest @@ -20,7 +20,6 @@ - From 1ede24adb4454f4ce6f319191317c2e0fd6e8b83 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 22 Dec 2016 15:02:45 +0900 Subject: [PATCH 11/34] Bug 1324998 - Set MOZ_AUTOMATION on rooting hazards builds. r=mshal --HG-- extra : rebase_source : 115285041faf873f709db522af19f16ab3259380 --- browser/config/mozconfigs/linux64/hazards | 6 ++++++ taskcluster/ci/hazard/kind.yml | 2 ++ 2 files changed, 8 insertions(+) diff --git a/browser/config/mozconfigs/linux64/hazards b/browser/config/mozconfigs/linux64/hazards index 3767d941e68f..b8dbea8a24f8 100644 --- a/browser/config/mozconfigs/linux64/hazards +++ b/browser/config/mozconfigs/linux64/hazards @@ -7,6 +7,12 @@ # with a script that invokes the real gcc with -fplugin and its configuration # directives. Instead, duplicate the contents of that mozconfig here: +MOZ_AUTOMATION_BUILD_SYMBOLS=0 +MOZ_AUTOMATION_L10N_CHECK=0 +MOZ_AUTOMATION_PACKAGE=0 +MOZ_AUTOMATION_PACKAGE_TESTS=0 +MOZ_AUTOMATION_UPLOAD=0 + . "$topsrcdir/build/mozconfig.common" ac_add_options --enable-elf-hack diff --git a/taskcluster/ci/hazard/kind.yml b/taskcluster/ci/hazard/kind.yml index e04af240ca72..7fdb38da5bf4 100644 --- a/taskcluster/ci/hazard/kind.yml +++ b/taskcluster/ci/hazard/kind.yml @@ -18,6 +18,8 @@ job-defaults: implementation: docker-worker max-run-time: 36000 docker-image: {in-tree: desktop-build} + env: + MOZ_AUTOMATION: "1" jobs: linux64-shell-haz/debug: From 6b392d8d0c6c01f97a8b6b1bd2ded22bf21c8144 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 21 Dec 2016 16:58:38 +0900 Subject: [PATCH 12/34] Bug 1324998 - Error out when a in-tree mozconfig is included. r=gps Many people have been shooting themselves in the foot for too long by including in-tree mozconfigs. This change adds a guard that makes it an error when this happens on builds not running on automation. Analysis of the in-tree mozconfigs indicate that build/mozconfig.automation is properly included by the in-tree mozconfig that matter, directly or indirectly. The only ones that don't include it are: b2g/config/mozconfigs/common.override b2g/graphene/config/mozconfigs/common.override browser/config/mozconfigs/linux64/source browser/config/mozconfigs/win64/common-win64 build/mozconfig.cache build/mozconfig.clang-cl build/mozconfig.common.override build/mozconfig.rust build/mozconfig.vs-common build/mozconfig.win-common build/unix/mozconfig.gtk build/unix/mozconfig.stdcxx build/win32/mozconfig.vs-latest build/win32/mozconfig.vs2015-win64 build/win64/mozconfig.vs-latest build/win64/mozconfig.vs2015 mobile/android/config/mozconfigs/common.override which are either empty for use in try builds (override files), or would already cause great pain if they were directly included, so there's little chance they would be. --HG-- extra : rebase_source : 0e6accf241759f8d44868f253874f6546dbadb52 --- build/moz.configure/init.configure | 12 ++++++++++-- build/mozconfig.automation | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure index 2d4998fdbf1f..5aa116190a17 100644 --- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -228,12 +228,20 @@ def early_options(): early_options = early_options() -@depends(mozconfig, '--help') +@depends(mozconfig, 'MOZ_AUTOMATION', '--help') # This gives access to the sandbox. Don't copy this blindly. @imports('__sandbox__') @imports('os') -def mozconfig_options(mozconfig, help): +def mozconfig_options(mozconfig, automation, help): if mozconfig['path']: + if 'MOZ_AUTOMATION_MOZCONFIG' in mozconfig['env']['added']: + if not automation: + log.error('%s directly or indirectly includes an in-tree ' + 'mozconfig.', mozconfig['path']) + log.error('In-tree mozconfigs make strong assumptions about ' + 'and are only meant to be used by Mozilla' + 'automation.') + die("Please don't use them.") helper = __sandbox__._helper log.info('Adding configure options from %s' % mozconfig['path']) for arg in mozconfig['configure_args']: diff --git a/build/mozconfig.automation b/build/mozconfig.automation index 057a4a0b51e4..c8f5b7ce8788 100644 --- a/build/mozconfig.automation +++ b/build/mozconfig.automation @@ -31,3 +31,5 @@ if test "$MOZ_AUTOMATION_PRETTY" = "1"; then # we don't build it without, so this is set to 1. mk_add_options "export MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING=1" fi + +export MOZ_AUTOMATION_MOZCONFIG=1 From 3526b1e58dddfa04c66d6478773c2df65d9f8876 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 29 Dec 2016 10:58:01 +1100 Subject: [PATCH 13/34] Bug 1325351 part 1 - Remove workaround for VC in Maybe. r=froydnj MozReview-Commit-ID: Anlrf3D2WtN --HG-- extra : rebase_source : 9cc2e29e374753ad40774ebd0a0efce9f9449e3b --- js/public/Proxy.h | 9 +++++++++ mfbt/Maybe.h | 6 ------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/js/public/Proxy.h b/js/public/Proxy.h index 5acb91b26e47..606fb9cc8084 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -593,6 +593,15 @@ class JS_FRIEND_API(AutoEnterPolicy) inline void recordLeave() {} #endif + private: + // This operator needs to be deleted explicitly, otherwise Visual C++ will + // create it automatically when it is part of the export JS API. In that + // case, compile would fail because HandleId is not allowed to be assigned + // and consequently instantiation of assign operator of mozilla::Maybe + // would fail. See bug 1325351 comment 16. Copy constructor is removed at + // the same time for consistency. + AutoEnterPolicy(const AutoEnterPolicy&) = delete; + AutoEnterPolicy& operator=(const AutoEnterPolicy&) = delete; }; #ifdef JS_DEBUG diff --git a/mfbt/Maybe.h b/mfbt/Maybe.h index 2a601ac49448..fb363d6d64e9 100644 --- a/mfbt/Maybe.h +++ b/mfbt/Maybe.h @@ -157,13 +157,7 @@ public: if (&aOther != this) { if (aOther.mIsSome) { if (mIsSome) { - // XXX(seth): The correct code for this branch, below, can't be used - // due to a bug in Visual Studio 2010. See bug 1052940. - /* ref() = aOther.ref(); - */ - reset(); - emplace(*aOther); } else { emplace(*aOther); } From 30961dadd7c29f37322d7d6f5bd35e93be51aaa2 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 23 Dec 2016 11:32:33 +1100 Subject: [PATCH 14/34] Bug 1325351 part 2 - Simplify 'Some' function. r=froydnj MozReview-Commit-ID: AkLVQw9WYwy --HG-- extra : rebase_source : 97449d0b2376d53ee7761da2a1ab425492c70ba6 --- mfbt/Maybe.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mfbt/Maybe.h b/mfbt/Maybe.h index fb363d6d64e9..3d941859f47c 100644 --- a/mfbt/Maybe.h +++ b/mfbt/Maybe.h @@ -438,11 +438,12 @@ public: * if you need to construct a Maybe value that holds a const, volatile, or * reference value, you need to use emplace() instead. */ -template -Maybe::Type>::Type> +template::type>::type> +Maybe Some(T&& aValue) { - typedef typename RemoveCV::Type>::Type U; Maybe value; value.emplace(Forward(aValue)); return value; From b4ceaa34749049cee882a759aef5a01b396df79b Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 23 Dec 2016 11:49:33 +1100 Subject: [PATCH 15/34] Bug 1325351 part 3 - Make Maybe accept value from different Maybe type when the inner type is convertible. r=froydnj MozReview-Commit-ID: 2kYTncYh1Or --HG-- extra : rebase_source : f3263ce10f3afae6e8ac734296dbb0e641c55c99 --- mfbt/Maybe.h | 54 +++++++--- mfbt/tests/TestMaybe.cpp | 219 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 258 insertions(+), 15 deletions(-) diff --git a/mfbt/Maybe.h b/mfbt/Maybe.h index 3d941859f47c..e35992b23043 100644 --- a/mfbt/Maybe.h +++ b/mfbt/Maybe.h @@ -103,16 +103,11 @@ public: } /** - * Maybe can be copy-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. + * Maybe can be copy-constructed from a Maybe if U is convertible to T. */ template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> + typename std::enable_if::value>::type> MOZ_IMPLICIT Maybe(const Maybe& aOther) : mIsSome(false) @@ -132,16 +127,11 @@ public: } /** - * Maybe can be move-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. + * Maybe can be move-constructed from a Maybe if U is convertible to T. */ template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> + typename std::enable_if::value>::type> MOZ_IMPLICIT Maybe(Maybe&& aOther) : mIsSome(false) @@ -168,6 +158,23 @@ public: return *this; } + template::value>::type> + Maybe& operator=(const Maybe& aOther) + { + if (aOther.isSome()) { + if (mIsSome) { + ref() = aOther.ref(); + } else { + emplace(*aOther); + } + } else { + reset(); + } + return *this; + } + Maybe& operator=(Maybe&& aOther) { MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); @@ -186,6 +193,25 @@ public: return *this; } + template::value>::type> + Maybe& operator=(Maybe&& aOther) + { + if (aOther.isSome()) { + if (mIsSome) { + ref() = Move(aOther.ref()); + } else { + emplace(Move(*aOther)); + } + aOther.reset(); + } else { + reset(); + } + + return *this; + } + /* Methods that check whether this Maybe contains a value */ explicit operator bool() const { return isSome(); } bool isSome() const { return mIsSome; } diff --git a/mfbt/tests/TestMaybe.cpp b/mfbt/tests/TestMaybe.cpp index 5817ab428d9e..ad4bbced7847 100644 --- a/mfbt/tests/TestMaybe.cpp +++ b/mfbt/tests/TestMaybe.cpp @@ -47,9 +47,11 @@ enum Status eWasConstructed, eWasCopyConstructed, eWasMoveConstructed, + eWasAssigned, eWasCopyAssigned, eWasMoveAssigned, - eWasMovedFrom + eWasCopiedFrom, + eWasMovedFrom, }; static size_t sUndestroyedObjects = 0; @@ -842,6 +844,220 @@ TestSomePointerConversion() return true; } +struct SourceType1 +{ + int mTag; + + operator int() const + { + return mTag; + } +}; +struct DestType +{ + int mTag; + Status mStatus; + + DestType() + : mTag(0) + , mStatus(eWasDefaultConstructed) + {} + + MOZ_IMPLICIT DestType(int aTag) + : mTag(aTag) + , mStatus(eWasConstructed) + {} + + MOZ_IMPLICIT DestType(SourceType1&& aSrc) + : mTag(aSrc.mTag) + , mStatus(eWasMoveConstructed) + {} + + MOZ_IMPLICIT DestType(const SourceType1& aSrc) + : mTag(aSrc.mTag) + , mStatus(eWasCopyConstructed) + {} + + DestType& operator=(int aTag) + { + mTag = aTag; + mStatus = eWasAssigned; + return *this; + } + + DestType& operator=(SourceType1&& aSrc) + { + mTag = aSrc.mTag; + mStatus = eWasMoveAssigned; + return *this; + } + + DestType& operator=(const SourceType1& aSrc) + { + mTag = aSrc.mTag; + mStatus = eWasCopyAssigned; + return *this; + } +}; +struct SourceType2 +{ + int mTag; + + operator DestType() const& + { + DestType result; + result.mTag = mTag; + result.mStatus = eWasCopiedFrom; + return result; + } + + operator DestType() && + { + DestType result; + result.mTag = mTag; + result.mStatus = eWasMovedFrom; + return result; + } +}; + +static bool +TestTypeConversion() +{ + { + Maybe src = Some(SourceType1 {1}); + Maybe dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopyConstructed); + + src = Some(SourceType1 {2}); + dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopyAssigned); + } + + { + Maybe src = Some(SourceType1 {1}); + Maybe dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasMoveConstructed); + + src = Some(SourceType1 {2}); + dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasMoveAssigned); + } + + { + Maybe src = Some(SourceType2 {1}); + Maybe dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopiedFrom); + + src = Some(SourceType2 {2}); + dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasCopiedFrom); + } + + { + Maybe src = Some(SourceType2 {1}); + Maybe dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasMovedFrom); + + src = Some(SourceType2 {2}); + dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasMovedFrom); + } + + { + Maybe src = Some(1); + Maybe dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && *src == 1); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasConstructed); + + src = Some(2); + dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && *src == 2); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasAssigned); + } + + { + Maybe src = Some(1); + Maybe dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 1); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasConstructed); + + src = Some(2); + dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && dest->mTag == 2); + MOZ_RELEASE_ASSERT(dest->mStatus == eWasAssigned); + } + + { + Maybe src = Some(SourceType1 {1}); + Maybe dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 1); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1); + + src = Some(SourceType1 {2}); + dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && src->mTag == 2); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2); + } + + { + Maybe src = Some(SourceType1 {1}); + Maybe dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1); + + src = Some(SourceType1 {2}); + dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2); + } + + { + Maybe src = Some(1); + Maybe dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && *src == 1); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1); + + src = Some(2); + dest = src; + MOZ_RELEASE_ASSERT(src.isSome() && *src == 2); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2); + } + + { + Maybe src = Some(1); + Maybe dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 1); + + src = Some(2); + dest = Move(src); + MOZ_RELEASE_ASSERT(src.isNothing()); + MOZ_RELEASE_ASSERT(dest.isSome() && *dest == 2); + } + + return true; +} + int main() { @@ -855,6 +1071,7 @@ main() RUN_TEST(TestVirtualFunction); RUN_TEST(TestSomeNullptrConversion); RUN_TEST(TestSomePointerConversion); + RUN_TEST(TestTypeConversion); return 0; } From a4755c4187059882cb7604649b7d3eaf4bf35c18 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 29 Dec 2016 10:22:49 +1100 Subject: [PATCH 16/34] Bug 1326125 - Rename enum version of SetIntValue to SetEnumValue. r=heycam MozReview-Commit-ID: EbXK827IRFP --HG-- extra : rebase_source : 3ee8247c211aeff6fae35168f968f0c2d20bb3e1 --- dom/html/nsGenericHTMLElement.cpp | 12 +++++------- layout/style/StyleAnimationValue.cpp | 12 ++++-------- layout/style/StyleAnimationValue.h | 4 ++-- layout/style/nsCSSParser.cpp | 13 +++++-------- layout/style/nsCSSValue.h | 4 ++-- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index af9ff90376f5..0192d7220dee 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -1257,12 +1257,10 @@ nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(const nsMappedAttribut if (value) { if (value->Equals(nsGkAtoms::_empty, eCaseMatters) || value->Equals(nsGkAtoms::_true, eIgnoreCase)) { - userModify->SetIntValue(StyleUserModify::ReadWrite, - eCSSUnit_Enumerated); + userModify->SetEnumValue(StyleUserModify::ReadWrite); } else if (value->Equals(nsGkAtoms::_false, eIgnoreCase)) { - userModify->SetIntValue(StyleUserModify::ReadOnly, - eCSSUnit_Enumerated); + userModify->SetEnumValue(StyleUserModify::ReadOnly); } } } @@ -1281,7 +1279,7 @@ nsGenericHTMLElement::MapCommonAttributesInto(const nsMappedAttributes* aAttribu nsCSSValue* display = aData->ValueForDisplay(); if (display->GetUnit() == eCSSUnit_Null) { if (aAttributes->IndexOfAttr(nsGkAtoms::hidden) >= 0) { - display->SetIntValue(StyleDisplay::None, eCSSUnit_Enumerated); + display->SetEnumValue(StyleDisplay::None); } } } @@ -1346,9 +1344,9 @@ nsGenericHTMLElement::MapImageAlignAttributeInto(const nsMappedAttributes* aAttr nsCSSValue* cssFloat = aRuleData->ValueForFloat(); if (cssFloat->GetUnit() == eCSSUnit_Null) { if (align == NS_STYLE_TEXT_ALIGN_LEFT) { - cssFloat->SetIntValue(StyleFloat::Left, eCSSUnit_Enumerated); + cssFloat->SetEnumValue(StyleFloat::Left); } else if (align == NS_STYLE_TEXT_ALIGN_RIGHT) { - cssFloat->SetIntValue(StyleFloat::Right, eCSSUnit_Enumerated); + cssFloat->SetEnumValue(StyleFloat::Right); } } nsCSSValue* verticalAlign = aRuleData->ValueForVerticalAlign(); diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index 984f4bf0e6af..1c008dc1f5d7 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -336,8 +336,7 @@ AppendCSSShadowValue(const nsCSSShadowItem *aShadow, arr->Item(4).SetColorValue(aShadow->mColor); } if (aShadow->mInset) { - arr->Item(5).SetIntValue(uint8_t(StyleBoxShadowType::Inset), - eCSSUnit_Enumerated); + arr->Item(5).SetEnumValue(StyleBoxShadowType::Inset); } nsCSSValueList *resultItem = new nsCSSValueList; @@ -4179,8 +4178,7 @@ StyleClipBasicShapeToCSSArray(const StyleClipPath& aClipPath, functionArray = aResult->Item(0).InitFunction(functionName, ShapeArgumentCount(functionName)); - functionArray->Item(1).SetIntValue(shape->GetFillRule(), - eCSSUnit_Enumerated); + functionArray->Item(1).SetEnumValue(shape->GetFillRule()); nsCSSValuePairList* list = functionArray->Item(2).SetPairListValue(); const nsTArray& coords = shape->Coordinates(); MOZ_ASSERT((coords.Length() % 2) == 0); @@ -4228,8 +4226,7 @@ StyleClipBasicShapeToCSSArray(const StyleClipPath& aClipPath, MOZ_ASSERT_UNREACHABLE("Unknown shape type"); return false; } - aResult->Item(1).SetIntValue(aClipPath.GetReferenceBox(), - eCSSUnit_Enumerated); + aResult->Item(1).SetEnumValue(aClipPath.GetReferenceBox()); return true; } @@ -4525,8 +4522,7 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, result->SetURLValue(clipPath.GetURL()); aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL); } else if (type == StyleShapeSourceType::Box) { - aComputedValue.SetIntValue(clipPath.GetReferenceBox(), - eUnit_Enumerated); + aComputedValue.SetEnumValue(clipPath.GetReferenceBox()); } else if (type == StyleShapeSourceType::Shape) { RefPtr result = nsCSSValue::Array::Create(2); if (!StyleClipBasicShapeToCSSArray(clipPath, result)) { diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index 96f33d3dc040..b084a441c080 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -491,11 +491,11 @@ public: void SetIntValue(int32_t aInt, Unit aUnit); template::value>::type> - void SetIntValue(T aInt, Unit aUnit) + void SetEnumValue(T aInt) { static_assert(mozilla::EnumTypeFitsWithin::value, "aValue must be an enum that fits within mValue.mInt"); - SetIntValue(static_cast(aInt), aUnit); + SetIntValue(static_cast(aInt), eUnit_Enumerated); } void SetCoordValue(nscoord aCoord); void SetPercentValue(float aPercent); diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 2c87009214cb..8167dae58717 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -12403,8 +12403,7 @@ CSSParserImpl::ParseImageLayersItem( aState.mImage->mValue.SetNoneValue(); aState.mAttachment->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL, eCSSUnit_Enumerated); - aState.mClip->mValue.SetIntValue(StyleGeometryBox::Border, - eCSSUnit_Enumerated); + aState.mClip->mValue.SetEnumValue(StyleGeometryBox::Border); aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_REPEAT, eCSSUnit_Enumerated); @@ -12416,11 +12415,9 @@ CSSParserImpl::ParseImageLayersItem( aState.mPositionY->mValue.SetArrayValue(positionYArr, eCSSUnit_Array); if (eCSSProperty_mask == aTable[nsStyleImageLayers::shorthand]) { - aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Border, - eCSSUnit_Enumerated); + aState.mOrigin->mValue.SetEnumValue(StyleGeometryBox::Border); } else { - aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Padding, - eCSSUnit_Enumerated); + aState.mOrigin->mValue.SetEnumValue(StyleGeometryBox::Padding); } positionXArr->Item(1).SetPercentValue(0.0f); positionYArr->Item(1).SetPercentValue(0.0f); @@ -17219,9 +17216,9 @@ CSSParserImpl::ParseAnimation() initialValues[1].SetIntValue(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE, eCSSUnit_Enumerated); initialValues[2].SetFloatValue(0.0, eCSSUnit_Seconds); - initialValues[3].SetIntValue(static_cast(mozilla::dom::PlaybackDirection::Normal), + initialValues[3].SetIntValue(static_cast(dom::PlaybackDirection::Normal), eCSSUnit_Enumerated); - initialValues[4].SetIntValue(static_cast(mozilla::dom::FillMode::None), + initialValues[4].SetIntValue(static_cast(dom::FillMode::None), eCSSUnit_Enumerated); initialValues[5].SetFloatValue(1.0f, eCSSUnit_Number); initialValues[6].SetIntValue(NS_STYLE_ANIMATION_PLAY_STATE_RUNNING, eCSSUnit_Enumerated); diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 7f062f0327cc..4c8fc45c3f79 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -890,11 +890,11 @@ public: void SetIntValue(int32_t aValue, nsCSSUnit aUnit); template::value>::type> - void SetIntValue(T aValue, nsCSSUnit aUnit) + void SetEnumValue(T aValue) { static_assert(mozilla::EnumTypeFitsWithin::value, "aValue must be an enum that fits within mValue.mInt"); - SetIntValue(static_cast(aValue), aUnit); + SetIntValue(static_cast(aValue), eCSSUnit_Enumerated); } void SetPercentValue(float aValue); void SetFloatValue(float aValue, nsCSSUnit aUnit); From 91e6ea18e7aa881047adf7619b3b424ff04e1e3f Mon Sep 17 00:00:00 2001 From: "gtatum@mozilla.com" Date: Tue, 11 Oct 2016 20:30:24 +0000 Subject: [PATCH 17/34] Bug 1309065 - Be smarter about filling in the client-side css properties db; r=tromey MozReview-Commit-ID: BOYwveTH1Hy --HG-- rename : devtools/server/tests/mochitest/test_css-properties_01.html => devtools/server/tests/mochitest/test_css-properties.html extra : rebase_source : 07118d9577635c57bcf1684a6e0be66937118944 --- devtools/server/actors/css-properties.js | 7 +- devtools/server/tests/mochitest/chrome.ini | 3 +- ...rties_01.html => test_css-properties.html} | 0 .../mochitest/test_css-properties_02.html | 86 --- .../shared/css/generated/mach_commands.py | 35 ++ .../shared/css/generated/properties-db.js | 585 +++++++++++++++++- .../shared/css/generated/properties-db.js.in | 6 + devtools/shared/fronts/css-properties.js | 17 +- .../tests/unit/test_css-properties-db.js | 52 +- 9 files changed, 667 insertions(+), 124 deletions(-) rename devtools/server/tests/mochitest/{test_css-properties_01.html => test_css-properties.html} (100%) delete mode 100644 devtools/server/tests/mochitest/test_css-properties_02.html diff --git a/devtools/server/actors/css-properties.js b/devtools/server/actors/css-properties.js index 928922934461..2a4538378584 100644 --- a/devtools/server/actors/css-properties.js +++ b/devtools/server/actors/css-properties.js @@ -68,17 +68,12 @@ function generateCssProperties() { let subproperties = DOMUtils.getSubpropertiesForCSSProperty(name); - // In order to maintain any backwards compatible changes when debugging older - // clients, take the definition from the static CSS properties database, and fill it - // in with the most recent property definition from the server. - const clientDefinition = CSS_PROPERTIES[name] || {}; - const serverDefinition = { + properties[name] = { isInherited: DOMUtils.isInheritedProperty(name), values, supports, subproperties, }; - properties[name] = Object.assign(clientDefinition, serverDefinition); }); return properties; diff --git a/devtools/server/tests/mochitest/chrome.ini b/devtools/server/tests/mochitest/chrome.ini index ae69d163e202..85cc75611b9c 100644 --- a/devtools/server/tests/mochitest/chrome.ini +++ b/devtools/server/tests/mochitest/chrome.ini @@ -30,8 +30,7 @@ support-files = [test_css-logic.html] [test_css-logic-media-queries.html] [test_css-logic-specificity.html] -[test_css-properties_01.html] -[test_css-properties_02.html] +[test_css-properties.html] [test_Debugger.Source.prototype.introductionScript.html] [test_Debugger.Source.prototype.introductionType.html] [test_Debugger.Source.prototype.element.html] diff --git a/devtools/server/tests/mochitest/test_css-properties_01.html b/devtools/server/tests/mochitest/test_css-properties.html similarity index 100% rename from devtools/server/tests/mochitest/test_css-properties_01.html rename to devtools/server/tests/mochitest/test_css-properties.html diff --git a/devtools/server/tests/mochitest/test_css-properties_02.html b/devtools/server/tests/mochitest/test_css-properties_02.html deleted file mode 100644 index 1a5d99d721f5..000000000000 --- a/devtools/server/tests/mochitest/test_css-properties_02.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - Test CSS Properties Actor - - - - - - - Mozilla Bug 1265798 - Test Document - - diff --git a/devtools/shared/css/generated/mach_commands.py b/devtools/shared/css/generated/mach_commands.py index 4d6016276aa7..fb002c3c4001 100644 --- a/devtools/shared/css/generated/mach_commands.py +++ b/devtools/shared/css/generated/mach_commands.py @@ -13,6 +13,7 @@ import os import sys import string import subprocess +from mozbuild import shellutil from mozbuild.base import ( MozbuildObject, MachCommandBase, @@ -39,12 +40,46 @@ class MachCommands(MachCommandBase): """Generate the static css properties database for devtools and write it to file.""" print("Re-generating the css properties database...") + preferences = self.get_preferences() db = self.get_properties_db_from_xpcshell() self.output_template({ + 'preferences': stringify(preferences), 'cssProperties': stringify(db['cssProperties']), 'pseudoElements': stringify(db['pseudoElements'])}) + def get_preferences(self): + """Get all of the preferences associated with enabling and disabling a property.""" + # Build the command to run the preprocessor on PythonCSSProps.h + headerPath = resolve_path(self.topsrcdir, 'layout/style/PythonCSSProps.h') + + cpp = self.substs['CPP'] + + if not cpp: + print("Unable to find the cpp program. Please do a full, nonartifact") + print("build and try this again.") + sys.exit(1) + + if type(cpp) is list: + cmd = cpp + else: + cmd = shellutil.split(cpp) + cmd += shellutil.split(self.substs['ACDEFINES']) + cmd.append(headerPath) + + # The preprocessed list takes the following form: + # [ (name, prop, id, flags, pref, proptype), ... ] + preprocessed = eval(subprocess.check_output(cmd)) + + # Map this list + # (name, prop, id, flags, pref, proptype) => (name, pref) + preferences = [ + (name, pref) + for name, prop, id, flags, pref, proptype in preprocessed + if 'CSS_PROPERTY_INTERNAL' not in flags and pref] + + return preferences + def get_properties_db_from_xpcshell(self): """Generate the static css properties db for devtools from an xpcshell script.""" build = MozbuildObject.from_environment() diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 0e2853499ced..fc3c398c69eb 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -2222,12 +2222,14 @@ exports.CSS_PROPERTIES = { "border-box", "content-box", "exclude", + "fill-box", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", + "no-clip", "no-repeat", "none", "padding-box", @@ -2239,9 +2241,11 @@ exports.CSS_PROPERTIES = { "repeating-radial-gradient", "round", "space", + "stroke-box", "subtract", "unset", - "url" + "url", + "view-box" ] }, "-webkit-mask-clip": { @@ -2253,10 +2257,14 @@ exports.CSS_PROPERTIES = { "values": [ "border-box", "content-box", + "fill-box", "inherit", "initial", + "no-clip", "padding-box", - "unset" + "stroke-box", + "unset", + "view-box" ] }, "-webkit-mask-composite": { @@ -2312,10 +2320,13 @@ exports.CSS_PROPERTIES = { "values": [ "border-box", "content-box", + "fill-box", "inherit", "initial", "padding-box", - "unset" + "stroke-box", + "unset", + "view-box" ] }, "-webkit-mask-position": { @@ -3257,6 +3268,7 @@ exports.CSS_PROPERTIES = { "flex", "flex-end", "flex-start", + "flow-root", "forwards", "full-width", "geometricprecision", @@ -3338,6 +3350,7 @@ exports.CSS_PROPERTIES = { "mixed", "multiply", "no-change", + "no-clip", "no-drag", "no-repeat", "non-scaling-stroke", @@ -3472,6 +3485,7 @@ exports.CSS_PROPERTIES = { "stretch", "stretch-to-fit", "stroke", + "stroke-box", "sub", "subtract", "super", @@ -5681,6 +5695,7 @@ exports.CSS_PROPERTIES = { "block", "contents", "flex", + "flow-root", "grid", "inherit", "initial", @@ -7189,12 +7204,14 @@ exports.CSS_PROPERTIES = { "border-box", "content-box", "exclude", + "fill-box", "inherit", "initial", "intersect", "linear-gradient", "luminance", "match-source", + "no-clip", "no-repeat", "none", "padding-box", @@ -7206,9 +7223,11 @@ exports.CSS_PROPERTIES = { "repeating-radial-gradient", "round", "space", + "stroke-box", "subtract", "unset", - "url" + "url", + "view-box" ] }, "mask-clip": { @@ -7220,10 +7239,14 @@ exports.CSS_PROPERTIES = { "values": [ "border-box", "content-box", + "fill-box", "inherit", "initial", + "no-clip", "padding-box", - "unset" + "stroke-box", + "unset", + "view-box" ] }, "mask-composite": { @@ -7294,10 +7317,13 @@ exports.CSS_PROPERTIES = { "values": [ "border-box", "content-box", + "fill-box", "inherit", "initial", "padding-box", - "unset" + "stroke-box", + "unset", + "view-box" ] }, "mask-position": { @@ -9377,3 +9403,550 @@ exports.PSEUDO_ELEMENTS = [ ":placeholder", ":-moz-color-swatch" ]; + +/** + * A list of the preferences keys for whether a CSS property is enabled or not. This is + * exposed for testing purposes. + */ +exports.PREFERENCES = [ + [ + "all", + "layout.css.all-shorthand.enabled" + ], + [ + "background-blend-mode", + "layout.css.background-blend-mode.enabled" + ], + [ + "box-decoration-break", + "layout.css.box-decoration-break.enabled" + ], + [ + "color-adjust", + "layout.css.color-adjust.enabled" + ], + [ + "contain", + "layout.css.contain.enabled" + ], + [ + "font-variation-settings", + "layout.css.font-variations.enabled" + ], + [ + "grid", + "layout.css.grid.enabled" + ], + [ + "grid-area", + "layout.css.grid.enabled" + ], + [ + "grid-auto-columns", + "layout.css.grid.enabled" + ], + [ + "grid-auto-flow", + "layout.css.grid.enabled" + ], + [ + "grid-auto-rows", + "layout.css.grid.enabled" + ], + [ + "grid-column", + "layout.css.grid.enabled" + ], + [ + "grid-column-end", + "layout.css.grid.enabled" + ], + [ + "grid-column-gap", + "layout.css.grid.enabled" + ], + [ + "grid-column-start", + "layout.css.grid.enabled" + ], + [ + "grid-gap", + "layout.css.grid.enabled" + ], + [ + "grid-row", + "layout.css.grid.enabled" + ], + [ + "grid-row-end", + "layout.css.grid.enabled" + ], + [ + "grid-row-gap", + "layout.css.grid.enabled" + ], + [ + "grid-row-start", + "layout.css.grid.enabled" + ], + [ + "grid-template", + "layout.css.grid.enabled" + ], + [ + "grid-template-areas", + "layout.css.grid.enabled" + ], + [ + "grid-template-columns", + "layout.css.grid.enabled" + ], + [ + "grid-template-rows", + "layout.css.grid.enabled" + ], + [ + "initial-letter", + "layout.css.initial-letter.enabled" + ], + [ + "image-orientation", + "layout.css.image-orientation.enabled" + ], + [ + "isolation", + "layout.css.isolation.enabled" + ], + [ + "mix-blend-mode", + "layout.css.mix-blend-mode.enabled" + ], + [ + "object-fit", + "layout.css.object-fit-and-position.enabled" + ], + [ + "object-position", + "layout.css.object-fit-and-position.enabled" + ], + [ + "-moz-osx-font-smoothing", + "layout.css.osx-font-smoothing.enabled" + ], + [ + "overflow-clip-box", + "layout.css.overflow-clip-box.enabled" + ], + [ + "paint-order", + "svg.paint-order.enabled" + ], + [ + "scroll-behavior", + "layout.css.scroll-behavior.property-enabled" + ], + [ + "scroll-snap-coordinate", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-destination", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-points-x", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-points-y", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type-x", + "layout.css.scroll-snap.enabled" + ], + [ + "scroll-snap-type-y", + "layout.css.scroll-snap.enabled" + ], + [ + "shape-outside", + "layout.css.shape-outside.enabled" + ], + [ + "text-combine-upright", + "layout.css.text-combine-upright.enabled" + ], + [ + "-webkit-text-fill-color", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke-color", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-stroke-width", + "layout.css.prefixes.webkit" + ], + [ + "touch-action", + "layout.css.touch_action.enabled" + ], + [ + "-moz-transform", + "layout.css.prefixes.transforms" + ], + [ + "transform-box", + "svg.transform-box.enabled" + ], + [ + "-moz-transform-origin", + "layout.css.prefixes.transforms" + ], + [ + "-moz-perspective-origin", + "layout.css.prefixes.transforms" + ], + [ + "-moz-perspective", + "layout.css.prefixes.transforms" + ], + [ + "-moz-transform-style", + "layout.css.prefixes.transforms" + ], + [ + "-moz-backface-visibility", + "layout.css.prefixes.transforms" + ], + [ + "-moz-border-image", + "layout.css.prefixes.border-image" + ], + [ + "-moz-transition", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-delay", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-duration", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-property", + "layout.css.prefixes.transitions" + ], + [ + "-moz-transition-timing-function", + "layout.css.prefixes.transitions" + ], + [ + "-moz-animation", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-delay", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-direction", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-duration", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-fill-mode", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-iteration-count", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-name", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-play-state", + "layout.css.prefixes.animations" + ], + [ + "-moz-animation-timing-function", + "layout.css.prefixes.animations" + ], + [ + "-moz-box-sizing", + "layout.css.prefixes.box-sizing" + ], + [ + "-moz-font-feature-settings", + "layout.css.prefixes.font-features" + ], + [ + "-moz-font-language-override", + "layout.css.prefixes.font-features" + ], + [ + "-webkit-animation", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-delay", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-duration", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-fill-mode", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-iteration-count", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-name", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-play-state", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-animation-timing-function", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-filter", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-text-size-adjust", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transform-style", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-backface-visibility", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-perspective", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-perspective-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-delay", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-duration", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-property", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-transition-timing-function", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-top-left-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-top-right-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-bottom-left-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-bottom-right-radius", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-clip", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-background-size", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-border-image", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-shadow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-sizing", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-flex", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-ordinal-group", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-orient", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-align", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-box-pack", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-direction", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-wrap", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-flow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-order", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-grow", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-shrink", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-flex-basis", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-justify-content", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-items", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-self", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-align-content", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-user-select", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-clip", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-composite", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-image", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-origin", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position-x", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-position-y", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-repeat", + "layout.css.prefixes.webkit" + ], + [ + "-webkit-mask-size", + "layout.css.prefixes.webkit" + ] +]; diff --git a/devtools/shared/css/generated/properties-db.js.in b/devtools/shared/css/generated/properties-db.js.in index 370c9199a02d..372e525e9776 100644 --- a/devtools/shared/css/generated/properties-db.js.in +++ b/devtools/shared/css/generated/properties-db.js.in @@ -18,3 +18,9 @@ exports.CSS_PROPERTIES = ${cssProperties}; * A list of the pseudo elements. */ exports.PSEUDO_ELEMENTS = ${pseudoElements}; + +/** + * A list of the preferences keys for whether a CSS property is enabled or not. This is + * exposed for testing purposes. + */ +exports.PREFERENCES = ${preferences}; diff --git a/devtools/shared/fronts/css-properties.js b/devtools/shared/fronts/css-properties.js index 4bf0fa88e086..655687232e46 100644 --- a/devtools/shared/fronts/css-properties.js +++ b/devtools/shared/fronts/css-properties.js @@ -234,15 +234,7 @@ const initCssProperties = Task.async(function* (toolbox) { // Get the list dynamically if the cssProperties actor exists. if (toolbox.target.hasActor("cssProperties")) { front = CssPropertiesFront(client, toolbox.target.form); - const serverDB = yield front.getCSSDatabase(); - - // Ensure the database was returned in a format that is understood. - // Older versions of the protocol could return a blank database. - if (!serverDB.properties && !serverDB.margin) { - db = CSS_PROPERTIES_DB; - } else { - db = serverDB; - } + db = yield front.getCSSDatabase(); } else { // The target does not support this actor, so require a static list of supported // properties. @@ -294,9 +286,6 @@ function normalizeCssData(db) { db = { properties: db }; } - // Fill in any missing DB information from the static database. - db = Object.assign({}, CSS_PROPERTIES_DB, db); - let missingSupports = !db.properties.color.supports; let missingValues = !db.properties.color.values; let missingSubproperties = !db.properties.background.subproperties; @@ -320,6 +309,10 @@ function normalizeCssData(db) { db.properties[name].subproperties = CSS_PROPERTIES_DB.properties[name].subproperties; } + // Add "isInherited" information to the css properties if it's missing. + if (db.properties.font.isInherited) { + db.properties[name].isInherited = CSS_PROPERTIES_DB.properties[name].isInherited; + } } } diff --git a/devtools/shared/tests/unit/test_css-properties-db.js b/devtools/shared/tests/unit/test_css-properties-db.js index 108650a3ed49..ec14a99a6683 100644 --- a/devtools/shared/tests/unit/test_css-properties-db.js +++ b/devtools/shared/tests/unit/test_css-properties-db.js @@ -22,8 +22,9 @@ const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); -const {PSEUDO_ELEMENTS, CSS_PROPERTIES} = require("devtools/shared/css/generated/properties-db"); +const {PSEUDO_ELEMENTS, CSS_PROPERTIES, PREFERENCES} = require("devtools/shared/css/generated/properties-db"); const {generateCssProperties} = require("devtools/server/actors/css-properties"); +const {Preferences} = require("resource://gre/modules/Preferences.jsm"); function run_test() { const propertiesErrorMessage = "If this assertion fails, then the client side CSS " + @@ -38,7 +39,9 @@ function run_test() { /** * Check that the platform and client match for the details on their CSS properties. - * Enumerate each property to aid in debugging. + * Enumerate each property to aid in debugging. Sometimes these properties don't + * completely agree due to differences in preferences. Check the currently set + * preference for that property to see if it's enabled. */ const platformProperties = generateCssProperties(); @@ -47,17 +50,18 @@ function run_test() { const clientProperty = CSS_PROPERTIES[propertyName]; const deepEqual = isJsonDeepEqual(platformProperty, clientProperty); + // The "all" property can contain information that can be turned on and off by + // preferences. These values can be different between OSes, so ignore the equality + // check for this property, since this is likely to fail. + if (propertyName === "all") { + continue; + } + if (deepEqual) { ok(true, `The static database and platform match for "${propertyName}".`); } else { - const prefMessage = `The static database and platform do not match ` + - `for "${propertyName}".`; - if (getPreference(propertyName) === false) { - ok(true, `${prefMessage} However, there is a preference for disabling this ` + - `property on the current build.`); - } else { - ok(false, `${prefMessage} ${propertiesErrorMessage}`); - } + ok(false, `The static database and platform do not match for ` + ` + "${propertyName}". ${propertiesErrorMessage}`); } } @@ -75,8 +79,14 @@ function run_test() { } mismatches.forEach(propertyName => { - ok(false, `The static database and platform do not agree on the property ` + - `"${propertyName}" ${propertiesErrorMessage}`); + if (getPreference(propertyName) === false) { + ok(true, `The static database and platform do not agree on the property ` + + `"${propertyName}" This is ok because it is currently disabled through ` + + `a preference.`); + } else { + ok(false, `The static database and platform do not agree on the property ` + + `"${propertyName}" ${propertiesErrorMessage}`); + } }); } @@ -134,3 +144,21 @@ function getKeyMismatches(a, b) { return aMismatches.concat(bMismatches); } + +/** + * Get the preference value of whether this property is enabled. Returns an empty string + * if no preference exists. + * + * @param {String} propertyName + * @return {Boolean|undefined} + */ +function getPreference(propertyName) { + const preference = PREFERENCES.find(([prefPropertyName, preferenceKey]) => { + return prefPropertyName === propertyName && !!preferenceKey; + }); + + if (preference) { + return Preferences.get(preference[1]); + } + return undefined; +} From 1fbe2eb9163c90f9b68dbd8053b6c4333497769c Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Wed, 7 Dec 2016 10:18:46 -1000 Subject: [PATCH 18/34] Bug 1320061 - Add pref that allows users to copy unescaped URL from the URL bar r=mak MozReview-Commit-ID: CDnMnkqj8gW * * * Bug 1320061 - Add test for copying non-ascii URL from the urlbar MozReview-Commit-ID: 72jymxn6DJv --HG-- extra : rebase_source : 06b33dc4a22745076ad5fbd61ccd573efb84ce4a --- browser/app/profile/firefox.js | 4 +++ .../test/urlbar/browser_urlbarCopying.js | 26 ++++++++++++++++++- browser/base/content/urlbarBindings.xml | 20 +++++++------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index cc5f8659bef0..eb1e38d858aa 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -318,6 +318,10 @@ pref("browser.urlbar.oneOffSearches", true); pref("browser.urlbar.oneOffSearches", false); #endif +// If changed to true, copying the entire URL from the location bar will put the +// human readable (percent-decoded) URL on the clipboard. +pref("browser.urlbar.decodeURLsOnCopy", false); + pref("browser.altClickSave", false); // Enable logging downloads operations to the Console. diff --git a/browser/base/content/test/urlbar/browser_urlbarCopying.js b/browser/base/content/test/urlbar/browser_urlbarCopying.js index e1a91bf63e1d..8c1d262d6d3b 100644 --- a/browser/base/content/test/urlbar/browser_urlbarCopying.js +++ b/browser/base/content/test/urlbar/browser_urlbarCopying.js @@ -3,6 +3,15 @@ const trimPref = "browser.urlbar.trimURLs"; const phishyUserPassPref = "network.http.phishy-userpass-length"; +const decodeURLpref = "browser.urlbar.decodeURLsOnCopy"; + +function toUnicode(input) { + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + return converter.ConvertToUnicode(input); +} function test() { @@ -12,6 +21,7 @@ function test() { gBrowser.removeTab(tab); Services.prefs.clearUserPref(trimPref); Services.prefs.clearUserPref(phishyUserPassPref); + Services.prefs.clearUserPref(decodeURLpref); URLBarSetURI(); }); @@ -141,7 +151,17 @@ var tests = [ { copyVal: ")", copyExpected: "data:text/html,(%C3%A9 %25P", - } + }, + { + setup: function() { Services.prefs.setBoolPref(decodeURLpref, true); }, + loadURL: "http://example.com/%D0%B1%D0%B8%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F", + expectedURL: toUnicode("example.com/биография"), + copyExpected: toUnicode("http://example.com/биография") + }, + { + copyVal: toUnicode("ография"), + copyExpected: toUnicode("http://example.com/би") + }, ]; function nextTest() { @@ -162,6 +182,10 @@ function runTest(testCase, cb) { testCopy(testCase.copyVal, testCase.copyExpected, cb); } + if (testCase.setup) { + testCase.setup(); + } + if (testCase.loadURL) { loadURL(testCase.loadURL, doCheck); } else { diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index cc07fcf610e1..8f40d7129e23 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -797,19 +797,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. uri = uriFixup.createExposableURI(uri); } catch (ex) {} - // If the entire URL is selected, just use the actual loaded URI. - if (inputVal == selectedVal) { - // ... but only if isn't a javascript: or data: URI, since those - // are hard to read when encoded - if (!uri.schemeIs("javascript") && !uri.schemeIs("data")) { - selectedVal = uri.spec; - } - - return selectedVal; + // If the entire URL is selected, just use the actual loaded URI, + // unless we want a decoded URI, or it's a data: or javascript: URI, + // since those are hard to read when encoded. + if (inputVal == selectedVal && + !uri.schemeIs("javascript") && !uri.schemeIs("data") && + !Services.prefs.getBoolPref("browser.urlbar.decodeURLsOnCopy")) { + return uri.spec; } - // Just the beginning of the URL is selected, check for a trimmed - // value + // Just the beginning of the URL is selected, or we want a decoded + // url. First check for a trimmed value. let spec = uri.spec; let trimmedSpec = this.trimValue(spec); if (spec != trimmedSpec) { From 3b00d747cbd232b9a2d2908436787c83326095cf Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 11:19:36 +0100 Subject: [PATCH 19/34] Bug 1323770 - Moztest should forward correct test result. r=ahal Registered callback handlers for tests should receive the correct test status when the test has been finished, and not always "Error". This change allows those callbacks to run specific code for individual test results, eg. only do screenshots for failures. MozReview-Commit-ID: FfbCRR0Jvjb --HG-- extra : rebase_source : c73253acbb666ca62b23f806145c20f0a70c934c --- testing/mozbase/moztest/moztest/adapters/unit.py | 13 ++++++++----- testing/mozbase/moztest/setup.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/testing/mozbase/moztest/moztest/adapters/unit.py b/testing/mozbase/moztest/moztest/adapters/unit.py index c31a6c3b37d1..cee0e05e92a0 100644 --- a/testing/mozbase/moztest/moztest/adapters/unit.py +++ b/testing/mozbase/moztest/moztest/adapters/unit.py @@ -134,7 +134,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addFailure(self, test, err): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "FAIL") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -145,10 +145,13 @@ class StructuredTestResult(TextTestResult): def addSuccess(self, test): extra = self._get_class_method_name(test) - self.logger.test_end(test.id(), "PASS", expected="PASS", extra=extra) + self.logger.test_end(test.id(), + "PASS", + expected="PASS", + extra=extra) def addExpectedFailure(self, test, err): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "FAIL") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "FAIL", @@ -158,7 +161,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addUnexpectedSuccess(self, test): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "PASS") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "PASS", @@ -166,7 +169,7 @@ class StructuredTestResult(TextTestResult): extra=extra) def addSkip(self, test, reason): - extra = self.call_callbacks(test, "ERROR") + extra = self.call_callbacks(test, "SKIP") extra.update(self._get_class_method_name(test)) self.logger.test_end(test.id(), "SKIP", diff --git a/testing/mozbase/moztest/setup.py b/testing/mozbase/moztest/setup.py index 24455c285b71..9c7c11789842 100644 --- a/testing/mozbase/moztest/setup.py +++ b/testing/mozbase/moztest/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages -PACKAGE_VERSION = '0.7' +PACKAGE_VERSION = '0.8' # dependencies deps = ['mozinfo'] From 35a7d605d5261c412741edbfeacc690f8831e4cc Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 15:19:40 +0100 Subject: [PATCH 20/34] Bug 1323770 - Marionette should not take screenshots for skipped tests. r=maja_zf Taking screenshots for skipped tests is useless and should be avoided to reduce the size of the test logs. MozReview-Commit-ID: 9HPH7pSXTj9 --HG-- extra : rebase_source : 41ea609a285e037160b1be535dac35de643f31c1 --- testing/marionette/harness/marionette_harness/runner/base.py | 4 ++++ testing/marionette/harness/requirements.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/marionette/harness/marionette_harness/runner/base.py b/testing/marionette/harness/marionette_harness/runner/base.py index 9527ea59142c..679efb87711b 100644 --- a/testing/marionette/harness/marionette_harness/runner/base.py +++ b/testing/marionette/harness/marionette_harness/runner/base.py @@ -552,6 +552,10 @@ class BaseMarionetteTestRunner(object): self.e10s = e10s def gather_debug(test, status): + # No screenshots and page source for skipped tests + if status == "SKIP": + return + rv = {} marionette = test._marionette_weakref() diff --git a/testing/marionette/harness/requirements.txt b/testing/marionette/harness/requirements.txt index 3fab7c2d1bda..75ab9ce92b2a 100644 --- a/testing/marionette/harness/requirements.txt +++ b/testing/marionette/harness/requirements.txt @@ -9,6 +9,6 @@ moznetwork >= 0.21 mozprocess >= 0.9 mozprofile >= 0.7 mozrunner >= 6.13 -moztest >= 0.7 +moztest >= 0.8 mozversion >= 1.1 wptserve >= 1.3.0 From feda1978495a0e73eaf404d1514ae3633f6c646a Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Thu, 29 Dec 2016 09:22:00 +0100 Subject: [PATCH 21/34] Bug 1323770 - Fix skip decorators for unit tests. r=maja_zf Marionette's skip decorators are currently not conform with the ones from the Python's unittest module, which require a reason as parameter. As such Marionette should behave the same and should also require a reason for more detailed skip messages. This is done by wrapping the actual decorator with another enclosing method. With the changes we also ensure that the wrapper has the same attributes as the wrapped function by using functools.wraps(). This hasn't used so far and makes debugging harder. Further a couple of skip methods and classes were copied from the unittest module, which should be better imported instead to reduce code duplication. MozReview-Commit-ID: 6XT6M6cbCFW --HG-- extra : rebase_source : 2fb8bce0f17eade182eb5f61479548d0f6ef8ecc --- .../security/test_ssl_status_after_restart.py | 2 +- .../marionette_test/__init__.py | 12 +- .../marionette_test/decorators.py | 188 ++++++++++-------- .../marionette_test/errors.py | 32 --- .../marionette_test/testcases.py | 12 +- .../tests/unit/test_about_pages.py | 12 +- .../tests/unit/test_click_scrolling.py | 2 +- .../tests/unit/test_crash.py | 2 +- .../tests/unit/test_import_script.py | 9 +- .../tests/unit/test_modal_dialogs.py | 2 +- .../tests/unit/test_screen_orientation.py | 20 +- .../tests/unit/test_screenshot.py | 19 +- .../tests/unit/test_transport.py | 4 +- 13 files changed, 153 insertions(+), 163 deletions(-) delete mode 100644 testing/marionette/harness/marionette_harness/marionette_test/errors.py diff --git a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py index d5c99dd8de29..f274d8f2fd28 100644 --- a/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py +++ b/testing/firefox-ui/tests/functional/security/test_ssl_status_after_restart.py @@ -46,7 +46,7 @@ class TestSSLStatusAfterRestart(PuppeteerMixin, MarionetteTestCase): finally: super(TestSSLStatusAfterRestart, self).tearDown() - @skip_if_e10s + @skip_if_e10s("Bug 1325047") def test_ssl_status_after_restart(self): for item in self.test_data: with self.marionette.using_context('content'): diff --git a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py index 2de79c91273a..f9baf737dff4 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/__init__.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/__init__.py @@ -5,11 +5,15 @@ __version__ = '3.1.0' -from .decorators import ( +from unittest.case import ( expectedFailure, + skip, + SkipTest, +) + +from .decorators import ( parameterized, run_if_e10s, - skip, skip_if_chrome, skip_if_desktop, skip_if_e10s, @@ -19,10 +23,6 @@ from .decorators import ( with_parameters, ) -from .errors import ( - SkipTest, -) - from .testcases import ( CommonTestCase, MarionetteTestCase, diff --git a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py index 8764532d660b..3a49868990a2 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/decorators.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/decorators.py @@ -3,28 +3,13 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import functools -import sys import types -from .errors import ( - _ExpectedFailure, - _UnexpectedSuccess, +from unittest.case import ( SkipTest, ) -def expectedFailure(func): - """Decorator which marks a test as expected fail.""" - @functools.wraps(func) - def wrapper(*args, **kwargs): - try: - func(*args, **kwargs) - except Exception: - raise _ExpectedFailure(sys.exc_info()) - raise _UnexpectedSuccess - return wrapper - - def parameterized(func_suffix, *args, **kwargs): r"""Decorator which generates methods given a base method and some data. @@ -61,85 +46,101 @@ def parameterized(func_suffix, *args, **kwargs): return wrapped -def run_if_e10s(target): +def run_if_e10s(reason): """Decorator which runs a test if e10s mode is active.""" - def wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - }""") - - if not multi_process_browser: - raise SkipTest('skipping due to e10s is disabled') - return target(self, *args, **kwargs) - return wrapper - - -def skip(reason): - """Decorator which unconditionally skips a test.""" def decorator(test_item): - if not isinstance(test_item, (type, types.ClassType)): - @functools.wraps(test_item) - def skip_wrapper(*args, **kwargs): - raise SkipTest(reason) - test_item = skip_wrapper + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') - test_item.__unittest_skip__ = True - test_item.__unittest_skip_why__ = reason - return test_item + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = not self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + } + """) + if multi_process_browser: + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper return decorator -def skip_if_chrome(target): +def skip_if_chrome(reason): """Decorator which skips a test if chrome context is active.""" - def wrapper(self, *args, **kwargs): - if self.marionette._send_message("getContext", key="value") == "chrome": - raise SkipTest("skipping test in chrome context") - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette._send_message('getContext', key='value') == 'chrome': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_desktop(target): +def skip_if_desktop(reason): """Decorator which skips a test if run on desktop.""" - def wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'firefox': - raise SkipTest('skipping due to desktop') - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'firefox': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_e10s(target): +def skip_if_e10s(reason): """Decorator which skips a test if e10s mode is active.""" - def wrapper(self, *args, **kwargs): - with self.marionette.using_context('chrome'): - multi_process_browser = self.marionette.execute_script(""" - try { - return Services.appinfo.browserTabsRemoteAutostart; - } catch (e) { - return false; - }""") + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') - if multi_process_browser: - raise SkipTest('skipping due to e10s') - return target(self, *args, **kwargs) - return wrapper + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + with self.marionette.using_context('chrome'): + multi_process_browser = self.marionette.execute_script(""" + try { + return Services.appinfo.browserTabsRemoteAutostart; + } catch (e) { + return false; + } + """) + if multi_process_browser: + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_if_mobile(target): +def skip_if_mobile(reason): """Decorator which skips a test if run on mobile.""" - def wrapper(self, *args, **kwargs): - if self.marionette.session_capabilities.get('browserName') == 'fennec': - raise SkipTest('skipping due to fennec') - return target(self, *args, **kwargs) - return wrapper + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): + if self.marionette.session_capabilities.get('browserName') == 'fennec': + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_unless_browser_pref(pref, predicate=bool): +def skip_unless_browser_pref(reason, pref, predicate=bool): """Decorator which skips a test based on the value of a browser preference. + :param reason: Message describing why the test need to be skipped. :param pref: the preference name :param predicate: a function that should return false to skip the test. The function takes one parameter, the preference value. @@ -150,33 +151,46 @@ def skip_unless_browser_pref(pref, predicate=bool): Example: :: class TestSomething(MarionetteTestCase): - @skip_unless_browser_pref("accessibility.tabfocus", - lambda value: value >= 7) + @skip_unless_browser_pref("Sessionstore needs to be enabled for crashes", + "browser.sessionstore.resume_from_crash", + lambda value: value is True, + ) def test_foo(self): pass # test implementation here + """ - def wrapper(target): - @functools.wraps(target) - def wrapped(self, *args, **kwargs): + def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + if not callable(predicate): + raise ValueError('predicate must be callable') + + @functools.wraps(test_item) + def skip_wrapper(self, *args, **kwargs): value = self.marionette.get_pref(pref) if value is None: self.fail("No such browser preference: {0!r}".format(pref)) if not predicate(value): - raise SkipTest("browser preference {0!r}: {1!r}".format((pref, value))) - return target(self, *args, **kwargs) - return wrapped - return wrapper + raise SkipTest(reason) + return test_item(self, *args, **kwargs) + return skip_wrapper + return decorator -def skip_unless_protocol(predicate): +def skip_unless_protocol(reason, predicate): """Decorator which skips a test if the predicate does not match the current protocol level.""" def decorator(test_item): + if not isinstance(test_item, types.FunctionType): + raise Exception('Decorator only supported for functions') + if not callable(predicate): + raise ValueError('predicate must be callable') + @functools.wraps(test_item) - def skip_wrapper(self): + def skip_wrapper(self, *args, **kwargs): level = self.marionette.client.protocol if not predicate(level): - raise SkipTest('skipping because protocol level is {}'.format(level)) - return test_item(self) + raise SkipTest(reason) + return test_item(self, *args, **kwargs) return skip_wrapper return decorator diff --git a/testing/marionette/harness/marionette_harness/marionette_test/errors.py b/testing/marionette/harness/marionette_harness/marionette_test/errors.py deleted file mode 100644 index 301cac82c7de..000000000000 --- a/testing/marionette/harness/marionette_harness/marionette_test/errors.py +++ /dev/null @@ -1,32 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -class SkipTest(Exception): - """ - Raise this exception in a test to skip it. - - Usually you can use TestResult.skip() or one of the skipping decorators - instead of raising this directly. - """ - - pass - - -class _ExpectedFailure(Exception): - """ - Raise this when a test is expected to fail. - - This is an implementation detail. - """ - - def __init__(self, exc_info): - super(_ExpectedFailure, self).__init__() - self.exc_info = exc_info - - -class _UnexpectedSuccess(Exception): - """The test was supposed to fail, but it didn't.""" - - pass diff --git a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py index 4c20e7eda221..5051e3351eeb 100644 --- a/testing/marionette/harness/marionette_harness/marionette_test/testcases.py +++ b/testing/marionette/harness/marionette_harness/marionette_test/testcases.py @@ -12,6 +12,12 @@ import unittest import warnings import weakref +from unittest.case import ( + _ExpectedFailure, + _UnexpectedSuccess, + SkipTest, +) + from marionette_driver.errors import ( MarionetteException, ScriptTimeoutException, @@ -19,12 +25,6 @@ from marionette_driver.errors import ( ) from mozlog import get_default_logger -from .errors import ( - _ExpectedFailure, - _UnexpectedSuccess, - SkipTest, -) - def _wraps_parameterized(func, func_suffix, args, kwargs): """Internal: Decorator used in class MetaParameterized.""" diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py index 493c813ec1f9..f0365f470a4f 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_about_pages.py @@ -26,7 +26,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): super(TestAboutPages, self).tearDown() - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_back_forward(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -46,7 +46,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_navigate_non_remote_about_pages(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -61,7 +61,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # On Android no shortcuts are available + @skip_if_mobile("On Android no shortcuts are available") def test_navigate_shortcut_key(self): def open_with_shortcut(): with self.marionette.using_context("chrome"): @@ -76,7 +76,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_type_to_non_remote_tab(self): # Bug 1311041 - Prevent changing of window handle by forcing the test # to be run in a new tab. @@ -93,7 +93,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.marionette.close() self.marionette.switch_to_window(self.start_tab) - @skip_if_mobile # Interacting with chrome elements not available for Fennec + @skip_if_mobile("Interacting with chrome elements not available for Fennec") def test_type_to_remote_tab(self): # about:blank keeps remoteness from remote_uri self.marionette.navigate("about:blank") @@ -103,7 +103,7 @@ class TestAboutPages(WindowManagerMixin, MarionetteTestCase): self.wait_for_condition(lambda mn: mn.get_url() == self.remote_uri) - @skip_if_mobile # Bug 1323185 - Add Fennec support to getWindowHandles + @skip_if_mobile("Bug 1323185 - Add Fennec support to getWindowHandles") def test_hang(self): # Open a new tab and close the first one new_tab = self.open_tab(trigger="menu") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py index 8c4b140a6657..5543126782a6 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py @@ -43,7 +43,7 @@ class TestClickScrolling(MarionetteTestCase): except MoveTargetOutOfBoundsException: self.fail("Should not be out of bounds") - @skip("Bug 1003682") + @skip("Bug 1200197 - Cannot interact with elements hidden inside overflow:scroll") def test_should_be_able_to_click_on_an_element_hidden_by_overflow(self): test_html = self.marionette.absolute_url("scroll.html") self.marionette.navigate(test_html) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py index 3f7bd0a3ed31..7e74f0857a12 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_crash.py @@ -104,7 +104,7 @@ class TestCrash(BaseCrashTestCase): # chrome and frame script. # self.marionette.get_url() - @run_if_e10s + @run_if_e10s("Content crashes only exist in e10s mode") def test_crash_content_process(self): # If e10s is disabled the chrome process crashes self.marionette.navigate(self.remote_uri) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py index 21a37e941784..e86de2bd579d 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_import_script.py @@ -31,6 +31,11 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.marionette.clear_imported_scripts() self.reset_context() + def tearDown(self): + self.close_all_windows() + + super(TestImportScriptContent, self).tearDown() + def reset_context(self): self.marionette.set_context("content") @@ -109,8 +114,8 @@ class TestImportScriptContent(WindowManagerMixin, MarionetteTestCase): self.assert_defined("testFunc") self.assert_defined("testAnotherFunc") - @skip_if_chrome - @skip_if_mobile # New windows not supported in Fennec + @skip_if_chrome("Needs content scope") + @skip_if_mobile("New windows not supported in Fennec") def test_imports_apply_globally(self): self.marionette.navigate( self.marionette.absolute_url("test_windows.html")) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py index 151dccd56219..cfc402d6819a 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py @@ -157,7 +157,7 @@ class TestTabModals(MarionetteTestCase): alert.accept() self.wait_for_condition(lambda mn: mn.get_url() == "about:blank") - @skip_if_e10s + @skip_if_e10s("Bug 1325044") def test_unrelated_command_when_alert_present(self): click_handler = self.marionette.find_element(By.ID, 'click-handler') text = self.marionette.find_element(By.ID, 'click-result').text diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py index 7dfafc1750c3..830795a1ec62 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py @@ -23,31 +23,31 @@ class TestScreenOrientation(MarionetteTestCase): self.assertEqual(self.marionette.orientation, default_orientation, "invalid state") MarionetteTestCase.tearDown(self) - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_portrait_primary(self): self.marionette.set_orientation("portrait-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_landscape_primary(self): self.marionette.set_orientation("landscape-primary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_portrait_secondary(self): self.marionette.set_orientation("portrait-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-secondary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_landscape_secondary(self): self.marionette.set_orientation("landscape-secondary") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-secondary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_shorthand_portrait(self): # Set orientation to something other than portrait-primary first, since the default is # portrait-primary. @@ -58,29 +58,29 @@ class TestScreenOrientation(MarionetteTestCase): new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "portrait-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_to_shorthand_landscape(self): self.marionette.set_orientation("landscape") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_orientation_with_mixed_casing(self): self.marionette.set_orientation("lAnDsCaPe") new_orientation = self.marionette.orientation self.assertEqual(new_orientation, "landscape-primary") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_invalid_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("cheese")): self.marionette.set_orientation("cheese") - @skip_if_desktop + @skip_if_desktop("Not supported in Firefox") def test_set_null_orientation(self): with self.assertRaisesRegexp(errors.MarionetteException, unknown_orientation.format("null")): self.marionette.set_orientation(None) - @skip_if_mobile + @skip_if_mobile("Specific test for Firefox") def test_unsupported_operation_on_desktop(self): with self.assertRaises(errors.UnsupportedOperationException): self.marionette.set_orientation("landscape-primary") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py b/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py index 3231c7ff89e2..7446e7fbe2bf 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py @@ -8,11 +8,14 @@ import imghdr import struct import urllib -from unittest import skip - from marionette_driver import By from marionette_driver.errors import JavascriptException, NoSuchWindowException -from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin +from marionette_harness import ( + MarionetteTestCase, + skip, + skip_if_mobile, + WindowManagerMixin, +) def inline(doc, mime="text/html;charset=utf-8"): @@ -149,7 +152,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase): screenshot_chrome = self.marionette.screenshot() self.assertNotEqual(screenshot_content, screenshot_chrome) - @skip_if_mobile + @skip_if_mobile("Fennec doesn't support other chrome windows") def test_capture_element(self): dialog = self.open_dialog() self.marionette.switch_to_window(dialog) @@ -212,7 +215,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase): self.marionette.close_chrome_window() self.marionette.switch_to_window(self.start_window) - @skip("https://bugzilla.mozilla.org/show_bug.cgi?id=1213875") + @skip("Bug 1213875") def test_capture_scroll_element_into_view(self): pass @@ -237,7 +240,7 @@ class TestScreenCaptureChrome(WindowManagerMixin, ScreenCaptureTestCase): with self.assertRaises(ValueError): self.marionette.screenshot(format="cheese") - @skip_if_mobile + @skip_if_mobile("Fennec doesn't support other chrome windows") def test_highlight_elements(self): dialog = self.open_dialog() self.marionette.switch_to_window(dialog) @@ -293,7 +296,7 @@ class TestScreenCaptureContent(WindowManagerMixin, ScreenCaptureTestCase): return [document.body.scrollWidth, document.body.scrollHeight] """)) - @skip_if_mobile # Needs application independent method to open a new tab + @skip_if_mobile("Needs application independent method to open a new tab") def test_capture_tab_already_closed(self): tab = self.open_tab() self.marionette.switch_to_window(tab) @@ -310,7 +313,7 @@ class TestScreenCaptureContent(WindowManagerMixin, ScreenCaptureTestCase): self.assertEqual(self.scale(self.get_element_dimensions(el)), self.get_image_dimensions(screenshot)) - @skip("https://bugzilla.mozilla.org/show_bug.cgi?id=1213875") + @skip("Bug 1213875") def test_capture_element_scrolled_into_view(self): self.marionette.navigate(long) el = self.marionette.find_element(By.TAG_NAME, "p") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py index 2d2d7a4e42ba..39e36a9b224c 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_transport.py @@ -33,14 +33,14 @@ class TestMessageSequencing(MarionetteTestCase): self.marionette.client.send(cmd) return self.last_id - @skip_unless_protocol(lambda level: level >= 3) + @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) def test_discard_older_messages(self): first = self.send(*get_current_url) second = self.send(*execute_script) resp = self.marionette.client.receive() self.assertEqual(second, resp.id) - @skip_unless_protocol(lambda level: level >= 3) + @skip_unless_protocol("Skip for level < 3", lambda level: level >= 3) def test_last_id_incremented(self): before = self.last_id self.send(*get_current_url) From 7346feaa9c9e2110e5b4a33925c69954e3b98235 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 21 Dec 2016 17:34:59 +0100 Subject: [PATCH 22/34] Bug 1323770 - Fix inappropriatelly skipped/disabled tests. r=maja_zf Commenting out test methods is not the way how we should mark tests as being skipped. The correct skip methods have to be used instead so that the final results also show the correct skip count. MozReview-Commit-ID: LKL4YQCyFko --HG-- extra : rebase_source : 4c50596a6477e2afa0926b5dd787466d2b6ce89a --- .../tests/unit/test_certificates.py | 8 +++--- .../tests/unit/test_element_state_chrome.py | 7 ++--- .../tests/unit/test_navigation.py | 14 +++++----- .../tests/unit/test_single_finger_desktop.py | 26 ++++++++++--------- .../tests/unit/test_text_chrome.py | 5 ++-- .../tests/unit/test_typing.py | 18 +++++-------- .../tests/unit/unit-tests.ini | 1 + 7 files changed, 39 insertions(+), 40 deletions(-) diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py index a19a433d3469..fb4c5c38b4d0 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_certificates.py @@ -4,10 +4,12 @@ from marionette_driver.errors import UnknownException -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip class TestCertificates(MarionetteTestCase): + + @skip("Bug 1325079") def test_block_insecure_sites(self): self.marionette.delete_session() self.marionette.start_session() @@ -17,16 +19,16 @@ class TestCertificates(MarionetteTestCase): with self.assertRaises(UnknownException): self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) + @skip("Bug 1325079") def test_accept_all_insecure(self): self.marionette.delete_session() self.marionette.start_session({"desiredCapability": {"acceptSslCerts": ["*"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) - """ + @skip("Bug 1325079") def test_accept_some_insecure(self): self.marionette.delete_session() self.marionette.start_session({"requiredCapabilities": {"acceptSslCerts": ["127.0.0.1"]}}) self.marionette.navigate(self.fixtures.where_is("test.html", on="https")) self.assertIn("https://", self.marionette.url) - """ \ No newline at end of file diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py index e2433dc6c6d7..01ed355c48a2 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py @@ -4,7 +4,7 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip class TestIsElementEnabledChrome(MarionetteTestCase): @@ -36,9 +36,7 @@ class TestIsElementEnabledChrome(MarionetteTestCase): self.assertTrue(rect['y'] > 0) -# Switched off in bug 896043, -# and to be turned on in bug 896046 -""" +@skip("Switched off in bug 896043, and to be turned on in bug 896046") class TestIsElementDisplayed(MarionetteTestCase): def test_isDisplayed(self): l = self.marionette.find_element(By.ID, "textInput") @@ -46,7 +44,6 @@ class TestIsElementDisplayed(MarionetteTestCase): self.marionette.execute_script("arguments[0].hidden = true;", [l]) self.assertFalse(l.is_displayed()) self.marionette.execute_script("arguments[0].hidden = false;", [l]) -""" class TestGetElementAttributeChrome(MarionetteTestCase): diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py index 3d2821b46e3f..fdb18814b7be 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py @@ -2,15 +2,17 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -from unittest import skip - import contextlib import time import urllib from marionette_driver import errors, By, Wait - -from marionette_harness import MarionetteTestCase, skip_if_mobile, WindowManagerMixin +from marionette_harness import ( + MarionetteTestCase, + skip, + skip_if_mobile, + WindowManagerMixin, +) def inline(doc): @@ -112,7 +114,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.marionette.switch_to_frame() self.assertTrue('test_iframe.html' in self.marionette.get_url()) - @skip_if_mobile # Bug 1323755 - Socket timeout + @skip_if_mobile("Bug 1323755 - Socket timeout") def test_invalid_protocol(self): with self.assertRaises(errors.MarionetteException): self.marionette.navigate("thisprotocoldoesnotexist://") @@ -150,7 +152,7 @@ class TestNavigate(WindowManagerMixin, MarionetteTestCase): self.assertTrue(self.marionette.execute_script( "return window.visited", sandbox=None)) - @skip_if_mobile # Fennec doesn't support other chrome windows + @skip_if_mobile("Fennec doesn't support other chrome windows") def test_about_blank_for_new_docshell(self): """ Bug 1312674 - Hang when loading about:blank for a new docshell.""" # Open a window to get a new docshell created for the first tab diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py index 019531efcfc3..8ac80c3c547c 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_single_finger_desktop.py @@ -6,9 +6,9 @@ import os import sys from marionette_driver.errors import MarionetteException -from marionette_driver.by import By +from marionette_driver import Actions, By -from marionette_harness import MarionetteTestCase +from marionette_harness import MarionetteTestCase, skip # add this directory to the path sys.path.append(os.path.dirname(__file__)) @@ -85,28 +85,30 @@ prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]); def test_wait_with_value(self): wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click") - """ - // Skipping due to Bug 1191066 + @skip("Bug 1191066") def test_context_menu(self): - context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click") + context_menu(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu", + "button1-mousemove-mousedown-contextmenu-mouseup-click") + @skip("Bug 1191066") def test_long_press_action(self): - long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") + long_press_action(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu-mouseup-click") + @skip("Bug 1191066") def test_long_press_on_xy_action(self): - long_press_on_xy_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click") - """ + long_press_on_xy_action(self.marionette, self.wait_for_condition, + "button1-mousemove-mousedown-contextmenu-mouseup-click") - """ - //Skipping due to Bug 865334 + @skip("Bug 865334") def test_long_press_fail(self): testAction = self.marionette.absolute_url("testAction.html") self.marionette.navigate(testAction) button = self.marionette.find_element(By.ID, "button1Copy") action = Actions(self.marionette) action.press(button).long_press(button, 5) - assertRaises(MarionetteException, action.perform) - """ + self.assertRaises(MarionetteException, action.perform) def test_chain(self): chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py index 065e10c9729b..e0b63de16f58 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py @@ -4,10 +4,10 @@ from marionette_driver.by import By -from marionette_harness import MarionetteTestCase, WindowManagerMixin +from marionette_harness import MarionetteTestCase, skip, WindowManagerMixin -''' Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046 +@skip("Disabled in bug 896043 and when working on Chrome code re-enable for bug 896046") class TestTextChrome(WindowManagerMixin, MarionetteTestCase): def setUp(self): @@ -42,4 +42,3 @@ class TestTextChrome(WindowManagerMixin, MarionetteTestCase): self.assertEqual("test", box.text) box.send_keys("at") self.assertEqual("attest", box.text) -''' diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py index bb7b2ff41c31..53d2bb4f1d67 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py @@ -8,7 +8,7 @@ from marionette_driver.by import By from marionette_driver.errors import ElementNotVisibleException from marionette_driver.keys import Keys -from marionette_harness import MarionetteTestCase, skip_if_mobile +from marionette_harness import MarionetteTestCase, skip, skip_if_mobile def inline(doc): @@ -32,7 +32,7 @@ class TestTypingChrome(TypingTestCase): super(TestTypingChrome, self).setUp() self.marionette.set_context("chrome") - @skip_if_mobile # Interacting with chrome elements not available for Fennec + @skip_if_mobile("Interacting with chrome elements not available for Fennec") def test_cut_and_paste_shortcuts(self): with self.marionette.using_context("content"): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -213,7 +213,7 @@ class TestTypingContent(TypingTestCase): # filled, we're a letter short here self.assertEqual(result.text, "I like chees") - @skip_if_mobile # Bug 1324752 - Arrow keys cannot be sent in Fennec + @skip_if_mobile("Bug 1324752 - Arrow keys cannot be sent in Fennec") def testShouldReportKeyCodeOfArrowKeysUpDownEvents(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -241,7 +241,7 @@ class TestTypingContent(TypingTestCase): # And leave no rubbish/printable keys in the "keyReporter" self.assertEqual("", element.get_property("value")) - """Disabled. Reenable in Bug 1068728 + @skip("Reenable in Bug 1068728") def testNumericShiftKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -252,7 +252,6 @@ class TestTypingContent(TypingTestCase): element.send_keys(numericShiftsEtc) self.assertEqual(numericShiftsEtc, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ def testLowerCaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") @@ -263,7 +262,7 @@ class TestTypingContent(TypingTestCase): element.send_keys(lowerAlphas) self.assertEqual(lowerAlphas, element.get_property("value")) - """Disabled. Reenable in Bug 1068735 + @skip("Reenable in Bug 1068735") def testUppercaseAlphaKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -274,9 +273,8 @@ class TestTypingContent(TypingTestCase): element.send_keys(upperAlphas) self.assertEqual(upperAlphas, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ - """Disabled. Reenable in Bug 1068726 + @skip("Reenable in Bug 1068726") def testAllPrintableKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -288,9 +286,8 @@ class TestTypingContent(TypingTestCase): self.assertTrue(allPrintable, element.get_property("value")) self.assertIn(" up: 16", result.text.strip()) - """ - """Disabled. Reenable in Bug 1068733 + @skip("Reenable in Bug 1068733") def testSpecialSpaceKeys(self): test_html = self.marionette.absolute_url("javascriptPage.html") self.marionette.navigate(test_html) @@ -298,7 +295,6 @@ class TestTypingContent(TypingTestCase): element = self.marionette.find_element(By.ID, "keyReporter") element.send_keys("abcd" + Keys.SPACE + "fgh" + Keys.SPACE + "ij") self.assertEqual("abcd fgh ij", element.get_property("value")) - """ def testShouldTypeAnInteger(self): test_html = self.marionette.absolute_url("javascriptPage.html") diff --git a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini index bb4fe03ececd..868cab610984 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini +++ b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini @@ -7,6 +7,7 @@ [test_expectedfail.py] expected = fail [test_import_script.py] +[test_certificates.py] [test_click.py] [test_click_chrome.py] skip-if = appname == 'fennec' From 7a4522824d41d76dc456d2fba92cc4a168b7877f Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 28 Dec 2016 17:50:44 +0800 Subject: [PATCH 23/34] Bug 1326023 - Make Element::GetBindingURL return a strong reference. r=smaug MozReview-Commit-ID: 5QI6UuvwDrE --HG-- extra : rebase_source : 42f7a481590020d4b7c30df7036cc922a5d9d275 --- dom/base/Element.cpp | 8 +++----- dom/base/Element.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 634ff3304ad2..cc8e61ccb637 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -448,7 +448,6 @@ Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult) nsCOMPtr shell = aDocument->GetShell(); if (!shell || GetPrimaryFrame() || !isXULorPluginElement) { *aResult = nullptr; - return true; } @@ -457,8 +456,7 @@ Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult) nsComputedDOMStyle::GetStyleContextForElementNoFlush(this, nullptr, shell); NS_ENSURE_TRUE(sc, false); - *aResult = sc->StyleDisplay()->mBinding; - + NS_IF_ADDREF(*aResult = sc->StyleDisplay()->mBinding); return true; } @@ -535,8 +533,8 @@ Element::WrapObject(JSContext *aCx, JS::Handle aGivenProto) // Make sure the style context goes away _before_ we load the binding // since that can destroy the relevant presshell. - mozilla::css::URLValue *bindingURL; - bool ok = GetBindingURL(doc, &bindingURL); + RefPtr bindingURL; + bool ok = GetBindingURL(doc, getter_AddRefs(bindingURL)); if (!ok) { dom::Throw(aCx, NS_ERROR_FAILURE); return nullptr; diff --git a/dom/base/Element.h b/dom/base/Element.h index 05e9044c67ba..b115a31f5aa7 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -387,7 +387,7 @@ public: } } - bool GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult); + bool GetBindingURL(nsIDocument* aDocument, css::URLValue **aResult); // The bdi element defaults to dir=auto if it has no dir attribute set. // Other elements will only have dir=auto if they have an explicit dir=auto, From 32471628fa0c91b79ebf13dff88c10dc591c7347 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Fri, 23 Dec 2016 16:00:46 +0000 Subject: [PATCH 24/34] Bug 1325623 - Fix most no-undef eslint issues in toolkit/components. r=mossop MozReview-Commit-ID: DYJa1uNVagw --HG-- extra : rebase_source : 11649d299fb6654bcadfb0e04bc0d8f19552529e --- testing/mochitest/mochitest.eslintrc.js | 3 ++ testing/xpcshell/xpcshell.eslintrc.js | 7 +++++ toolkit/.eslintrc.js | 1 + .../tests/unit/.eslintrc.js | 7 +++++ .../cookie/content/cookieAcceptDialog.js | 2 +- .../ctypes/tests/unit/test_finalizer.js | 7 ++--- .../ctypes/tests/unit/test_jsctypes.js | 28 +++++++++---------- .../extensions/test/mochitest/.eslintrc.js | 1 - toolkit/components/feeds/FeedProcessor.js | 2 +- toolkit/components/filepicker/nsFilePicker.js | 1 + .../formautofill/test/xpcshell/head.js | 4 ++- .../formautofill/test/xpcshell/loader.js | 2 ++ .../jsdownloads/src/DownloadCore.jsm | 1 + .../components/jsdownloads/src/Downloads.jsm | 1 + .../test/unit/common_test_Download.js | 3 ++ .../components/jsdownloads/test/unit/head.js | 1 + toolkit/components/mozintl/test/.eslintrc.js | 7 +++++ .../components/places/nsPlacesExpiration.js | 2 +- .../places/tests/bookmarks/head_bookmarks.js | 1 + .../test_1016953-renaming-uncompressed.js | 2 +- .../test_818584-discard-duplicate-backups.js | 2 +- .../test_818593-store-backup-metadata.js | 3 +- .../places/tests/bookmarks/test_bookmarks.js | 2 +- .../test_bookmarks_eraseEverything.js | 2 +- .../tests/bookmarks/test_bookmarks_remove.js | 2 +- .../tests/expiration/head_expiration.js | 1 + .../test_notifications_onDeleteURI.js | 2 +- .../test_notifications_onDeleteVisits.js | 2 +- .../places/tests/favicons/head_favicons.js | 1 + .../places/tests/history/head_history.js | 1 + .../places/tests/migration/head_migration.js | 1 + .../places/tests/queries/head_queries.js | 1 + .../unifiedcomplete/head_autocomplete.js | 1 + .../test_autocomplete_functional.js | 6 ++-- .../test_search_engine_current.js | 2 +- .../places/tests/unit/head_bookmarks.js | 1 + .../places/tests/unit/test_415757.js | 2 +- .../tests/unit/test_async_transactions.js | 2 +- .../places/tests/unit/test_bookmarks_html.js | 2 +- .../places/tests/unit/test_bookmarks_json.js | 2 +- .../test_bookmarks_restore_notification.js | 2 +- .../places/tests/unit/test_history_clear.js | 2 +- .../tests/unit/test_preventive_maintenance.js | 4 +-- .../places/tests/unit/test_sync_utils.js | 16 +++++------ .../printing/content/printPreviewBindings.xml | 9 +++--- .../components/printing/content/printUtils.js | 2 +- .../printing/content/printdialog.js | 3 +- .../prompts/test/test_bug619644.html | 1 + .../prompts/test/test_bug620145.html | 6 ++-- .../prompts/test/test_dom_prompts.html | 13 +++++---- .../test/test_subresources_prompts.html | 6 ++-- toolkit/components/reader/test/.eslintrc.js | 7 +++++ .../browser_privbrowsing_perwindowpb.js | 2 +- .../components/satchel/test/satchel_common.js | 2 ++ .../satchel/test/test_bug_511615.html | 3 +- .../satchel/test/test_bug_787624.html | 1 + .../test/test_datalist_with_caching.html | 3 ++ .../satchel/test/test_form_autocomplete.html | 3 +- .../test_form_autocomplete_with_list.html | 2 ++ .../satchel/test/test_form_submission.html | 6 ++-- .../test/test_form_submission_cap.html | 7 +++-- .../test/test_form_submission_cap2.html | 1 + .../satchel/test/test_popup_direction.html | 1 + .../satchel/test/test_popup_enter_event.html | 2 ++ .../satchel/test/unit/test_db_update_v4b.js | 2 +- .../satchel/test/unit/test_history_api.js | 10 +++---- .../search/tests/xpcshell/test_json_cache.js | 2 +- .../startup/tests/unit/head_startup.js | 4 ++- .../telemetry/datareporting-prefs.js | 2 ++ .../telemetry/healthreport-prefs.js | 2 ++ .../telemetry/tests/browser/.eslintrc.js | 7 +++++ .../tests/browser/browser_TelemetryGC.js | 2 ++ .../components/telemetry/tests/unit/head.js | 6 ++++ .../tests/unit/test_TelemetryCaptureStack.js | 2 +- .../tests/unit/test_TelemetryController.js | 2 +- .../tests/unit/test_TelemetryEvents.js | 2 +- .../tests/unit/test_TelemetrySession.js | 10 +++---- .../tests/unit/test_TelemetryStopwatch.js | 2 +- toolkit/components/thumbnails/test/head.js | 4 +++ .../components/tooltiptext/tests/.eslintrc.js | 7 +++++ 80 files changed, 196 insertions(+), 95 deletions(-) create mode 100644 toolkit/components/contextualidentity/tests/unit/.eslintrc.js create mode 100644 toolkit/components/mozintl/test/.eslintrc.js create mode 100644 toolkit/components/reader/test/.eslintrc.js create mode 100644 toolkit/components/telemetry/tests/browser/.eslintrc.js create mode 100644 toolkit/components/tooltiptext/tests/.eslintrc.js diff --git a/testing/mochitest/mochitest.eslintrc.js b/testing/mochitest/mochitest.eslintrc.js index 3532ecf7454c..137fbabf4720 100644 --- a/testing/mochitest/mochitest.eslintrc.js +++ b/testing/mochitest/mochitest.eslintrc.js @@ -12,6 +12,8 @@ module.exports = { // All globals made available in the test environment. "globals": { + // $ is defined in SimpleTest.js + "$": false, "add_task": false, "Assert": false, "EventUtils": false, @@ -25,6 +27,7 @@ module.exports = { "is": false, "isDeeply": false, "isnot": false, + "netscape": false, "ok": false, "promise": false, "registerCleanupFunction": false, diff --git a/testing/xpcshell/xpcshell.eslintrc.js b/testing/xpcshell/xpcshell.eslintrc.js index 4f8fc3d5185f..87b99af5aed4 100644 --- a/testing/xpcshell/xpcshell.eslintrc.js +++ b/testing/xpcshell/xpcshell.eslintrc.js @@ -8,10 +8,12 @@ module.exports = { // All globals made available in the test environment. "globals": { + "_TEST_FILE": false, "add_task": false, "add_test": false, "Assert": false, "deepEqual": false, + "do_await_remote_message": false, "do_check_eq": false, "do_check_false": false, "do_check_matches": false, @@ -30,6 +32,7 @@ module.exports = { "do_print": false, "do_register_cleanup": false, "do_report_unexpected_exception": false, + "do_send_remote_message": false, "do_test_finished": false, "do_test_pending": false, "do_throw": false, @@ -45,6 +48,7 @@ module.exports = { "notEqual": false, "notStrictEqual": false, "ok": false, + "runningInParent": false, "run_next_test": false, "run_test": false, "run_test_in_child": false, @@ -53,5 +57,8 @@ module.exports = { "todo": false, "todo_check_false": false, "todo_check_true": false, + // Firefox specific function. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval + "uneval": false, } }; diff --git a/toolkit/.eslintrc.js b/toolkit/.eslintrc.js index 5e23b48151fd..c79d8702d966 100644 --- a/toolkit/.eslintrc.js +++ b/toolkit/.eslintrc.js @@ -208,5 +208,6 @@ module.exports = { "dump": true, "openDialog": false, "sizeToContent": false, + "ChromeWorker": false, } }; diff --git a/toolkit/components/contextualidentity/tests/unit/.eslintrc.js b/toolkit/components/contextualidentity/tests/unit/.eslintrc.js new file mode 100644 index 000000000000..d35787cd2c49 --- /dev/null +++ b/toolkit/components/contextualidentity/tests/unit/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../../testing/xpcshell/xpcshell.eslintrc.js" + ] +}; diff --git a/toolkit/components/cookie/content/cookieAcceptDialog.js b/toolkit/components/cookie/content/cookieAcceptDialog.js index 0c605295b42a..41311fe8e751 100644 --- a/toolkit/components/cookie/content/cookieAcceptDialog.js +++ b/toolkit/components/cookie/content/cookieAcceptDialog.js @@ -92,7 +92,7 @@ function onload() // use childnodes here, the text can wrap for (var i = 1; i < messageParagraphs.length; i++) { var descriptionNode = document.createElement("description"); - text = document.createTextNode(messageParagraphs[i]); + let text = document.createTextNode(messageParagraphs[i]); descriptionNode.appendChild(text); messageParent.appendChild(descriptionNode); } diff --git a/toolkit/components/ctypes/tests/unit/test_finalizer.js b/toolkit/components/ctypes/tests/unit/test_finalizer.js index f580279fe304..d50437da6eb5 100644 --- a/toolkit/components/ctypes/tests/unit/test_finalizer.js +++ b/toolkit/components/ctypes/tests/unit/test_finalizer.js @@ -259,7 +259,7 @@ function run_test() // if we want to avoid tests overlapping. function test_cycles(size, tc) { // Now, restart this with unreferenced cycles - for (i = 0; i < size / 2; ++i) { + for (let i = 0; i < size / 2; ++i) { let a = { a: ctypes.CDataFinalizer(tc.acquire(i * 2), tc.release), b: { @@ -325,7 +325,7 @@ function test_result_dispose(size, tc, cleanup) { } do_check_eq(count_finalized(size, tc), 0); - for (i = 0; i < size; ++i) { + for (let i = 0; i < size; ++i) { let witness = ref[i].dispose(); ref[i] = null; if (!tc.released(i, witness)) { @@ -367,7 +367,7 @@ function test_executing_dispose(size, tc, cleanup) ref = []; // Re-acquire data and make sure that everything has been reinialized - for (i = 0; i < size; ++i) { + for (let i = 0; i < size; ++i) { tc.acquire(i); } @@ -449,4 +449,3 @@ function test_do_not_execute_finalizers_on_referenced_stuff(size, tc, cleanup) // Check that _nothing_ has been finalized do_check_eq(count_finalized(size, tc), 0); } - diff --git a/toolkit/components/ctypes/tests/unit/test_jsctypes.js b/toolkit/components/ctypes/tests/unit/test_jsctypes.js index ea8fcee70518..18861a185c3c 100644 --- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js +++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js @@ -10,8 +10,8 @@ try { } catch (e) { } -CTYPES_TEST_LIB = ctypes.libraryName("jsctypes-test"); -CTYPES_UNICODE_LIB = ctypes.libraryName("jsctyp\u00E8s-t\u00EB\u00DFt"); +const CTYPES_TEST_LIB = ctypes.libraryName("jsctypes-test"); +const CTYPES_UNICODE_LIB = ctypes.libraryName("jsctyp\u00E8s-t\u00EB\u00DFt"); function do_check_throws(f, type, stack) { @@ -72,9 +72,9 @@ function run_test() run_float_tests(library, ctypes.double, "double", 8); // Test the wrapped integer types. - s64limits = ["-9223372036854775808", "9223372036854775807", - "-9223372036854775809", "9223372036854775808"]; - u64limits = ["0", "18446744073709551615", "-1", "18446744073709551616"]; + const s64limits = ["-9223372036854775808", "9223372036854775807", + "-9223372036854775809", "9223372036854775808"]; + const u64limits = ["0", "18446744073709551615", "-1", "18446744073709551616"]; run_wrapped_integer_tests(library, ctypes.int64_t, "int64_t", 8, true, ctypes.Int64, "ctypes.Int64", s64limits); @@ -85,8 +85,8 @@ function run_test() run_wrapped_integer_tests(library, ctypes.unsigned_long_long, "unsigned_long_long", 8, false, ctypes.UInt64, "ctypes.UInt64", u64limits); - s32limits = [-0x80000000, 0x7fffffff, -0x80000001, 0x80000000]; - u32limits = [0, 0xffffffff, -1, 0x100000000]; + const s32limits = [-0x80000000, 0x7fffffff, -0x80000001, 0x80000000]; + const u32limits = [0, 0xffffffff, -1, 0x100000000]; let slimits, ulimits; if (ctypes.long.size == 8) { @@ -1771,7 +1771,7 @@ function run_PointerType_tests() { " can be converted to " + item_type + " array"); // Convert ArrayBuffer to array of the right size and check contents - c_array = array_type(c_arraybuffer); + let c_array = array_type(c_arraybuffer); for (let k = 0; k < number_of_items; ++k) { do_check_eq(c_array[k], view[k]); } @@ -2690,14 +2690,14 @@ function run_variadic_tests(library) { do_check_eq(result.value, 3 + 5 + 7 + 11); - result = ctypes.int32_t.array(3)([1, 1, 1]), - v1 = ctypes.int32_t.array(4)([1, 2, 3, 5]), - v2 = ctypes.int32_t.array(3)([7, 11, 13]), - vector_add_va = library.declare("test_vector_add_va_cdecl", + result = ctypes.int32_t.array(3)([1, 1, 1]); + let v1 = ctypes.int32_t.array(4)([1, 2, 3, 5]); + let v2 = ctypes.int32_t.array(3)([7, 11, 13]); + let vector_add_va = library.declare("test_vector_add_va_cdecl", ctypes.default_abi, ctypes.int32_t.ptr, - ctypes.uint8_t, ctypes.uint8_t, "..."), + ctypes.uint8_t, ctypes.uint8_t, "..."); // Note that vector_add_va zeroes out result first. - vec_sum = vector_add_va(2, 3, result, v1, v2); + let vec_sum = vector_add_va(2, 3, result, v1, v2); do_check_eq(vec_sum.contents, 8); do_check_eq(result[0], 8); do_check_eq(result[1], 13); diff --git a/toolkit/components/extensions/test/mochitest/.eslintrc.js b/toolkit/components/extensions/test/mochitest/.eslintrc.js index 53938410b75e..30d41f0b23ee 100644 --- a/toolkit/components/extensions/test/mochitest/.eslintrc.js +++ b/toolkit/components/extensions/test/mochitest/.eslintrc.js @@ -8,7 +8,6 @@ module.exports = { // eslint-disable-line no-undef }, "globals": { - "ChromeWorker": false, "onmessage": true, "sendAsyncMessage": false, diff --git a/toolkit/components/feeds/FeedProcessor.js b/toolkit/components/feeds/FeedProcessor.js index 682da785f3d6..305d90fa40d6 100644 --- a/toolkit/components/feeds/FeedProcessor.js +++ b/toolkit/components/feeds/FeedProcessor.js @@ -155,7 +155,7 @@ function bagHasKey(bag, key) { function makePropGetter(key) { return function FeedPropGetter(bag) { try { - return value = bag.getProperty(key); + return bag.getProperty(key); } catch (e) { } diff --git a/toolkit/components/filepicker/nsFilePicker.js b/toolkit/components/filepicker/nsFilePicker.js index 7823a8d4476b..97bb78e7631f 100644 --- a/toolkit/components/filepicker/nsFilePicker.js +++ b/toolkit/components/filepicker/nsFilePicker.js @@ -20,6 +20,7 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); const DEBUG = false; /* set to true to enable debug messages */ +var debug; const LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1"; const APPSHELL_SERV_CONTRACTID = "@mozilla.org/appshell/appShellService;1"; diff --git a/toolkit/components/formautofill/test/xpcshell/head.js b/toolkit/components/formautofill/test/xpcshell/head.js index 1cee023f2179..082b802f0dde 100644 --- a/toolkit/components/formautofill/test/xpcshell/head.js +++ b/toolkit/components/formautofill/test/xpcshell/head.js @@ -4,9 +4,11 @@ /* * Initialization specific to Form Autofill xpcshell tests. * - * This file is loaded by "loader.js". + * This file is loaded alongside loader.js. */ +/* import-globals-from loader.js */ + "use strict"; // The testing framework is fully initialized at this point, you can add diff --git a/toolkit/components/formautofill/test/xpcshell/loader.js b/toolkit/components/formautofill/test/xpcshell/loader.js index 97a789b3eaa5..955533d4cbf5 100644 --- a/toolkit/components/formautofill/test/xpcshell/loader.js +++ b/toolkit/components/formautofill/test/xpcshell/loader.js @@ -17,6 +17,7 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); Cu.import("resource://gre/modules/Services.jsm", this); +/* import-globals-from ../loader_common.js */ Services.scriptloader.loadSubScript( Services.io.newFileURI(do_get_file("loader_common.js")).spec, this); @@ -33,6 +34,7 @@ var add_task_in_parent_process = add_task; var add_task_in_child_process = function() {}; var add_task_in_both_processes = add_task; +/* import-globals-from ../head_common.js */ Services.scriptloader.loadSubScript( Services.io.newFileURI(do_get_file("head_common.js")).spec, this); diff --git a/toolkit/components/jsdownloads/src/DownloadCore.jsm b/toolkit/components/jsdownloads/src/DownloadCore.jsm index 53126fb613be..043f20cc18e9 100644 --- a/toolkit/components/jsdownloads/src/DownloadCore.jsm +++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm @@ -88,6 +88,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gPrintSettingsService", "@mozilla.org/gfx/printsettings-service;1", Ci.nsIPrintSettingsService); +/* global DownloadIntegration */ Integration.downloads.defineModuleGetter(this, "DownloadIntegration", "resource://gre/modules/DownloadIntegration.jsm"); diff --git a/toolkit/components/jsdownloads/src/Downloads.jsm b/toolkit/components/jsdownloads/src/Downloads.jsm index 775416eabca9..174f807a5977 100644 --- a/toolkit/components/jsdownloads/src/Downloads.jsm +++ b/toolkit/components/jsdownloads/src/Downloads.jsm @@ -38,6 +38,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise", XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); +/* global DownloadIntegration */ Integration.downloads.defineModuleGetter(this, "DownloadIntegration", "resource://gre/modules/DownloadIntegration.jsm"); diff --git a/toolkit/components/jsdownloads/test/unit/common_test_Download.js b/toolkit/components/jsdownloads/test/unit/common_test_Download.js index fad23071e39d..3310eef05a19 100644 --- a/toolkit/components/jsdownloads/test/unit/common_test_Download.js +++ b/toolkit/components/jsdownloads/test/unit/common_test_Download.js @@ -9,6 +9,9 @@ * the "copy" and "legacy" saver implementations. */ +/* import-globals-from head.js */ +/* global gUseLegacySaver */ + "use strict"; // Globals diff --git a/toolkit/components/jsdownloads/test/unit/head.js b/toolkit/components/jsdownloads/test/unit/head.js index b9d5c0c60575..42fa2bb96f87 100644 --- a/toolkit/components/jsdownloads/test/unit/head.js +++ b/toolkit/components/jsdownloads/test/unit/head.js @@ -48,6 +48,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gExternalHelperAppService", "@mozilla.org/uriloader/external-helper-app-service;1", Ci.nsIExternalHelperAppService); +/* global DownloadIntegration */ Integration.downloads.defineModuleGetter(this, "DownloadIntegration", "resource://gre/modules/DownloadIntegration.jsm"); diff --git a/toolkit/components/mozintl/test/.eslintrc.js b/toolkit/components/mozintl/test/.eslintrc.js new file mode 100644 index 000000000000..fee088c17903 --- /dev/null +++ b/toolkit/components/mozintl/test/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../testing/xpcshell/xpcshell.eslintrc.js" + ] +}; diff --git a/toolkit/components/places/nsPlacesExpiration.js b/toolkit/components/places/nsPlacesExpiration.js index 4b05f8b73359..44e945819d3a 100644 --- a/toolkit/components/places/nsPlacesExpiration.js +++ b/toolkit/components/places/nsPlacesExpiration.js @@ -833,7 +833,7 @@ nsPlacesExpiration.prototype = { memSizeBytes = Services.sysinfo.getProperty("memsize"); } catch (ex) {} if (memSizeBytes <= 0) { - memsize = MEMSIZE_FALLBACK_BYTES; + memSizeBytes = MEMSIZE_FALLBACK_BYTES; } let diskAvailableBytes = DISKSIZE_FALLBACK_BYTES; diff --git a/toolkit/components/places/tests/bookmarks/head_bookmarks.js b/toolkit/components/places/tests/bookmarks/head_bookmarks.js index 842a66b313c1..042f75a7238f 100644 --- a/toolkit/components/places/tests/bookmarks/head_bookmarks.js +++ b/toolkit/components/places/tests/bookmarks/head_bookmarks.js @@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/bookmarks/test_1016953-renaming-uncompressed.js b/toolkit/components/places/tests/bookmarks/test_1016953-renaming-uncompressed.js index b6982987b520..610bc6bbebea 100644 --- a/toolkit/components/places/tests/bookmarks/test_1016953-renaming-uncompressed.js +++ b/toolkit/components/places/tests/bookmarks/test_1016953-renaming-uncompressed.js @@ -58,7 +58,7 @@ add_task(function* test_same_date_diff_hash() { let backupFile = OS.Path.join(backupFolder, filename); yield OS.File.move(tempPath, backupFile); yield PlacesBackups.create(); // Force compressed backup - mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup(); + let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup(); // Decode lz4 compressed file to json and check if json is valid let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. diff --git a/toolkit/components/places/tests/bookmarks/test_818584-discard-duplicate-backups.js b/toolkit/components/places/tests/bookmarks/test_818584-discard-duplicate-backups.js index c88323478f3d..68b3b9b95844 100644 --- a/toolkit/components/places/tests/bookmarks/test_818584-discard-duplicate-backups.js +++ b/toolkit/components/places/tests/bookmarks/test_818584-discard-duplicate-backups.js @@ -46,7 +46,7 @@ add_task(function*() { // backup will replace the existing one. yield PlacesBackups.create(undefined, true); do_check_eq(backupFiles.length, 1); - recentBackup = yield PlacesBackups.getMostRecentBackup(); + let recentBackup = yield PlacesBackups.getMostRecentBackup(); do_check_neq(recentBackup, OS.Path.join(backupFolder, oldBackupName)); matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex); do_check_eq(matches[1], PlacesBackups.toISODateString(new Date())); diff --git a/toolkit/components/places/tests/bookmarks/test_818593-store-backup-metadata.js b/toolkit/components/places/tests/bookmarks/test_818593-store-backup-metadata.js index 4ea07fb3935e..28713b615fb6 100644 --- a/toolkit/components/places/tests/bookmarks/test_818593-store-backup-metadata.js +++ b/toolkit/components/places/tests/bookmarks/test_818593-store-backup-metadata.js @@ -43,7 +43,7 @@ add_task(function* test_saveBookmarksToJSONFile_and_create() yield PlacesBackups.create(); do_check_eq((yield PlacesBackups.getBackupFiles()).length, 1); - mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup(); + let mostRecentBackupFile = yield PlacesBackups.getMostRecentBackup(); do_check_neq(mostRecentBackupFile, null); matches = OS.Path.basename(recentBackup).match(PlacesBackups.filenamesRegex); do_check_eq(matches[2], nodeCount); @@ -54,4 +54,3 @@ add_task(function* test_saveBookmarksToJSONFile_and_create() yield PlacesBackups.create(0); PlacesUtils.bookmarks.removeItem(bookmarkId); }); - diff --git a/toolkit/components/places/tests/bookmarks/test_bookmarks.js b/toolkit/components/places/tests/bookmarks/test_bookmarks.js index bc4734affc95..d8b51716489a 100644 --- a/toolkit/components/places/tests/bookmarks/test_bookmarks.js +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks.js @@ -357,7 +357,7 @@ add_task(function* test_bookmarks() { bs.removeFolderChildren(tmpFolder); // 4) confirm that folder has 0 children try { - result = hs.executeQuery(query, options); + let result = hs.executeQuery(query, options); let rootNode = result.root; rootNode.containerOpen = true; do_check_eq(rootNode.childCount, 0); diff --git a/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js b/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js index e8414359b5a4..e298eb829c83 100644 --- a/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js @@ -68,7 +68,7 @@ add_task(function* test_eraseEverything() { // Bug 1306445 will eventually remove the mobile root anno. Assert.equal(annoAttrs.length, 1); Assert.equal(annoAttrs[0].getResultByName("name"), PlacesUtils.MOBILE_ROOT_ANNO); - let annos = rows = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`); + let annos = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`); Assert.equal(annos.length, 1); Assert.equal(annos[0].getResultByName("item_id"), PlacesUtils.mobileFolderId); Assert.equal(annos[0].getResultByName("anno_attribute_id"), annoAttrs[0].getResultByName("id")); diff --git a/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js b/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js index 19085a2823ca..3d3dc8682d33 100644 --- a/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js @@ -103,7 +103,7 @@ add_task(function* remove_bookmark_orphans() { // Bug 1306445 will eventually remove the mobile root anno. Assert.equal(annoAttrs.length, 1); Assert.equal(annoAttrs[0].getResultByName("name"), PlacesUtils.MOBILE_ROOT_ANNO); - let annos = rows = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`); + let annos = yield conn.execute(`SELECT item_id, anno_attribute_id FROM moz_items_annos`); Assert.equal(annos.length, 1); Assert.equal(annos[0].getResultByName("item_id"), PlacesUtils.mobileFolderId); Assert.equal(annos[0].getResultByName("anno_attribute_id"), annoAttrs[0].getResultByName("id")); diff --git a/toolkit/components/places/tests/expiration/head_expiration.js b/toolkit/components/places/tests/expiration/head_expiration.js index 2be4af307ce4..3eb7bf0477bd 100644 --- a/toolkit/components/places/tests/expiration/head_expiration.js +++ b/toolkit/components/places/tests/expiration/head_expiration.js @@ -13,6 +13,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/expiration/test_notifications_onDeleteURI.js b/toolkit/components/places/tests/expiration/test_notifications_onDeleteURI.js index d51f3b4f37fb..0a32e9caab7f 100644 --- a/toolkit/components/places/tests/expiration/test_notifications_onDeleteURI.js +++ b/toolkit/components/places/tests/expiration/test_notifications_onDeleteURI.js @@ -77,7 +77,7 @@ add_task(function* test_notifications_onDeleteURI() { } // Observe history. - historyObserver = { + let historyObserver = { onBeginUpdateBatch: function PEX_onBeginUpdateBatch() {}, onEndUpdateBatch: function PEX_onEndUpdateBatch() {}, onClearHistory: function() {}, diff --git a/toolkit/components/places/tests/expiration/test_notifications_onDeleteVisits.js b/toolkit/components/places/tests/expiration/test_notifications_onDeleteVisits.js index 30065a126ef6..af70e3f22da0 100644 --- a/toolkit/components/places/tests/expiration/test_notifications_onDeleteVisits.js +++ b/toolkit/components/places/tests/expiration/test_notifications_onDeleteVisits.js @@ -102,7 +102,7 @@ add_task(function* test_notifications_onDeleteVisits() { } // Observe history. - historyObserver = { + let historyObserver = { onBeginUpdateBatch: function PEX_onBeginUpdateBatch() {}, onEndUpdateBatch: function PEX_onEndUpdateBatch() {}, onClearHistory: function() {}, diff --git a/toolkit/components/places/tests/favicons/head_favicons.js b/toolkit/components/places/tests/favicons/head_favicons.js index ed919482df5a..f8c3bf9e0142 100644 --- a/toolkit/components/places/tests/favicons/head_favicons.js +++ b/toolkit/components/places/tests/favicons/head_favicons.js @@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/history/head_history.js b/toolkit/components/places/tests/history/head_history.js index 870802dc1da5..3f51c9eaa60c 100644 --- a/toolkit/components/places/tests/history/head_history.js +++ b/toolkit/components/places/tests/history/head_history.js @@ -13,6 +13,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/migration/head_migration.js b/toolkit/components/places/tests/migration/head_migration.js index 1ebecd4c0fb8..83d0bf96293c 100644 --- a/toolkit/components/places/tests/migration/head_migration.js +++ b/toolkit/components/places/tests/migration/head_migration.js @@ -9,6 +9,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/queries/head_queries.js b/toolkit/components/places/tests/queries/head_queries.js index 7d6bc833223f..a3187f509673 100644 --- a/toolkit/components/places/tests/queries/head_queries.js +++ b/toolkit/components/places/tests/queries/head_queries.js @@ -13,6 +13,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js b/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js index ff849a4ea9ef..36955f3c8cff 100644 --- a/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js +++ b/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js @@ -14,6 +14,7 @@ Cu.import("resource://testing-common/httpd.js"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js index cd2dfdb17a26..bbd39c1b8372 100644 --- a/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js +++ b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js @@ -153,19 +153,19 @@ add_task(function* test_complete_fragment() { add_task(function* test_autocomplete_enabled_pref() { Services.prefs.setBoolPref(PREF_AUTOCOMPLETE_ENABLED, false); let types = ["history", "bookmark", "openpage"]; - for (type of types) { + for (let type of types) { do_check_eq(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false, "suggest." + type + "pref should be false"); } Services.prefs.setBoolPref(PREF_AUTOCOMPLETE_ENABLED, true); - for (type of types) { + for (let type of types) { do_check_eq(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), true, "suggest." + type + "pref should be true"); } // Clear prefs. Services.prefs.clearUserPref(PREF_AUTOCOMPLETE_ENABLED); - for (type of types) { + for (let type of types) { Services.prefs.clearUserPref("browser.urlbar.suggest." + type); } }); diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js index b41d9884bd81..767acb609501 100644 --- a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js +++ b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js @@ -32,7 +32,7 @@ add_task(function*() { do_print("search engine, after current engine has changed"); Services.search.addEngineWithDetails("MozSearch2", "", "", "", "GET", "http://s.example.com/search2"); - engine = Services.search.getEngineByName("MozSearch2"); + let engine = Services.search.getEngineByName("MozSearch2"); notEqual(Services.search.currentEngine, engine, "New engine shouldn't be the current engine yet"); Services.search.currentEngine = engine; yield check_autocomplete({ diff --git a/toolkit/components/places/tests/unit/head_bookmarks.js b/toolkit/components/places/tests/unit/head_bookmarks.js index 842a66b313c1..042f75a7238f 100644 --- a/toolkit/components/places/tests/unit/head_bookmarks.js +++ b/toolkit/components/places/tests/unit/head_bookmarks.js @@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // Import common head. { + /* import-globals-from ../head_common.js */ let commonFile = do_get_file("../head_common.js", false); let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); diff --git a/toolkit/components/places/tests/unit/test_415757.js b/toolkit/components/places/tests/unit/test_415757.js index afd396183afa..16bd888e6313 100644 --- a/toolkit/components/places/tests/unit/test_415757.js +++ b/toolkit/components/places/tests/unit/test_415757.js @@ -86,7 +86,7 @@ add_task(function* test_execute() // check that annotation on the removed item does not exists try { - PlacesUtils.annotations.getPageAnnotation(testAnnoDeletedURI, testAnnoName); + PlacesUtils.annotations.getPageAnnotation(testAnnoDeletedURI, testAnnoDeletedName); do_throw("fetching page-annotation that doesn't exist, should've thrown"); } catch (ex) {} diff --git a/toolkit/components/places/tests/unit/test_async_transactions.js b/toolkit/components/places/tests/unit/test_async_transactions.js index a05ff82614c8..b1a131364f2f 100644 --- a/toolkit/components/places/tests/unit/test_async_transactions.js +++ b/toolkit/components/places/tests/unit/test_async_transactions.js @@ -1471,7 +1471,7 @@ add_task(function* test_livemark_txns() { add_task(function* test_copy() { function* duplicate_and_test(aOriginalGuid) { let txn = PT.Copy({ guid: aOriginalGuid, newParentGuid: rootGuid }); - yield duplicateGuid = yield txn.transact(); + let duplicateGuid = yield txn.transact(); let originalInfo = yield PlacesUtils.promiseBookmarksTree(aOriginalGuid); let duplicateInfo = yield PlacesUtils.promiseBookmarksTree(duplicateGuid); yield ensureEqualBookmarksTrees(originalInfo, duplicateInfo, false); diff --git a/toolkit/components/places/tests/unit/test_bookmarks_html.js b/toolkit/components/places/tests/unit/test_bookmarks_html.js index f5831b3a1b89..c9876a133607 100644 --- a/toolkit/components/places/tests/unit/test_bookmarks_html.js +++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js @@ -304,7 +304,7 @@ function* checkItem(aExpected, aNode) let id = aNode.itemId; return Task.spawn(function* () { - for (prop in aExpected) { + for (let prop in aExpected) { switch (prop) { case "type": do_check_eq(aNode.type, aExpected.type); diff --git a/toolkit/components/places/tests/unit/test_bookmarks_json.js b/toolkit/components/places/tests/unit/test_bookmarks_json.js index 98a623c6ca75..164f43d06eeb 100644 --- a/toolkit/components/places/tests/unit/test_bookmarks_json.js +++ b/toolkit/components/places/tests/unit/test_bookmarks_json.js @@ -158,7 +158,7 @@ function* checkItem(aExpected, aNode) { let id = aNode.itemId; return Task.spawn(function* () { - for (prop in aExpected) { + for (let prop in aExpected) { switch (prop) { case "type": do_check_eq(aNode.type, aExpected.type); diff --git a/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js b/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js index 97b5a4e24ff4..76c2c9355a55 100644 --- a/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js +++ b/toolkit/components/places/tests/unit/test_bookmarks_restore_notification.js @@ -116,7 +116,7 @@ function* checkObservers(expectPromises, expectedData) { // Make sure folder ID is what is expected. For importing HTML into a // folder, this will be an integer, otherwise null. if (resultSubject) { - Assert.equal(aSubject.QueryInterface(Ci.nsISupportsPRInt64).data, + Assert.equal(resultSubject.QueryInterface(Ci.nsISupportsPRInt64).data, expectedData.folderId); } else { Assert.equal(expectedData.folderId, null); diff --git a/toolkit/components/places/tests/unit/test_history_clear.js b/toolkit/components/places/tests/unit/test_history_clear.js index 56d34994f7ab..e493a8298c23 100644 --- a/toolkit/components/places/tests/unit/test_history_clear.js +++ b/toolkit/components/places/tests/unit/test_history_clear.js @@ -106,7 +106,7 @@ add_task(function* test_history_clear() // Check that frecency for not cleared items (bookmarks) has been converted // to -1. - stmt = mDBConn.createStatement( + let stmt = mDBConn.createStatement( "SELECT h.id FROM moz_places h WHERE h.frecency > 0 "); do_check_false(stmt.executeStep()); stmt.finalize(); diff --git a/toolkit/components/places/tests/unit/test_preventive_maintenance.js b/toolkit/components/places/tests/unit/test_preventive_maintenance.js index f406423989eb..9e9295e3eefb 100644 --- a/toolkit/components/places/tests/unit/test_preventive_maintenance.js +++ b/toolkit/components/places/tests/unit/test_preventive_maintenance.js @@ -834,7 +834,7 @@ tests.push({ // Add a place to ensure place_id = 1 is valid this._placeId = addPlace(); // Add a valid visit and an invalid one - stmt = mDBConn.createStatement("INSERT INTO moz_historyvisits(place_id) VALUES (:place_id)"); + let stmt = mDBConn.createStatement("INSERT INTO moz_historyvisits(place_id) VALUES (:place_id)"); stmt.params["place_id"] = this._placeId; stmt.execute(); stmt.reset(); @@ -960,7 +960,7 @@ tests.push({ // Insert a bookmark this._bookmarkId = addBookmark(this._placeId); // Add a used attribute. - stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); + let stmt = mDBConn.createStatement("INSERT INTO moz_anno_attributes (name) VALUES (:anno)"); stmt.params['anno'] = this._usedItemAttribute; stmt.execute(); stmt.finalize(); diff --git a/toolkit/components/places/tests/unit/test_sync_utils.js b/toolkit/components/places/tests/unit/test_sync_utils.js index 58f6b9dbc9db..df20cceae829 100644 --- a/toolkit/components/places/tests/unit/test_sync_utils.js +++ b/toolkit/components/places/tests/unit/test_sync_utils.js @@ -257,11 +257,11 @@ add_task(function* test_dedupe() { url: "http://getthunderbird.com", }); - yield rejects( + yield Assert.rejects( PlacesSyncUtils.bookmarks.dedupe(makeGuid(), makeGuid(), makeGuid()), "Should reject attempts to de-dupe nonexistent items" ); - yield rejects(PlacesSyncUtils.bookmarks.dedupe("menu", makeGuid(), "places"), + yield Assert.rejects(PlacesSyncUtils.bookmarks.dedupe("menu", makeGuid(), "places"), "Should reject attempts to de-dupe local roots"); do_print("De-dupe with same remote parent"); @@ -282,7 +282,7 @@ add_task(function* test_dedupe() { ok(!(yield PlacesUtils.bookmarks.fetch(mozBmk.syncId)), "Bookmark with old local sync ID should not exist"); - yield rejects(PlacesUtils.promiseItemId(mozBmk.syncId), + yield Assert.rejects(PlacesUtils.promiseItemId(mozBmk.syncId), "Should invalidate GUID cache entry for old local sync ID"); let newMozBmk = yield PlacesUtils.bookmarks.fetch(newRemoteSyncId); @@ -701,7 +701,7 @@ add_task(function* test_update_move_root() { } do_print("Try reparenting root"); - yield rejects(PlacesSyncUtils.bookmarks.update({ + yield Assert.rejects(PlacesSyncUtils.bookmarks.update({ syncId: "menu", parentSyncId: "toolbar", })); @@ -871,7 +871,7 @@ add_task(function* test_update_livemark() { // Since we're reinserting, we need to pass all properties required // for a new livemark. `update` won't merge the old and new ones. - yield rejects(PlacesSyncUtils.bookmarks.update({ + yield Assert.rejects(PlacesSyncUtils.bookmarks.update({ syncId: livemark.guid, feed: site + "/feed/2", }), "Reinserting livemark with changed feed URL requires full record"); @@ -897,7 +897,7 @@ add_task(function* test_update_livemark() { ok(livemark.feedURI.equals(feedURI), "Livemark feed URI should match"); ok(!livemark.siteURI, "Livemark should not have site URI"); - yield rejects(PlacesSyncUtils.bookmarks.update({ + yield Assert.rejects(PlacesSyncUtils.bookmarks.update({ syncId: livemark.guid, site, }), "Reinserting livemark with new site URL requires full record"); @@ -928,7 +928,7 @@ add_task(function* test_update_livemark() { index: PlacesUtils.bookmarks.DEFAULT_INDEX, }); - yield rejects(PlacesSyncUtils.bookmarks.update({ + yield Assert.rejects(PlacesSyncUtils.bookmarks.update({ syncId: livemark.guid, site: null, }), "Reinserting livemark witout site URL requires full record"); @@ -956,7 +956,7 @@ add_task(function* test_update_livemark() { index: PlacesUtils.bookmarks.DEFAULT_INDEX, }); - yield rejects(PlacesSyncUtils.bookmarks.update({ + yield Assert.rejects(PlacesSyncUtils.bookmarks.update({ syncId: livemark.guid, site: site + "/new", }), "Reinserting livemark with changed site URL requires full record"); diff --git a/toolkit/components/printing/content/printPreviewBindings.xml b/toolkit/components/printing/content/printPreviewBindings.xml index ee699de24801..6b279d5cca42 100644 --- a/toolkit/components/printing/content/printPreviewBindings.xml +++ b/toolkit/components/printing/content/printPreviewBindings.xml @@ -15,7 +15,7 @@ xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - @@ -52,7 +52,7 @@ - @@ -68,7 +68,7 @@ - @@ -81,7 +81,7 @@ accesskey="&portrait.accesskey;" type="radio" group="orient" class="toolbar-portrait-page tabbable" oncommand="parentNode.parentNode.orient('portrait');"/> - @@ -172,6 +172,7 @@ Mozilla Bug 619644
   
+  
   
   
 
@@ -10,7 +10,7 @@