summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/mochitest')
-rwxr-xr-x[-rw-r--r--]dom/tests/mochitest/general/mochitest.ini3
-rwxr-xr-xdom/tests/mochitest/general/test_reduce_time_precision.html143
-rwxr-xr-xdom/tests/mochitest/general/worker_child.js28
-rwxr-xr-xdom/tests/mochitest/general/worker_grandchild.js10
4 files changed, 184 insertions, 0 deletions
diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini
index d59527801..d00ea1d4b 100644..100755
--- a/dom/tests/mochitest/general/mochitest.ini
+++ b/dom/tests/mochitest/general/mochitest.ini
@@ -43,6 +43,8 @@ support-files =
frameStoragePrevented.html
frameStorageChrome.html
frameStorageNullprincipal.sjs
+ worker_child.js
+ worker_grandchild.js
workerStorageAllowed.js
workerStoragePrevented.js
storagePermissionsUtils.js
@@ -108,6 +110,7 @@ support-files = test_offsets.js
[test_picture_mutations.html]
[test_pointerPreserves3D.html]
[test_pointerPreserves3DClip.html]
+[test_reduce_time_precision.html]
[test_resource_timing.html]
[test_resource_timing_cross_origin.html]
[test_resource_timing_frameset.html]
diff --git a/dom/tests/mochitest/general/test_reduce_time_precision.html b/dom/tests/mochitest/general/test_reduce_time_precision.html
new file mode 100755
index 000000000..6f149f28d
--- /dev/null
+++ b/dom/tests/mochitest/general/test_reduce_time_precision.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Tor bug
+https://trac.torproject.org/projects/tor/ticket/1517
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Tor Bug 1517 and Mozilla Bug 1424341</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://trac.torproject.org/projects/tor/ticket/1517">Tor Bug 1517</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1424341">Mozilla Bug 1424341</a>
+
+<!-- Canvas for testing 'currentTime' -->
+<canvas id="test-canvas" width="100" height="100"></canvas>
+
+<!-- The main testing script -->
+<script type="application/javascript">
+ SimpleTest.requestFlakyTimeout("testing JS time-based fingerprinting");
+
+ // Prepare for test of AudioContext.currentTime
+ let audioContext = new AudioContext();
+ // Prepare for test of CanvasStream.currentTime
+ let canvas = document.getElementById("test-canvas");
+ let context = canvas.getContext("2d");
+ context.fillText("test", 20, 20);
+ let canvasStream = canvas.captureStream(25);
+
+ // Known ways to generate time stamps, in milliseconds
+ const timeStampCodes = [
+ "performance.now()",
+ "new Date().getTime()",
+ "new Event(\"\").timeStamp",
+ "new File([], \"\").lastModified",
+ "new File([], \"\").lastModifiedDate.getTime()",
+ ];
+ // These are measured in seconds, so we need to scale them up
+ var timeStampCodesDOM = timeStampCodes.concat([
+ "audioContext.currentTime * 1000",
+ "canvasStream.currentTime * 1000",
+ ]);
+
+ let isRounded = (x) => {
+ expectedPrecision = 2;
+ let rounded = (Math.floor(x / expectedPrecision) * expectedPrecision);
+ // First we do the perfectly normal check that should work just fine
+ if (rounded === x || x === 0)
+ return true;
+
+ // When we're diving by non-whole numbers, we may not get perfect
+ // multiplication/division because of floating points.
+ // When dealing with ms since epoch, a double's precision is on the order
+ // of 1/5 of a microsecond, so we use a value a little higher than that as
+ // our epsilon.
+ // To be clear, this error is introduced in our re-calculation of 'rounded'
+ // above in JavaScript.
+ if (Math.abs(rounded - x + expectedPrecision) < .0005) {
+ return true;
+ } else if (Math.abs(rounded - x) < .0005) {
+ return true;
+ }
+
+ // Then we handle the case where you're sub-millisecond and the timer is not
+ // We check that the timer is not sub-millisecond by assuming it is not if it
+ // returns an even number of milliseconds
+ if (expectedPrecision < 1 && Math.round(x) == x) {
+ if (Math.round(rounded) == x) {
+ return true;
+ }
+ }
+
+ ok(false, "Looming Test Failure, Additional Debugging Info: Expected Precision: " + expectedPrecision + " Measured Value: " + x +
+ " Rounded Vaue: " + rounded + " Fuzzy1: " + Math.abs(rounded - x + expectedPrecision) +
+ " Fuzzy 2: " + Math.abs(rounded - x));
+
+ return false;
+ };
+
+ // ================================================================================================
+ // ================================================================================================
+
+ function* checkWorker(worker) {
+ // The child worker will send the results back.
+ let checkWorkerTimeStamps = () => new Promise(function(resolve) {
+ let onMessage = function(event) {
+ worker.removeEventListener("message", onMessage);
+
+ let timeStamps = event.data;
+ for (let i = 0; i < timeStampCodes.length; i++) {
+ let timeStamp = timeStamps[i];
+ ok(isRounded(timeStamp),
+ "'" + timeStampCodes[i] +
+ "' should be rounded to nearest 2 ms in workers; saw " +
+ timeStamp);
+ }
+ resolve();
+ };
+ worker.addEventListener("message", onMessage);
+ });
+
+ // Send the codes to its child worker.
+ worker.postMessage(timeStampCodes);
+
+ // First, check the child's results.
+ yield checkWorkerTimeStamps();
+ // Then, check the grandchild's results.
+ yield checkWorkerTimeStamps();
+
+ worker.terminate();
+ }
+
+ add_task(function*() {
+ let worker = new Worker("worker_child.js");
+ // Allow ~550 ms to elapse, so we can get non-zero
+ // time values for all elements.
+ yield new Promise(resolve => window.setTimeout(resolve, 550));
+ yield checkWorker(worker);
+ });
+
+ // ================================================================================================
+ // ================================================================================================
+
+
+ add_task(function*() {
+ // Loop through each timeStampCode, evaluate it,
+ // and check if it is rounded
+ for (let timeStampCode of timeStampCodesDOM) {
+ let timeStamp = eval(timeStampCode);
+ ok(isRounded(timeStamp),
+ "'" + timeStampCode + "' should be rounded to nearest 2ms" +
+ " saw " + timeStamp);
+ }
+ });
+
+</script>
+
+
+</body>
+</html>
diff --git a/dom/tests/mochitest/general/worker_child.js b/dom/tests/mochitest/general/worker_child.js
new file mode 100755
index 000000000..fa340fc65
--- /dev/null
+++ b/dom/tests/mochitest/general/worker_child.js
@@ -0,0 +1,28 @@
+let timeStampCodes;
+let worker = new Worker("worker_grandchild.js");
+
+function listenToParent(event) {
+ self.removeEventListener("message", listenToParent);
+ timeStampCodes = event.data;
+
+ let timeStamps = [];
+ for (let timeStampCode of timeStampCodes) {
+ timeStamps.push(eval(timeStampCode));
+ }
+ // Send the timeStamps to the parent.
+ postMessage(timeStamps);
+
+ // Tell the grandchild to start.
+ worker.postMessage(timeStampCodes);
+}
+
+// The worker grandchild will send results back.
+function listenToChild(event) {
+ worker.removeEventListener("message", listenToChild);
+ // Pass the results to the parent.
+ postMessage(event.data);
+ worker.terminate();
+}
+
+worker.addEventListener("message", listenToChild);
+self.addEventListener("message", listenToParent);
diff --git a/dom/tests/mochitest/general/worker_grandchild.js b/dom/tests/mochitest/general/worker_grandchild.js
new file mode 100755
index 000000000..cd21508b2
--- /dev/null
+++ b/dom/tests/mochitest/general/worker_grandchild.js
@@ -0,0 +1,10 @@
+self.addEventListener("message", function(event) {
+ let timeStampCodes = event.data;
+
+ let timeStamps = [];
+ for (let timeStampCode of timeStampCodes) {
+ timeStamps.push(eval(timeStampCode));
+ }
+ // Send the timeStamps to the parent.
+ postMessage(timeStamps);
+});