forked from mirrors/gecko-dev
Bug 1866437 - Add some telemetry for the highlight feature in pdf.js r=pdfjs-reviewers,marco
Differential Revision: https://phabricator.services.mozilla.com/D203023
This commit is contained in:
parent
23b0c44284
commit
6e5d2981a4
8 changed files with 630 additions and 88 deletions
|
|
@ -265,6 +265,8 @@ export class GeckoViewPdfjsParent extends GeckoViewActorParent {
|
|||
return this.#getExperimentFeature();
|
||||
case "PDFJS:Parent:recordExposure":
|
||||
return this.#recordExposure();
|
||||
case "PDFJS:Parent:reportTelemetry":
|
||||
return this.#reportTelemetry(aMsg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -355,6 +357,10 @@ export class GeckoViewPdfjsParent extends GeckoViewActorParent {
|
|||
warn`Cannot record experiment exposure: ${e}`;
|
||||
}
|
||||
}
|
||||
|
||||
#reportTelemetry(aMsg) {
|
||||
lazy.PdfJsTelemetry.report(aMsg.data);
|
||||
}
|
||||
}
|
||||
|
||||
const { debug, warn } = GeckoViewPdfjsParent.initLogging(
|
||||
|
|
|
|||
|
|
@ -12,44 +12,127 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* eslint max-len: ["error", 100] */
|
||||
|
||||
export const PdfJsTelemetry = {
|
||||
onViewerIsUsed() {
|
||||
export class PdfJsTelemetryContent {
|
||||
static onViewerIsUsed() {
|
||||
Glean.pdfjs.used.add(1);
|
||||
},
|
||||
onTimeToView(ms) {
|
||||
}
|
||||
}
|
||||
|
||||
export class PdfJsTelemetry {
|
||||
static report(aData) {
|
||||
const { type } = aData;
|
||||
switch (type) {
|
||||
case "pageInfo":
|
||||
this.onTimeToView(aData.timestamp);
|
||||
break;
|
||||
case "editing":
|
||||
this.onEditing(aData);
|
||||
break;
|
||||
case "buttons":
|
||||
case "gv-buttons":
|
||||
{
|
||||
const id = aData.data.id.replace(
|
||||
/([A-Z])/g,
|
||||
c => `_${c.toLowerCase()}`
|
||||
);
|
||||
if (type === "buttons") {
|
||||
this.onButtons(id);
|
||||
} else {
|
||||
this.onGeckoview(id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static onTimeToView(ms) {
|
||||
Glean.pdfjs.timeToView.accumulateSamples([ms]);
|
||||
},
|
||||
onEditing({ subtype, data }) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (!subtype && data.type) {
|
||||
Glean.pdfjs.editing[data.type].add(1);
|
||||
}
|
||||
|
||||
static onEditing({ type, data }) {
|
||||
if (type !== "editing" || !data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (subtype !== "stamp") {
|
||||
return;
|
||||
switch (data.type) {
|
||||
case "freetext":
|
||||
case "ink":
|
||||
Glean.pdfjs.editing[data.type].add(1);
|
||||
return;
|
||||
case "print":
|
||||
case "save":
|
||||
{
|
||||
Glean.pdfjs.editing[data.type].add(1);
|
||||
if (!data.stats) {
|
||||
return;
|
||||
}
|
||||
const numbers = ["one", "two", "three", "four", "five"];
|
||||
Glean.pdfjsEditingHighlight[data.type].add(1);
|
||||
Glean.pdfjsEditingHighlight.numberOfColors[
|
||||
numbers[data.stats.highlight.numberOfColors - 1]
|
||||
].add(1);
|
||||
}
|
||||
return;
|
||||
case "stamp":
|
||||
if (data.action === "added") {
|
||||
Glean.pdfjs.editing.stamp.add(1);
|
||||
return;
|
||||
}
|
||||
Glean.pdfjs.stamp[data.action].add(1);
|
||||
for (const key of [
|
||||
"alt_text_keyboard",
|
||||
"alt_text_decorative",
|
||||
"alt_text_description",
|
||||
"alt_text_edit",
|
||||
]) {
|
||||
if (data[key]) {
|
||||
Glean.pdfjs.stamp[key].add(1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case "highlight":
|
||||
case "free_highlight":
|
||||
switch (data.action) {
|
||||
case "added":
|
||||
Glean.pdfjsEditingHighlight.kind[data.type].add(1);
|
||||
Glean.pdfjsEditingHighlight.method[data.methodOfCreation].add(1);
|
||||
Glean.pdfjsEditingHighlight.color[data.color].add(1);
|
||||
if (data.type === "free_highlight") {
|
||||
Glean.pdfjsEditingHighlight.thickness.accumulateSamples([
|
||||
data.thickness,
|
||||
]);
|
||||
}
|
||||
break;
|
||||
case "color_changed":
|
||||
Glean.pdfjsEditingHighlight.color[data.color].add(1);
|
||||
Glean.pdfjsEditingHighlight.colorChanged.add(1);
|
||||
break;
|
||||
case "thickness_changed":
|
||||
Glean.pdfjsEditingHighlight.thickness.accumulateSamples([
|
||||
data.thickness,
|
||||
]);
|
||||
Glean.pdfjsEditingHighlight.thicknessChanged.add(1);
|
||||
break;
|
||||
case "deleted":
|
||||
Glean.pdfjsEditingHighlight.deleted.add(1);
|
||||
break;
|
||||
case "edited":
|
||||
Glean.pdfjsEditingHighlight.edited.add(1);
|
||||
break;
|
||||
case "toggle_visibility":
|
||||
Glean.pdfjsEditingHighlight.toggleVisibility.add(1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Glean.pdfjs.stamp[data.action].add(1);
|
||||
for (const key of [
|
||||
"alt_text_keyboard",
|
||||
"alt_text_decorative",
|
||||
"alt_text_description",
|
||||
"alt_text_edit",
|
||||
]) {
|
||||
if (data[key]) {
|
||||
Glean.pdfjs.stamp[key].add(1);
|
||||
}
|
||||
}
|
||||
},
|
||||
onButtons(id) {
|
||||
static onButtons(id) {
|
||||
Glean.pdfjs.buttons[id].add(1);
|
||||
},
|
||||
onGeckoview(id) {
|
||||
}
|
||||
|
||||
static onGeckoview(id) {
|
||||
Glean.pdfjs.geckoview[id].add(1);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||
NetUtil: "resource://gre/modules/NetUtil.sys.mjs",
|
||||
NetworkManager: "resource://pdf.js/PdfJsNetwork.sys.mjs",
|
||||
PdfJs: "resource://pdf.js/PdfJs.sys.mjs",
|
||||
PdfJsTelemetry: "resource://pdf.js/PdfJsTelemetry.sys.mjs",
|
||||
PdfJsTelemetryContent: "resource://pdf.js/PdfJsTelemetry.sys.mjs",
|
||||
PdfSandbox: "resource://pdf.js/PdfSandbox.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
});
|
||||
|
|
@ -331,27 +331,8 @@ class ChromeActions {
|
|||
|
||||
reportTelemetry(data) {
|
||||
const probeInfo = JSON.parse(data);
|
||||
const { type } = probeInfo;
|
||||
switch (type) {
|
||||
case "pageInfo":
|
||||
lazy.PdfJsTelemetry.onTimeToView(probeInfo.timestamp);
|
||||
break;
|
||||
case "editing":
|
||||
lazy.PdfJsTelemetry.onEditing(probeInfo);
|
||||
break;
|
||||
case "buttons":
|
||||
case "gv-buttons":
|
||||
const id = probeInfo.data.id.replace(
|
||||
/([A-Z])/g,
|
||||
c => `_${c.toLowerCase()}`
|
||||
);
|
||||
if (type === "buttons") {
|
||||
lazy.PdfJsTelemetry.onButtons(id);
|
||||
} else {
|
||||
lazy.PdfJsTelemetry.onGeckoview(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
const actor = getActor(this.domWindow);
|
||||
actor?.sendAsyncMessage("PDFJS:Parent:reportTelemetry", probeInfo);
|
||||
}
|
||||
|
||||
updateFindControlState(data) {
|
||||
|
|
@ -1010,7 +991,7 @@ PdfStreamConverter.prototype = {
|
|||
aRequest.setResponseHeader("Refresh", "", false);
|
||||
}
|
||||
|
||||
lazy.PdfJsTelemetry.onViewerIsUsed();
|
||||
lazy.PdfJsTelemetryContent.onViewerIsUsed();
|
||||
|
||||
// The document will be loaded via the stream converter as html,
|
||||
// but since we may have come here via a download or attachment
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const lazy = {};
|
|||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
||||
PdfJsTelemetry: "resource://pdf.js/PdfJsTelemetry.sys.mjs",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
||||
SetClipboardSearchString: "resource://gre/modules/Finder.sys.mjs",
|
||||
});
|
||||
|
|
@ -69,6 +70,8 @@ export class PdfjsParent extends JSWindowActorParent {
|
|||
return this._saveURL(aMsg);
|
||||
case "PDFJS:Parent:recordExposure":
|
||||
return this._recordExposure();
|
||||
case "PDFJS:Parent:reportTelemetry":
|
||||
return this._reportTelemetry(aMsg);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
@ -85,6 +88,10 @@ export class PdfjsParent extends JSWindowActorParent {
|
|||
lazy.NimbusFeatures.pdfjs.recordExposureEvent({ once: true });
|
||||
}
|
||||
|
||||
_reportTelemetry(aMsg) {
|
||||
lazy.PdfJsTelemetry.report(aMsg.data);
|
||||
}
|
||||
|
||||
_saveURL(aMsg) {
|
||||
const data = aMsg.data;
|
||||
this.browser.ownerGlobal.saveURL(
|
||||
|
|
|
|||
|
|
@ -140,3 +140,195 @@ pdfjs:
|
|||
notification_emails:
|
||||
- cdenizet@mozilla.com
|
||||
- mcastelluccio@mozilla.com
|
||||
pdfjs.editing.highlight:
|
||||
kind:
|
||||
type: labeled_counter
|
||||
labels:
|
||||
- free_highlight
|
||||
- highlight
|
||||
description: >
|
||||
Counts the number of times a given kind is used to highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
method:
|
||||
type: labeled_counter
|
||||
labels:
|
||||
- context_menu
|
||||
- main_toolbar
|
||||
- floating_button
|
||||
description: >
|
||||
Counts the number of times a given method is used to highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
color:
|
||||
type: labeled_counter
|
||||
labels:
|
||||
- yellow
|
||||
- green
|
||||
- blue
|
||||
- pink
|
||||
- red
|
||||
description: >
|
||||
Counts the number of times a given color is used to highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
color_changed:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user changes the color of a highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
number_of_colors:
|
||||
type: labeled_counter
|
||||
labels:
|
||||
- one
|
||||
- two
|
||||
- three
|
||||
- four
|
||||
- five
|
||||
description: >
|
||||
Counts the number of different colors used to highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
thickness:
|
||||
type: custom_distribution
|
||||
range_min: 8
|
||||
range_max: 24
|
||||
bucket_count: 17
|
||||
histogram_type: linear
|
||||
unit: pixels
|
||||
description: >
|
||||
The thickness used to draw a free highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
thickness_changed:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user changes the thickness of a free highlight.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
save:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user saves a PDF with highlights.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
print:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user prints a PDF with highlights.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
edited:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user edits highlights.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
deleted:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user deletes highlights.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
||||
toggle_visibility:
|
||||
type: counter
|
||||
description: >
|
||||
Counts the number of times the user toggles the visibility of highlights.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1866437#c1
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- pdfjs-team@mozilla.com
|
||||
expires: never
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ support-files = ["file_pdfjs_form.pdf"]
|
|||
["browser_pdfjs_hcm.js"]
|
||||
support-files = ["file_pdfjs_hcm.pdf"]
|
||||
|
||||
["browser_pdfjs_highlight_telemetry.js"]
|
||||
skip-if = ["true"]
|
||||
|
||||
["browser_pdfjs_js.js"]
|
||||
support-files = ["file_pdfjs_js.pdf"]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,234 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const RELATIVE_DIR = "toolkit/components/pdfjs/test/";
|
||||
const TESTROOT = "https://example.com/browser/" + RELATIVE_DIR;
|
||||
|
||||
// Test telemetry.
|
||||
add_task(async function test() {
|
||||
let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
let handlerInfo = mimeService.getFromTypeAndExtension(
|
||||
"application/pdf",
|
||||
"pdf"
|
||||
);
|
||||
|
||||
// Make sure pdf.js is the default handler.
|
||||
is(
|
||||
handlerInfo.alwaysAskBeforeHandling,
|
||||
false,
|
||||
"pdf handler defaults to always-ask is false"
|
||||
);
|
||||
is(
|
||||
handlerInfo.preferredAction,
|
||||
Ci.nsIHandlerInfo.handleInternally,
|
||||
"pdf handler defaults to internal"
|
||||
);
|
||||
|
||||
info("Pref action: " + handlerInfo.preferredAction);
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:blank" },
|
||||
async function (browser) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["pdfjs.annotationEditorMode", 0],
|
||||
["pdfjs.enableHighlight", true],
|
||||
],
|
||||
});
|
||||
|
||||
Services.fog.testResetFOG();
|
||||
|
||||
// check that PDF is opened with internal viewer
|
||||
await waitForPdfJSAllLayers(browser, TESTROOT + "file_pdfjs_test.pdf", [
|
||||
[
|
||||
"annotationEditorLayer",
|
||||
"annotationLayer",
|
||||
"textLayer",
|
||||
"canvasWrapper",
|
||||
],
|
||||
["annotationEditorLayer", "textLayer", "canvasWrapper"],
|
||||
]);
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(
|
||||
(Glean.pdfjsEditingHighlight.kind.freeHighlight.testGetValue() || 0) +
|
||||
(Glean.pdfjsEditingHighlight.kind.highlight.testGetValue() || 0),
|
||||
0,
|
||||
"Should have no highlight"
|
||||
);
|
||||
|
||||
await enableEditor(browser, "Highlight");
|
||||
const strs = ["In production", "buildbot automation"];
|
||||
for (let i = 0; i < strs.length; i++) {
|
||||
const str = strs[i];
|
||||
const N = i + 1;
|
||||
const spanBox = await getSpanBox(browser, str);
|
||||
await clickAt(
|
||||
browser,
|
||||
spanBox.x + 0.75 * spanBox.width,
|
||||
spanBox.y + 0.5 * spanBox.height,
|
||||
2
|
||||
);
|
||||
await waitForEditors(browser, ".highlightEditor", N);
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.kind.highlight.testGetValue(),
|
||||
N,
|
||||
`Should have ${N} highlights`
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.color.yellow.testGetValue(),
|
||||
N,
|
||||
`Should have ${N} yellow highlights`
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.method.main_toolbar.testGetValue(),
|
||||
N,
|
||||
`Should have ${N} highlights created from the toolbar`
|
||||
);
|
||||
|
||||
await EventUtils.synthesizeKey("KEY_Escape");
|
||||
await waitForSelector(browser, ".highlightEditor:not(.selectedEditor)");
|
||||
|
||||
document.getElementById("cmd_print").doCommand();
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
let preview = document.querySelector(".printPreviewBrowser");
|
||||
return preview && BrowserTestUtils.isVisible(preview);
|
||||
});
|
||||
await EventUtils.synthesizeKey("KEY_Escape");
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
Assert.equal(Glean.pdfjs.editing.print.testGetValue(), N);
|
||||
Assert.equal(Glean.pdfjsEditingHighlight.print.testGetValue(), N);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.numberOfColors.one.testGetValue(),
|
||||
N
|
||||
);
|
||||
}
|
||||
|
||||
await click(
|
||||
browser,
|
||||
"#highlightParamsToolbarContainer button[title='Green']"
|
||||
);
|
||||
const spanBox = await getSpanBox(browser, "Mozilla automated testing");
|
||||
await BrowserTestUtils.synthesizeMouseAtPoint(
|
||||
spanBox.x - 10,
|
||||
spanBox.y + spanBox.height / 2,
|
||||
{
|
||||
type: "mousedown",
|
||||
button: 0,
|
||||
},
|
||||
browser
|
||||
);
|
||||
await BrowserTestUtils.synthesizeMouseAtPoint(
|
||||
spanBox.x + spanBox.width,
|
||||
spanBox.y + spanBox.height / 2,
|
||||
{
|
||||
type: "mousemove",
|
||||
button: 0,
|
||||
},
|
||||
browser
|
||||
);
|
||||
await BrowserTestUtils.synthesizeMouseAtPoint(
|
||||
spanBox.x + spanBox.width,
|
||||
spanBox.y + spanBox.height / 2,
|
||||
{
|
||||
type: "mouseup",
|
||||
button: 0,
|
||||
},
|
||||
browser
|
||||
);
|
||||
await waitForEditors(browser, ".highlightEditor", 3);
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(Glean.pdfjsEditingHighlight.color.green.testGetValue(), 1);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.kind.free_highlight.testGetValue(),
|
||||
1
|
||||
);
|
||||
|
||||
let telemetryPromise = waitForTelemetry(browser);
|
||||
await focus(browser, "#editorFreeHighlightThickness");
|
||||
await EventUtils.synthesizeKey("KEY_ArrowRight");
|
||||
|
||||
await telemetryPromise;
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.thickness.testGetValue().values[12],
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.thickness.testGetValue().values[13],
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.thicknessChanged.testGetValue(),
|
||||
1
|
||||
);
|
||||
|
||||
document.getElementById("cmd_print").doCommand();
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
let preview = document.querySelector(".printPreviewBrowser");
|
||||
return preview && BrowserTestUtils.isVisible(preview);
|
||||
});
|
||||
await EventUtils.synthesizeKey("KEY_Escape");
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
|
||||
Assert.equal(Glean.pdfjs.editing.print.testGetValue(), 3);
|
||||
Assert.equal(Glean.pdfjsEditingHighlight.print.testGetValue(), 3);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.numberOfColors.one.testGetValue(),
|
||||
2
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.numberOfColors.two.testGetValue(),
|
||||
1
|
||||
);
|
||||
|
||||
await click(browser, ".highlightEditor.free button.colorPicker");
|
||||
telemetryPromise = waitForTelemetry(browser);
|
||||
await click(
|
||||
browser,
|
||||
".highlightEditor.free button.colorPicker button[title='Red']"
|
||||
);
|
||||
await telemetryPromise;
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(Glean.pdfjsEditingHighlight.colorChanged.testGetValue(), 1);
|
||||
|
||||
document.getElementById("cmd_print").doCommand();
|
||||
await BrowserTestUtils.waitForCondition(() => {
|
||||
let preview = document.querySelector(".printPreviewBrowser");
|
||||
return preview && BrowserTestUtils.isVisible(preview);
|
||||
});
|
||||
await EventUtils.synthesizeKey("KEY_Escape");
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.numberOfColors.one.testGetValue(),
|
||||
2
|
||||
);
|
||||
Assert.equal(
|
||||
Glean.pdfjsEditingHighlight.numberOfColors.two.testGetValue(),
|
||||
2
|
||||
);
|
||||
|
||||
telemetryPromise = waitForTelemetry(browser);
|
||||
await EventUtils.synthesizeKey("KEY_Delete");
|
||||
await telemetryPromise;
|
||||
|
||||
await Services.fog.testFlushAllChildren();
|
||||
Assert.equal(Glean.pdfjsEditingHighlight.deleted.testGetValue(), 1);
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
const viewer = content.wrappedJSObject.PDFViewerApplication;
|
||||
viewer.pdfDocument.annotationStorage.resetModified();
|
||||
await viewer.close();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
@ -119,6 +119,7 @@ async function waitForSelector(browser, selector, message) {
|
|||
}
|
||||
|
||||
async function click(browser, selector) {
|
||||
await waitForSelector(browser, selector);
|
||||
await SpecialPowers.spawn(browser, [selector], async function (sel) {
|
||||
const el = content.document.querySelector(sel);
|
||||
await new Promise(r => {
|
||||
|
|
@ -128,6 +129,17 @@ async function click(browser, selector) {
|
|||
});
|
||||
}
|
||||
|
||||
async function waitForTelemetry(browser) {
|
||||
await BrowserTestUtils.waitForContentEvent(
|
||||
browser,
|
||||
"reporttelemetry",
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
await TestUtils.waitForTick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable an editor (Ink, FreeText, ...).
|
||||
* @param {Object} browser
|
||||
|
|
@ -160,33 +172,40 @@ async function enableEditor(browser, name) {
|
|||
* @param {string} text
|
||||
* @returns {Object} the bbox of the span containing the text.
|
||||
*/
|
||||
async function getSpanBox(browser, text) {
|
||||
return SpecialPowers.spawn(browser, [text], async function (text) {
|
||||
const { ContentTaskUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/ContentTaskUtils.sys.mjs"
|
||||
);
|
||||
const { document } = content;
|
||||
async function getSpanBox(browser, text, pageNumber = 1) {
|
||||
return SpecialPowers.spawn(
|
||||
browser,
|
||||
[text, pageNumber],
|
||||
async function (text, number) {
|
||||
const { ContentTaskUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/ContentTaskUtils.sys.mjs"
|
||||
);
|
||||
const { document } = content;
|
||||
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => !!document.querySelector(".textLayer .endOfContent"),
|
||||
"The text layer must be displayed"
|
||||
);
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() =>
|
||||
!!document.querySelector(
|
||||
`.page[data-page-number='${number}'] .textLayer .endOfContent`
|
||||
),
|
||||
"The text layer must be displayed"
|
||||
);
|
||||
|
||||
let targetSpan = null;
|
||||
for (const span of document.querySelectorAll(
|
||||
`.textLayer span[role="presentation"]`
|
||||
)) {
|
||||
if (span.innerText.includes(text)) {
|
||||
targetSpan = span;
|
||||
break;
|
||||
let targetSpan = null;
|
||||
for (const span of document.querySelectorAll(
|
||||
`.page[data-page-number='${number}'] .textLayer span`
|
||||
)) {
|
||||
if (span.innerText.includes(text)) {
|
||||
targetSpan = span;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.ok(!!targetSpan, `document must have a span containing '${text}'`);
|
||||
|
||||
const { x, y, width, height } = targetSpan.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
}
|
||||
|
||||
Assert.ok(targetSpan, `document must have a span containing '${text}'`);
|
||||
|
||||
const { x, y, width, height } = targetSpan.getBoundingClientRect();
|
||||
return { x, y, width, height };
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -210,14 +229,16 @@ async function countElements(browser, selector) {
|
|||
* @param {Object} browser
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} n
|
||||
*/
|
||||
async function clickAt(browser, x, y) {
|
||||
async function clickAt(browser, x, y, n = 1) {
|
||||
await BrowserTestUtils.synthesizeMouseAtPoint(
|
||||
x,
|
||||
y,
|
||||
{
|
||||
type: "mousedown",
|
||||
button: 0,
|
||||
clickCount: n,
|
||||
},
|
||||
browser
|
||||
);
|
||||
|
|
@ -227,6 +248,7 @@ async function clickAt(browser, x, y) {
|
|||
{
|
||||
type: "mouseup",
|
||||
button: 0,
|
||||
clickCount: n,
|
||||
},
|
||||
browser
|
||||
);
|
||||
|
|
@ -256,20 +278,30 @@ async function clickOn(browser, selector) {
|
|||
await clickAt(browser, x, y);
|
||||
}
|
||||
|
||||
async function focusEditorLayer(browser) {
|
||||
return SpecialPowers.spawn(browser, [], async function () {
|
||||
const layer = content.document.querySelector(".annotationEditorLayer");
|
||||
if (layer === content.document.activeElement) {
|
||||
function focusEditorLayer(browser) {
|
||||
return focus(browser, ".annotationEditorLayer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus an element corresponding to the given selector.
|
||||
* @param {Object} browser
|
||||
* @param {string} selector
|
||||
* @returns
|
||||
*/
|
||||
async function focus(browser, selector) {
|
||||
return SpecialPowers.spawn(browser, [selector], function (sel) {
|
||||
const el = content.document.querySelector(sel);
|
||||
if (el === content.document.activeElement) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const promise = new Promise(resolve => {
|
||||
const listener = () => {
|
||||
layer.removeEventListener("focus", listener);
|
||||
el.removeEventListener("focus", listener);
|
||||
resolve();
|
||||
};
|
||||
layer.addEventListener("focus", listener);
|
||||
el.addEventListener("focus", listener);
|
||||
});
|
||||
layer.focus();
|
||||
el.focus();
|
||||
return promise;
|
||||
});
|
||||
}
|
||||
|
|
@ -317,14 +349,18 @@ async function addFreeText(browser, text, box) {
|
|||
const count = await countElements(browser, ".freeTextEditor");
|
||||
await focusEditorLayer(browser);
|
||||
await clickAt(browser, x + 0.1 * width, y + 0.5 * height);
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
async () => (await countElements(browser, ".freeTextEditor")) === count + 1
|
||||
);
|
||||
await waitForEditors(browser, ".freeTextEditor", count + 1);
|
||||
|
||||
await write(browser, text);
|
||||
await escape(browser);
|
||||
}
|
||||
|
||||
async function waitForEditors(browser, selector, count) {
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
async () => (await countElements(browser, selector)) === count
|
||||
);
|
||||
}
|
||||
|
||||
function changeMimeHandler(preferredAction, alwaysAskBeforeHandling) {
|
||||
let handlerService = Cc[
|
||||
"@mozilla.org/uriloader/handler-service;1"
|
||||
|
|
|
|||
Loading…
Reference in a new issue