Cu.import("resource://gre/modules/Promise.jsm"); const SINGLE_TRY_TIMEOUT = 100; const NUMBER_OF_TRIES = 30; function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES) { let defer = Promise.defer(); let tries = 0; function checkCondition() { if (tries >= tryCount) { defer.reject(timeoutMsg); } var conditionPassed; try { conditionPassed = condition(); } catch (e) { return defer.reject(e); } if (conditionPassed) { return defer.resolve(); } tries++; setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); return undefined; } setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); return defer.promise; } function waitForCondition(condition, nextTest, errorMsg) { waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => { ok(false, reason + (reason.stack ? "\n" + reason.stack : "")); }); } /** * Checks if the snapshotted keyed scalars contain the expected * data. * * @param {Object} scalars * The snapshot of the keyed scalars. * @param {String} scalarName * The name of the keyed scalar to check. * @param {String} key * The key that must be within the keyed scalar. * @param {String|Boolean|Number} expectedValue * The expected value for the provided key in the scalar. */ function checkKeyedScalar(scalars, scalarName, key, expectedValue) { Assert.ok(scalarName in scalars, scalarName + " must be recorded."); Assert.ok(key in scalars[scalarName], scalarName + " must contain the '" + key + "' key."); Assert.ok(scalars[scalarName][key], expectedValue, scalarName + "['" + key + "'] must contain the expected value"); } /** * An utility function to write some text in the search input box * in a content page. * @param {Object} browser * The browser that contains the content. * @param {String} text * The string to write in the search field. * @param {String} fieldName * The name of the field to write to. */ let typeInSearchField = Task.async(function* (browser, text, fieldName) { yield ContentTask.spawn(browser, { fieldName, text }, function* ({fieldName, text}) { // Avoid intermittent failures. if (fieldName === "searchText") { content.wrappedJSObject.gContentSearchController.remoteTimeout = 5000; } // Put the focus on the search box. let searchInput = content.document.getElementById(fieldName); searchInput.focus(); searchInput.value = text; }); }); /** * Clear and get the SEARCH_COUNTS histogram. */ function getSearchCountsHistogram() { let search_hist = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS"); search_hist.clear(); return search_hist; } /** * Check that the keyed histogram contains the right value. */ function checkKeyedHistogram(h, key, expectedValue) { const snapshot = h.snapshot(); Assert.ok(key in snapshot, `The histogram must contain ${key}.`); Assert.equal(snapshot[key].sum, expectedValue, `The key ${key} must contain ${expectedValue}.`); } function checkEvents(events, expectedEvents) { if (!Services.telemetry.canRecordExtended) { // Currently we only collect the tested events when extended Telemetry is enabled. return; } Assert.equal(events.length, expectedEvents.length, "Should have matching amount of events."); // Strip timestamps from the events for easier comparison. events = events.map(e => e.slice(1)); for (let i = 0; i < events.length; ++i) { Assert.deepEqual(events[i], expectedEvents[i], "Events should match."); } }