243 lines
9.2 KiB
HTML
243 lines
9.2 KiB
HTML
<!-- webkit-test-runner [ MediaSessionCoordinatorEnabled=true ] -->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>mock-mediasession-coordinator</title>
|
|
<script src="../video-test.js"></script>
|
|
<script>
|
|
|
|
let waiting = false;
|
|
async function waitForDebugger()
|
|
{
|
|
let counter = 0;
|
|
while (waiting) {
|
|
await sleepFor(100);
|
|
counter++;
|
|
}
|
|
}
|
|
|
|
function changeHandler(change)
|
|
{
|
|
window.latestChange = change;
|
|
}
|
|
|
|
window.addEventListener('load', async event => {
|
|
|
|
window.latestAction = '';
|
|
window.latestChange = '';
|
|
|
|
if (!window.internals) {
|
|
failTest('This test requires Internals');
|
|
return;
|
|
}
|
|
|
|
let changePromise = () => {
|
|
return new Promise(resolve => {
|
|
navigator.mediaSession.coordinator.addEventListener('coordinatorstatechange', (event) => {
|
|
consoleWrite(`EVENT(${event.type} STATE(${navigator.mediaSession.coordinator.state})`);
|
|
resolve();
|
|
}, { once: true });
|
|
});
|
|
}
|
|
|
|
await waitForDebugger();
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** There mediaSession.coordinator.state should be closed initially.');
|
|
|
|
testExpected('navigator.mediaSession.coordinator.state', "closed");
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** Test that mediaSession.coordinator.coordinatorstatechange event is fired when it changes.');
|
|
|
|
run('internals.registerMockMediaSessionCoordinator(changeHandler)');
|
|
|
|
await changePromise();
|
|
|
|
['play', 'pause', 'seekto'].forEach(action => {
|
|
navigator.mediaSession.setActionHandler(action, actionDetails => {
|
|
consoleWrite(`ACTION(${actionDetails.action})`);
|
|
latestAction = actionDetails.action;
|
|
});
|
|
});
|
|
|
|
let testAction = async (action, func, expectFailure) => {
|
|
latestAction = '';
|
|
|
|
run(`promise = ${func.toString()}`);
|
|
try {
|
|
if (expectFailure)
|
|
await shouldReject(promise);
|
|
else
|
|
await shouldResolve(promise);
|
|
} catch(ex) {}
|
|
|
|
consoleWrite('');
|
|
};
|
|
|
|
let testReadyStates = async (testCallback) => {
|
|
let previousState = 'havenothing';
|
|
navigator.mediaSession.readyState = 'havenothing';
|
|
for (let state of ['havemetadata', 'havecurrentdata', 'havefuturedata', 'haveenoughdata', 'havenothing']) {
|
|
testExpected('navigator.mediaSession.readyState', previousState);
|
|
|
|
latestChange = '';
|
|
run(`navigator.mediaSession.readyState = '${state}'`);
|
|
|
|
await testCallback()
|
|
|
|
testExpected('navigator.mediaSession.readyState', state);
|
|
previousState = state;
|
|
consoleWrite('');
|
|
};
|
|
}
|
|
|
|
let testPlaybackStates = async (testCallback) => {
|
|
let previousState = 'none';
|
|
navigator.mediaSession.playbackState = 'none';
|
|
for (let state of ['paused', 'playing', 'none']) {
|
|
|
|
testExpected('navigator.mediaSession.playbackState', previousState);
|
|
|
|
latestChange = '';
|
|
run(`navigator.mediaSession.playbackState = '${state}'`);
|
|
|
|
await testCallback()
|
|
|
|
testExpected('navigator.mediaSession.playbackState', state);
|
|
previousState = state;
|
|
consoleWrite('');
|
|
};
|
|
}
|
|
|
|
let actions = [
|
|
{ action: 'play', func : 'navigator.mediaSession.coordinator.play()' },
|
|
{ action: 'pause', func : 'navigator.mediaSession.coordinator.pause()' },
|
|
{ action: 'seekto', func : 'navigator.mediaSession.coordinator.seekTo(10)' },
|
|
];
|
|
|
|
// Before joining
|
|
consoleWrite('');
|
|
consoleWrite('** navigator.mediaSession.coordinator.state should be "waiting" initially')
|
|
testExpected('navigator.mediaSession.coordinator.state', 'waiting');
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** Test that when coordinator methods fail and promises reject before mediaSession.join() is called.')
|
|
for (let action of actions)
|
|
await testAction(action.action, action.func, true);
|
|
|
|
consoleWrite(`** Test that mediaSession does not notify coordinator when states change before mediaSession.join() is called.`)
|
|
consoleWrite('* PositionState');
|
|
latestChange = '';
|
|
run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 1, position: 0 })');
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
|
|
consoleWrite('');
|
|
consoleWrite('* ReadyState');
|
|
await testReadyStates(async () => {
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
});
|
|
|
|
consoleWrite('* PlaybackState');
|
|
await testPlaybackStates(async () => {
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
});
|
|
|
|
consoleWrite('<br>');
|
|
consoleWrite('** session.join() should reject on failure');
|
|
run('internals.setMockMediaSessionCoordinatorCommandsShouldFail(true)');
|
|
run('promise = navigator.mediaSession.coordinator.join()');
|
|
await shouldReject(promise).then(() => { }).catch(() => { });
|
|
testExpected('navigator.mediaSession.coordinator.state', 'waiting');
|
|
testExpected('latestChange', '');
|
|
|
|
consoleWrite('');
|
|
run('internals.setMockMediaSessionCoordinatorCommandsShouldFail(false)');
|
|
run('promise = navigator.mediaSession.coordinator.join()');
|
|
await changePromise();
|
|
await shouldResolve(promise).then(() => { }).catch(() => { });
|
|
testExpected('navigator.mediaSession.coordinator.state', 'joined');
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** Test that when coordinator methods succeed, promises resolve and mediaSession action handlers are called.')
|
|
internals.setMockMediaSessionCoordinatorCommandsShouldFail(false);
|
|
for (let action of actions)
|
|
await testAction(action.action, action.func, false);
|
|
|
|
consoleWrite('** Test that when coordinator methods fail, promises reject and mediaSession action handlers are not called.')
|
|
internals.setMockMediaSessionCoordinatorCommandsShouldFail(true);
|
|
for (let action of actions)
|
|
await testAction(action.action, action.func, true);
|
|
|
|
consoleWrite(`** Test that mediaSession notifies coordinator when positionState changes.`)
|
|
run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 1, position: 0 })');
|
|
await testExpectedEventually('latestChange', 'positionStateChanged', '==', 100);
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** Test that mediaSession notifies coordinator when readyState changes.');
|
|
await testReadyStates(async () => { await testExpectedEventually('latestChange', 'readyStateChanged', '==', 100); })
|
|
|
|
consoleWrite('** Test that mediaSession notifies coordinator when playbackState changes.')
|
|
await testPlaybackStates(async () => { testExpectedEventually('latestChange', 'playbackStateChanged', '==', 100); });
|
|
|
|
// After leaving
|
|
consoleWrite('<br>');
|
|
consoleWrite('** Leave the session')
|
|
run('navigator.mediaSession.coordinator.leave()');
|
|
await changePromise();
|
|
testExpected('navigator.mediaSession.coordinator.state', 'closed');
|
|
|
|
latestChange = '';
|
|
|
|
consoleWrite('');
|
|
consoleWrite('** Test that when coordinator methods fail and promises reject after mediaSession.leave() has been called.')
|
|
for (let action of actions)
|
|
await testAction(action.action, action.func, true);
|
|
|
|
consoleWrite(`** Test that mediaSession does not notify coordinator when states change after mediaSession.leave() has been called.`)
|
|
consoleWrite('* PositionState');
|
|
latestChange = '';
|
|
run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 1, position: 0 })');
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
|
|
consoleWrite('');
|
|
consoleWrite('* ReadyState');
|
|
await testReadyStates(async () => {
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
});
|
|
|
|
consoleWrite('* PlaybackState');
|
|
await testPlaybackStates(async () => {
|
|
await sleepFor(20);
|
|
testExpected('latestChange', '');
|
|
});
|
|
|
|
consoleWrite('<br>');
|
|
consoleWrite('** It should not be possible to join or leave a closed session');
|
|
run('promise = navigator.mediaSession.coordinator.join()');
|
|
await shouldReject(promise).then(() => { }).catch(() => { });
|
|
|
|
let exception;
|
|
try {
|
|
navigator.mediaSession.coordinator.leave();
|
|
} catch (ex) {
|
|
exception = ex;
|
|
}
|
|
let expected = 'InvalidStateError: Unable to leave when state is closed';
|
|
logResult(exception.toString() == expected, `TEST(navigator.mediaSession.coordinator.leave()) THROWS(${expected})`);
|
|
|
|
consoleWrite('');
|
|
endTest();
|
|
}, {once: true});
|
|
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
</body>
|
|
</html> |