Bug 1137944 - Add tests. r=roc

This commit is contained in:
Jim Mathies 2015-10-06 14:23:24 -05:00
parent 1137203dba
commit d10be39a5c
7 changed files with 421 additions and 65 deletions

View File

@ -1,8 +1,13 @@
[DEFAULT]
support-files =
head.js
plugin_test.html
[browser_bug1163570.js]
skip-if = (!e10s || os != "win")
[browser_bug1196539.js]
skip-if = (!e10s || os != "win")
[browser_tabswitchbetweenplugins.js]
skip-if = (!e10s || os != "win")
[browser_pluginscroll.js]
skip-if = (!e10s || os != "win")

View File

@ -1,27 +1,5 @@
var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
// Returns the chrome side nsIPluginTag for this plugin
function getTestPlugin(aName) {
let pluginName = aName || "Test Plug-in";
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let tags = ph.getPluginTags();
// Find the test plugin
for (let i = 0; i < tags.length; i++) {
if (tags[i].name == pluginName)
return tags[i];
}
ok(false, "Unable to find plugin");
return null;
}
// Set the test plugin state, disabling features like click-to-play
function setTestPluginEnabledState(newEnabledState, pluginName) {
let name = pluginName || "Test Plug-in";
let plugin = getTestPlugin(name);
plugin.enabledState = newEnabledState;
}
// simple tab load helper, pilfered from browser plugin tests
function promiseTabLoad(tab, url, eventType="load") {
return new Promise((resolve, reject) => {

View File

@ -1,45 +1,5 @@
let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
// Returns the chrome side nsIPluginTag for this plugin
function getTestPlugin(aName) {
let pluginName = aName || "Test Plug-in";
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let tags = ph.getPluginTags();
// Find the test plugin
for (let i = 0; i < tags.length; i++) {
if (tags[i].name == pluginName)
return tags[i];
}
ok(false, "Unable to find plugin");
return null;
}
// Set the test plugin state, disabling features like click-to-play
function setTestPluginEnabledState(newEnabledState, pluginName) {
let name = pluginName || "Test Plug-in";
let plugin = getTestPlugin(name);
plugin.enabledState = newEnabledState;
}
function promiseNewTabSwitched() {
return new Promise(resolve => {
gBrowser.addEventListener("TabSwitchDone", function onSwitch() {
gBrowser.removeEventListener("TabSwitchDone", onSwitch);
executeSoon(resolve);
});
});
}
function waitForMs(aMs) {
return new Promise((resolve) => {
setTimeout(done, aMs);
function done() {
resolve(true);
}
});
}
function checkPaintCount(aCount) {
ok(aCount != 0, "paint count can't be greater than zero, count was " + aCount);
ok(aCount < kMaxPaints, "paint count should be within limits, count was " + aCount);
@ -82,7 +42,7 @@ add_task(function* () {
});
// select plugin tab
tabSwitchedPromise = promiseNewTabSwitched();
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = pluginTab;
yield tabSwitchedPromise;
@ -105,7 +65,7 @@ add_task(function* () {
checkPaintCount(result);
// select home tab
tabSwitchedPromise = promiseNewTabSwitched();
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = homeTab;
yield tabSwitchedPromise;
@ -142,7 +102,7 @@ add_task(function* () {
});
// select plugin tab
tabSwitchedPromise = promiseNewTabSwitched();
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = pluginTab;
yield tabSwitchedPromise;

View File

@ -0,0 +1,173 @@
let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
/**
* tests for plugin windows and scroll
*/
function coordinatesRelativeToWindow(aX, aY, aElement) {
var targetWindow = aElement.ownerDocument.defaultView;
var scale = targetWindow.devicePixelRatio;
var rect = aElement.getBoundingClientRect();
return {
x: targetWindow.mozInnerScreenX + ((rect.left + aX) * scale),
y: targetWindow.mozInnerScreenY + ((rect.top + aY) * scale)
};
}
let apzEnabled = Preferences.get("layers.async-pan-zoom.enabled", false);
let pluginHideEnabled = Preferences.get("gfx.e10s.hide-plugins-for-scroll", true);
add_task(function* () {
registerCleanupFunction(function () {
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
});
});
add_task(function*() {
yield new Promise((resolve) => {
SpecialPowers.pushPrefEnv({
"set": [
["general.smoothScroll", true],
["general.smoothScroll.other", true],
["general.smoothScroll.mouseWheel", true],
["general.smoothScroll.other.durationMaxMS", 2000],
["general.smoothScroll.other.durationMinMS", 1999],
["general.smoothScroll.mouseWheel.durationMaxMS", 2000],
["general.smoothScroll.mouseWheel.durationMinMS", 1999],
]}, resolve);
});
});
/*
* test plugin visibility when scrolling with scroll wheel and apz.
*/
add_task(function* () {
let result;
if (!apzEnabled) {
ok(true, "nothing to test, need apz");
return;
}
if (!pluginHideEnabled) {
ok(true, "nothing to test, need gfx.e10s.hide-plugins-for-scroll");
return;
}
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
let testTab = gBrowser.selectedTab;
let pluginTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gTestRoot + "plugin_test.html");
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return !!plugin;
});
is(result, true, "plugin is loaded");
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin is visible");
let nativeId = nativeVerticalWheelEventMsg();
let utils = SpecialPowers.getDOMWindowUtils(window);
let screenCoords = coordinatesRelativeToWindow(10, 10,
gBrowser.selectedBrowser);
utils.sendNativeMouseScrollEvent(screenCoords.x, screenCoords.y,
nativeId, 0, -50, 0, 0, 0,
gBrowser.selectedBrowser);
yield waitScrollStart(gBrowser.selectedBrowser);
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin is hidden");
yield waitScrollFinish(gBrowser.selectedBrowser);
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin is visible");
gBrowser.removeTab(pluginTab);
});
/*
* test visibility when scrolling with keyboard shortcuts. This circumvents apz
* and relies on dom scroll, which is what we want to target for this test. Note
* this test should only run with e10s since we do not hide plugin windows when
* scrolling in single process mode.
*/
add_task(function* () {
let result;
if (!pluginHideEnabled) {
ok(true, "nothing to test, need gfx.e10s.hide-plugins-for-scroll");
return;
}
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
let testTab = gBrowser.selectedTab;
let pluginTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gTestRoot + "plugin_test.html");
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return !!plugin;
});
is(result, true, "plugin is loaded");
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin is visible");
EventUtils.synthesizeKey("VK_END", {});
yield waitScrollStart(gBrowser.selectedBrowser);
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin is hidden");
yield waitScrollFinish(gBrowser.selectedBrowser);
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin is hidden");
EventUtils.synthesizeKey("VK_HOME", {});
yield waitScrollFinish(gBrowser.selectedBrowser);
result = yield ContentTask.spawn(pluginTab.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin is visible");
gBrowser.removeTab(pluginTab);
});

View File

@ -0,0 +1,105 @@
let gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
// tests that we get plugin updates when we flip between tabs that
// have the same plugin in the same position in the page.
add_task(function* () {
let result, tabSwitchedPromise;
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
let testTab = gBrowser.selectedTab;
let pluginTab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gTestRoot + "plugin_test.html");
let pluginTab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gTestRoot + "plugin_test.html");
result = yield ContentTask.spawn(pluginTab1.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return !!plugin;
});
is(result, true, "plugin1 is loaded");
result = yield ContentTask.spawn(pluginTab2.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return !!plugin;
});
is(result, true, "plugin2 is loaded");
// plugin tab 2 should be selected
is(gBrowser.selectedTab == pluginTab2, true, "plugin2 is selected");
result = yield ContentTask.spawn(pluginTab1.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin1 is hidden");
result = yield ContentTask.spawn(pluginTab2.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin2 is visible");
// select plugin1 tab
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = pluginTab1;
yield tabSwitchedPromise;
result = yield ContentTask.spawn(pluginTab1.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin1 is visible");
result = yield ContentTask.spawn(pluginTab2.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin2 is hidden");
// select plugin2 tab
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = pluginTab2;
yield tabSwitchedPromise;
result = yield ContentTask.spawn(pluginTab1.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin1 is hidden");
result = yield ContentTask.spawn(pluginTab2.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, true, "plugin2 is visible");
// select test tab
tabSwitchedPromise = waitTabSwitched();
gBrowser.selectedTab = testTab;
yield tabSwitchedPromise;
result = yield ContentTask.spawn(pluginTab1.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin1 is hidden");
result = yield ContentTask.spawn(pluginTab2.linkedBrowser, null, function*() {
let doc = content.document;
let plugin = doc.getElementById("testplugin");
return XPCNativeWrapper.unwrap(plugin).nativeWidgetIsVisible();
});
is(result, false, "plugin2 is hidden");
gBrowser.removeTab(pluginTab1);
gBrowser.removeTab(pluginTab2);
});

View File

@ -0,0 +1,134 @@
/**
* Waits for a tab switch.
*/
function waitTabSwitched() {
return new Promise(resolve => {
gBrowser.addEventListener("TabSwitchDone", function onSwitch() {
gBrowser.removeEventListener("TabSwitchDone", onSwitch);
executeSoon(resolve);
});
});
}
/**
* Waits a specified number of miliseconds.
*
* Usage:
* let wait = yield waitForMs(2000);
* ok(wait, "2 seconds should now have elapsed");
*
* @param aMs the number of miliseconds to wait for
* @returns a Promise that resolves to true after the time has elapsed
*/
function waitForMs(aMs) {
return new Promise((resolve) => {
setTimeout(done, aMs);
function done() {
resolve(true);
}
});
}
/**
* Platform string helper for nativeVerticalWheelEventMsg
*/
function getPlatform() {
if (navigator.platform.indexOf("Win") == 0) {
return "windows";
}
if (navigator.platform.indexOf("Mac") == 0) {
return "mac";
}
if (navigator.platform.indexOf("Linux") == 0) {
return "linux";
}
return "unknown";
}
/**
* Returns a native wheel scroll event id for dom window
* uitls sendNativeMouseScrollEvent.
*/
function nativeVerticalWheelEventMsg() {
switch (getPlatform()) {
case "windows": return 0x020A; // WM_MOUSEWHEEL
case "mac": return 0; // value is unused, can be anything
case "linux": return 4; // value is unused, pass GDK_SCROLL_SMOOTH anyway
}
throw "Native wheel events not supported on platform " + getPlatform();
}
/**
* Waits for the first dom "scroll" event.
*/
function waitScrollStart(aTarget) {
return new Promise((resolve, reject) => {
aTarget.addEventListener("scroll", function listener(event) {
aTarget.removeEventListener("scroll", listener, true);
resolve(event);
}, true);
});
}
/**
* Waits for the last dom "scroll" event which generally indicates
* a scroll operation is complete. To detect this the helper waits
* 1 second intervals checking for scroll events from aTarget. If
* a scroll event is not received during that time, it considers
* the scroll operation complete. Not super accurate, be careful.
*/
function waitScrollFinish(aTarget) {
return new Promise((resolve, reject) => {
let recent = false;
let count = 0;
function listener(event) {
recent = true;
}
aTarget.addEventListener("scroll", listener, true);
setInterval(function () {
// one second passed and we didn't receive a scroll event.
if (!recent) {
aTarget.removeEventListener("scroll", listener, true);
resolve();
return;
}
recent = false;
// ten seconds
if (count > 10) {
aTarget.removeEventListener("scroll", listener, true);
reject();
}
}, 1000);
});
}
/**
* Set a plugin activation state. See nsIPluginTag for
* supported states. Affected plugin default to the first
* test plugin.
*/
function setTestPluginEnabledState(aState, aPluginName) {
let name = aPluginName || "Test Plug-in";
let plugin = getTestPlugin(name);
plugin.enabledState = aState;
}
/**
* Returns the chrome side nsIPluginTag for this plugin, helper for
* setTestPluginEnabledState.
*/
function getTestPlugin(aName) {
let pluginName = aName || "Test Plug-in";
let ph = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
let tags = ph.getPluginTags();
// Find the test plugin
for (let i = 0; i < tags.length; i++) {
if (tags[i].name == pluginName)
return tags[i];
}
ok(false, "Unable to find plugin");
return null;
}

View File

@ -6,5 +6,6 @@
<body>
<embed id="testplugin" type="application/x-test" drawmode="solid" color="ff00ff00" wmode="window"
style="position:absolute; top:50px; left:50px; width:500px; height:250px">
<div style="display:block; height:3000px;"></div>
</body>
</html>