tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 9156b88c5d65f33a209e8707f6c2ceb65200e435
parent 7dc7190ab81287ab549e439f8507032f6f8e31aa
Author: Calixte Denizet <calixte.denizet@gmail.com>
Date:   Thu,  2 Oct 2025 11:51:26 +0000

Bug 1991172 - Add some new telemetry metrics for the commenting feature in the pdf viewer r=marco

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

Diffstat:
Mtoolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs | 17+++++++++++++++++
Mtoolkit/components/pdfjs/metrics.yaml | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/components/pdfjs/test/browser.toml | 3+++
Atoolkit/components/pdfjs/test/browser_pdfjs_comment_telemetry.js | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/components/pdfjs/test/head.js | 2+-
5 files changed, 232 insertions(+), 1 deletion(-)

diff --git a/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs b/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs @@ -58,6 +58,12 @@ export class PdfJsTelemetry { case "signatureCertificates": this.onSignatureCertificates(aData.data); break; + case "comment": + this.onComment(aData.data); + break; + case "commentSidebar": + this.onCommentSidebar(aData.data); + break; } } @@ -127,6 +133,9 @@ export class PdfJsTelemetry { data: stats.signature, }); } + if (stats.comments) { + Glean.pdfjsComment.save.record(stats.comments); + } return; } case "signature": @@ -307,4 +316,12 @@ export class PdfJsTelemetry { static onGeckoview(id) { Glean.pdfjs.geckoview[id].add(1); } + + static onComment({ deleted }) { + Glean.pdfjsComment.edit[deleted ? "deleted" : "edited"].add(1); + } + + static onCommentSidebar({ numberOfAnnotations }) { + Glean.pdfjsComment.sidebar.record({ comments_count: numberOfAnnotations }); + } } diff --git a/toolkit/components/pdfjs/metrics.yaml b/toolkit/components/pdfjs/metrics.yaml @@ -917,3 +917,63 @@ pdfjs.digital_signature: notification_emails: - pdfjs-team@mozilla.com expires: 147 + +pdfjs.comment: + edit: + type: labeled_counter + description: > + Counts the number of times the user edits or deletes comments. + labels: + - deleted + - edited + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172#c1 + data_sensitivity: + - interaction + notification_emails: + - pdfjs-team@mozilla.com + expires: never + + sidebar: + type: event + description: > + Recorded when the comment sidebar is opened. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172#c1 + data_sensitivity: + - interaction + notification_emails: + - pdfjs-team@mozilla.com + expires: never + extra_keys: + comments_count: + type: quantity + description: > + Number of comments in the sidebar. + + save: + type: event + description: > + Recorded when the user saves a PDF with some deleted/edited comments. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1991172#c1 + data_sensitivity: + - interaction + notification_emails: + - pdfjs-team@mozilla.com + expires: never + extra_keys: + edited: + type: quantity + description: > + Number of edited comments. + deleted: + type: quantity + description: > + Number of deleted comments. diff --git a/toolkit/components/pdfjs/test/browser.toml b/toolkit/components/pdfjs/test/browser.toml @@ -22,6 +22,9 @@ run-if = ["nightly_build"] # Bug 1890946 ["browser_pdfjs_comment.js"] +["browser_pdfjs_comment_telemetry.js"] +run-if = ["!headless"] + ["browser_pdfjs_download_button.js"] ["browser_pdfjs_editing_contextmenu.js"] diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_comment_telemetry.js b/toolkit/components/pdfjs/test/browser_pdfjs_comment_telemetry.js @@ -0,0 +1,151 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const { PdfJsTelemetry } = ChromeUtils.importESModule( + "resource://pdf.js/PdfJsTelemetry.sys.mjs" +); +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); + +const RELATIVE_DIR = "toolkit/components/pdfjs/test/"; +const TESTROOT = "https://example.com/browser/" + RELATIVE_DIR; + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js", + this +); + +const commentPref = "pdfjs.enableComment"; +const highlightPref = "pdfjs.enableHighlight"; +const sandbox = sinon.createSandbox(); +registerCleanupFunction(() => { + sandbox.restore(); +}); + +const original = PdfJsTelemetry.report.bind(PdfJsTelemetry); +const resolvers = new Map(); +sandbox.stub(PdfJsTelemetry, "report").callsFake(aData => { + const { type, data } = aData; + if (!type.includes("comment") || !data) { + return; + } + resolvers.get(type)?.resolve(); + original(aData); +}); +const getPromise = name => { + const resolver = Promise.withResolvers(); + resolvers.set(name, resolver); + return resolver.promise; +}; +let telemetryPromise; + +async function enableComment(browser) { + await SpecialPowers.pushPrefEnv({ + set: [ + ["pdfjs.annotationEditorMode", 0], + [commentPref, true], + [highlightPref, true], + ], + }); + + await Services.fog.testFlushAllChildren(); + Services.fog.testResetFOG(); + + await waitForPdfJSAllLayers(browser, TESTROOT + "file_pdfjs_test.pdf", [ + ["annotationEditorLayer", "annotationLayer", "textLayer", "canvasWrapper"], + ]); +} + +// Test telemetry for comment flow. + +add_task(async function test_telemetry_no_comment() { + await BrowserTestUtils.withNewTab( + { gBrowser, url: "about:blank" }, + async function (browser) { + await enableComment(browser); + + Services.fog.testResetFOG(); + + telemetryPromise = getPromise("commentSidebar"); + await clickOn(browser, "#editorCommentButton"); + await waitForSelector(browser, "#editorCommentsSidebar"); + + await telemetryPromise; + await testTelemetryEventExtra( + Glean.pdfjsComment.sidebar, + [ + { + comments_count: "0", + }, + ], + false + ); + + await waitForPdfJSClose(browser); + await SpecialPowers.popPrefEnv(); + } + ); +}); + +add_task(async function test_telemetry_one_comment() { + await BrowserTestUtils.withNewTab( + { gBrowser, url: "about:blank" }, + async function (browser) { + await enableComment(browser); + await enableEditor(browser, "Highlight", 1); + + const spanBox = await getSpanBox(browser, "In production"); + await clickAt( + browser, + spanBox.x + 0.75 * spanBox.width, + spanBox.y + 0.5 * spanBox.height, + 2 + ); + await waitForEditors(browser, ".highlightEditor", 1); + await Services.fog.testFlushAllChildren(); + await clickOn(browser, "button.comment"); + await waitForSelector(browser, "#commentManagerDialog"); + + await clickOn(browser, "#commentManagerTextInput"); + await write(browser, "Hello Pdf.js World"); + + Services.fog.testResetFOG(); + + telemetryPromise = getPromise("comment"); + await clickOn(browser, "#commentManagerSaveButton"); + await telemetryPromise; + let value = Glean.pdfjsComment.edit.edited.testGetValue(); + Assert.equal(value, 1, "Should have a comment"); + + Services.fog.testResetFOG(); + + telemetryPromise = getPromise("commentSidebar"); + await clickOn(browser, "#editorCommentButton"); + await waitForSelector(browser, "#editorCommentsSidebar"); + + await telemetryPromise; + await testTelemetryEventExtra( + Glean.pdfjsComment.sidebar, + [ + { + comments_count: "1", + }, + ], + false + ); + + Services.fog.testResetFOG(); + + await clickOn(browser, "#editorCommentsSidebarList li:first-child"); + telemetryPromise = getPromise("comment"); + await clickOn(browser, "button.commentPopupDelete"); + await telemetryPromise; + value = Glean.pdfjsComment.edit.deleted.testGetValue(); + Assert.equal(value, 1, "Should have a deleted comment"); + + await waitForPdfJSClose(browser); + await SpecialPowers.popPrefEnv(); + } + ); +}); diff --git a/toolkit/components/pdfjs/test/head.js b/toolkit/components/pdfjs/test/head.js @@ -393,7 +393,7 @@ async function hitKey(browser, char) { async function write(browser, text) { info(`Write: ${text}`); for (const char of text.split("")) { - hitKey(browser, char); + await hitKey(browser, char); } }