blob: 5eb715fa9977713548be5704d1d7e476862624dc [file] [log] [blame]
<!DOCTYPE html>
<!--
| Test the SpeechSynthesis interface.
-->
<html>
<head>
<style>
body {
background-color: #FFFFFF;
}
</style>
<script>
var on_voices_changed_event_count = 0;
function log_info(message) {
console.log(message);
document.getElementById('info').innerHTML += message + '.\n';
}
function log_error(message) {
console.log(message);
document.getElementById('error').innerHTML += message + '.\n';
}
function assert(condition, message) {
if (!condition) { log_error('ASSERT: ' + message + '.'); }
}
function SaySomething(voice) {
var unheard_utterance_text = 'You Should Not Hear This.';
var utterance_text = 'Cobalt can talk.';
var final_utterance_text = 'It really can!';
var utterance = new SpeechSynthesisUtterance(unheard_utterance_text);
assert(utterance, 'new SpeechSynthesisUtterance failed');
assert(typeof utterance != undefined,
'new SpeechSynthesisUtterance undefined');
assert(utterance.text === unheard_utterance_text,
'SpeechSynthesisUtterance doesn\'t get text from constructor');
assert(utterance.onstart !== undefined,
'SpeechSynthesisUtterance doesn\'t define start event handler');
assert(utterance.onend !== undefined,
'SpeechSynthesisUtterance doesn\'t define end event handler');
assert(utterance.onpause !== undefined,
'SpeechSynthesisUtterance doesn\'t define pause event handler');
assert(utterance.onresume !== undefined,
'SpeechSynthesisUtterance doesn\'t define resume event handler');
assert(utterance.onmark !== undefined,
'SpeechSynthesisUtterance doesn\'t define mark event handler');
utterance.onmark = function(e) { log_info('SpeechSynthesisUtterance onmark called for: ' + e.utterance.text); }
assert(utterance.onboundary !== undefined,
'SpeechSynthesisUtterance doesn\'t define boundary event handler');
utterance.onboundary = function(e) { log_info('SpeechSynthesisUtterance onboundary called for: ' + e.utterance.text); }
assert(utterance.voice !== undefined,
'SpeechSynthesisUtterance doesn\'t define voice attribute');
assert(typeof utterance.voice !== 'SpeechSynthesisVoice',
'SpeechSynthesisUtterance voice isn\'t of type SpeechSynthesisVoice');
utterance.voice = voice;
assert(utterance.volume !== undefined,
'SpeechSynthesisUtterance doesn\'t define volume attribute');
utterance.volume = 1.0;
assert(utterance.rate !== undefined,
'SpeechSynthesisUtterance doesn\'t define rate attribute');
utterance.rate = 1.0;
assert(utterance.pitch !== undefined,
'SpeechSynthesisUtterance doesn\'t define pitch attribute');
utterance.pitch = 1.0;
assert(utterance.onerror !== undefined,
'SpeechSynthesisUtterance doesn\'t define error event handler');
utterance.onerror = function(e) { log_info('SpeechSynthesisUtterance onerror called as expected with: ' + e.error); }
assert(utterance.lang !== undefined,
'SpeechSynthesisUtterance doesn\'t define lang attribute');
utterance.lang = "Martian is not a language";
utterance.onstart = function(e) { log_error('SpeechSynthesisUtterance onstart called for: ' + e.utterance.text); }
utterance.onend = function(e) { log_error('SpeechSynthesisUtterance onend called for: ' + e.utterance.text); }
utterance.onpause = function(e) { log_error('SpeechSynthesisUtterance onpause called for: ' + e.utterance.text); }
utterance.onresume = function(e) { log_error('SpeechSynthesisUtterance onresume called for: ' + e.utterance.text); }
assert(speechSynthesis.speak !== undefined,
'SpeechSynthesis doesn\'t define speak');
speechSynthesis.speak(utterance);
utterance.lang = voice.lang;
assert(speechSynthesis.pause !== undefined,
'SpeechSynthesis doesn\'t define pause');
speechSynthesis.pause();
// These will be canceled below. They will not be heard.
speechSynthesis.speak(utterance);
speechSynthesis.speak(utterance);
speechSynthesis.speak(utterance);
utterance.onerror = function(e) { log_error('SpeechSynthesisUtterance onerror called as with: ' + e.error); }
assert(speechSynthesis.cancel !== undefined,
'SpeechSynthesis doesn\'t define cancel');
speechSynthesis.cancel();
assert(speechSynthesis.resume !== undefined,
'SpeechSynthesis doesn\'t define resume');
speechSynthesis.resume();
speechSynthesis.pause();
utterance.text = utterance_text;
utterance.onstart = function(e) { log_info('SpeechSynthesisUtterance onstart called for: ' + e.utterance.text); }
utterance.onend = function(e) { log_info('SpeechSynthesisUtterance onend called for: ' + e.utterance.text); }
assert(utterance.text === utterance_text,
'SpeechSynthesisUtterance text doesn\'t get text updated');
speechSynthesis.speak(utterance);
utterance.text = final_utterance_text;
utterance.onstart = function(e) { log_info('SpeechSynthesisUtterance onstart called again for: ' + e.utterance.text); }
utterance.onend = function(e) { log_info('SpeechSynthesisUtterance onend called again for: ' + e.utterance.text); }
speechSynthesis.resume();
log_info('You should hear \"' + utterance_text + '\" being spoken (once), with onstart and onend calls');
speechSynthesis.speak(utterance);
log_info('You should hear \"' + final_utterance_text + '\" being spoken (once), with onstart and onend calls');
}
function onVoicesChanged() {
if (on_voices_changed_event_count) {
console.log('Note: onVoicesChanged called more than once.');
return;
}
++on_voices_changed_event_count;
assert(speechSynthesis.getVoices !== undefined,
'SpeechSynthesis doesn\'t define getVoices');
var voices = speechSynthesis.getVoices();
assert(voices, 'SpeechSynthesis.getVoices() returned nothing');
assert(typeof voices !== undefined,
'SpeechSynthesis.getVoices() returned undefined type');
document.getElementById('voice_count').innerHTML = voices.length;
assert(voices.length > 0,
'SpeechSynthesis.getVoices() returned no voices');
var voice = voices[0];
assert(voice, 'First voice element is nothing');
assert(typeof voice !== undefined,
'First voice element is of undefined type');
assert(voice.name !== undefined, 'Voice does not have a name attribute');
assert(voice.lang !== undefined,
'Voice does not have a language attribute');
assert(voice.lang.length > 0,
'Voice has an empty language attribute string');
assert(voice.voiceURI !== undefined,
'Voice does not have a URI attribute');
assert(voice.localService !== undefined,
'Voice does not have a localservice attribute');
assert(voice.default !== undefined,
'Voice does not have a default attribute');
var voice_data = 'name=\'' + voice.name + '\' ' +
'lang=\'' + voice.lang + '\' ' +
'URI=\'' + voice.voiceURI + '\' ' +
'local=' + voice.localService + ' ' +
'default=' + voice.default;
document.getElementById('voice_data').innerHTML = voice_data;
SaySomething(voice);
}
window.onload = function() {
document.getElementById('lang').innerHTML = navigator.language;
assert(window.speechSynthesis !== undefined,
'window.SpeechSynthesis doesn\'t exist');
assert(speechSynthesis, 'SpeechSynthesis doesn\'t exist');
assert(typeof speechSynthesis !== undefined,
'SpeechSynthesis is of undefined type');
assert(speechSynthesis === window.speechSynthesis,
'SpeechSynthesis doesn\'t match window.SpeechSynthesis');
assert(speechSynthesis.onvoiceschanged !== undefined,
'SpeechSynthesis doesn\'t define voiceschanged event handler');
speechSynthesis.onvoiceschanged = onVoicesChanged;
assert(speechSynthesis.pending !== undefined,
'SpeechSynthesis does not define pending attribute');
assert(speechSynthesis.speaking !== undefined,
'SpeechSynthesis does not define speaking attribute');
assert(speechSynthesis.paused !== undefined,
'SpeechSynthesis does not define paused attribute');
window.setTimeout(function() {
if (!on_voices_changed_event_count) {
log_error('ERROR: onVoicesChanged never called!');
}
}, 333);
}
</script>
</head>
<body>
<div>Speech Synthesis Test
<div>Document Language: <span id='lang'>-</div>
<div>Voice Count: <span id='voice_count'>-</div>
<div>Voice Data: <span id='voice_data'>-</div>
<span id='error' style='white-space: pre; color:#FFFFFF; background-color:#FF0000'></span>
<span id='info' style='white-space: pre; background-color:#00FF00'></span>
<div>
</div>
</body>
</html>