author | Raymond Toy <rtoy@chromium.org> |
Tue, 15 May 2018 13:38:16 +0000 | |
changeset 418587 | ec6270ca64e1a8df3175a806ccb745900933e894 |
parent 418586 | 7eb1c0f8b5714878acb0dcb507f4ee3c1dc0514e |
child 418588 | f34462ac250eea30820e4c7def5becb9b2755c29 |
push id | 34007 |
push user | csabou@mozilla.com |
push date | Thu, 17 May 2018 09:47:02 +0000 |
treeherder | mozilla-central@8fb36531f7d0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1459265, 10852, 745778, 1042858, 556962 |
milestone | 62.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -371061,16 +371061,34 @@ ] ], "webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [ [ "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html", {} ] ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html": [ + [ + "/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html", + {} + ] + ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html": [ + [ + "/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html", + {} + ] + ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html": [ + [ + "/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html", + {} + ] + ], "webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html": [ [ "/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html", {} ] ], "webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html": [ [ @@ -612056,16 +612074,28 @@ "webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [ "ce84d25460435564021a13dc9e26384bc30e9d96", "testharness" ], "webaudio/the-audio-api/the-audiocontext-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html": [ + "03d32deacab7a98f3cce29562b84158e3f512668", + "testharness" + ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html": [ + "0ef6d19b75e1437ea71846d5a0d1af7dd426dc83", + "testharness" + ], + "webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html": [ + "21ea30d8fa92e908da66e79fd127e8fa0203a4c5", + "testharness" + ], "webaudio/the-audio-api/the-audiodestinationnode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], "webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html": [ "3e8b55e707434899be9af13334d935368579f1dc", "testharness" ],
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-getoutputtimestamp.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Testing AudioContext.getOutputTimestamp() method + </title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit.js"></script> + </head> + <body> + <script id="layout-test-code"> + let audit = Audit.createTaskRunner(); + + audit.define('getoutputtimestamp-initial-values', function(task, should) { + let context = new AudioContext; + let timestamp = context.getOutputTimestamp(); + + should(timestamp.contextTime, 'timestamp.contextTime').exist(); + should(timestamp.performanceTime, 'timestamp.performanceTime').exist(); + + should(timestamp.contextTime, 'timestamp.contextTime').beEqualTo(0); + should(timestamp.performanceTime, 'timestamp.performanceTime') + .beEqualTo(0); + + task.done(); + }); + + audit.run(); + </script> + </body> +</html>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontext-suspend-resume.html @@ -0,0 +1,145 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Test AudioContext.suspend() and AudioContext.resume() + </title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> + </head> + <body> + <script id="layout-test-code"> + let offlineContext; + let osc; + let p1; + let p2; + let p3; + + let sampleRate = 44100; + let durationInSeconds = 1; + + let audit = Audit.createTaskRunner(); + + // Task: test suspend(). + audit.define( + { + label: 'test-suspend', + description: 'Test suspend() for offline context' + }, + function(task, should) { + // Test suspend/resume. Ideally this test is best with a online + // AudioContext, but content shell doesn't really have a working + // online AudioContext. Hence, use an OfflineAudioContext. Not all + // possible scenarios can be easily checked with an offline context + // instead of an online context. + + // Create an audio context with an oscillator. + should( + () => { + offlineContext = new OfflineAudioContext( + 1, durationInSeconds * sampleRate, sampleRate); + }, + 'offlineContext = new OfflineAudioContext(1, ' + + (durationInSeconds * sampleRate) + ', ' + sampleRate + ')') + .notThrow(); + osc = offlineContext.createOscillator(); + osc.connect(offlineContext.destination); + + // Verify the state. + should(offlineContext.state, 'offlineContext.state') + .beEqualTo('suspended'); + + // Multiple calls to suspend() should not be a problem. But we can't + // test that on an offline context. Thus, check that suspend() on + // an OfflineAudioContext rejects the promise. + should( + () => p1 = offlineContext.suspend(), + 'p1 = offlineContext.suspend()') + .notThrow(); + should(p1 instanceof Promise, 'p1 instanceof Promise').beTrue(); + + should(p1, 'p1').beRejected().then(task.done.bind(task)); + }); + + + // Task: test resume(). + audit.define( + { + label: 'test-resume', + description: 'Test resume() for offline context' + }, + function(task, should) { + // Multiple calls to resume should not be a problem. But we can't + // test that on an offline context. Thus, check that resume() on an + // OfflineAudioContext rejects the promise. + should( + () => p2 = offlineContext.resume(), + 'p2 = offlineContext.resume()') + .notThrow(); + should(p2 instanceof Promise, 'p2 instanceof Promise').beTrue(); + + // Resume doesn't actually resume an offline context + should(offlineContext.state, 'After resume, offlineContext.state') + .beEqualTo('suspended'); + should(p2, 'p2').beRejected().then(task.done.bind(task)); + }); + + // Task: test the state after context closed. + audit.define( + { + label: 'test-after-close', + description: 'Test state after context closed' + }, + function(task, should) { + // Render the offline context. + osc.start(); + + // Test suspend/resume in tested promise pattern. We don't care + // about the actual result of the offline rendering. + should( + () => p3 = offlineContext.startRendering(), + 'p3 = offlineContext.startRendering()') + .notThrow(); + + p3.then(() => { + should(offlineContext.state, 'After close, offlineContext.state') + .beEqualTo('closed'); + + // suspend() should be rejected on a closed context. + should(offlineContext.suspend(), 'offlineContext.suspend()') + .beRejected() + .then(() => { + // resume() should be rejected on closed context. + should(offlineContext.resume(), 'offlineContext.resume()') + .beRejected() + .then(task.done.bind(task)); + }) + }); + }); + + audit.define( + { + label: 'resume-running-context', + description: 'Test resuming a running context' + }, + (task, should) => { + let context; + should(() => context = new AudioContext(), 'Create online context') + .notThrow(); + + should(context.state, 'context.state').beEqualTo('running'); + should(context.resume(), 'context.resume') + .beResolved() + .then(() => { + should(context.state, 'context.state after resume') + .beEqualTo('running'); + }) + .then(() => task.done()); + }); + + audit.run(); + </script> + </body> +</html>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html @@ -0,0 +1,162 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Test AudioContextOptions + </title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit.js"></script> + </head> + <body> + <script id="layout-test-code"> + let context; + let defaultLatency; + let interactiveLatency; + let balancedLatency; + let playbackLatency; + + let audit = Audit.createTaskRunner(); + + audit.define( + { + label: 'test-audiocontextoptions-latencyHint-basic', + description: 'Test creating contexts with basic latencyHint types.' + }, + function(task, should) { + let closingPromises = []; + + // Verify that an AudioContext can be created with default options. + should(function() { + context = new AudioContext() + }, 'context = new AudioContext()').notThrow(); + + should(context.sampleRate, + `context.sampleRate (${context.sampleRate} Hz)`).beGreaterThan(0); + + defaultLatency = context.baseLatency; + should(defaultLatency, 'default baseLatency').beGreaterThan(0); + + // Verify that an AudioContext can be created with the expected + // latency types. + should( + function() { + context = new AudioContext({'latencyHint': 'interactive'}) + }, + 'context = new AudioContext({\'latencyHint\': \'interactive\'})') + .notThrow(); + + interactiveLatency = context.baseLatency; + should(interactiveLatency, 'interactive baseLatency') + .beEqualTo(defaultLatency); + closingPromises.push(context.close()); + + should( + function() { + context = new AudioContext({'latencyHint': 'balanced'}) + }, + 'context = new AudioContext({\'latencyHint\': \'balanced\'})') + .notThrow(); + + balancedLatency = context.baseLatency; + should(balancedLatency, 'balanced baseLatency') + .beGreaterThanOrEqualTo(interactiveLatency); + closingPromises.push(context.close()); + + should( + function() { + context = new AudioContext({'latencyHint': 'playback'}) + }, + 'context = new AudioContext({\'latencyHint\': \'playback\'})') + .notThrow(); + + playbackLatency = context.baseLatency; + should(playbackLatency, 'playback baseLatency') + .beGreaterThanOrEqualTo(balancedLatency); + closingPromises.push(context.close()); + + Promise.all(closingPromises).then(function() { + task.done(); + }); + }); + + audit.define( + { + label: 'test-audiocontextoptions-latencyHint-double', + description: + 'Test creating contexts with explicit latencyHint values.' + }, + function(task, should) { + let closingPromises = []; + + // Verify too small exact latency clamped to 'interactive' + should( + function() { + context = + new AudioContext({'latencyHint': interactiveLatency / 2}) + }, + 'context = new AudioContext({\'latencyHint\': ' + + 'interactiveLatency/2})') + .notThrow(); + should(context.baseLatency, 'double-constructor baseLatency small') + .beLessThanOrEqualTo(interactiveLatency); + closingPromises.push(context.close()); + + // Verify that exact latency in range works as expected + let validLatency = (interactiveLatency + playbackLatency) / 2; + should( + function() { + context = new AudioContext({'latencyHint': validLatency}) + }, + 'context = new AudioContext({\'latencyHint\': validLatency})') + .notThrow(); + should( + context.baseLatency, 'double-constructor baseLatency inrange 1') + .beGreaterThanOrEqualTo(interactiveLatency); + should( + context.baseLatency, 'double-constructor baseLatency inrange 2') + .beLessThanOrEqualTo(playbackLatency); + closingPromises.push(context.close()); + + // Verify too big exact latency clamped to some value + let context1; + let context2; + should(function() { + context1 = + new AudioContext({'latencyHint': playbackLatency * 10}); + context2 = + new AudioContext({'latencyHint': playbackLatency * 20}); + }, 'creating two high latency contexts').notThrow(); + should(context1.baseLatency, 'high latency context baseLatency') + .beEqualTo(context2.baseLatency); + should(context1.baseLatency, 'high latency context baseLatency') + .beGreaterThan(interactiveLatency); + closingPromises.push(context1.close()); + closingPromises.push(context2.close()); + + // Verify that invalid latencyHint values are rejected. + should( + function() { + context = new AudioContext({'latencyHint': 'foo'}) + }, + 'context = new AudioContext({\'latencyHint\': \'foo\'})') + .throw('TypeError'); + + // Verify that no extra options can be passed into the + // AudioContextOptions. + should( + function() { + context = new AudioContext('latencyHint') + }, + 'context = new AudioContext(\'latencyHint\')') + .throw('TypeError'); + + Promise.all(closingPromises).then(function() { + task.done(); + }); + }); + + audit.run(); + </script> + </body> +</html>