summaryrefslogtreecommitdiffstats
path: root/docshell/test/browser/frame-head.js
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/browser/frame-head.js')
-rw-r--r--docshell/test/browser/frame-head.js113
1 files changed, 113 insertions, 0 deletions
diff --git a/docshell/test/browser/frame-head.js b/docshell/test/browser/frame-head.js
new file mode 100644
index 000000000..5cb3b1513
--- /dev/null
+++ b/docshell/test/browser/frame-head.js
@@ -0,0 +1,113 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Functions that are automatically loaded as frame scripts for
+// timeline tests.
+
+var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
+var { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {});
+
+Cu.import("resource://gre/modules/Timer.jsm");
+
+// Functions that look like mochitest functions but forward to the
+// browser process.
+
+this.ok = function(value, message) {
+ sendAsyncMessage("browser:test:ok", {
+ value: !!value,
+ message: message});
+}
+
+this.is = function(v1, v2, message) {
+ ok(v1 == v2, message);
+}
+
+this.info = function(message) {
+ sendAsyncMessage("browser:test:info", {message: message});
+}
+
+this.finish = function() {
+ sendAsyncMessage("browser:test:finish");
+}
+
+/* Start a task that runs some timeline tests in the ordinary way.
+ *
+ * @param array tests
+ * The tests to run. This is an array where each element
+ * is of the form { desc, searchFor, setup, check }.
+ *
+ * desc is the test description, a string.
+ * searchFor is a string or a function
+ * If a string, then when a marker with this name is
+ * found, marker-reading is stopped.
+ * If a function, then the accumulated marker array is
+ * passed to it, and marker reading stops when it returns
+ * true.
+ * setup is a function that takes the docshell as an argument.
+ * It should start the test.
+ * check is a function that takes an array of markers
+ * as an argument and checks the results of the test.
+ */
+this.timelineContentTest = function(tests) {
+ Task.spawn(function*() {
+ let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ info("Start recording");
+ docShell.recordProfileTimelineMarkers = true;
+
+ for (let {desc, searchFor, setup, check} of tests) {
+
+ info("Running test: " + desc);
+
+ info("Flushing the previous markers if any");
+ docShell.popProfileTimelineMarkers();
+
+ info("Running the test setup function");
+ let onMarkers = timelineWaitForMarkers(docShell, searchFor);
+ setup(docShell);
+ info("Waiting for new markers on the docShell");
+ let markers = yield onMarkers;
+
+ // Cycle collection markers are non-deterministic, and none of these tests
+ // expect them to show up.
+ markers = markers.filter(m => m.name.indexOf("nsCycleCollector") === -1);
+
+ info("Running the test check function");
+ check(markers);
+ }
+
+ info("Stop recording");
+ docShell.recordProfileTimelineMarkers = false;
+ finish();
+ });
+}
+
+function timelineWaitForMarkers(docshell, searchFor) {
+ if (typeof(searchFor) == "string") {
+ let searchForString = searchFor;
+ let f = function (markers) {
+ return markers.some(m => m.name == searchForString);
+ };
+ searchFor = f;
+ }
+
+ return new Promise(function(resolve, reject) {
+ let waitIterationCount = 0;
+ let maxWaitIterationCount = 10; // Wait for 2sec maximum
+ let markers = [];
+
+ setTimeout(function timeoutHandler() {
+ let newMarkers = docshell.popProfileTimelineMarkers();
+ markers = [...markers, ...newMarkers];
+ if (searchFor(markers) || waitIterationCount > maxWaitIterationCount) {
+ resolve(markers);
+ } else {
+ setTimeout(timeoutHandler, 200);
+ waitIterationCount++;
+ }
+ }, 200);
+ });
+}