From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/client/webaudioeditor/test/.eslintrc.js | 6 + devtools/client/webaudioeditor/test/440hz_sine.ogg | Bin 0 -> 11822 bytes devtools/client/webaudioeditor/test/browser.ini | 77 +++ ...browser_audionode-actor-add-automation-event.js | 52 ++ .../test/browser_audionode-actor-bypass.js | 36 ++ .../test/browser_audionode-actor-bypassable.js | 38 ++ ...owser_audionode-actor-connectnode-disconnect.js | 39 ++ .../test/browser_audionode-actor-connectparam.js | 32 ++ ...owser_audionode-actor-get-automation-data-01.js | 53 ++ ...owser_audionode-actor-get-automation-data-02.js | 42 ++ ...owser_audionode-actor-get-automation-data-03.js | 34 ++ .../browser_audionode-actor-get-param-flags.js | 47 ++ .../test/browser_audionode-actor-get-params-01.js | 49 ++ .../test/browser_audionode-actor-get-params-02.js | 52 ++ .../test/browser_audionode-actor-get-set-param.js | 47 ++ .../test/browser_audionode-actor-source.js | 27 + .../test/browser_audionode-actor-type.js | 28 ++ .../webaudioeditor/test/browser_callwatcher-01.js | 26 + .../webaudioeditor/test/browser_callwatcher-02.js | 44 ++ .../test/browser_wa_automation-view-01.js | 57 +++ .../test/browser_wa_automation-view-02.js | 55 ++ .../test/browser_wa_controller-01.js | 28 ++ .../test/browser_wa_destroy-node-01.js | 59 +++ .../webaudioeditor/test/browser_wa_first-run.js | 49 ++ .../webaudioeditor/test/browser_wa_graph-click.js | 49 ++ .../test/browser_wa_graph-markers.js | 61 +++ .../test/browser_wa_graph-render-01.js | 44 ++ .../test/browser_wa_graph-render-02.js | 48 ++ .../test/browser_wa_graph-render-03.js | 34 ++ .../test/browser_wa_graph-render-04.js | 37 ++ .../test/browser_wa_graph-render-05.js | 28 ++ .../test/browser_wa_graph-render-06.js | 25 + .../test/browser_wa_graph-selected.js | 49 ++ .../webaudioeditor/test/browser_wa_graph-zoom.js | 43 ++ .../test/browser_wa_inspector-bypass-01.js | 61 +++ .../test/browser_wa_inspector-toggle.js | 60 +++ .../test/browser_wa_inspector-width.js | 57 +++ .../webaudioeditor/test/browser_wa_inspector.js | 46 ++ .../webaudioeditor/test/browser_wa_navigate.js | 44 ++ .../test/browser_wa_properties-view-edit-01.js | 65 +++ .../test/browser_wa_properties-view-edit-02.js | 44 ++ .../test/browser_wa_properties-view-media-nodes.js | 76 +++ .../browser_wa_properties-view-params-objects.js | 46 ++ .../test/browser_wa_properties-view-params.js | 43 ++ .../test/browser_wa_properties-view.js | 42 ++ .../webaudioeditor/test/browser_wa_reset-01.js | 67 +++ .../webaudioeditor/test/browser_wa_reset-02.js | 37 ++ .../webaudioeditor/test/browser_wa_reset-03.js | 48 ++ .../webaudioeditor/test/browser_wa_reset-04.js | 66 +++ .../browser_webaudio-actor-automation-event.js | 52 ++ .../test/browser_webaudio-actor-connect-param.js | 25 + .../test/browser_webaudio-actor-destroy-node.js | 41 ++ .../test/browser_webaudio-actor-simple.js | 30 ++ .../client/webaudioeditor/test/doc_automation.html | 30 ++ .../webaudioeditor/test/doc_buffer-and-array.html | 56 +++ .../webaudioeditor/test/doc_bug_1112378.html | 57 +++ .../webaudioeditor/test/doc_bug_1125817.html | 23 + .../webaudioeditor/test/doc_bug_1130901.html | 22 + .../webaudioeditor/test/doc_bug_1141261.html | 25 + .../webaudioeditor/test/doc_complex-context.html | 44 ++ .../test/doc_connect-multi-param.html | 32 ++ .../webaudioeditor/test/doc_connect-param.html | 28 ++ .../webaudioeditor/test/doc_destroy-nodes.html | 36 ++ .../webaudioeditor/test/doc_iframe-context.html | 14 + .../test/doc_media-node-creation.html | 29 ++ .../webaudioeditor/test/doc_simple-context.html | 33 ++ .../test/doc_simple-node-creation.html | 28 ++ devtools/client/webaudioeditor/test/head.js | 556 +++++++++++++++++++++ 68 files changed, 3358 insertions(+) create mode 100644 devtools/client/webaudioeditor/test/.eslintrc.js create mode 100644 devtools/client/webaudioeditor/test/440hz_sine.ogg create mode 100644 devtools/client/webaudioeditor/test/browser.ini create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-add-automation-event.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-bypass.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-bypassable.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-connectnode-disconnect.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-connectparam.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-03.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-param-flags.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-get-set-param.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-source.js create mode 100644 devtools/client/webaudioeditor/test/browser_audionode-actor-type.js create mode 100644 devtools/client/webaudioeditor/test/browser_callwatcher-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_callwatcher-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_automation-view-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_automation-view-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_controller-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_first-run.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-click.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-markers.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-03.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-04.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-05.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-render-06.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-selected.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_graph-zoom.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_inspector-bypass-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_inspector-toggle.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_inspector-width.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_inspector.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_navigate.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view-media-nodes.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view-params-objects.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view-params.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_properties-view.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_reset-01.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_reset-02.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_reset-03.js create mode 100644 devtools/client/webaudioeditor/test/browser_wa_reset-04.js create mode 100644 devtools/client/webaudioeditor/test/browser_webaudio-actor-automation-event.js create mode 100644 devtools/client/webaudioeditor/test/browser_webaudio-actor-connect-param.js create mode 100644 devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js create mode 100644 devtools/client/webaudioeditor/test/browser_webaudio-actor-simple.js create mode 100644 devtools/client/webaudioeditor/test/doc_automation.html create mode 100644 devtools/client/webaudioeditor/test/doc_buffer-and-array.html create mode 100644 devtools/client/webaudioeditor/test/doc_bug_1112378.html create mode 100644 devtools/client/webaudioeditor/test/doc_bug_1125817.html create mode 100644 devtools/client/webaudioeditor/test/doc_bug_1130901.html create mode 100644 devtools/client/webaudioeditor/test/doc_bug_1141261.html create mode 100644 devtools/client/webaudioeditor/test/doc_complex-context.html create mode 100644 devtools/client/webaudioeditor/test/doc_connect-multi-param.html create mode 100644 devtools/client/webaudioeditor/test/doc_connect-param.html create mode 100644 devtools/client/webaudioeditor/test/doc_destroy-nodes.html create mode 100644 devtools/client/webaudioeditor/test/doc_iframe-context.html create mode 100644 devtools/client/webaudioeditor/test/doc_media-node-creation.html create mode 100644 devtools/client/webaudioeditor/test/doc_simple-context.html create mode 100644 devtools/client/webaudioeditor/test/doc_simple-node-creation.html create mode 100644 devtools/client/webaudioeditor/test/head.js (limited to 'devtools/client/webaudioeditor/test') diff --git a/devtools/client/webaudioeditor/test/.eslintrc.js b/devtools/client/webaudioeditor/test/.eslintrc.js new file mode 100644 index 000000000..8d15a76d9 --- /dev/null +++ b/devtools/client/webaudioeditor/test/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + // Extend from the shared list of defined globals for mochitests. + "extends": "../../../.eslintrc.mochitests.js" +}; diff --git a/devtools/client/webaudioeditor/test/440hz_sine.ogg b/devtools/client/webaudioeditor/test/440hz_sine.ogg new file mode 100644 index 000000000..bd84564e2 Binary files /dev/null and b/devtools/client/webaudioeditor/test/440hz_sine.ogg differ diff --git a/devtools/client/webaudioeditor/test/browser.ini b/devtools/client/webaudioeditor/test/browser.ini new file mode 100644 index 000000000..cad17a530 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser.ini @@ -0,0 +1,77 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + doc_simple-context.html + doc_complex-context.html + doc_simple-node-creation.html + doc_buffer-and-array.html + doc_media-node-creation.html + doc_destroy-nodes.html + doc_connect-param.html + doc_connect-multi-param.html + doc_iframe-context.html + doc_automation.html + doc_bug_1112378.html + doc_bug_1125817.html + doc_bug_1130901.html + doc_bug_1141261.html + 440hz_sine.ogg + head.js + +[browser_audionode-actor-get-param-flags.js] +[browser_audionode-actor-get-params-01.js] +[browser_audionode-actor-get-params-02.js] +[browser_audionode-actor-get-set-param.js] +[browser_audionode-actor-type.js] +[browser_audionode-actor-source.js] +[browser_audionode-actor-bypass.js] +[browser_audionode-actor-bypassable.js] +[browser_audionode-actor-connectnode-disconnect.js] +[browser_audionode-actor-connectparam.js] +skip-if = true # bug 1092571 +# [browser_audionode-actor-add-automation-event.js] bug 1134036 +# [browser_audionode-actor-get-automation-data-01.js] bug 1134036 +# [browser_audionode-actor-get-automation-data-02.js] bug 1134036 +# [browser_audionode-actor-get-automation-data-03.js] bug 1134036 +[browser_callwatcher-01.js] +[browser_callwatcher-02.js] +[browser_webaudio-actor-simple.js] +[browser_webaudio-actor-destroy-node.js] +[browser_webaudio-actor-connect-param.js] +# [browser_webaudio-actor-automation-event.js] bug 1134036 + +# [browser_wa_automation-view-01.js] bug 1134036 +# [browser_wa_automation-view-02.js] bug 1134036 +[browser_wa_controller-01.js] +[browser_wa_destroy-node-01.js] +[browser_wa_first-run.js] +[browser_wa_graph-click.js] +[browser_wa_graph-markers.js] +[browser_wa_graph-render-01.js] +[browser_wa_graph-render-02.js] +[browser_wa_graph-render-03.js] +[browser_wa_graph-render-04.js] +[browser_wa_graph-render-05.js] +skip-if = true # bug 1092571 +[browser_wa_graph-render-06.js] +[browser_wa_graph-selected.js] +[browser_wa_graph-zoom.js] +[browser_wa_inspector.js] +[browser_wa_inspector-toggle.js] +[browser_wa_inspector-width.js] +[browser_wa_inspector-bypass-01.js] +[browser_wa_navigate.js] +[browser_wa_properties-view.js] +[browser_wa_properties-view-edit-01.js] +skip-if = true # bug 1010423 +[browser_wa_properties-view-edit-02.js] +skip-if = true # bug 1010423 +[browser_wa_properties-view-media-nodes.js] +skip-if = os == 'mac' # bug 1216542 +[browser_wa_properties-view-params.js] +[browser_wa_properties-view-params-objects.js] +[browser_wa_reset-01.js] +[browser_wa_reset-02.js] +[browser_wa_reset-03.js] +[browser_wa_reset-04.js] diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-add-automation-event.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-add-automation-event.js new file mode 100644 index 000000000..4b451c826 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-add-automation-event.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#addAutomationEvent(); + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + let count = 0; + let counter = () => count++; + front.on("automation-event", counter); + + let t0 = 0, t1 = 0.1, t2 = 0.2, t3 = 0.3, t4 = 0.4, t5 = 0.6, t6 = 0.7, t7 = 1; + let curve = [-1, 0, 1]; + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.2, t0]); + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.3, t1]); + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.4, t2]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [1, t3]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [0.15, t4]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [0.75, t5]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [0.5, t6]); + yield oscNode.addAutomationEvent("frequency", "setValueCurveAtTime", [curve, t7, t7 - t6]); + yield oscNode.addAutomationEvent("frequency", "setTargetAtTime", [20, 2, 5]); + + ok(true, "successfully set automation events for valid automation events"); + + try { + yield oscNode.addAutomationEvent("frequency", "notAMethod", 20, 2, 5); + ok(false, "non-automation methods should not be successful"); + } catch (e) { + ok(/invalid/.test(e.message), "AudioNode:addAutomationEvent fails for invalid automation methods"); + } + + try { + yield oscNode.addAutomationEvent("invalidparam", "setValueAtTime", 0.2, t0); + ok(false, "automating non-AudioParams should not be successful"); + } catch (e) { + ok(/invalid/.test(e.message), "AudioNode:addAutomationEvent fails for a non AudioParam"); + } + + front.off("automation-event", counter); + + is(count, 9, + "when calling `addAutomationEvent`, the WebAudioActor should still fire `automation-event`."); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-bypass.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-bypass.js new file mode 100644 index 000000000..e9fc7f321 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-bypass.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#bypass(), AudioNode#isBypassed() + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + + is((yield gainNode.isBypassed()), false, "Nodes start off unbypassed."); + + info("Calling node#bypass(true)"); + let isBypassed = yield gainNode.bypass(true); + + is(isBypassed, true, "node.bypass(true) resolves to true"); + is((yield gainNode.isBypassed()), true, "Node is now bypassed."); + + info("Calling node#bypass(false)"); + isBypassed = yield gainNode.bypass(false); + + is(isBypassed, false, "node.bypass(false) resolves to false"); + is((yield gainNode.isBypassed()), false, "Node back to being unbypassed."); + + info("Calling node#bypass(true) on unbypassable node"); + isBypassed = yield destNode.bypass(true); + + is(isBypassed, false, "node.bypass(true) resolves to false for unbypassable node"); + is((yield gainNode.isBypassed()), false, "Unbypassable node is unaffect"); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-bypassable.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-bypassable.js new file mode 100644 index 000000000..2f093f2e4 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-bypassable.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#bypassable + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 14) + ]); + + let actualBypassability = nodes.map(node => node.bypassable); + let expectedBypassability = [ + false, // AudioDestinationNode + true, // AudioBufferSourceNode + true, // ScriptProcessorNode + true, // AnalyserNode + true, // GainNode + true, // DelayNode + true, // BiquadFilterNode + true, // WaveShaperNode + true, // PannerNode + true, // ConvolverNode + false, // ChannelSplitterNode + false, // ChannelMergerNode + true, // DynamicsCompressNode + true, // OscillatorNode + ]; + + expectedBypassability.forEach((bypassable, i) => { + is(actualBypassability[i], bypassable, `${nodes[i].type} has correct ".bypassable" status`); + }); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-connectnode-disconnect.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-connectnode-disconnect.js new file mode 100644 index 000000000..dcd1689f5 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-connectnode-disconnect.js @@ -0,0 +1,39 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that AudioNodeActor#connectNode() and AudioNodeActor#disconnect() work. + * Uses the editor front as the actors do not retain connect state. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let [dest, osc, gain] = actors; + + info("Disconnecting oscillator..."); + osc.disconnect(); + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 1), + once(gAudioNodes, "disconnect") + ]); + ok(true, "Oscillator disconnected, event emitted."); + + info("Reconnecting oscillator..."); + osc.connectNode(gain); + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 2), + once(gAudioNodes, "connect") + ]); + ok(true, "Oscillator reconnected."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-connectparam.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-connectparam.js new file mode 100644 index 000000000..454f0d563 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-connectparam.js @@ -0,0 +1,32 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that AudioNodeActor#connectParam() work. + * Uses the editor front as the actors do not retain connect state. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let [dest, osc, gain] = actors; + + yield osc.disconnect(); + + osc.connectParam(gain, "gain"); + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 1, 1), + once(gAudioNodes, "connect") + ]); + ok(true, "Oscillator connect to Gain's Gain AudioParam, event emitted."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-01.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-01.js new file mode 100644 index 000000000..640b3e351 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-01.js @@ -0,0 +1,53 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#addAutomationEvent() checking automation values, also using + * a curve as the last event to check duration spread. + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + + let t0 = 0, t1 = 0.1, t2 = 0.2, t3 = 0.3, t4 = 0.4, t5 = 0.6, t6 = 0.7, t7 = 1; + let curve = [-1, 0, 1]; + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.2, t0]); + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.3, t1]); + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [0.4, t2]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [1, t3]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [0.15, t4]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [0.75, t5]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [0.05, t6]); + // End with a curve here so we can get proper results on the last event (which takes into account + // duration) + yield oscNode.addAutomationEvent("frequency", "setValueCurveAtTime", [curve, t6, t7 - t6]); + + let { events, values } = yield oscNode.getAutomationData("frequency"); + + is(events.length, 8, "8 recorded events returned."); + is(values.length, 2000, "2000 value points returned."); + + checkAutomationValue(values, 0.05, 0.2); + checkAutomationValue(values, 0.1, 0.3); + checkAutomationValue(values, 0.15, 0.3); + checkAutomationValue(values, 0.2, 0.4); + checkAutomationValue(values, 0.25, 0.7); + checkAutomationValue(values, 0.3, 1); + checkAutomationValue(values, 0.35, 0.575); + checkAutomationValue(values, 0.4, 0.15); + checkAutomationValue(values, 0.45, 0.15 * Math.pow(0.75 / 0.15, 0.05 / 0.2)); + checkAutomationValue(values, 0.5, 0.15 * Math.pow(0.75 / 0.15, 0.5)); + checkAutomationValue(values, 0.55, 0.15 * Math.pow(0.75 / 0.15, 0.15 / 0.2)); + checkAutomationValue(values, 0.6, 0.75); + checkAutomationValue(values, 0.65, 0.75 * Math.pow(0.05 / 0.75, 0.5)); + checkAutomationValue(values, 0.705, -1); // Increase this time a bit to prevent off by the previous exponential amount + checkAutomationValue(values, 0.8, 0); + checkAutomationValue(values, 0.9, 1); + checkAutomationValue(values, 1, 1); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-02.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-02.js new file mode 100644 index 000000000..f24fb1905 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-02.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#addAutomationEvent() when automation series ends with + * `setTargetAtTime`, which approaches its target to infinity. + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [300, 0.1]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [500, 0.4]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [200, 0.6]); + // End with a setTargetAtTime event, as the target approaches infinity, which will + // give us more points to render than the default 2000 + yield oscNode.addAutomationEvent("frequency", "setTargetAtTime", [1000, 2, 0.5]); + + var { events, values } = yield oscNode.getAutomationData("frequency"); + + is(events.length, 4, "4 recorded events returned."); + is(values.length, 4000, "4000 value points returned when ending with exponentiall approaching automator."); + + checkAutomationValue(values, 2.01, 215.055); + checkAutomationValue(values, 2.1, 345.930); + checkAutomationValue(values, 3, 891.601); + checkAutomationValue(values, 5, 998.01); + + // Refetch the automation data to ensure it recalculates correctly (bug 1118071) + var { events, values } = yield oscNode.getAutomationData("frequency"); + + checkAutomationValue(values, 2.01, 215.055); + checkAutomationValue(values, 2.1, 345.930); + checkAutomationValue(values, 3, 891.601); + checkAutomationValue(values, 5, 998.01); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-03.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-03.js new file mode 100644 index 000000000..7de509ccd --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-automation-data-03.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that `cancelScheduledEvents` clears out events on and after + * its argument. + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [300, 0]); + yield oscNode.addAutomationEvent("frequency", "linearRampToValueAtTime", [500, 0.9]); + yield oscNode.addAutomationEvent("frequency", "setValueAtTime", [700, 1]); + yield oscNode.addAutomationEvent("frequency", "exponentialRampToValueAtTime", [1000, 2]); + yield oscNode.addAutomationEvent("frequency", "cancelScheduledValues", [1]); + + var { events, values } = yield oscNode.getAutomationData("frequency"); + + is(events.length, 2, "2 recorded events returned."); + is(values.length, 2000, "2000 value points returned"); + + checkAutomationValue(values, 0, 300); + checkAutomationValue(values, 0.5, 411.15); + checkAutomationValue(values, 0.9, 499.9); + checkAutomationValue(values, 1, 499.9); + checkAutomationValue(values, 2, 499.9); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-param-flags.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-param-flags.js new file mode 100644 index 000000000..17f7bf846 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-param-flags.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#getParamFlags() + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 15) + ]); + + let allNodeParams = yield Promise.all(nodes.map(node => node.getParams())); + let nodeTypes = [ + "AudioDestinationNode", + "AudioBufferSourceNode", "ScriptProcessorNode", "AnalyserNode", "GainNode", + "DelayNode", "BiquadFilterNode", "WaveShaperNode", "PannerNode", "ConvolverNode", + "ChannelSplitterNode", "ChannelMergerNode", "DynamicsCompressorNode", "OscillatorNode", + "StereoPannerNode" + ]; + + // For some reason nodeTypes.forEach and params.forEach fail here so we use + // simple for loops. + for (let i = 0; i < nodeTypes.length; i++) { + let type = nodeTypes[i]; + let params = allNodeParams[i]; + + for (let {param, value, flags} of params) { + let testFlags = yield nodes[i].getParamFlags(param); + ok(typeof testFlags === "object", type + " has flags from #getParamFlags(" + param + ")"); + + if (param === "buffer") { + is(flags.Buffer, true, "`buffer` params have Buffer flag"); + } + else if (param === "bufferSize" || param === "frequencyBinCount") { + is(flags.readonly, true, param + " is readonly"); + } + else if (param === "curve") { + is(flags["Float32Array"], true, "`curve` param has Float32Array flag"); + } + } + } + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-01.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-01.js new file mode 100644 index 000000000..6cfabbe85 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-01.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#getParams() + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 15) + ]); + + yield loadFrameScripts(); + + let allNodeParams = yield Promise.all(nodes.map(node => node.getParams())); + let nodeTypes = [ + "AudioDestinationNode", + "AudioBufferSourceNode", "ScriptProcessorNode", "AnalyserNode", "GainNode", + "DelayNode", "BiquadFilterNode", "WaveShaperNode", "PannerNode", "ConvolverNode", + "ChannelSplitterNode", "ChannelMergerNode", "DynamicsCompressorNode", "OscillatorNode", + "StereoPannerNode" + ]; + + let defaults = yield Promise.all(nodeTypes.map(type => nodeDefaultValues(type))); + + nodeTypes.map((type, i) => { + let params = allNodeParams[i]; + + params.forEach(({param, value, flags}) => { + ok(param in defaults[i], "expected parameter for " + type); + + ok(typeof flags === "object", type + " has a flags object"); + + if (param === "buffer") { + is(flags.Buffer, true, "`buffer` params have Buffer flag"); + } + else if (param === "bufferSize" || param === "frequencyBinCount") { + is(flags.readonly, true, param + " is readonly"); + } + else if (param === "curve") { + is(flags["Float32Array"], true, "`curve` param has Float32Array flag"); + } + }); + }); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-02.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-02.js new file mode 100644 index 000000000..8d60a5e4d --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-params-02.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that default properties are returned with the correct type + * from the AudioNode actors. + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 15) + ]); + + yield loadFrameScripts(); + + let allParams = yield Promise.all(nodes.map(node => node.getParams())); + let types = [ + "AudioDestinationNode", "AudioBufferSourceNode", "ScriptProcessorNode", + "AnalyserNode", "GainNode", "DelayNode", "BiquadFilterNode", "WaveShaperNode", + "PannerNode", "ConvolverNode", "ChannelSplitterNode", "ChannelMergerNode", + "DynamicsCompressorNode", "OscillatorNode", "StereoPannerNode" + ]; + + let defaults = yield Promise.all(types.map(type => nodeDefaultValues(type))); + + info(JSON.stringify(defaults)); + + allParams.forEach((params, i) => { + compare(params, defaults[i], types[i]); + }); + + yield removeTab(target.tab); +}); + +function compare(actual, expected, type) { + actual.forEach(({ value, param }) => { + value = getGripValue(value); + if (typeof expected[param] === "function") { + ok(expected[param](value), type + " has a passing value for " + param); + } + else { + is(value, expected[param], type + " has correct default value and type for " + param); + } + }); + + info(Object.keys(expected).join(",") + " - " + JSON.stringify(expected)); + + is(actual.length, Object.keys(expected).length, + type + " has correct amount of properties."); +} diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-get-set-param.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-set-param.js new file mode 100644 index 000000000..0d4c7c5c7 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-get-set-param.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#getParam() / AudioNode#setParam() + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, [destNode, oscNode, gainNode]] = yield Promise.all([ + front.setup({ reload: true }), + get3(front, "create-node") + ]); + + let freq = yield oscNode.getParam("frequency"); + info(typeof freq); + is(freq, 440, "AudioNode:getParam correctly fetches AudioParam"); + + let type = yield oscNode.getParam("type"); + is(type, "sine", "AudioNode:getParam correctly fetches non-AudioParam"); + + type = yield oscNode.getParam("not-a-valid-param"); + ok(type.type === "undefined", + "AudioNode:getParam correctly returns a grip value for `undefined` for an invalid param."); + + let resSuccess = yield oscNode.setParam("frequency", 220); + freq = yield oscNode.getParam("frequency"); + is(freq, 220, "AudioNode:setParam correctly sets a `number` AudioParam"); + is(resSuccess, undefined, "AudioNode:setParam returns undefined for correctly set AudioParam"); + + resSuccess = yield oscNode.setParam("type", "square"); + type = yield oscNode.getParam("type"); + is(type, "square", "AudioNode:setParam correctly sets a `string` non-AudioParam"); + is(resSuccess, undefined, "AudioNode:setParam returns undefined for correctly set AudioParam"); + + try { + yield oscNode.setParam("frequency", "hello"); + ok(false, "setParam with invalid types should throw"); + } catch (e) { + ok(/is not a finite floating-point/.test(e.message), "AudioNode:setParam returns error with correct message when attempting an invalid assignment"); + is(e.type, "TypeError", "AudioNode:setParam returns error with correct type when attempting an invalid assignment"); + freq = yield oscNode.getParam("frequency"); + is(freq, 220, "AudioNode:setParam does not modify value when an error occurs"); + } + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-source.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-source.js new file mode 100644 index 000000000..203e88012 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-source.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#source + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 14) + ]); + + let actualTypes = nodes.map(node => node.type); + let isSourceResult = nodes.map(node => node.source); + + actualTypes.forEach((type, i) => { + let shouldBeSource = type === "AudioBufferSourceNode" || type === "OscillatorNode"; + if (shouldBeSource) + is(isSourceResult[i], true, type + "'s `source` is `true`"); + else + is(isSourceResult[i], false, type + "'s `source` is `false`"); + }); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_audionode-actor-type.js b/devtools/client/webaudioeditor/test/browser_audionode-actor-type.js new file mode 100644 index 000000000..58712067e --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_audionode-actor-type.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test AudioNode#type + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_NODES_URL); + let [_, nodes] = yield Promise.all([ + front.setup({ reload: true }), + getN(front, "create-node", 14) + ]); + + let actualTypes = nodes.map(node => node.type); + let expectedTypes = [ + "AudioDestinationNode", + "AudioBufferSourceNode", "ScriptProcessorNode", "AnalyserNode", "GainNode", + "DelayNode", "BiquadFilterNode", "WaveShaperNode", "PannerNode", "ConvolverNode", + "ChannelSplitterNode", "ChannelMergerNode", "DynamicsCompressorNode", "OscillatorNode" + ]; + + expectedTypes.forEach((type, i) => { + is(actualTypes[i], type, type + " successfully created with correct type"); + }); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_callwatcher-01.js b/devtools/client/webaudioeditor/test/browser_callwatcher-01.js new file mode 100644 index 000000000..11c3ad11c --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_callwatcher-01.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Bug 1130901 + * Tests to ensure that calling call/apply on methods wrapped + * via CallWatcher do not throw a security permissions error: + * "Error: Permission denied to access property 'call'" + */ + +const BUG_1130901_URL = EXAMPLE_URL + "doc_bug_1130901.html"; + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(BUG_1130901_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let rendered = waitForGraphRendered(panelWin, 3, 0); + reload(target); + yield rendered; + + ok(true, "Successfully created a node from AudioContext via `call`."); + ok(true, "Successfully created a node from AudioContext via `apply`."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_callwatcher-02.js b/devtools/client/webaudioeditor/test/browser_callwatcher-02.js new file mode 100644 index 000000000..f901efdcb --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_callwatcher-02.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Bug 1112378 + * Tests to ensure that errors called on wrapped functions via call-watcher + * correctly looks like the error comes from the content, not from within the devtools. + */ + +const BUG_1112378_URL = EXAMPLE_URL + "doc_bug_1112378.html"; + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(BUG_1112378_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + loadFrameScripts(); + + let rendered = waitForGraphRendered(panelWin, 2, 0); + reload(target); + yield rendered; + + let error = yield evalInDebuggee("throwError()"); + is(error.lineNumber, 21, "error has correct lineNumber"); + is(error.columnNumber, 11, "error has correct columnNumber"); + is(error.name, "TypeError", "error has correct name"); + is(error.message, "Argument 1 is not valid for any of the 2-argument overloads of AudioNode.connect.", "error has correct message"); + is(error.stringified, "TypeError: Argument 1 is not valid for any of the 2-argument overloads of AudioNode.connect.", "error is stringified correctly"); + is(error.instanceof, true, "error is correctly an instanceof TypeError"); + is(error.fileName, "http://example.com/browser/devtools/client/webaudioeditor/test/doc_bug_1112378.html", "error has correct fileName"); + + error = yield evalInDebuggee("throwDOMException()"); + is(error.lineNumber, 37, "exception has correct lineNumber"); + is(error.columnNumber, 0, "exception has correct columnNumber"); + is(error.code, 9, "exception has correct code"); + is(error.result, 2152923145, "exception has correct result"); + is(error.name, "NotSupportedError", "exception has correct name"); + is(error.message, "Operation is not supported", "exception has correct message"); + is(error.stringified, "NotSupportedError: Operation is not supported", "exception is stringified correctly"); + is(error.instanceof, true, "exception is correctly an instance of DOMException"); + is(error.filename, "http://example.com/browser/devtools/client/webaudioeditor/test/doc_bug_1112378.html", "exception has correct filename"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_automation-view-01.js b/devtools/client/webaudioeditor/test/browser_wa_automation-view-01.js new file mode 100644 index 000000000..1e0034b5b --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_automation-view-01.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that automation view shows the correct view depending on if events + * or params exist. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(AUTOMATION_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + let $tabbox = $("#web-audio-editor-tabs"); + + // Oscillator node + click(panelWin, findGraphNode(panelWin, nodeIds[1])); + yield waitForInspectorRender(panelWin, EVENTS); + $tabbox.selectedIndex = 1; + + ok(isVisible($("#automation-graph-container")), "graph container should be visible"); + ok(isVisible($("#automation-content")), "automation content should be visible"); + ok(!isVisible($("#automation-no-events")), "no-events panel should not be visible"); + ok(!isVisible($("#automation-empty")), "empty panel should not be visible"); + + // Gain node + click(panelWin, findGraphNode(panelWin, nodeIds[2])); + yield waitForInspectorRender(panelWin, EVENTS); + $tabbox.selectedIndex = 1; + + ok(!isVisible($("#automation-graph-container")), "graph container should not be visible"); + ok(isVisible($("#automation-content")), "automation content should be visible"); + ok(isVisible($("#automation-no-events")), "no-events panel should be visible"); + ok(!isVisible($("#automation-empty")), "empty panel should not be visible"); + + // destination node + click(panelWin, findGraphNode(panelWin, nodeIds[0])); + yield waitForInspectorRender(panelWin, EVENTS); + $tabbox.selectedIndex = 1; + + ok(!isVisible($("#automation-graph-container")), "graph container should not be visible"); + ok(!isVisible($("#automation-content")), "automation content should not be visible"); + ok(!isVisible($("#automation-no-events")), "no-events panel should not be visible"); + ok(isVisible($("#automation-empty")), "empty panel should be visible"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_automation-view-02.js b/devtools/client/webaudioeditor/test/browser_wa_automation-view-02.js new file mode 100644 index 000000000..a0f5f5a04 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_automation-view-02.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that automation view selects the first parameter by default and + * switching between AudioParam rerenders the graph. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(AUTOMATION_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, AutomationView } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + // Oscillator node + click(panelWin, findGraphNode(panelWin, nodeIds[1])); + yield waitForInspectorRender(panelWin, EVENTS); + click(panelWin, $("#automation-tab")); + + ok(AutomationView._selectedParamName, "frequency", + "AutomatioView is set on 'frequency'"); + ok($(".automation-param-button[data-param='frequency']").getAttribute("selected"), + "frequency param should be selected on load"); + ok(!$(".automation-param-button[data-param='detune']").getAttribute("selected"), + "detune param should not be selected on load"); + ok(isVisible($("#automation-content")), "automation content should be visible"); + ok(isVisible($("#automation-graph-container")), "graph container should be visible"); + ok(!isVisible($("#automation-no-events")), "no-events panel should not be visible"); + + click(panelWin, $(".automation-param-button[data-param='detune']")); + yield once(panelWin, EVENTS.UI_AUTOMATION_TAB_RENDERED); + + ok(true, "automation tab rerendered"); + + ok(AutomationView._selectedParamName, "detune", + "AutomatioView is set on 'detune'"); + ok(!$(".automation-param-button[data-param='frequency']").getAttribute("selected"), + "frequency param should not be selected after clicking detune"); + ok($(".automation-param-button[data-param='detune']").getAttribute("selected"), + "detune param should be selected after clicking detune"); + ok(isVisible($("#automation-content")), "automation content should be visible"); + ok(!isVisible($("#automation-graph-container")), "graph container should not be visible"); + ok(isVisible($("#automation-no-events")), "no-events panel should be visible"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_controller-01.js b/devtools/client/webaudioeditor/test/browser_wa_controller-01.js new file mode 100644 index 000000000..a7064df1f --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_controller-01.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Bug 1125817 + * Tests to ensure that disconnecting a node immediately + * after creating it does not fail. + */ + +const BUG_1125817_URL = EXAMPLE_URL + "doc_bug_1125817.html"; + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(BUG_1125817_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let events = Promise.all([ + once(gAudioNodes, "add", 2), + once(gAudioNodes, "disconnect"), + waitForGraphRendered(panelWin, 2, 0) + ]); + reload(target); + yield events; + + ok(true, "Successfully disconnected a just-created node."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js b/devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js new file mode 100644 index 000000000..d7dde4d97 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_destroy-node-01.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that the destruction node event is fired and that the nodes are no + * longer stored internally in the tool, that the graph is updated properly, and + * that selecting a soon-to-be dead node clears the inspector. + * + * All done in one test since this test takes a few seconds to clear GC. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(DESTROY_NODES_URL); + let { panelWin } = panel; + let { gFront, $, $$, gAudioNodes } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getNSpread(gAudioNodes, "add", 13), + waitForGraphRendered(panelWin, 13, 2) + ]); + reload(target); + let [created] = yield events; + + // Flatten arrays of event arguments and take the first (AudioNodeModel) + // and get its ID. + let actorIDs = created.map(ev => ev[0].id); + + // Click a soon-to-be dead buffer node + yield clickGraphNode(panelWin, actorIDs[5]); + + let destroyed = getN(gAudioNodes, "remove", 10); + + // Force a CC in the child process to collect the orphaned nodes. + forceNodeCollection(); + + // Wait for destruction and graph to re-render + yield Promise.all([destroyed, waitForGraphRendered(panelWin, 3, 2)]); + + // Test internal storage + is(panelWin.gAudioNodes.length, 3, "All nodes should be GC'd except one gain, osc and dest node."); + + // Test graph rendering + ok(findGraphNode(panelWin, actorIDs[0]), "dest should be in graph"); + ok(findGraphNode(panelWin, actorIDs[1]), "osc should be in graph"); + ok(findGraphNode(panelWin, actorIDs[2]), "gain should be in graph"); + + let { nodes, edges } = countGraphObjects(panelWin); + + is(nodes, 3, "Only 3 nodes rendered in graph."); + is(edges, 2, "Only 2 edges rendered in graph."); + + // Test that the inspector reset to no node selected + ok(isVisible($("#web-audio-editor-details-pane-empty")), + "InspectorView empty message should show if the currently selected node gets collected."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_first-run.js b/devtools/client/webaudioeditor/test/browser_wa_first-run.js new file mode 100644 index 000000000..d2d96932e --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_first-run.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// +// Whitelisting this test. +// As part of bug 1077403, the leaking uncaught rejection should be fixed. +// +thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed"); + +/** + * Tests that the reloading/onContentLoaded hooks work. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { gFront, $ } = panel.panelWin; + + is($("#reload-notice").hidden, false, + "The 'reload this page' notice should initially be visible."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should initially be hidden."); + is($("#content").hidden, true, + "The tool's content should initially be hidden."); + + let navigating = once(target, "will-navigate"); + let started = once(gFront, "start-context"); + + reload(target); + + yield navigating; + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden when navigating."); + is($("#waiting-notice").hidden, false, + "The 'waiting for an audio context' notice should be visible when navigating."); + is($("#content").hidden, true, + "The tool's content should still be hidden."); + + yield started; + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden after context found."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be hidden after context found."); + is($("#content").hidden, false, + "The tool's content should not be hidden anymore."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-click.js b/devtools/client/webaudioeditor/test/browser_wa_graph-click.js new file mode 100644 index 000000000..b075d30db --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-click.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that the clicking on a node in the GraphView opens and sets + * the correct node in the InspectorView + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(COMPLEX_CONTEXT_URL); + let panelWin = panel.panelWin; + let { gFront, $, $$, InspectorView } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getN(gFront, "create-node", 8), + waitForGraphRendered(panel.panelWin, 8, 8) + ]); + reload(target); + let [actors, _] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + ok(!InspectorView.isVisible(), "InspectorView hidden on start."); + + yield clickGraphNode(panelWin, nodeIds[1], true); + + ok(InspectorView.isVisible(), "InspectorView visible after selecting a node."); + is(InspectorView.getCurrentAudioNode().id, nodeIds[1], "InspectorView has correct node set."); + + yield clickGraphNode(panelWin, nodeIds[2]); + + ok(InspectorView.isVisible(), "InspectorView still visible after selecting another node."); + is(InspectorView.getCurrentAudioNode().id, nodeIds[2], "InspectorView has correct node set on second node."); + + yield clickGraphNode(panelWin, nodeIds[2]); + is(InspectorView.getCurrentAudioNode().id, nodeIds[2], "Clicking the same node again works (idempotent)."); + + yield clickGraphNode(panelWin, $("rect", findGraphNode(panelWin, nodeIds[3]))); + is(InspectorView.getCurrentAudioNode().id, nodeIds[3], "Clicking on a works as expected."); + + yield clickGraphNode(panelWin, $("tspan", findGraphNode(panelWin, nodeIds[4]))); + is(InspectorView.getCurrentAudioNode().id, nodeIds[4], "Clicking on a works as expected."); + + ok(InspectorView.isVisible(), + "InspectorView still visible after several nodes have been clicked."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-markers.js b/devtools/client/webaudioeditor/test/browser_wa_graph-markers.js new file mode 100644 index 000000000..adc15d0c3 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-markers.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that the SVG marker styling is updated when devtools theme changes. + */ + +const { setTheme } = require("devtools/client/shared/theme"); + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, MARKER_STYLING } = panelWin; + + let currentTheme = Services.prefs.getCharPref("devtools.theme"); + + ok(MARKER_STYLING.light, "Marker styling exists for light theme."); + ok(MARKER_STYLING.dark, "Marker styling exists for dark theme."); + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + + is(getFill($("#arrowhead")), MARKER_STYLING[currentTheme], + "marker initially matches theme."); + + // Switch to light + setTheme("light"); + is(getFill($("#arrowhead")), MARKER_STYLING.light, + "marker styling matches light theme on change."); + + // Switch to dark + setTheme("dark"); + is(getFill($("#arrowhead")), MARKER_STYLING.dark, + "marker styling matches dark theme on change."); + + // Switch to dark again + setTheme("dark"); + is(getFill($("#arrowhead")), MARKER_STYLING.dark, + "marker styling remains dark."); + + // Switch to back to light again + setTheme("light"); + is(getFill($("#arrowhead")), MARKER_STYLING.light, + "marker styling switches back to light once again."); + + yield teardown(target); +}); + +/** + * Returns a hex value found in styling for an element. So parses + * and returns "#abcdef" + */ +function getFill(el) { + return el.getAttribute("style").match(/(#.*)$/)[1]; +} diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-01.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-01.js new file mode 100644 index 000000000..cee1987b9 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-01.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that SVG nodes and edges were created for the Graph View. + */ + +var connectCount = 0; + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let started = once(gFront, "start-context"); + + gAudioNodes.on("connect", onConnectNode); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let [destId, oscId, gainId] = actors.map(actor => actor.actorID); + + ok(findGraphNode(panelWin, oscId).classList.contains("type-OscillatorNode"), "found OscillatorNode with class"); + ok(findGraphNode(panelWin, gainId).classList.contains("type-GainNode"), "found GainNode with class"); + ok(findGraphNode(panelWin, destId).classList.contains("type-AudioDestinationNode"), "found AudioDestinationNode with class"); + is(findGraphEdge(panelWin, oscId, gainId).toString(), "[object SVGGElement]", "found edge for osc -> gain"); + is(findGraphEdge(panelWin, gainId, destId).toString(), "[object SVGGElement]", "found edge for gain -> dest"); + + yield wait(1000); + + is(connectCount, 2, "Only two node connect events should be fired."); + + gAudioNodes.off("connect", onConnectNode); + + yield teardown(target); +}); + +function onConnectNode() { + ++connectCount; +} diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-02.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-02.js new file mode 100644 index 000000000..00a63c6b2 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-02.js @@ -0,0 +1,48 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests more edge rendering for complex graphs. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(COMPLEX_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$ } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getN(gFront, "create-node", 8), + waitForGraphRendered(panelWin, 8, 8) + ]); + reload(target); + let [actors] = yield events; + let nodeIDs = actors.map(actor => actor.actorID); + + let types = ["AudioDestinationNode", "OscillatorNode", "GainNode", "ScriptProcessorNode", + "OscillatorNode", "GainNode", "AudioBufferSourceNode", "BiquadFilterNode"]; + + + types.forEach((type, i) => { + ok(findGraphNode(panelWin, nodeIDs[i]).classList.contains("type-" + type), "found " + type + " with class"); + }); + + let edges = [ + [1, 2, "osc1 -> gain1"], + [1, 3, "osc1 -> proc"], + [2, 0, "gain1 -> dest"], + [4, 5, "osc2 -> gain2"], + [5, 0, "gain2 -> dest"], + [6, 7, "buf -> filter"], + [4, 7, "osc2 -> filter"], + [7, 0, "filter -> dest"], + ]; + + edges.forEach(([source, target, msg], i) => { + is(findGraphEdge(panelWin, nodeIDs[source], nodeIDs[target]).toString(), "[object SVGGElement]", + "found edge for " + msg); + }); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-03.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-03.js new file mode 100644 index 000000000..ffd9b9881 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-03.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests to ensure that selected nodes stay selected on graph redraw. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let events = Promise.all([ + getN(gFront, "create-node", 3), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let [dest, osc, gain] = actors; + + yield clickGraphNode(panelWin, gain.actorID); + ok(findGraphNode(panelWin, gain.actorID).classList.contains("selected"), + "Node selected once."); + + // Disconnect a node to trigger a rerender + osc.disconnect(); + + yield once(panelWin, EVENTS.UI_GRAPH_RENDERED); + + ok(findGraphNode(panelWin, gain.actorID).classList.contains("selected"), + "Node still selected after rerender."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-04.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-04.js new file mode 100644 index 000000000..9ed3ceffd --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-04.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests audio param connection rendering. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(CONNECT_MULTI_PARAM_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getN(gFront, "create-node", 5), + waitForGraphRendered(panelWin, 5, 2, 3) + ]); + reload(target); + let [actors] = yield events; + let nodeIDs = actors.map(actor => actor.actorID); + + let [, carrier, gain, mod1, mod2] = nodeIDs; + + let edges = [ + [mod1, gain, "gain", "mod1 -> gain[gain]"], + [mod2, carrier, "frequency", "mod2 -> carrier[frequency]"], + [mod2, carrier, "detune", "mod2 -> carrier[detune]"] + ]; + + edges.forEach(([source, target, param, msg], i) => { + let edge = findGraphEdge(panelWin, source, target, param); + ok(edge.classList.contains("param-connection"), "edge is classified as a param-connection"); + }); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-05.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-05.js new file mode 100644 index 000000000..2748984d0 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-05.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests to ensure that param connections trigger graph redraws + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let events = Promise.all([ + getN(gFront, "create-node", 3), + waitForGraphRendered(panelWin, 3, 2, 0) + ]); + reload(target); + let [actors] = yield events; + let [dest, osc, gain] = actors; + + yield osc.disconnect(); + + osc.connectParam(gain, "gain"); + yield waitForGraphRendered(panelWin, 3, 1, 1); + ok(true, "Graph re-rendered upon param connection"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-render-06.js b/devtools/client/webaudioeditor/test/browser_wa_graph-render-06.js new file mode 100644 index 000000000..c47d60b7c --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-render-06.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests to ensure that param connections trigger graph redraws + */ + +const BUG_1141261_URL = EXAMPLE_URL + "doc_bug_1141261.html"; + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(BUG_1141261_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let events = Promise.all([ + getN(gFront, "create-node", 3), + waitForGraphRendered(panelWin, 3, 1, 0) + ]); + reload(target); + yield events; + + ok(true, "Graph correctly shows gain node as disconnected"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-selected.js b/devtools/client/webaudioeditor/test/browser_wa_graph-selected.js new file mode 100644 index 000000000..72044b7bd --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-selected.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that SVG nodes and edges were created for the Graph View. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS } = panelWin; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let [destId, oscId, gainId] = actors.map(actor => actor.actorID); + + ok(!findGraphNode(panelWin, destId).classList.contains("selected"), + "No nodes selected on start. (destination)"); + ok(!findGraphNode(panelWin, oscId).classList.contains("selected"), + "No nodes selected on start. (oscillator)"); + ok(!findGraphNode(panelWin, gainId).classList.contains("selected"), + "No nodes selected on start. (gain)"); + + yield clickGraphNode(panelWin, oscId); + + ok(findGraphNode(panelWin, oscId).classList.contains("selected"), + "Selected node has class 'selected'."); + ok(!findGraphNode(panelWin, destId).classList.contains("selected"), + "Non-selected nodes do not have class 'selected'."); + ok(!findGraphNode(panelWin, gainId).classList.contains("selected"), + "Non-selected nodes do not have class 'selected'."); + + yield clickGraphNode(panelWin, gainId); + + ok(!findGraphNode(panelWin, oscId).classList.contains("selected"), + "Previously selected node no longer has class 'selected'."); + ok(!findGraphNode(panelWin, destId).classList.contains("selected"), + "Non-selected nodes do not have class 'selected'."); + ok(findGraphNode(panelWin, gainId).classList.contains("selected"), + "Newly selected node now has class 'selected'."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_graph-zoom.js b/devtools/client/webaudioeditor/test/browser_wa_graph-zoom.js new file mode 100644 index 000000000..240b6d5a1 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_graph-zoom.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that the graph's scale and position is reset on a page reload. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, ContextView } = panelWin; + + let started = once(gFront, "start-context"); + + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 2), + reload(target), + ]); + + is(ContextView.getCurrentScale(), 1, "Default graph scale is 1."); + is(ContextView.getCurrentTranslation()[0], 20, "Default x-translation is 20."); + is(ContextView.getCurrentTranslation()[1], 20, "Default y-translation is 20."); + + // Change both attribute and D3's internal store + panelWin.d3.select("#graph-target").attr("transform", "translate([100, 400]) scale(10)"); + ContextView._zoomBinding.scale(10); + ContextView._zoomBinding.translate([100, 400]); + + is(ContextView.getCurrentScale(), 10, "After zoom, scale is 10."); + is(ContextView.getCurrentTranslation()[0], 100, "After zoom, x-translation is 100."); + is(ContextView.getCurrentTranslation()[1], 400, "After zoom, y-translation is 400."); + + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 2), + reload(target), + ]); + + is(ContextView.getCurrentScale(), 1, "After refresh, graph scale is 1."); + is(ContextView.getCurrentTranslation()[0], 20, "After refresh, x-translation is 20."); + is(ContextView.getCurrentTranslation()[1], 20, "After refresh, y-translation is 20."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_inspector-bypass-01.js b/devtools/client/webaudioeditor/test/browser_wa_inspector-bypass-01.js new file mode 100644 index 000000000..c9d3450e3 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_inspector-bypass-01.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that nodes are correctly bypassed when bypassing. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + // Wait for the node to be set as well as the inspector to come fully into the view + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[1]), true); + + let $bypass = $("toolbarbutton.bypass"); + + is((yield actors[1].isBypassed()), false, "AudioNodeActor is not bypassed by default."); + is($bypass.checked, true, "Button is 'on' for normal nodes"); + is($bypass.disabled, false, "Bypass button is not disabled for normal nodes"); + + command($bypass); + yield once(gAudioNodes, "bypass"); + + is((yield actors[1].isBypassed()), true, "AudioNodeActor is bypassed."); + is($bypass.checked, false, "Button is 'off' when clicked"); + is($bypass.disabled, false, "Bypass button is not disabled after click"); + ok(findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"), + "AudioNode has 'bypassed' class."); + + command($bypass); + yield once(gAudioNodes, "bypass"); + + is((yield actors[1].isBypassed()), false, "AudioNodeActor is no longer bypassed."); + is($bypass.checked, true, "Button is back on when clicked"); + is($bypass.disabled, false, "Bypass button is not disabled after click"); + ok(!findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"), + "AudioNode no longer has 'bypassed' class."); + + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[0])); + + is((yield actors[0].isBypassed()), false, "Unbypassable AudioNodeActor is not bypassed."); + is($bypass.checked, false, "Button is 'off' for unbypassable nodes"); + is($bypass.disabled, true, "Bypass button is disabled for unbypassable nodes"); + + command($bypass); + is((yield actors[0].isBypassed()), false, + "Clicking button on unbypassable node does not change bypass state on actor."); + is($bypass.checked, false, "Button is still 'off' for unbypassable nodes"); + is($bypass.disabled, true, "Bypass button is still disabled for unbypassable nodes"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_inspector-toggle.js b/devtools/client/webaudioeditor/test/browser_wa_inspector-toggle.js new file mode 100644 index 000000000..251f92471 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_inspector-toggle.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that the inspector toggle button shows and hides + * the inspector panel as intended. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, InspectorView } = panelWin; + let gVars = InspectorView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + ok(!InspectorView.isVisible(), "InspectorView hidden on start."); + + // Open inspector pane + $("#inspector-pane-toggle").click(); + yield once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED); + + ok(InspectorView.isVisible(), "InspectorView shown after toggling."); + + ok(isVisible($("#web-audio-editor-details-pane-empty")), + "InspectorView empty message should still be visible."); + ok(!isVisible($("#web-audio-editor-tabs")), + "InspectorView tabs view should still be hidden."); + + // Close inspector pane + $("#inspector-pane-toggle").click(); + yield once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED); + + ok(!InspectorView.isVisible(), "InspectorView back to being hidden."); + + // Open again to test node loading while open + $("#inspector-pane-toggle").click(); + yield once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED); + + ok(InspectorView.isVisible(), "InspectorView being shown."); + ok(!isVisible($("#web-audio-editor-tabs")), + "InspectorView tabs are still hidden."); + + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[1])); + + ok(!isVisible($("#web-audio-editor-details-pane-empty")), + "Empty message hides even when loading node while open."); + ok(isVisible($("#web-audio-editor-tabs")), + "Switches to tab view when loading node while open."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_inspector-width.js b/devtools/client/webaudioeditor/test/browser_wa_inspector-width.js new file mode 100644 index 000000000..d37774013 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_inspector-width.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that the WebAudioInspector's Width is saved as + * a preference + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, InspectorView } = panelWin; + let gVars = InspectorView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + ok(!InspectorView.isVisible(), "InspectorView hidden on start."); + + // Open inspector pane + $("#inspector-pane-toggle").click(); + yield once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED); + + let newInspectorWidth = 500; + + // Setting width to new_inspector_width + $("#web-audio-inspector").setAttribute("width", newInspectorWidth); + + // Width should be 500 after reloading + events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + [actors] = yield events; + nodeIds = actors.map(actor => actor.actorID); + + // Open inspector pane + $("#inspector-pane-toggle").click(); + yield once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED); + + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[1])); + + // Getting the width of the audio inspector + let width = $("#web-audio-inspector").getAttribute("width"); + + is(width, newInspectorWidth, "WebAudioEditor's Inspector width should be saved as a preference"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_inspector.js b/devtools/client/webaudioeditor/test/browser_wa_inspector.js new file mode 100644 index 000000000..5599ad36f --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_inspector.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that inspector view opens on graph node click, and + * loads the correct node inside the inspector. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, InspectorView } = panelWin; + let gVars = InspectorView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + ok(!InspectorView.isVisible(), "InspectorView hidden on start."); + ok(isVisible($("#web-audio-editor-details-pane-empty")), + "InspectorView empty message should show when no node's selected."); + ok(!isVisible($("#web-audio-editor-tabs")), + "InspectorView tabs view should be hidden when no node's selected."); + + // Wait for the node to be set as well as the inspector to come fully into the view + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[1]), true); + + ok(InspectorView.isVisible(), "InspectorView shown once node selected."); + ok(!isVisible($("#web-audio-editor-details-pane-empty")), + "InspectorView empty message hidden when node selected."); + ok(isVisible($("#web-audio-editor-tabs")), + "InspectorView tabs view visible when node selected."); + + is($("#web-audio-editor-tabs").selectedIndex, 0, + "default tab selected should be the parameters tab."); + + yield clickGraphNode(panelWin, findGraphNode(panelWin, nodeIds[2])); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_navigate.js b/devtools/client/webaudioeditor/test/browser_wa_navigate.js new file mode 100644 index 000000000..e1f094384 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_navigate.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests naviating from a page to another will repopulate + * the audio graph if both pages have an AudioContext. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $ } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + yield events; + + var { nodes, edges } = countGraphObjects(panelWin); + is(nodes, 3, "should only be 3 nodes."); + is(edges, 2, "should only be 2 edges."); + + events = Promise.all([ + getN(gFront, "create-node", 15), + waitForGraphRendered(panelWin, 15, 0) + ]); + navigate(target, SIMPLE_NODES_URL); + yield events; + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden after context found after navigation."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be hidden after context found after navigation."); + is($("#content").hidden, false, + "The tool's content should reappear without closing and reopening the toolbox."); + + var { nodes, edges } = countGraphObjects(panelWin); + is(nodes, 15, "after navigation, should have 15 nodes"); + is(edges, 0, "after navigation, should have 0 edges."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-01.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-01.js new file mode 100644 index 000000000..ac7deca26 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-01.js @@ -0,0 +1,65 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that properties are updated when modifying the VariablesView. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + click(panelWin, findGraphNode(panelWin, nodeIds[1])); + // Wait for the node to be set as well as the inspector to come fully into the view + yield Promise.all([ + waitForInspectorRender(panelWin, EVENTS), + once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED) + ]); + + let setAndCheck = setAndCheckVariable(panelWin, gVars); + + checkVariableView(gVars, 0, { + "type": "sine", + "frequency": 440, + "detune": 0 + }, "default loaded string"); + + click(panelWin, findGraphNode(panelWin, nodeIds[2])); + yield waitForInspectorRender(panelWin, EVENTS), + checkVariableView(gVars, 0, { + "gain": 0 + }, "default loaded number"); + + click(panelWin, findGraphNode(panelWin, nodeIds[1])); + yield waitForInspectorRender(panelWin, EVENTS), + yield setAndCheck(0, "type", "square", "square", "sets string as string"); + + click(panelWin, findGraphNode(panelWin, nodeIds[2])); + yield waitForInspectorRender(panelWin, EVENTS), + yield setAndCheck(0, "gain", "0.005", 0.005, "sets number as number"); + yield setAndCheck(0, "gain", "0.1", 0.1, "sets float as float"); + yield setAndCheck(0, "gain", ".2", 0.2, "sets float without leading zero as float"); + + yield teardown(target); +}); + +function setAndCheckVariable(panelWin, gVars) { + return Task.async(function* (varNum, prop, value, expected, desc) { + yield modifyVariableView(panelWin, gVars, varNum, prop, value); + var props = {}; + props[prop] = expected; + checkVariableView(gVars, varNum, props, desc); + }); +} diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-02.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-02.js new file mode 100644 index 000000000..d7c54822d --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view-edit-02.js @@ -0,0 +1,44 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that properties are not updated when modifying the VariablesView. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(COMPLEX_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getN(gFront, "create-node", 8), + waitForGraphRendered(panelWin, 8, 8) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + click(panelWin, findGraphNode(panelWin, nodeIds[3])); + // Wait for the node to be set as well as the inspector to come fully into the view + yield Promise.all([ + waitForInspectorRender(panelWin, EVENTS), + once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED), + ]); + + let errorEvent = once(panelWin, EVENTS.UI_SET_PARAM_ERROR); + + try { + yield modifyVariableView(panelWin, gVars, 0, "bufferSize", 2048); + } catch (e) { + // we except modifyVariableView to fail here, because bufferSize is not writable + } + + yield errorEvent; + + checkVariableView(gVars, 0, {bufferSize: 4096}, "check that unwritable variable is not updated"); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view-media-nodes.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view-media-nodes.js new file mode 100644 index 000000000..c1a916a1f --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view-media-nodes.js @@ -0,0 +1,76 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that params view correctly displays all properties for nodes + * correctly, with default values and correct types. + */ + +var MEDIA_PERMISSION = "media.navigator.permission.disabled"; + +function waitForDeviceClosed() { + info("Checking that getUserMedia streams are no longer in use."); + + let temp = {}; + Cu.import("resource:///modules/webrtcUI.jsm", temp); + let webrtcUI = temp.webrtcUI; + + if (!webrtcUI.showGlobalIndicator) + return Promise.resolve(); + + let deferred = Promise.defer(); + + const message = "webrtc:UpdateGlobalIndicators"; + let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"] + .getService(Ci.nsIMessageBroadcaster); + ppmm.addMessageListener(message, function listener(aMessage) { + info("Received " + message + " message"); + if (!aMessage.data.showGlobalIndicator) { + ppmm.removeMessageListener(message, listener); + deferred.resolve(); + } + }); + + return deferred.promise; +} + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(MEDIA_NODES_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + // Auto enable getUserMedia + let mediaPermissionPref = Services.prefs.getBoolPref(MEDIA_PERMISSION); + Services.prefs.setBoolPref(MEDIA_PERMISSION, true); + + yield loadFrameScripts(); + + let events = Promise.all([ + getN(gFront, "create-node", 4), + waitForGraphRendered(panelWin, 4, 0) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + let types = [ + "AudioDestinationNode", "MediaElementAudioSourceNode", + "MediaStreamAudioSourceNode", "MediaStreamAudioDestinationNode" + ]; + + let defaults = yield Promise.all(types.map(type => nodeDefaultValues(type))); + + for (let i = 0; i < types.length; i++) { + click(panelWin, findGraphNode(panelWin, nodeIds[i])); + yield waitForInspectorRender(panelWin, EVENTS); + checkVariableView(gVars, 0, defaults[i], types[i]); + } + + // Reset permissions on getUserMedia + Services.prefs.setBoolPref(MEDIA_PERMISSION, mediaPermissionPref); + + yield teardown(target); + + yield waitForDeviceClosed(); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view-params-objects.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view-params-objects.js new file mode 100644 index 000000000..e0a555201 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view-params-objects.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that params view correctly displays non-primitive properties + * like AudioBuffer and Float32Array in properties of AudioNodes. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(BUFFER_AND_ARRAY_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + getN(gFront, "create-node", 3), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + click(panelWin, findGraphNode(panelWin, nodeIds[2])); + yield waitForInspectorRender(panelWin, EVENTS); + checkVariableView(gVars, 0, { + "curve": "Float32Array" + }, "WaveShaper's `curve` is listed as an `Float32Array`."); + + let aVar = gVars.getScopeAtIndex(0).get("curve"); + let state = aVar.target.querySelector(".theme-twisty").hasAttribute("invisible"); + ok(state, "Float32Array property should not have a dropdown."); + + click(panelWin, findGraphNode(panelWin, nodeIds[1])); + yield waitForInspectorRender(panelWin, EVENTS); + checkVariableView(gVars, 0, { + "buffer": "AudioBuffer" + }, "AudioBufferSourceNode's `buffer` is listed as an `AudioBuffer`."); + + aVar = gVars.getScopeAtIndex(0).get("buffer"); + state = aVar.target.querySelector(".theme-twisty").hasAttribute("invisible"); + ok(state, "AudioBuffer property should not have a dropdown."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view-params.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view-params.js new file mode 100644 index 000000000..31319e8c5 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view-params.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that params view correctly displays all properties for nodes + * correctly, with default values and correct types. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_NODES_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + let started = once(gFront, "start-context"); + + yield loadFrameScripts(); + + let events = Promise.all([ + getN(gFront, "create-node", 15), + waitForGraphRendered(panelWin, 15, 0) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + let types = [ + "AudioDestinationNode", "AudioBufferSourceNode", "ScriptProcessorNode", + "AnalyserNode", "GainNode", "DelayNode", "BiquadFilterNode", "WaveShaperNode", + "PannerNode", "ConvolverNode", "ChannelSplitterNode", "ChannelMergerNode", + "DynamicsCompressorNode", "OscillatorNode" + ]; + + let defaults = yield Promise.all(types.map(type => nodeDefaultValues(type))); + + for (let i = 0; i < types.length; i++) { + click(panelWin, findGraphNode(panelWin, nodeIds[i])); + yield waitForInspectorRender(panelWin, EVENTS); + checkVariableView(gVars, 0, defaults[i], types[i]); + } + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_properties-view.js b/devtools/client/webaudioeditor/test/browser_wa_properties-view.js new file mode 100644 index 000000000..bda51e4ac --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_properties-view.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that params view shows params when they exist, and are hidden otherwise. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, PropertiesView } = panelWin; + let gVars = PropertiesView._propsView; + + let started = once(gFront, "start-context"); + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + // Gain node + click(panelWin, findGraphNode(panelWin, nodeIds[2])); + yield waitForInspectorRender(panelWin, EVENTS); + + ok(isVisible($("#properties-content")), "Parameters shown when they exist."); + ok(!isVisible($("#properties-empty")), + "Empty message hidden when AudioParams exist."); + + // Destination node + click(panelWin, findGraphNode(panelWin, nodeIds[0])); + yield waitForInspectorRender(panelWin, EVENTS); + + ok(!isVisible($("#properties-content")), + "Parameters hidden when they don't exist."); + ok(isVisible($("#properties-empty")), + "Empty message shown when no AudioParams exist."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_reset-01.js b/devtools/client/webaudioeditor/test/browser_wa_reset-01.js new file mode 100644 index 000000000..67a0c33ff --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_reset-01.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// +// Whitelisting this test. +// As part of bug 1077403, the leaking uncaught rejection should be fixed. +// +thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed"); + +/** + * Tests that reloading a tab will properly listen for the `start-context` + * event and reshow the tools after reloading. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { gFront, $ } = panel.panelWin; + + is($("#reload-notice").hidden, false, + "The 'reload this page' notice should initially be visible."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should initially be hidden."); + is($("#content").hidden, true, + "The tool's content should initially be hidden."); + + let navigating = once(target, "will-navigate"); + let started = once(gFront, "start-context"); + + reload(target); + + yield navigating; + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden when navigating."); + is($("#waiting-notice").hidden, false, + "The 'waiting for an audio context' notice should be visible when navigating."); + is($("#content").hidden, true, + "The tool's content should still be hidden."); + + yield started; + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden after context found."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be hidden after context found."); + is($("#content").hidden, false, + "The tool's content should not be hidden anymore."); + + navigating = once(target, "will-navigate"); + started = once(gFront, "start-context"); + + reload(target); + + yield Promise.all([navigating, started]); + let rendered = waitForGraphRendered(panel.panelWin, 3, 2); + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden after context found after reload."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be hidden after context found after reload."); + is($("#content").hidden, false, + "The tool's content should reappear without closing and reopening the toolbox."); + + yield rendered; + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_reset-02.js b/devtools/client/webaudioeditor/test/browser_wa_reset-02.js new file mode 100644 index 000000000..c9516b364 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_reset-02.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests reloading a tab with the tools open properly cleans up + * the graph. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $ } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + yield events; + + let { nodes, edges } = countGraphObjects(panelWin); + is(nodes, 3, "should only be 3 nodes."); + is(edges, 2, "should only be 2 edges."); + + events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + yield events; + + ({ nodes, edges } = countGraphObjects(panelWin)); + is(nodes, 3, "after reload, should only be 3 nodes."); + is(edges, 2, "after reload, should only be 2 edges."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_reset-03.js b/devtools/client/webaudioeditor/test/browser_wa_reset-03.js new file mode 100644 index 000000000..1207793f5 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_reset-03.js @@ -0,0 +1,48 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests reloading a tab with the tools open properly cleans up + * the inspector and selected node. + */ + +add_task(function* () { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, InspectorView } = panelWin; + + let events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + let [actors] = yield events; + let nodeIds = actors.map(actor => actor.actorID); + + yield clickGraphNode(panelWin, nodeIds[1], true); + ok(InspectorView.isVisible(), "InspectorView visible after selecting a node."); + is(InspectorView.getCurrentAudioNode().id, nodeIds[1], "InspectorView has correct node set."); + + /** + * Reload + */ + + events = Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + reload(target); + [actors] = yield events; + nodeIds = actors.map(actor => actor.actorID); + + ok(!InspectorView.isVisible(), "InspectorView hidden on start."); + is(InspectorView.getCurrentAudioNode(), null, + "InspectorView has no current node set on reset."); + + yield clickGraphNode(panelWin, nodeIds[2], true); + ok(InspectorView.isVisible(), + "InspectorView visible after selecting a node after a reset."); + is(InspectorView.getCurrentAudioNode().id, nodeIds[2], "InspectorView has correct node set upon clicking graph node after a reset."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_wa_reset-04.js b/devtools/client/webaudioeditor/test/browser_wa_reset-04.js new file mode 100644 index 000000000..7ad009020 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_wa_reset-04.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// +// Whitelisting this test. +// As part of bug 1077403, the leaking uncaught rejection should be fixed. +// +thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Error: Connection closed"); + +/** + * Tests that switching to an iframe works fine. + */ + +add_task(function* () { + Services.prefs.setBoolPref("devtools.command-button-frames.enabled", true); + + let { target, panel, toolbox } = yield initWebAudioEditor(IFRAME_CONTEXT_URL); + let { gFront, $ } = panel.panelWin; + + is($("#reload-notice").hidden, false, + "The 'reload this page' notice should initially be visible."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should initially be hidden."); + is($("#content").hidden, true, + "The tool's content should initially be hidden."); + + let btn = toolbox.doc.getElementById("command-button-frames"); + ok(!btn.firstChild, "The frame list button has no children"); + + // Open frame menu and wait till it's available on the screen. + let menu = toolbox.showFramesMenu({target: btn}); + yield once(menu, "open"); + + let frames = menu.items; + is(frames.length, 2, "We have both frames in the list"); + + // Select the iframe + frames[1].click(); + + let navigating = once(target, "will-navigate"); + + yield navigating; + + is($("#reload-notice").hidden, false, + "The 'reload this page' notice should still be visible when switching to a frame."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be kept hidden when switching to a frame."); + is($("#content").hidden, true, + "The tool's content should still be hidden."); + + navigating = once(target, "will-navigate"); + let started = once(gFront, "start-context"); + + reload(target); + + yield Promise.all([navigating, started]); + + is($("#reload-notice").hidden, true, + "The 'reload this page' notice should be hidden after reloading the frame."); + is($("#waiting-notice").hidden, true, + "The 'waiting for an audio context' notice should be hidden after reloading the frame."); + is($("#content").hidden, false, + "The tool's content should appear after reload."); + + yield teardown(target); +}); diff --git a/devtools/client/webaudioeditor/test/browser_webaudio-actor-automation-event.js b/devtools/client/webaudioeditor/test/browser_webaudio-actor-automation-event.js new file mode 100644 index 000000000..9d542d5f0 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_webaudio-actor-automation-event.js @@ -0,0 +1,52 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that the WebAudioActor receives and emits the `automation-event` events + * with correct arguments from the content. + */ + +add_task(function* () { + let { target, front } = yield initBackend(AUTOMATION_URL); + let events = []; + + let expected = [ + ["setValueAtTime", 0.2, 0], + ["linearRampToValueAtTime", 1, 0.3], + ["exponentialRampToValueAtTime", 0.75, 0.6], + ["setValueCurveAtTime", [-1, 0, 1], 0.7, 0.3], + ]; + + front.on("automation-event", onAutomationEvent); + + let [_, __, [destNode, oscNode, gainNode], [connect1, connect2]] = yield Promise.all([ + front.setup({ reload: true }), + once(front, "start-context"), + get3(front, "create-node"), + get2(front, "connect-node") + ]); + + is(events.length, 4, "correct number of events fired"); + + function onAutomationEvent(e) { + let { eventName, paramName, args } = e; + let exp = expected[events.length]; + + is(eventName, exp[0], "correct eventName in event"); + is(paramName, "frequency", "correct paramName in event"); + is(args.length, exp.length - 1, "correct length in args"); + + args.forEach((a, i) => { + // In the case of an array + if (typeof a === "object") { + a.forEach((f, j) => is(f, exp[i + 1][j], `correct argument in Float32Array: ${f}`)); + } else { + is(a, exp[i + 1], `correct ${i + 1}th argument in args: ${a}`); + } + }); + events.push([eventName].concat(args)); + } + + front.off("automation-event", onAutomationEvent); + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_webaudio-actor-connect-param.js b/devtools/client/webaudioeditor/test/browser_webaudio-actor-connect-param.js new file mode 100644 index 000000000..2910d5bd1 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_webaudio-actor-connect-param.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test the `connect-param` event on the web audio actor. + */ + +add_task(function* () { + let { target, front } = yield initBackend(CONNECT_PARAM_URL); + let [, , [destNode, carrierNode, modNode, gainNode], , connectParam] = yield Promise.all([ + front.setup({ reload: true }), + once(front, "start-context"), + getN(front, "create-node", 4), + get2(front, "connect-node"), + once(front, "connect-param") + ]); + + info(connectParam); + + is(connectParam.source.actorID, modNode.actorID, "`connect-param` has correct actor for `source`"); + is(connectParam.dest.actorID, gainNode.actorID, "`connect-param` has correct actor for `dest`"); + is(connectParam.param, "gain", "`connect-param` has correct parameter name for `param`"); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js b/devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js new file mode 100644 index 000000000..e48836c3f --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_webaudio-actor-destroy-node.js @@ -0,0 +1,41 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test `destroy-node` event on WebAudioActor. + */ + +add_task(function* () { + let { target, front } = yield initBackend(DESTROY_NODES_URL); + + let [, , created] = yield Promise.all([ + front.setup({ reload: true }), + once(front, "start-context"), + // Should create dest, gain, and oscillator node and 10 + // disposable buffer nodes + getN(front, "create-node", 13) + ]); + + let waitUntilDestroyed = getN(front, "destroy-node", 10); + + // Force CC so we can ensure it's run to clear out dead AudioNodes + forceNodeCollection(); + + let destroyed = yield waitUntilDestroyed; + + destroyed.forEach((node, i) => { + ok(node.type, "AudioBufferSourceNode", "Only buffer nodes are destroyed"); + ok(actorIsInList(created, destroyed[i]), + "`destroy-node` called only on AudioNodes in current document."); + }); + + yield removeTab(target.tab); +}); + +function actorIsInList(list, actor) { + for (let i = 0; i < list.length; i++) { + if (list[i].actorID === actor.actorID) + return list[i]; + } + return null; +} diff --git a/devtools/client/webaudioeditor/test/browser_webaudio-actor-simple.js b/devtools/client/webaudioeditor/test/browser_webaudio-actor-simple.js new file mode 100644 index 000000000..28ff75651 --- /dev/null +++ b/devtools/client/webaudioeditor/test/browser_webaudio-actor-simple.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test basic communication of Web Audio actor + */ + +add_task(function* () { + let { target, front } = yield initBackend(SIMPLE_CONTEXT_URL); + let [_, __, [destNode, oscNode, gainNode], [connect1, connect2]] = yield Promise.all([ + front.setup({ reload: true }), + once(front, "start-context"), + get3(front, "create-node"), + get2(front, "connect-node") + ]); + + is(destNode.type, "AudioDestinationNode", "WebAudioActor:create-node returns AudioNodeActor for AudioDestination"); + is(oscNode.type, "OscillatorNode", "WebAudioActor:create-node returns AudioNodeActor"); + is(gainNode.type, "GainNode", "WebAudioActor:create-node returns AudioNodeActor"); + + let { source, dest } = connect1; + is(source.actorID, oscNode.actorID, "WebAudioActor:connect-node returns correct actor with ID on source (osc->gain)"); + is(dest.actorID, gainNode.actorID, "WebAudioActor:connect-node returns correct actor with ID on dest (osc->gain)"); + + ({ source, dest } = connect2); + is(source.actorID, gainNode.actorID, "WebAudioActor:connect-node returns correct actor with ID on source (gain->dest)"); + is(dest.actorID, destNode.actorID, "WebAudioActor:connect-node returns correct actor with ID on dest (gain->dest)"); + + yield removeTab(target.tab); +}); diff --git a/devtools/client/webaudioeditor/test/doc_automation.html b/devtools/client/webaudioeditor/test/doc_automation.html new file mode 100644 index 000000000..6f074208c --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_automation.html @@ -0,0 +1,30 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_buffer-and-array.html b/devtools/client/webaudioeditor/test/doc_buffer-and-array.html new file mode 100644 index 000000000..ef4cec8b6 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_buffer-and-array.html @@ -0,0 +1,56 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_bug_1112378.html b/devtools/client/webaudioeditor/test/doc_bug_1112378.html new file mode 100644 index 000000000..ecdfd7d63 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_bug_1112378.html @@ -0,0 +1,57 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_bug_1125817.html b/devtools/client/webaudioeditor/test/doc_bug_1125817.html new file mode 100644 index 000000000..49a2be11a --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_bug_1125817.html @@ -0,0 +1,23 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_bug_1130901.html b/devtools/client/webaudioeditor/test/doc_bug_1130901.html new file mode 100644 index 000000000..1ce1ebf55 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_bug_1130901.html @@ -0,0 +1,22 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_bug_1141261.html b/devtools/client/webaudioeditor/test/doc_bug_1141261.html new file mode 100644 index 000000000..87c1210a4 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_bug_1141261.html @@ -0,0 +1,25 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_complex-context.html b/devtools/client/webaudioeditor/test/doc_complex-context.html new file mode 100644 index 000000000..396bbce3f --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_complex-context.html @@ -0,0 +1,44 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_connect-multi-param.html b/devtools/client/webaudioeditor/test/doc_connect-multi-param.html new file mode 100644 index 000000000..ed4bd84e8 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_connect-multi-param.html @@ -0,0 +1,32 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_connect-param.html b/devtools/client/webaudioeditor/test/doc_connect-param.html new file mode 100644 index 000000000..9185c0b05 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_connect-param.html @@ -0,0 +1,28 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_destroy-nodes.html b/devtools/client/webaudioeditor/test/doc_destroy-nodes.html new file mode 100644 index 000000000..98dfc9ad2 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_destroy-nodes.html @@ -0,0 +1,36 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/devtools/client/webaudioeditor/test/doc_iframe-context.html b/devtools/client/webaudioeditor/test/doc_iframe-context.html new file mode 100644 index 000000000..a0a411a47 --- /dev/null +++ b/devtools/client/webaudioeditor/test/doc_iframe-context.html @@ -0,0 +1,14 @@ + + + + + + + Web Audio Editor test page with an iframe + + + +