diff options
Diffstat (limited to 'docshell/test/browser/frame-head.js')
-rw-r--r-- | docshell/test/browser/frame-head.js | 114 |
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); + }); +} |