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.js114
1 files changed, 114 insertions, 0 deletions
diff --git a/docshell/test/browser/frame-head.js b/docshell/test/browser/frame-head.js
new file mode 100644
index 0000000000..4cebb32165
--- /dev/null
+++ b/docshell/test/browser/frame-head.js
@@ -0,0 +1,114 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* eslint-env mozilla/frame-script */
+
+// Functions that are automatically loaded as frame scripts for
+// timeline tests.
+
+// eslint assumes we inherit browser window stuff, but this
+// framescript doesn't.
+// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix
+const { setTimeout } = ChromeUtils.importESModule(
+ "resource://gre/modules/Timer.sys.mjs"
+);
+
+// Functions that look like mochitest functions but forward to the
+// browser process.
+
+this.ok = function (value, message) {
+ sendAsyncMessage("browser:test:ok", {
+ value: !!value,
+ message,
+ });
+};
+
+this.is = function (v1, v2, message) {
+ ok(v1 == v2, message);
+};
+
+this.info = function (message) {
+ sendAsyncMessage("browser:test:info", { 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) {
+ (async function () {
+ let docShell = content.docShell;
+
+ 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 = await onMarkers;
+
+ // Cycle collection markers are non-deterministic, and none of these tests
+ // expect them to show up.
+ markers = markers.filter(m => !m.name.includes("nsCycleCollector"));
+
+ 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);
+ });
+}