Bug 1483701 - Split and re-enable browser_ext_browserAction_popup_resize.js. r=mixedpuppy

This patch applies the following changes:

- Reduce the chances of retrieving the initial popup panel size while it is resizing, by comparing the
  content dimensions retrieved before and after the delay (which is already set to a value comparable
  to the time used by the resize debouncing timer), and wait until both the dimensions collected are the same

- split browser_ext_browserAction_popup_resize.js into two test files (as it seems, based on the investigations
  I did by reproducing this intermittent locally, that the part that can still fail intermittently from time
  to time with the change describe above is related to the testBrowserActionMenuResizeBottomArrow test case)

- move the test helpers shared between the two test files into a new head_browserAction.js support file

- re-enabled browser_ext_browserAction_popup_resize.js

- mark the new browser_ext_browserAction_popup_resize_bottom.js as disabled on debug build,
  because it is consistently triggering a "shutdown leak" failure when running locally

Differential Revision: https://phabricator.services.mozilla.com/D17267

--HG--
rename : browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js => browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize_bottom.js
rename : browser/components/extensions/test/browser/browser_ext_browserAction_popup_resize.js => browser/components/extensions/test/browser/head_browserAction.js
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2019-01-25 19:54:57 +00:00
parent daa2b37d25
commit b73f5349af
5 changed files with 315 additions and 250 deletions

View File

@ -4,6 +4,7 @@ prefs =
dom.animations-api.timelines.enabled=true
support-files =
silence.ogg
head_browserAction.js
head_pageAction.js
head_sessions.js
head_webNavigation.js
@ -60,7 +61,8 @@ skip-if = (debug && os == 'linux' && bits == 32) || (os == 'win' && !debug) # Bu
[browser_ext_browserAction_popup_preload.js]
skip-if = (os == 'win' && !debug) || (verify && debug && (os == 'mac')) # bug 1352668
[browser_ext_browserAction_popup_resize.js]
skip-if = (os == 'mac' || os == 'win' || os == 'linux') || (verify && debug) #Bug 1482004,1483701
[browser_ext_browserAction_popup_resize_bottom.js]
skip-if = debug # Bug 1522164
[browser_ext_browserAction_simple.js]
[browser_ext_browserAction_telemetry.js]
[browser_ext_browserAction_theme_icons.js]

View File

@ -2,11 +2,8 @@
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function openPanel(extension, win = window, awaitLoad = false) {
clickBrowserAction(extension, win);
return awaitExtensionPanel(extension, win, awaitLoad);
}
Services.scriptloader.loadSubScript(new URL("head_browserAction.js", gTestPath).href,
this);
add_task(async function testSetup() {
Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
@ -28,7 +25,7 @@ add_task(async function testBrowserActionPopupResize() {
await extension.startup();
let browser = await openPanel(extension, undefined, true);
let browser = await openBrowserActionPanel(extension, undefined, true);
async function checkSize(expected) {
let dims = await promiseContentDimensions(browser);
@ -61,219 +58,13 @@ add_task(async function testBrowserActionPopupResize() {
await checkSize(size);
}
let popup = getBrowserActionPopup(extension);
await closeBrowserAction(extension);
is(popup.state, "closed", "browserAction popup has been closed");
await extension.unload();
});
async function testPopupSize(standardsMode, browserWin = window, arrowSide = "top") {
let docType = standardsMode ? "<!DOCTYPE html>" : "";
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {
"default_popup": "popup.html",
"browser_style": false,
},
},
files: {
"popup.html": `${docType}
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
body > span {
display: inline-block;
width: 10px;
height: 150px;
border: 2px solid black;
}
.big > span {
width: 300px;
height: 100px;
}
.bigger > span {
width: 150px;
height: 150px;
}
.huge > span {
height: ${2 * screen.height}px;
}
</style>
</head>
<body>
<span></span>
<span></span>
<span></span>
<span></span>
</body>
</html>`,
},
});
await extension.startup();
if (arrowSide == "top") {
// Test the standalone panel for a toolbar button.
let browser = await openPanel(extension, browserWin, true);
let dims = await promiseContentDimensions(browser);
is(dims.isStandards, standardsMode, "Document has the expected compat mode");
let {innerWidth, innerHeight} = dims.window;
dims = await alterContent(browser, () => {
content.document.body.classList.add("bigger");
});
let win = dims.window;
is(win.innerHeight, innerHeight, "Window height should not change");
ok(win.innerWidth > innerWidth, `Window width should increase (${win.innerWidth} > ${innerWidth})`);
dims = await alterContent(browser, () => {
content.document.body.classList.remove("bigger");
});
win = dims.window;
is(win.innerHeight, innerHeight, "Window height should not change");
// The getContentSize calculation is not always reliable to single-pixel
// precision.
ok(Math.abs(win.innerWidth - innerWidth) <= 1,
`Window width should return to approximately its original value (${win.innerWidth} ~= ${innerWidth})`);
await closeBrowserAction(extension, browserWin);
}
// Test the PanelUI panel for a menu panel button.
let widget = getBrowserActionWidget(extension);
CustomizableUI.addWidgetToArea(widget.id, getCustomizableUIPanelID());
let panel = browserWin.PanelUI.overflowPanel;
panel.setAttribute("animate", "false");
let panelMultiView = panel.firstElementChild;
let widgetId = makeWidgetId(extension.id);
// The 'ViewShown' event is the only way to correctly determine when the extensions'
// panelview has finished transitioning and is fully in view.
let shownPromise = BrowserTestUtils.waitForEvent(panelMultiView, "ViewShown",
e => (e.originalTarget.id || "").includes(widgetId));
let browser = await openPanel(extension, browserWin);
let origPanelRect = panel.getBoundingClientRect();
// Check that the panel is still positioned as expected.
let checkPanelPosition = () => {
is(panel.getAttribute("side"), arrowSide, "Panel arrow is positioned as expected");
let panelRect = panel.getBoundingClientRect();
if (arrowSide == "top") {
is(panelRect.top, origPanelRect.top, "Panel has not moved downwards");
ok(panelRect.bottom >= origPanelRect.bottom, `Panel has not shrunk from original size (${panelRect.bottom} >= ${origPanelRect.bottom})`);
let screenBottom = browserWin.screen.availTop + browserWin.screen.availHeight;
let panelBottom = browserWin.mozInnerScreenY + panelRect.bottom;
ok(Math.round(panelBottom) <= screenBottom, `Bottom of popup should be on-screen. (${panelBottom} <= ${screenBottom})`);
} else {
is(panelRect.bottom, origPanelRect.bottom, "Panel has not moved upwards");
ok(panelRect.top <= origPanelRect.top, `Panel has not shrunk from original size (${panelRect.top} <= ${origPanelRect.top})`);
let panelTop = browserWin.mozInnerScreenY + panelRect.top;
ok(panelTop >= browserWin.screen.availTop, `Top of popup should be on-screen. (${panelTop} >= ${browserWin.screen.availTop})`);
}
};
await awaitBrowserLoaded(browser);
await shownPromise;
// Wait long enough to make sure the initial resize debouncing timer has
// expired.
await delay(500);
let dims = await promiseContentDimensions(browser);
is(dims.isStandards, standardsMode, "Document has the expected compat mode");
// If the browser's preferred height is smaller than the initial height of the
// panel, then it will still take up the full available vertical space. Even
// so, we need to check that we've gotten the preferred height calculation
// correct, so check that explicitly.
let getHeight = () => parseFloat(browser.style.height);
let {innerWidth, innerHeight} = dims.window;
let height = getHeight();
let setClass = className => {
content.document.body.className = className;
};
info("Increase body children's width. " +
"Expect them to wrap, and the frame to grow vertically rather than widen.");
dims = await alterContent(browser, setClass, "big");
let win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
info("Increase body children's width and height. " +
"Expect them to wrap, and the frame to grow vertically rather than widen.");
dims = await alterContent(browser, setClass, "bigger");
win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
info("Increase body height beyond the height of the screen. " +
"Expect the panel to grow to accommodate, but not larger than the height of the screen.");
dims = await alterContent(browser, setClass, "huge");
win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight > innerHeight, `Window height should increase (${win.innerHeight} > ${innerHeight})`);
// Commented out check for the window height here which mysteriously breaks
// on infra but not locally. bug 1396843 covers re-enabling this.
// ok(win.innerHeight < screen.height, `Window height be less than the screen height (${win.innerHeight} < ${screen.height})`);
ok(win.scrollMaxY > 0, `Document should be vertically scrollable (${win.scrollMaxY} > 0)`);
checkPanelPosition();
info("Restore original styling. Expect original dimensions.");
dims = await alterContent(browser, setClass, "");
win = dims.window;
is(getHeight(), height, "Browser height should return to its original value");
is(win.innerWidth, innerWidth, "Window width should not change");
is(win.innerHeight, innerHeight, "Window height should return to its original value");
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
await closeBrowserAction(extension, browserWin);
await extension.unload();
}
add_task(async function testBrowserActionMenuResizeStandards() {
await testPopupSize(true);
@ -283,40 +74,6 @@ add_task(async function testBrowserActionMenuResizeQuirks() {
await testPopupSize(false);
});
// Test that we still make reasonable maximum size calculations when the window
// is close enough to the bottom of the screen that the menu panel opens above,
// rather than below, its button.
add_task(async function testBrowserActionMenuResizeBottomArrow() {
const WIDTH = 800;
const HEIGHT = 80;
let left = screen.availLeft + screen.availWidth - WIDTH;
let top = screen.availTop + screen.availHeight - HEIGHT;
let win = await BrowserTestUtils.openNewBrowserWindow();
win.resizeTo(WIDTH, HEIGHT);
// Sometimes we run into problems on Linux with resizing being asynchronous
// and window managers not allowing us to move the window so that any part of
// it is off-screen, so we need to try more than once.
for (let i = 0; i < 20; i++) {
win.moveTo(left, top);
if (win.screenX == left && win.screenY == top) {
break;
}
await delay(100);
}
await SimpleTest.promiseFocus(win);
await testPopupSize(true, win, "bottom");
await BrowserTestUtils.closeWindow(win);
});
add_task(async function testTeardown() {
Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
});

View File

@ -0,0 +1,48 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
Services.scriptloader.loadSubScript(new URL("head_browserAction.js", gTestPath).href,
this);
add_task(async function testSetup() {
Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
});
// Test that we still make reasonable maximum size calculations when the window
// is close enough to the bottom of the screen that the menu panel opens above,
// rather than below, its button.
add_task(async function testBrowserActionMenuResizeBottomArrow() {
const WIDTH = 800;
const HEIGHT = 80;
let left = screen.availLeft + screen.availWidth - WIDTH;
let top = screen.availTop + screen.availHeight - HEIGHT;
let win = await BrowserTestUtils.openNewBrowserWindow();
win.resizeTo(WIDTH, HEIGHT);
// Sometimes we run into problems on Linux with resizing being asynchronous
// and window managers not allowing us to move the window so that any part of
// it is off-screen, so we need to try more than once.
for (let i = 0; i < 20; i++) {
win.moveTo(left, top);
if (win.screenX == left && win.screenY == top) {
break;
}
await delay(100);
}
await SimpleTest.promiseFocus(win);
await testPopupSize(true, win, "bottom");
await BrowserTestUtils.closeWindow(win);
});
add_task(async function testTeardown() {
Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
});

View File

@ -6,6 +6,7 @@
* getBrowserActionWidget
* clickBrowserAction clickPageAction
* getBrowserActionPopup getPageActionPopup getPageActionButton
* openBrowserActionPanel
* closeBrowserAction closePageAction
* promisePopupShown promisePopupHidden
* toggleBookmarksToolbar
@ -288,6 +289,12 @@ function closeBrowserAction(extension, win = window) {
return Promise.resolve();
}
function openBrowserActionPanel(extension, win = window, awaitLoad = false) {
clickBrowserAction(extension, win);
return awaitExtensionPanel(extension, win, awaitLoad);
}
async function toggleBookmarksToolbar(visible = true) {
let bookmarksToolbar = document.getElementById("PersonalToolbar");
let transitionPromise =

View File

@ -0,0 +1,251 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
/* exported testPopupSize */
// This file is imported into the same scope as head.js.
/* import-globals-from head.js */
// A test helper that retrives an old and new value after a given delay
// and then check that calls an `isCompleted` callback to check that
// the value has reached the expected value.
function waitUntilValue({getValue, isCompleted, message, delay: delayTime}) {
return BrowserTestUtils.waitForCondition(async () => {
const oldVal = await getValue();
await delay(delayTime);
const newVal = await getValue();
return isCompleted(oldVal, newVal);
}, message);
}
async function testPopupSize(standardsMode, browserWin = window, arrowSide = "top") {
let docType = standardsMode ? "<!DOCTYPE html>" : "";
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {
"default_popup": "popup.html",
"browser_style": false,
},
},
files: {
"popup.html": `${docType}
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
body > span {
display: inline-block;
width: 10px;
height: 150px;
border: 2px solid black;
}
.big > span {
width: 300px;
height: 100px;
}
.bigger > span {
width: 150px;
height: 150px;
}
.huge > span {
height: ${2 * screen.height}px;
}
</style>
</head>
<body>
<span></span>
<span></span>
<span></span>
<span></span>
</body>
</html>`,
},
});
await extension.startup();
if (arrowSide == "top") {
// Test the standalone panel for a toolbar button.
let browser = await openBrowserActionPanel(extension, browserWin, true);
let dims = await promiseContentDimensions(browser);
is(dims.isStandards, standardsMode, "Document has the expected compat mode");
let {innerWidth, innerHeight} = dims.window;
dims = await alterContent(browser, () => {
content.document.body.classList.add("bigger");
});
let win = dims.window;
is(win.innerHeight, innerHeight, "Window height should not change");
ok(win.innerWidth > innerWidth, `Window width should increase (${win.innerWidth} > ${innerWidth})`);
dims = await alterContent(browser, () => {
content.document.body.classList.remove("bigger");
});
win = dims.window;
is(win.innerHeight, innerHeight, "Window height should not change");
// The getContentSize calculation is not always reliable to single-pixel
// precision.
ok(Math.abs(win.innerWidth - innerWidth) <= 1,
`Window width should return to approximately its original value (${win.innerWidth} ~= ${innerWidth})`);
await closeBrowserAction(extension, browserWin);
}
// Test the PanelUI panel for a menu panel button.
let widget = getBrowserActionWidget(extension);
CustomizableUI.addWidgetToArea(widget.id, getCustomizableUIPanelID());
let panel = browserWin.PanelUI.overflowPanel;
panel.setAttribute("animate", "false");
let panelMultiView = panel.firstElementChild;
let widgetId = makeWidgetId(extension.id);
// The 'ViewShown' event is the only way to correctly determine when the extensions'
// panelview has finished transitioning and is fully in view.
let shownPromise = BrowserTestUtils.waitForEvent(panelMultiView, "ViewShown",
e => (e.originalTarget.id || "").includes(widgetId));
let browser = await openBrowserActionPanel(extension, browserWin);
// Wait long enough to make sure the initial popup positioning has been completed.
await waitUntilValue({
getValue: () => panel.getBoundingClientRect().top,
isCompleted: (oldVal, newVal) => {
// Wait for the popup positioning to be started and the value stable.
return newVal !== 0 && oldVal === newVal;
},
message: "Wait the popup opening to be completed",
delay: 500,
});
let origPanelRect = panel.getBoundingClientRect();
// Check that the panel is still positioned as expected.
let checkPanelPosition = () => {
is(panel.getAttribute("side"), arrowSide, "Panel arrow is positioned as expected");
let panelRect = panel.getBoundingClientRect();
if (arrowSide == "top") {
is(panelRect.top, origPanelRect.top, "Panel has not moved downwards");
ok(panelRect.bottom >= origPanelRect.bottom, `Panel has not shrunk from original size (${panelRect.bottom} >= ${origPanelRect.bottom})`);
let screenBottom = browserWin.screen.availTop + browserWin.screen.availHeight;
let panelBottom = browserWin.mozInnerScreenY + panelRect.bottom;
ok(Math.round(panelBottom) <= screenBottom, `Bottom of popup should be on-screen. (${panelBottom} <= ${screenBottom})`);
} else {
is(panelRect.bottom, origPanelRect.bottom, "Panel has not moved upwards");
ok(panelRect.top <= origPanelRect.top, `Panel has not shrunk from original size (${panelRect.top} <= ${origPanelRect.top})`);
let panelTop = browserWin.mozInnerScreenY + panelRect.top;
ok(panelTop >= browserWin.screen.availTop, `Top of popup should be on-screen. (${panelTop} >= ${browserWin.screen.availTop})`);
}
};
await awaitBrowserLoaded(browser);
await shownPromise;
// Wait long enough to make sure the initial resize debouncing timer has
// expired.
await waitUntilValue({
getValue: () => promiseContentDimensions(browser),
isCompleted: (oldDims, newDims) => {
return oldDims.window.innerWidth === newDims.window.innerWidth &&
oldDims.window.innerHeight === newDims.window.innerHeight;
},
message: "Wait the popup resize to be completed",
delay: 500,
});
let dims = await promiseContentDimensions(browser);
is(dims.isStandards, standardsMode, "Document has the expected compat mode");
// If the browser's preferred height is smaller than the initial height of the
// panel, then it will still take up the full available vertical space. Even
// so, we need to check that we've gotten the preferred height calculation
// correct, so check that explicitly.
let getHeight = () => parseFloat(browser.style.height);
let {innerWidth, innerHeight} = dims.window;
let height = getHeight();
let setClass = className => {
content.document.body.className = className;
};
info("Increase body children's width. " +
"Expect them to wrap, and the frame to grow vertically rather than widen.");
dims = await alterContent(browser, setClass, "big");
let win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
info("Increase body children's width and height. " +
"Expect them to wrap, and the frame to grow vertically rather than widen.");
dims = await alterContent(browser, setClass, "bigger");
win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight >= innerHeight, `Window height should increase (${win.innerHeight} >= ${innerHeight})`);
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
info("Increase body height beyond the height of the screen. " +
"Expect the panel to grow to accommodate, but not larger than the height of the screen.");
dims = await alterContent(browser, setClass, "huge");
win = dims.window;
ok(getHeight() > height, `Browser height should increase (${getHeight()} > ${height})`);
is(win.innerWidth, innerWidth, "Window width should not change");
ok(win.innerHeight > innerHeight, `Window height should increase (${win.innerHeight} > ${innerHeight})`);
// Commented out check for the window height here which mysteriously breaks
// on infra but not locally. bug 1396843 covers re-enabling this.
// ok(win.innerHeight < screen.height, `Window height be less than the screen height (${win.innerHeight} < ${screen.height})`);
ok(win.scrollMaxY > 0, `Document should be vertically scrollable (${win.scrollMaxY} > 0)`);
checkPanelPosition();
info("Restore original styling. Expect original dimensions.");
dims = await alterContent(browser, setClass, "");
win = dims.window;
is(getHeight(), height, "Browser height should return to its original value");
is(win.innerWidth, innerWidth, "Window width should not change");
is(win.innerHeight, innerHeight, "Window height should return to its original value");
Assert.lessOrEqual(win.scrollMaxY, 1, "Document should not be vertically scrollable");
checkPanelPosition();
await closeBrowserAction(extension, browserWin);
await extension.unload();
}