blob: 8c16380b9a6cc867460b063fafd397231b770ddd [file] [log] [blame] [edit]
<!doctype html>
<html>
<head>
<title>Test AudioContext.suspend() and AudioContext.resume()</title>
<script src="../resources/js-test.js"></script>
<script src="resources/compatibility.js"></script>
<script src="resources/audio-testing.js"></script>
</head>
<body>
<script>
description("Test suspend/resume for an (offline) AudioContext");
window.jsTestIsAsync = true;
var offlineContext;
var osc;
var p1;
var p2;
var p3;
var sampleRate = 44100;
var durationInSeconds = 1;
var audit = Audit.createTaskRunner();
// Convenience function that returns a function that calls the |passFailFunc|
// with the given |message|. The |passFailFunc| should be either |testPassed|
// or |testFailed|.
function handlePromise(passFailFunc, message) {
return function () {
passFailFunc(message);
};
}
// Task: test suspend().
audit.defineTask('test-suspend', function (done) {
// 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.
shouldNotThrow("offlineContext = new OfflineAudioContext(1, durationInSeconds * sampleRate, sampleRate)");
osc = offlineContext.createOscillator();
osc.connect(offlineContext.destination);
// Verify the state.
shouldBeEqualToString("offlineContext.state", "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.
shouldNotThrow("p1 = offlineContext.suspend()");
shouldBeType("p1", "Promise");
p1.then(
handlePromise(testFailed, "offlineContext.suspend() should have been rejected for an offline context"),
function (e) {
if (e.name === "InvalidAccessError") {
testPassed(
"offlineContext.suspend() was correctly rejected: " + e);
} else {
testFailed(
"offlineContext.suspend() was correctly rejected but expected InvalidAccessError, not: " + e);
}
}
).then(done);
});
// Task: test resume().
audit.defineTask('test-resume', function (done) {
// 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.
shouldNotThrow("p2 = offlineContext.resume()");
shouldBeType("p2", "Promise");
// Resume doesn't actually resume an offline context
shouldBeEqualToString("offlineContext.state", "suspended");
p2.then(
handlePromise(testFailed, "offlineContext.resume() should have been rejected for an offline context"),
function (e) {
if (e.name === "InvalidAccessError") {
testPassed(
"offlineContext.resume() was correctly rejected: " + e);
} else {
testFailed(
"offlineContext.resume() was correctly rejected but expected InvalidAccessError, not: " + e);
}
}
).then(done);
});
// Task: test the state after context closed.
audit.defineTask('test-after-close', function (done) {
// 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.
shouldNotThrow("p3 = offlineContext.startRendering()");
p3.then(function () {
shouldBeEqualToString("offlineContext.state", "closed");
// suspend() should be rejected on a closed context.
offlineContext.suspend().then(
handlePromise(testFailed, "offlineContext.suspend() on a closed context not rejected"),
function (e) {
if (e.name === "InvalidAccessError") {
testPassed("offlineContext.suspend() on a closed context rejected: " + e);
} else {
testFailed("offlineContext.suspend() on a closed context rejected but expected InvalidAccessError, not: " + e);
}
}
).then(function () {
// resume() should be rejected on closed context.
offlineContext.resume().then(
handlePromise(testFailed, "offlineContext.resume() on a closed context not rejected"),
function (e) {
if (e.name === "InvalidAccessError") {
testPassed("offlineContext.resume() on a closed context rejected: " + e);
} else {
testFailed("offlineContext.resume() on a closed context rejected but expected InvalidAccessError, not: " + e);
}
}
).then(done);
});
});
});
audit.defineTask('finish-test', function (done) {
done();
finishJSTest();
});
audit.runTasks(
'test-suspend',
'test-resume',
'test-after-close',
'finish-test'
);
successfullyParsed = true;
</script>
</body>
</html>