fune/toolkit/content/tests/browser/head.js
Timothy Guan-tin Chien 9292b73037 Bug 1512489 - Convert datetime-popup binding to a JSM r=Felipe
Differential Revision: https://phabricator.services.mozilla.com/D13944

--HG--
rename : toolkit/content/widgets/datetimepopup.xml => toolkit/modules/DateTimePickerPanel.jsm
extra : moz-landing-system : lando
2018-12-21 21:51:57 +00:00

299 lines
8.9 KiB
JavaScript

"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
/**
* A wrapper for the findbar's method "close", which is not synchronous
* because of animation.
*/
function closeFindbarAndWait(findbar) {
return new Promise((resolve) => {
if (findbar.hidden) {
resolve();
return;
}
findbar.addEventListener("transitionend", function cont(aEvent) {
if (aEvent.propertyName != "visibility") {
return;
}
findbar.removeEventListener("transitionend", cont);
resolve();
});
findbar.close();
});
}
function pushPrefs(...aPrefs) {
return new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
});
}
/**
* Used to check whether the audio unblocking icon is in the tab.
*/
async function waitForTabBlockEvent(tab, expectBlocked) {
if (tab.activeMediaBlocked == expectBlocked) {
ok(true, "The tab should " + (expectBlocked ? "" : "not ") + "be blocked");
} else {
info("Block state doens't match, wait for attributes changes.");
await BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, (event) => {
if (event.detail.changed.includes("activemedia-blocked")) {
is(tab.activeMediaBlocked, expectBlocked, "The tab should " + (expectBlocked ? "" : "not ") + "be blocked");
return true;
}
return false;
});
}
}
/**
* Used to check whether the tab has soundplaying attribute.
*/
async function waitForTabPlayingEvent(tab, expectPlaying) {
if (tab.soundPlaying == expectPlaying) {
ok(true, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
} else {
info("Playing state doens't match, wait for attributes changes.");
await BrowserTestUtils.waitForEvent(tab, "TabAttrModified", false, (event) => {
if (event.detail.changed.includes("soundplaying")) {
is(tab.soundPlaying, expectPlaying, "The tab should " + (expectPlaying ? "" : "not ") + "be playing");
return true;
}
return false;
});
}
}
function getTestPlugin(pluginName) {
var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
.getService(SpecialPowers.Ci.nsIPluginHost);
var tags = ph.getPluginTags();
var name = pluginName || "Test Plug-in";
for (var tag of tags) {
if (tag.name == name) {
return tag;
}
}
ok(false, "Could not find plugin tag with plugin name '" + name + "'");
return null;
}
function setTestPluginEnabledState(newEnabledState, pluginName) {
var oldEnabledState = SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName);
if (!oldEnabledState) {
return;
}
var plugin = getTestPlugin(pluginName);
// Run a nested event loop to wait for the preference change to
// propagate to the child. Yuck!
SpecialPowers.Services.tm.spinEventLoopUntil(() => {
return plugin.enabledState == newEnabledState;
});
SimpleTest.registerCleanupFunction(function() {
SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName);
});
}
function disable_non_test_mouse(disable) {
let utils = window.windowUtils;
utils.disableNonTestMouseEvents(disable);
}
function hover_icon(icon, tooltip) {
disable_non_test_mouse(true);
let popupShownPromise = BrowserTestUtils.waitForEvent(tooltip, "popupshown");
EventUtils.synthesizeMouse(icon, 1, 1, {type: "mouseover"});
EventUtils.synthesizeMouse(icon, 2, 2, {type: "mousemove"});
EventUtils.synthesizeMouse(icon, 3, 3, {type: "mousemove"});
EventUtils.synthesizeMouse(icon, 4, 4, {type: "mousemove"});
return popupShownPromise;
}
function leave_icon(icon) {
EventUtils.synthesizeMouse(icon, 0, 0, {type: "mouseout"});
EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mousemove"});
disable_non_test_mouse(false);
}
/**
* Helper class for testing datetime input picker widget
*/
class DateTimeTestHelper {
constructor() {
this.panel = document.getElementById("DateTimePickerPanel");
this.panel.setAttribute("animate", false);
this.tab = null;
this.frame = null;
}
/**
* Opens a new tab with the URL of the test page, and make sure the picker is
* ready for testing.
*
* @param {String} pageUrl
*/
async openPicker(pageUrl) {
this.tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
await BrowserTestUtils.synthesizeMouseAtCenter("input", {}, gBrowser.selectedBrowser);
this.frame = this.panel.querySelector("#dateTimePopupFrame");
await this.waitForPickerReady();
}
async waitForPickerReady() {
let readyPromise;
let loadPromise = new Promise(resolve => {
this.frame.addEventListener("load", () => {
// Add the PickerReady event listener directly inside the load event
// listener to avoid missing the event.
readyPromise = BrowserTestUtils.waitForEvent(this.frame.contentDocument, "PickerReady");
resolve();
}, { capture: true, once: true });
});
await loadPromise;
// Wait for picker elements to be ready
await readyPromise;
}
/**
* Find an element on the picker.
*
* @param {String} selector
* @return {DOMElement}
*/
getElement(selector) {
return this.frame.contentDocument.querySelector(selector);
}
/**
* Find the children of an element on the picker.
*
* @param {String} selector
* @return {Array<DOMElement>}
*/
getChildren(selector) {
return Array.from(this.getElement(selector).children);
}
/**
* Click on an element
*
* @param {DOMElement} element
*/
click(element) {
EventUtils.synthesizeMouseAtCenter(element, {}, this.frame.contentWindow);
}
/**
* Close the panel and the tab
*/
async tearDown() {
if (!this.panel.hidden) {
let pickerClosePromise = new Promise(resolve => {
this.panel.addEventListener("popuphidden", resolve, {once: true});
});
this.panel.hidePopup();
await pickerClosePromise;
}
BrowserTestUtils.removeTab(this.tab);
this.tab = null;
}
/**
* Clean up after tests. Remove the frame to prevent leak.
*/
cleanup() {
this.frame.remove();
this.frame = null;
this.panel.removeAttribute("animate");
this.panel = null;
}
}
/**
* Used to listen events if you just need it once
*/
function once(target, name) {
var p = new Promise(function(resolve, reject) {
target.addEventListener(name, function() {
resolve();
}, {once: true});
});
return p;
}
// Runs a content script that creates an autoplay video.
// browser: the browser to run the script in.
// args: test case definition, required members {
// mode: String, "autoplay attribute" or "call play".
// }
function loadAutoplayVideo(browser, args) {
return ContentTask.spawn(browser, args, async (args) => {
info("- create a new autoplay video -");
let video = content.document.createElement("video");
video.id = "v1";
video.didPlayPromise = new Promise((resolve, reject) => {
video.addEventListener("playing", (e) => {
video.didPlay = true;
resolve();
}, {once: true});
video.addEventListener("blocked", (e) => {
video.didPlay = false;
resolve();
}, {once: true});
});
if (args.mode == "autoplay attribute") {
info("autoplay attribute set to true");
video.autoplay = true;
} else if (args.mode == "call play") {
info("will call play() when reached loadedmetadata");
video.addEventListener("loadedmetadata", (e) => {
video.play().then(
() => {
info("video play() resolved");
},
() => {
info("video play() rejected");
});
}, {once: true});
} else {
ok(false, "Invalid 'mode' arg");
}
video.src = "gizmo.mp4";
content.document.body.appendChild(video);
});
}
// Runs a content script that checks whether the video created by
// loadAutoplayVideo() started playing.
// Parameters:
// browser: the browser to run the script in.
// args: test case definition, required members {
// name: String, description of test.
// mode: String, "autoplay attribute" or "call play".
// shouldPlay: boolean, whether video should play.
// }
function checkVideoDidPlay(browser, args) {
return ContentTask.spawn(browser, args, async (args) => {
let video = content.document.getElementById("v1");
await video.didPlayPromise;
is(video.didPlay, args.shouldPlay,
args.name + " should " + (!args.shouldPlay ? "not " : "") + "be able to autoplay");
video.src = "";
content.document.body.remove(video);
});
}
// The JS content loaded by frame script can be used across different content
// tasks.
function loadFrameScript(browser, fn) {
const mm = browser.messageManager;
mm.loadFrameScript("data:,(" + fn.toString() + ")();", false);
}