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