Backed out changeset 9ec09eb75c9f (bug 1842037) for causing bc failures on browser_screenshots_drag_test.js CLOSED TREE

This commit is contained in:
Norisz Fay 2023-11-14 04:06:58 +02:00
parent 91215b6057
commit ba48d1612a
12 changed files with 251 additions and 531 deletions

View File

@ -24,7 +24,7 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
case "Screenshots:ShowOverlay":
return this.startScreenshotsOverlay();
case "Screenshots:HideOverlay":
return this.endScreenshotsOverlay(message.data);
return this.endScreenshotsOverlay();
case "Screenshots:isOverlayShowing":
return this.overlay?.initialized;
case "Screenshots:getFullPageBounds":
@ -33,8 +33,6 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
return this.getVisibleBounds();
case "Screenshots:getDocumentTitle":
return this.getDocumentTitle();
case "Screenshots:GetMethodsUsed":
return this.getMethodsUsed();
}
return null;
}
@ -117,7 +115,7 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
requestCopyScreenshot(region) {
region.devicePixelRatio = this.contentWindow.devicePixelRatio;
this.sendAsyncMessage("Screenshots:CopyScreenshot", { region });
this.endScreenshotsOverlay({ doNotResetMethods: true });
this.endScreenshotsOverlay();
}
/**
@ -130,7 +128,7 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
title: this.getDocumentTitle(),
region,
});
this.endScreenshotsOverlay({ doNotResetMethods: true });
this.endScreenshotsOverlay();
}
showPanel() {
@ -149,12 +147,6 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
this.sendAsyncMessage("Screenshots:OverlaySelection", data);
}
getMethodsUsed() {
let methodsUsed = this.#overlay.methodsUsed;
this.#overlay.resetMethodsUsed();
return methodsUsed;
}
/**
* Resolves when the document is ready to have an overlay injected into it.
*
@ -220,13 +212,13 @@ export class ScreenshotsComponentChild extends JSWindowActorChild {
/**
* Removes event listeners and the screenshots overlay.
*/
endScreenshotsOverlay(options = {}) {
endScreenshotsOverlay() {
this.document.removeEventListener("keydown", this);
this.document.ownerGlobal.removeEventListener("beforeunload", this);
this.contentWindow.removeEventListener("resize", this);
this.contentWindow.removeEventListener("scroll", this);
this.contentWindow.removeEventListener("visibilitychange", this);
this.overlay?.tearDown(options);
this.overlay?.tearDown();
this.#resizeTask?.disarm();
this.#scrollTask?.disarm();
}

View File

@ -44,7 +44,6 @@ const REGION_CHANGE_THRESHOLD = 5;
const SCROLL_BY_EDGE = 20;
export class ScreenshotsOverlay {
#content;
#initialized = false;
#state = "";
#moverId;
@ -54,7 +53,6 @@ export class ScreenshotsOverlay {
#lastClientX;
#lastClientY;
#previousDimensions;
#methodsUsed;
get markup() {
let [cancel, instructions, download, copy] =
@ -146,10 +144,6 @@ export class ScreenshotsOverlay {
return this.#state;
}
get methodsUsed() {
return this.#methodsUsed;
}
constructor(contentDocument) {
this.document = contentDocument;
this.window = contentDocument.ownerGlobal;
@ -157,14 +151,13 @@ export class ScreenshotsOverlay {
this.windowDimensions = new WindowDimensions();
this.selectionRegion = new Region(this.windowDimensions);
this.hoverElementRegion = new Region(this.windowDimensions);
this.resetMethodsUsed();
}
get content() {
if (!this.#content || Cu.isDeadWrapper(this.#content)) {
if (!this._content || Cu.isDeadWrapper(this._content)) {
return null;
}
return this.#content;
return this._content;
}
getElementById(id) {
@ -178,8 +171,8 @@ export class ScreenshotsOverlay {
this.windowDimensions.reset();
this.#content = this.document.insertAnonymousContent();
this.#content.root.appendChild(this.fragment);
this._content = this.document.insertAnonymousContent();
this._content.root.appendChild(this.fragment);
this.initializeElements();
this.updateWindowDimensions();
@ -221,21 +214,17 @@ export class ScreenshotsOverlay {
/**
* Removes all event listeners and removes the overlay from the Anonymous Content
*/
tearDown(options = {}) {
if (this.#content) {
tearDown() {
if (this._content) {
this.removeEventListeners();
if (!(options.doNotResetMethods === true)) {
this.resetMethodsUsed();
}
try {
this.document.removeAnonymousContent(this.#content);
this.document.removeAnonymousContent(this._content);
} catch (e) {
// If the current window isn't the one the content was inserted into, this
// will fail, but that's fine.
}
}
this.#initialized = false;
this.#setState("");
}
/**
@ -292,15 +281,6 @@ export class ScreenshotsOverlay {
this.screenshotsContainer.removeEventListener("pointerup", this);
}
resetMethodsUsed() {
this.#methodsUsed = {
element: 0,
region: 0,
move: 0,
resize: 0,
};
}
/**
* Returns the x and y coordinates of the event relative to both the
* viewport and the page.
@ -762,7 +742,6 @@ export class ScreenshotsOverlay {
eventName: "selected",
reason: "element",
});
this.#methodsUsed.element += 1;
} else {
this.#setState("crosshairs");
}
@ -780,29 +759,7 @@ export class ScreenshotsOverlay {
};
this.selectionRegion.sortCoords();
this.#setState("selected");
this.maybeRecordRegionSelected();
this.#methodsUsed.region += 1;
}
/**
* Update the selection region dimensions by calling `resizingDrag` and set
* the state to selected.
* @param {Number} pageX The x position relative to the page
* @param {Number} pageY The y position relative to the page
*/
resizingDragEnd(pageX, pageY, targetId) {
this.resizingDrag(pageX, pageY, targetId);
this.selectionRegion.sortCoords();
this.#setState("selected");
this.maybeRecordRegionSelected();
if (targetId === "highlight") {
this.#methodsUsed.move += 1;
} else {
this.#methodsUsed.resize += 1;
}
}
maybeRecordRegionSelected() {
let { width, height } = this.selectionRegion.dimensions;
if (
@ -820,6 +777,18 @@ export class ScreenshotsOverlay {
this.#previousDimensions = { width, height };
}
/**
* Update the selection region dimensions by calling `resizingDrag` and set
* the state to selected.
* @param {Number} pageX The x position relative to the page
* @param {Number} pageY The y position relative to the page
*/
resizingDragEnd(pageX, pageY, targetId) {
this.resizingDrag(pageX, pageY, targetId);
this.selectionRegion.sortCoords();
this.#setState("selected");
}
/**
* Draw the preview eyes pointer towards the mouse.
* @param {Number} clientX The x position relative to the viewport

View File

@ -89,7 +89,6 @@ export const UIPhases = {
export var ScreenshotsUtils = {
browserToScreenshotsState: new WeakMap(),
initialized: false,
methodsUsed: {},
/**
* Figures out which of various states the screenshots UI is in, for the given browser.
@ -111,10 +110,6 @@ export var ScreenshotsUtils = {
return UIPhases.CLOSED;
},
resetMethodsUsed() {
this.methodsUsed = { fullpage: 0, visible: 0 };
},
initialize() {
if (!this.initialized) {
if (
@ -125,9 +120,9 @@ export var ScreenshotsUtils = {
) {
return;
}
this.resetMethodsUsed();
Services.telemetry.setEventRecordingEnabled("screenshots", true);
Services.obs.addObserver(this, "menuitem-screenshot");
Services.obs.addObserver(this, "screenshots-take-screenshot");
this.initialized = true;
if (Cu.isInAutomation) {
Services.obs.notifyObservers(null, "screenshots-component-initialized");
@ -138,6 +133,7 @@ export var ScreenshotsUtils = {
uninitialize() {
if (this.initialized) {
Services.obs.removeObserver(this, "menuitem-screenshot");
Services.obs.removeObserver(this, "screenshots-take-screenshot");
this.initialized = false;
}
},
@ -165,6 +161,16 @@ export var ScreenshotsUtils = {
this.start(browser, data);
break;
}
case "screenshots-take-screenshot": {
this.closePanel(browser);
this.closeOverlay(browser);
// init UI as a tab dialog box
this.openPreviewDialog(browser).then(dialog => {
this.doScreenshot(browser, dialog, data);
});
break;
}
}
},
@ -228,7 +234,6 @@ export var ScreenshotsUtils = {
this.closeDialogBox(browser);
this.closePanel(browser);
this.closeOverlay(browser);
this.resetMethodsUsed();
this.browserToScreenshotsState.delete(browser);
if (Cu.isInAutomation) {
Services.obs.notifyObservers(null, "screenshots-exit");
@ -385,9 +390,9 @@ export var ScreenshotsUtils = {
* The overlay lives in the child document; so although closing is actually async, we assume success.
* @param browser The current browser.
*/
closeOverlay(browser, options = {}) {
closeOverlay(browser) {
let actor = this.getActor(browser);
actor?.sendAsyncMessage("Screenshots:HideOverlay", options);
actor?.sendAsyncMessage("Screenshots:HideOverlay");
if (this.browserToScreenshotsState.has(browser)) {
this.setPerBrowserState(browser, {
@ -555,27 +560,23 @@ export var ScreenshotsUtils = {
},
/**
* Open and add screenshot-ui to the dialog box and then take the screenshot
* Add screenshot-ui to the dialog box and then take the screenshot
* @param browser The current browser.
* @param dialog The dialog box to show the screenshot preview.
* @param type The type of screenshot taken.
*/
async doScreenshot(browser, type) {
this.closePanel(browser);
this.closeOverlay(browser, { doNotResetMethods: true });
let dialog = await this.openPreviewDialog(browser);
async doScreenshot(browser, dialog, type) {
await dialog._dialogReady;
let screenshotsUI =
dialog._frame.contentDocument.createElement("screenshots-ui");
dialog._frame.contentDocument.body.appendChild(screenshotsUI);
let rect;
if (type === "full_page") {
if (type === "full-page") {
rect = await this.fetchFullPageBounds(browser);
this.methodsUsed.fullpage += 1;
type = "full_page";
} else {
rect = await this.fetchVisibleBounds(browser);
this.methodsUsed.visible += 1;
}
this.recordTelemetryEvent("selected", type, {});
return this.takeScreenshot(browser, dialog, rect);
@ -677,19 +678,17 @@ export var ScreenshotsUtils = {
let canvas = await this.createCanvas(region, browser);
let url = canvas.toDataURL();
await this.copyScreenshot(url, browser, {
object: "overlay_copy",
});
this.copyScreenshot(url, browser);
this.recordTelemetryEvent("copy", "overlay_copy", {});
},
/**
* Copy the image to the clipboard
* This is called from the preview dialog
* @param dataUrl The image data
* @param browser The current browser
* @param data Telemetry data
*/
async copyScreenshot(dataUrl, browser, data) {
copyScreenshot(dataUrl, browser) {
// Guard against missing image data.
if (!dataUrl) {
return;
@ -722,15 +721,6 @@ export var ScreenshotsUtils = {
);
this.showCopiedConfirmationHint(browser);
let extra = await this.getActor(browser).sendQuery(
"Screenshots:GetMethodsUsed"
);
this.recordTelemetryEvent("copy", data.object, {
...extra,
...this.methodsUsed,
});
this.resetMethodsUsed();
},
/**
@ -743,20 +733,18 @@ export var ScreenshotsUtils = {
let canvas = await this.createCanvas(region, browser);
let dataUrl = canvas.toDataURL();
await this.downloadScreenshot(title, dataUrl, browser, {
object: "overlay_download",
});
await this.downloadScreenshot(title, dataUrl, browser);
this.recordTelemetryEvent("download", "overlay_download", {});
},
/**
* Download the screenshot
* This is called from the preview dialog
* @param title The title of the current page or null and getFilename will get the title
* @param dataUrl The image data
* @param browser The current browser
* @param data Telemetry data
*/
async downloadScreenshot(title, dataUrl, browser, data) {
async downloadScreenshot(title, dataUrl, browser) {
// Guard against missing image data.
if (!dataUrl) {
return;
@ -785,23 +773,9 @@ export var ScreenshotsUtils = {
// Await successful completion of the save via the download manager
await download.start();
} catch (ex) {}
let extra = await this.getActor(browser).sendQuery(
"Screenshots:GetMethodsUsed"
);
this.recordTelemetryEvent("download", data.object, {
...extra,
...this.methodsUsed,
});
this.resetMethodsUsed();
},
recordTelemetryEvent(type, object, args) {
if (args) {
for (let key of Object.keys(args)) {
args[key] = args[key].toString();
}
}
Services.telemetry.recordEvent("screenshots", type, object, null, args);
},
};

View File

@ -6,6 +6,8 @@
"use strict";
ChromeUtils.defineESModuleGetters(this, {
Downloads: "resource://gre/modules/Downloads.sys.mjs",
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs",
});
@ -76,16 +78,15 @@ class ScreenshotsUI extends HTMLElement {
await ScreenshotsUtils.downloadScreenshot(
null,
dataUrl,
this.openerBrowser,
{ object: "preview_download" }
this.openerBrowser
);
ScreenshotsUtils.recordTelemetryEvent("download", "preview_download", {});
this.close();
}
async saveToClipboard(dataUrl) {
await ScreenshotsUtils.copyScreenshot(dataUrl, this.openerBrowser, {
object: "preview_copy",
});
saveToClipboard(dataUrl) {
ScreenshotsUtils.copyScreenshot(dataUrl, this.openerBrowser);
ScreenshotsUtils.recordTelemetryEvent("copy", "preview_copy", {});
this.close();
}
}

View File

@ -8,10 +8,6 @@
// This is loaded into chrome windows with the subscript loader. Wrap in
// a block to prevent accidentally leaking globals onto `window`.
{
ChromeUtils.defineESModuleGetters(this, {
ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs",
});
class ScreenshotsButtons extends MozXULElement {
static get markup() {
return `
@ -29,14 +25,22 @@
let fragment = MozXULElement.parseXULToFragment(this.constructor.markup);
this.shadowRoot.append(fragment);
let visibleButton = shadowRoot.querySelector(".visible-page");
visibleButton.onclick = function () {
ScreenshotsUtils.doScreenshot(gBrowser.selectedBrowser, "visible");
let button1 = shadowRoot.querySelector(".visible-page");
button1.onclick = function () {
Services.obs.notifyObservers(
gBrowser.ownerGlobal,
"screenshots-take-screenshot",
"visible"
);
};
let fullpageButton = shadowRoot.querySelector(".full-page");
fullpageButton.onclick = function () {
ScreenshotsUtils.doScreenshot(gBrowser.selectedBrowser, "full_page");
let button2 = shadowRoot.querySelector(".full-page");
button2.onclick = function () {
Services.obs.notifyObservers(
gBrowser.ownerGlobal,
"screenshots-take-screenshot",
"full-page"
);
};
}

View File

@ -16,9 +16,6 @@ add_task(async function dragTest() {
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let expected = Math.floor(
490 * (await getContentDevicePixelRatio(browser))
);
helper.triggerUIFromToolbar();
@ -26,18 +23,21 @@ add_task(async function dragTest() {
await helper.dragOverlay(10, 10, 500, 500);
let clipboardChanged = helper.waitForRawClipboardChange(
expected,
expected
);
let clipboardChanged = helper.waitForRawClipboardChange();
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
let expected = Math.floor(
490 * (await getContentDevicePixelRatio(browser))
);
Assert.equal(
result.width,
expected,
@ -68,9 +68,6 @@ add_task(async function dragTest1Point5Zoom() {
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let expected = Math.floor(
50 * (await getContentDevicePixelRatio(browser))
);
helper.triggerUIFromToolbar();
@ -78,16 +75,14 @@ add_task(async function dragTest1Point5Zoom() {
await helper.dragOverlay(300, 100, 350, 150);
let clipboardChanged = helper.waitForRawClipboardChange(
expected,
expected
);
let clipboardChanged = helper.waitForRawClipboardChange();
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
result.zoom = zoom;
result.devicePixelRatio = window.devicePixelRatio;
result.contentDevicePixelRatio = await getContentDevicePixelRatio(
@ -96,6 +91,10 @@ add_task(async function dragTest1Point5Zoom() {
info("result: " + JSON.stringify(result, null, 2));
let expected = Math.floor(
50 * (await getContentDevicePixelRatio(browser))
);
Assert.equal(
result.width,
expected,
@ -164,7 +163,7 @@ add_task(async function overlayCancelButton() {
await helper.dragOverlay(10, 10, 300, 300);
await helper.clickCancelButton();
helper.clickCancelButton();
await helper.waitForOverlayClosed();
@ -188,9 +187,6 @@ add_task(async function preserveBoxSizeWhenMovingOutOfWindowBounds() {
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let expected = Math.floor(
490 * (await getContentDevicePixelRatio(browser))
);
helper.triggerUIFromToolbar();
@ -221,18 +217,21 @@ add_task(async function preserveBoxSizeWhenMovingOutOfWindowBounds() {
Math.floor((endY - startY) / 2)
);
let clipboardChanged = helper.waitForRawClipboardChange(
expected,
expected
);
let clipboardChanged = helper.waitForRawClipboardChange();
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
let expected = Math.floor(
490 * (await getContentDevicePixelRatio(browser))
);
Assert.equal(
result.width,
expected,
@ -262,9 +261,6 @@ add_task(async function resizeAllEdges() {
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let expected = Math.floor(
300 * (await getContentDevicePixelRatio(browser))
);
helper.triggerUIFromToolbar();
@ -336,21 +332,24 @@ add_task(async function resizeAllEdges() {
state = await helper.getOverlayState();
Assert.equal(state, "selected", "The overlay is in the selected state");
let clipboardChanged = helper.waitForRawClipboardChange(
expected,
expected
);
let clipboardChanged = helper.waitForRawClipboardChange();
helper.endX = 400;
helper.endY = 400;
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
let expected = Math.floor(
300 * (await getContentDevicePixelRatio(browser))
);
Assert.equal(
result.width,
expected,
@ -380,9 +379,6 @@ add_task(async function resizeAllCorners() {
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let expected = Math.floor(
300 * (await getContentDevicePixelRatio(browser))
);
helper.triggerUIFromToolbar();
@ -446,21 +442,24 @@ add_task(async function resizeAllCorners() {
state = await helper.getOverlayState();
Assert.equal(state, "selected", "The overlay is in the selected state");
let clipboardChanged = helper.waitForRawClipboardChange(
expected,
expected
);
let clipboardChanged = helper.waitForRawClipboardChange();
helper.endX = 400;
helper.endY = 400;
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
let expected = Math.floor(
300 * (await getContentDevicePixelRatio(browser))
);
Assert.equal(
result.width,
expected,

View File

@ -37,49 +37,11 @@ const COPY_EVENTS = [
];
const CONTENT_EVENTS = [
{ category: "screenshots", method: "selected", object: "region_selection" },
{ category: "screenshots", method: "selected", object: "region_selection" },
{ category: "screenshots", method: "started", object: "overlay_retry" },
{ category: "screenshots", method: "selected", object: "element" },
];
const EXTRA_OVERLAY_EVENTS = [
{ category: "screenshots", method: "started", object: "toolbar_button" },
{
category: "screenshots",
method: "copy",
object: "overlay_copy",
extra: {
element: "1",
region: "1",
move: "1",
resize: "1",
fullpage: "0",
visible: "0",
},
},
];
const EXTRA_EVENTS = [
{ category: "screenshots", method: "started", object: "toolbar_button" },
{ category: "screenshots", method: "selected", object: "visible" },
{ category: "screenshots", method: "started", object: "preview_retry" },
{ category: "screenshots", method: "selected", object: "full_page" },
{
category: "screenshots",
method: "copy",
object: "preview_copy",
extra: {
element: "0",
region: "0",
move: "0",
resize: "0",
fullpage: "1",
visible: "1",
},
},
];
add_task(async function test_started_and_canceled_events() {
await SpecialPowers.pushPrefEnv({
set: [
@ -272,7 +234,7 @@ add_task(async function test_canceled() {
await helper.dragOverlay(50, 50, 300, 300);
screenshotExit = TestUtils.topicObserved("screenshots-exit");
await helper.clickCancelButton();
helper.clickCancelButton();
await helper.waitForOverlayClosed();
await screenshotExit;
@ -291,16 +253,6 @@ add_task(async function test_copy() {
async browser => {
await clearAllTelemetryEvents();
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
helper.triggerUIFromToolbar();
info("waiting for overlay");
@ -325,10 +277,7 @@ add_task(async function test_copy() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
let screenshotExit = TestUtils.topicObserved("screenshots-exit");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
info("clicking the copy button");
@ -345,13 +294,10 @@ add_task(async function test_copy() {
await helper.dragOverlay(50, 50, 300, 300);
clipboardChanged = helper.waitForRawClipboardChange(
devicePixelRatio * 250,
devicePixelRatio * 250
);
clipboardChanged = helper.waitForRawClipboardChange();
screenshotExit = TestUtils.topicObserved("screenshots-exit");
await helper.clickCopyButton();
helper.clickCopyButton();
info("Waiting for clipboard change");
await clipboardChanged;
@ -379,89 +325,12 @@ add_task(async function test_content_events() {
await helper.dragOverlay(50, 50, 300, 300);
await helper.dragOverlay(300, 300, 333, 333, "selected");
await helper.dragOverlay(150, 150, 200, 200, "selected");
mouse.click(11, 11);
await helper.waitForStateChange("crosshairs");
await helper.clickTestPageElement();
let screenshotExit = TestUtils.topicObserved("screenshots-exit");
await helper.clickCopyButton();
info("Waiting for exit");
await screenshotExit;
await assertScreenshotsEvents(CONTENT_EVENTS, "content", false);
await assertScreenshotsEvents(EXTRA_OVERLAY_EVENTS);
}
);
});
add_task(async function test_extra_telemetry() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: TEST_PAGE,
},
async browser => {
await clearAllTelemetryEvents();
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
helper.triggerUIFromToolbar();
info("waiting for overlay");
await helper.waitForOverlay();
info("waiting for panel");
let panel = await helper.waitForPanel();
let screenshotReady = TestUtils.topicObserved(
"screenshots-preview-ready"
);
// click the visible page button in panel
let visiblePageButton = panel
.querySelector("screenshots-buttons")
.shadowRoot.querySelector(".visible-page");
visiblePageButton.click();
info("clicked visible page, waiting for screenshots-preview-ready");
await screenshotReady;
let dialog = helper.getDialog();
let retryButton = dialog._frame.contentDocument.getElementById("retry");
retryButton.click();
info("waiting for panel");
panel = await helper.waitForPanel();
screenshotReady = TestUtils.topicObserved("screenshots-preview-ready");
// click the full page button in panel
let fullPageButton = panel
.querySelector("screenshots-buttons")
.shadowRoot.querySelector(".full-page");
fullPageButton.click();
await screenshotReady;
let screenshotExit = TestUtils.topicObserved("screenshots-exit");
dialog = helper.getDialog();
let copyButton = dialog._frame.contentDocument.getElementById("copy");
retryButton.click();
// click copy button on dialog box
info("clicking the copy button");
copyButton.click();
info("waiting for screenshot exit");
await screenshotExit;
info("Waiting for assertScreenshotsEvents");
await assertScreenshotsEvents(EXTRA_EVENTS);
await assertScreenshotsEvents(CONTENT_EVENTS, "content");
}
);
});

View File

@ -84,7 +84,7 @@ add_task(async function test_download_without_filepicker() {
await helper.waitForOverlay();
await helper.dragOverlay(10, 10, 500, 500);
await helper.clickDownloadButton();
helper.clickDownloadButton();
info("wait for download to finish");
let download = await downloadFinishedPromise;
@ -170,7 +170,7 @@ add_task(async function test_download_with_filepicker() {
let filePicker = waitForFilePicker();
let screenshotExit = TestUtils.topicObserved("screenshots-exit");
await helper.clickDownloadButton();
helper.clickDownloadButton();
await filePicker;
ok(true, "Export file picker opened");

View File

@ -17,14 +17,6 @@ add_task(async function test_fullpageScreenshot() {
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.scrollWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.scrollHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -48,22 +40,29 @@ add_task(async function test_fullpageScreenshot() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
Assert.equal(result.width, expectedWidth, "Widths should be equal");
Assert.equal(result.height, expectedHeight, "Heights should be equal");
Assert.equal(
contentInfo.scrollWidth,
result.width,
"Widths should be equal"
);
Assert.equal(
contentInfo.scrollHeight,
result.height,
"Heights should be equal"
);
// top left
assertRange(result.color.topLeft[0], 110, 111, "R color value");
@ -102,14 +101,6 @@ add_task(async function test_fullpageScreenshotScrolled() {
});
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.scrollWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.scrollHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -134,22 +125,29 @@ add_task(async function test_fullpageScreenshotScrolled() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
Assert.equal(result.width, expectedWidth, "Widths should be equal");
Assert.equal(result.height, expectedHeight, "Heights should be equal");
Assert.equal(
contentInfo.scrollWidth,
result.width,
"Widths should be equal"
);
Assert.equal(
contentInfo.scrollHeight,
result.height,
"Heights should be equal"
);
// top left
assertRange(result.color.topLeft[0], 110, 111, "R color value");

View File

@ -15,13 +15,6 @@ add_task(async function test_visibleScreenshot() {
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -48,21 +41,26 @@ add_task(async function test_visibleScreenshot() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
Assert.equal(result.width, expectedWidth, "Widths should be equal");
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
Assert.equal(result.height, expectedHeight, "Heights should be equal");
// top left
@ -88,7 +86,7 @@ add_task(async function test_visibleScreenshot() {
);
});
add_task(async function test_visibleScreenshotScrolledY() {
add_task(async function test_visibleScreenshotScrolled() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
@ -102,14 +100,6 @@ add_task(async function test_visibleScreenshotScrolledY() {
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -136,24 +126,27 @@ add_task(async function test_visibleScreenshotScrolledY() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
// let result = await helper.getImageSizeAndColorFromClipboard();
// debugger;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
Assert.equal(result.width, expectedWidth, "Widths should be equal");
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
Assert.equal(result.height, expectedHeight, "Heights should be equal");
// top left
@ -179,7 +172,7 @@ add_task(async function test_visibleScreenshotScrolledY() {
);
});
add_task(async function test_visibleScreenshotScrolledX() {
add_task(async function test_visibleScreenshotScrolled() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
@ -193,14 +186,6 @@ add_task(async function test_visibleScreenshotScrolledX() {
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -227,21 +212,27 @@ add_task(async function test_visibleScreenshotScrolledX() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
Assert.equal(result.width, expectedWidth, "Widths should be equal");
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
Assert.equal(result.height, expectedHeight, "Heights should be equal");
// top left
@ -267,7 +258,7 @@ add_task(async function test_visibleScreenshotScrolledX() {
);
});
add_task(async function test_visibleScreenshotScrolledXAndY() {
add_task(async function test_visibleScreenshotScrolled() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
@ -281,14 +272,6 @@ add_task(async function test_visibleScreenshotScrolledXAndY() {
let helper = new ScreenshotsHelper(browser);
let contentInfo = await helper.getContentDimensions();
ok(contentInfo, "Got dimensions back from the content");
let devicePixelRatio = await getContentDevicePixelRatio(browser);
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
// click toolbar button so panel shows
helper.triggerUIFromToolbar();
@ -315,21 +298,27 @@ add_task(async function test_visibleScreenshotScrolledXAndY() {
let copyButton = dialog._frame.contentDocument.getElementById("copy");
ok(copyButton, "Got the copy button");
let clipboardChanged = helper.waitForRawClipboardChange(
expectedWidth,
expectedHeight
);
let clipboardChanged = helper.waitForRawClipboardChange();
// click copy button on dialog box
copyButton.click();
info("Waiting for clipboard change");
let result = await clipboardChanged;
await clipboardChanged;
let result = await helper.getImageSizeAndColorFromClipboard();
info("result: " + JSON.stringify(result, null, 2));
info("contentInfo: " + JSON.stringify(contentInfo, null, 2));
let expectedWidth = Math.floor(
devicePixelRatio * contentInfo.clientWidth
);
Assert.equal(result.width, expectedWidth, "Widths should be equal");
let expectedHeight = Math.floor(
devicePixelRatio * contentInfo.clientHeight
);
Assert.equal(result.height, expectedHeight, "Heights should be equal");
// top left

View File

@ -143,7 +143,7 @@ class ScreenshotsHelper {
}
async waitForStateChange(newState) {
return BrowserTestUtils.waitForCondition(async () => {
await BrowserTestUtils.waitForCondition(async () => {
let state = await this.getOverlayState();
return state === newState;
}, `Waiting for state change to ${newState}`);
@ -204,36 +204,26 @@ class ScreenshotsHelper {
* @param {Number} endX The end X coordinate. The right edge of the overlay rect.
* @param {Number} endY The end Y coordinate. The bottom edge of the overlay rect.
*/
async dragOverlay(
startX,
startY,
endX,
endY,
expectedStartingState = "crosshairs"
) {
await this.waitForStateChange(expectedStartingState);
async dragOverlay(startX, startY, endX, endY) {
await this.waitForStateChange("crosshairs");
let state = await this.getOverlayState();
Assert.equal(
state,
expectedStartingState,
`The overlay is in the ${state} state`
);
Assert.equal(state, "crosshairs", "The overlay is in the crosshairs state");
mouse.down(startX, startY);
await Promise.any([
this.waitForStateChange("draggingReady"),
this.waitForStateChange("resizing"),
]);
Assert.ok(true, "The overlay is in the draggingReady or resizing state");
await this.waitForStateChange("draggingReady");
state = await this.getOverlayState();
Assert.equal(
state,
"draggingReady",
"The overlay is in the draggingReady state"
);
mouse.move(endX, endY);
await Promise.any([
this.waitForStateChange("dragging"),
this.waitForStateChange("resizing"),
]);
Assert.ok(true, "The overlay is in the dragging or resizing state");
await this.waitForStateChange("dragging");
state = await this.getOverlayState();
Assert.equal(state, "dragging", "The overlay is in the dragging state");
mouse.up(endX, endY);
@ -281,64 +271,31 @@ class ScreenshotsHelper {
});
}
async clickDownloadButton() {
let { centerX: x, centerY: y } = await ContentTask.spawn(
this.browser,
null,
async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
let { left, top, width, height } =
screenshotsChild.overlay.downloadButton.getBoundingClientRect();
let centerX = left + width / 2;
let centerY = top + height / 2;
return { centerX, centerY };
}
);
info(`clicking download button at ${x}, ${y}`);
mouse.click(x, y);
clickDownloadButton() {
ContentTask.spawn(this.browser, null, async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
screenshotsChild.overlay.downloadButton.click();
});
}
async clickCopyButton() {
let { centerX: x, centerY: y } = await ContentTask.spawn(
this.browser,
null,
async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
let { left, top, width, height } =
screenshotsChild.overlay.copyButton.getBoundingClientRect();
let centerX = left + width / 2;
let centerY = top + height / 2;
return { centerX, centerY };
}
);
info(`clicking copy button at ${x}, ${y}`);
mouse.click(x, y);
clickCopyButton() {
ContentTask.spawn(this.browser, null, async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
screenshotsChild.overlay.copyButton.click();
});
}
async clickCancelButton() {
let { centerX: x, centerY: y } = await ContentTask.spawn(
this.browser,
null,
async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
let { left, top, width, height } =
screenshotsChild.overlay.cancelButton.getBoundingClientRect();
let centerX = left + width / 2;
let centerY = top + height / 2;
return { centerX, centerY };
}
);
info(`clicking cancel button at ${x}, ${y}`);
mouse.click(x, y);
clickCancelButton() {
ContentTask.spawn(this.browser, null, async () => {
let screenshotsChild = content.windowGlobalChild.getActor(
"ScreenshotsComponent"
);
screenshotsChild.overlay.cancelButton.click();
});
}
async clickTestPageElement() {
@ -403,32 +360,21 @@ class ScreenshotsHelper {
* Returns a promise that resolves when the clipboard data has changed
* Otherwise rejects
*/
waitForRawClipboardChange(epectedWidth, expectedHeight) {
waitForRawClipboardChange() {
const initialClipboardData = Date.now().toString();
SpecialPowers.clipboardCopyString(initialClipboardData);
return TestUtils.waitForCondition(
async () => {
let data;
try {
data = await this.getImageSizeAndColorFromClipboard();
} catch (e) {
console.log("Failed to get image/png clipboard data:", e);
return false;
}
if (
data &&
initialClipboardData !== data &&
data.height === expectedHeight &&
data.width === epectedWidth
) {
return data;
}
let promiseChanged = TestUtils.waitForCondition(() => {
let data;
try {
data = getRawClipboardData("image/png");
} catch (e) {
console.log("Failed to get image/png clipboard data:", e);
return false;
},
"Waiting for screenshot to copy to clipboard",
200
);
}
return data && initialClipboardData !== data;
});
return promiseChanged;
}
/**
@ -525,9 +471,7 @@ class ScreenshotsHelper {
async getImageSizeAndColorFromClipboard() {
let flavor = "image/png";
let image = getRawClipboardData(flavor);
if (!image) {
return false;
}
ok(image, "screenshot data exists on the clipboard");
// Due to the differences in how images could be stored in the clipboard the
// checks below are needed. The clipboard could already provide the image as
@ -550,11 +494,10 @@ class ScreenshotsHelper {
binaryStream.setInputStream(image);
const available = binaryStream.available();
const buffer = new ArrayBuffer(available);
info(
`${binaryStream.readArrayBuffer(
available,
buffer
)} read, ${available} available`
is(
binaryStream.readArrayBuffer(available, buffer),
available,
"Read expected amount of data"
);
// We are going to load the image in the content page to measure its size.
@ -707,18 +650,14 @@ async function waitForScreenshotsEventCount(count, process = "parent") {
);
}
async function assertScreenshotsEvents(
expectedEvents,
process = "parent",
clearEvents = true
) {
async function assertScreenshotsEvents(expectedEvents, process = "parent") {
info(`Expected events: ${JSON.stringify(expectedEvents, null, 2)}`);
// Make sure we have recorded the correct number of events
await waitForScreenshotsEventCount(expectedEvents.length, process);
TelemetryTestUtils.assertEvents(
expectedEvents,
{ category: "screenshots" },
{ clear: clearEvents, process }
{ category: "screenshots", clear: true },
{ process }
);
}

View File

@ -4225,13 +4225,6 @@ screenshots:
- 1801019
expiry_version: "never"
release_channel_collection: opt-out
extra_keys:
fullpage: Number of times a full page was selected
visible: Number of times a visible page was selected
element: Number of times an element was selected
region: Number of times a region was selected
move: Number of times a region was moved
resize: Number of times a region was resized
copy:
objects: ["overlay_copy", "preview_copy"]
description: >
@ -4246,13 +4239,6 @@ screenshots:
- 1801019
expiry_version: "never"
release_channel_collection: opt-out
extra_keys:
fullpage: Number of times a full page was selected
visible: Number of times a visible page was selected
element: Number of times an element was selected
region: Number of times a region was selected
move: Number of times a region was moved
resize: Number of times a region was resized
selected:
objects: ["element", "region_selection", "visible", "full_page"]
description: >