Bug 1333641 - Part 2: Add a test case to verify the behavior of speechSynthesis API when 'privacy.resistfingerprinting' is true. r?smaug,arthuredelstein
This patch adds a test case to verify the speechSynthesis API when fingerprinting
resistance is enabled. This test will first make sure the speechSynthesis has been
setup correctly and then flip the pref 'privacy.resistFingerprinting'. Then, it
will test speechSynthesis.getVoices(), onvoiceschanged event and speechSynthesis.speak().
MozReview-Commit-ID: 33BcZcHPgat
--- a/browser/components/resistfingerprinting/test/mochitest/mochitest.ini
+++ b/browser/components/resistfingerprinting/test/mochitest/mochitest.ini
@@ -6,8 +6,9 @@ support-files =
!/dom/tests/mochitest/geolocation/network_geolocation.sjs
[test_device_sensor_event.html]
[test_geolocation.html]
scheme = https
[test_reduce_time_precision.html]
[test_hide_gamepad_info.html]
support-files = test_hide_gamepad_info_iframe.html
+[test_speech_synthesis.html]
new file mode 100644
--- /dev/null
+++ b/browser/components/resistfingerprinting/test/mochitest/test_speech_synthesis.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1333641
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1333641</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1333641 **/
+ SimpleTest.waitForExplicitFinish();
+ window.onload = setupSpeechSynthesis;
+
+ // This function setup the speechSynthesis and flip 'privacy.resistFingerprinting'
+ // after it has been setup correctly.
+ function setupSpeechSynthesis() {
+ window.speechSynthesis.addEventListener("voiceschanged", () => {
+ isnot(window.speechSynthesis.getVoices().length, 0, "Voices added");
+ SimpleTest.waitForFocus(() => {
+ SpecialPowers.pushPrefEnv({"set":
+ [["privacy.resistFingerprinting", true]]
+ }, doGetVoicesTest);
+ }, window);
+ }, {once: true});
+
+ is(window.speechSynthesis.getVoices().length, 0, "No voices added initially");
+ }
+
+ function doGetVoicesTest() {
+ is(window.speechSynthesis.getVoices().length, 0,
+ "There should be no voices after fingerprinting resistance is enabled.");
+ doVoiceschangedEventTest();
+ }
+
+ function doVoiceschangedEventTest() {
+ window.speechSynthesis.addEventListener("voiceschanged", () => {
+ ok(false, "The voiceschanged event should not be fired.");
+ doSpeakTestAsync();
+ }, {once: true});
+
+ window.addEventListener("TestEvent", () => {
+ // If we receive this event without receiving a 'voiceschanged' event, this means
+ // the voiceschanged event has been blocked correctly.
+ ok(true, "Got the 'TestEvent' event.");
+ doSpeakTestAsync();
+ }, {once: true});
+
+ // Notify 'synth-voices-changed' for triggering the voiceschanged event.
+ SpecialPowers.Services.obs.notifyObservers(null, "synth-voices-changed");
+ window.dispatchEvent(new CustomEvent("TestEvent"));
+ }
+
+ // This tests Speak() and its asynchronousness.
+ function doSpeakTestAsync() {
+ // For non-e10s, this test will always fail since the event will be triggered immediately
+ // after speak() is called. So, new added events after speak() won't be called. We skip
+ // this test if it is non-e10s.
+ if (SpecialPowers.Services.appinfo.browserTabsRemoteAutostart) {
+ let utterance = new window.SpeechSynthesisUtterance("Hello, world!");
+ window.speechSynthesis.speak(utterance);
+
+ utterance.addEventListener("start", () => {
+ ok(false, "speechSynthesis should not start speaking if fingerprinting resistance is enabled.");
+ doSpeakTestSync();
+ }, {once: true});
+
+ utterance.addEventListener("error", () => {
+ ok(true, "speechSynthesis.speak should fail if fingerprinting resistance is enabled.");
+ doSpeakTestSync();
+ }, {once: true});
+ } else {
+ doSpeakTestSync();
+ }
+ }
+
+ // This tests Speak() and its synchronousness.
+ function doSpeakTestSync() {
+ let utterance = new window.SpeechSynthesisUtterance("Hello, world!");
+ utterance.addEventListener("start", () => {
+ ok(false, "speechSynthesis should not start speaking if fingerprinting resistance is enabled.");
+ SimpleTest.finish();
+ }, {once: true});
+
+ utterance.addEventListener("error", () => {
+ ok(true, "speechSynthesis.speak should fail if fingerprinting resistance is enabled.");
+ SimpleTest.finish();
+ }, {once: true});
+
+ window.speechSynthesis.speak(utterance);
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test"></pre>
+</body>
+</html>