492 lines
15 KiB
JavaScript
492 lines
15 KiB
JavaScript
/* 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 MockFilePicker = SpecialPowers.MockFilePicker;
|
|
const file = new FileUtils.File(getTestFilePath("moz.png"));
|
|
const altTextPref = "pdfjs.enableAltText";
|
|
const guessAltTextPref = "pdfjs.enableGuessAltText";
|
|
const newFlowPref = "pdfjs.enableUpdatedAddImage";
|
|
const browserMLPref = "browser.ml.enable";
|
|
|
|
add_setup(async function () {
|
|
MockFilePicker.init(window.browsingContext);
|
|
MockFilePicker.setFiles([file]);
|
|
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
|
registerCleanupFunction(function () {
|
|
MockFilePicker.cleanup();
|
|
});
|
|
});
|
|
|
|
const sandbox = sinon.createSandbox();
|
|
registerCleanupFunction(() => {
|
|
sandbox.restore();
|
|
});
|
|
|
|
const original = PdfJsTelemetry.report.bind(PdfJsTelemetry);
|
|
const resolvers = new Map();
|
|
sandbox.stub(PdfJsTelemetry, "report").callsFake(aData => {
|
|
// console.log("Telemetry", aData);
|
|
const name = aData.data?.action?.split(".").pop();
|
|
resolvers.get(name)?.resolve();
|
|
original(aData);
|
|
});
|
|
const getPromise = name => {
|
|
const resolver = Promise.withResolvers();
|
|
resolvers.set(name, resolver);
|
|
return resolver.promise;
|
|
};
|
|
let telemetryPromise;
|
|
|
|
// Test telemetry for new alt-text flow.
|
|
|
|
add_task(async function test_telemetry_new_alt_text_settings() {
|
|
makePDFJSHandler();
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{ gBrowser, url: "about:blank" },
|
|
async function (browser) {
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["pdfjs.annotationEditorMode", 0],
|
|
[altTextPref, true],
|
|
[guessAltTextPref, true],
|
|
[newFlowPref, true],
|
|
[browserMLPref, true],
|
|
],
|
|
});
|
|
|
|
await Services.fog.testFlushAllChildren();
|
|
Services.fog.testResetFOG();
|
|
|
|
telemetryPromise = getPromise("alt_text_edit");
|
|
|
|
// check that PDF is opened with internal viewer
|
|
await waitForPdfJSAllLayers(browser, TESTROOT + "file_empty_test.pdf", [
|
|
[
|
|
"annotationEditorLayer",
|
|
"annotationLayer",
|
|
"textLayer",
|
|
"canvasWrapper",
|
|
],
|
|
]);
|
|
|
|
await telemetryPromise;
|
|
await Services.fog.testFlushAllChildren();
|
|
let value = Glean.pdfjsImage.altTextEdit.ai_generation.testGetValue();
|
|
Assert.ok(value, "Should have ai_generation enabled");
|
|
|
|
value = Glean.pdfjsImage.altTextEdit.ask_to_edit.testGetValue();
|
|
Assert.ok(value, "Should have ask_to_edit enabled");
|
|
|
|
// We test the telemetry for the settings dialog.
|
|
await clickOn(browser, "#secondaryToolbarToggle");
|
|
|
|
telemetryPromise = getPromise("settings_displayed");
|
|
await clickOn(browser, "#imageAltTextSettings");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.settingsDisplayed, [
|
|
{},
|
|
]);
|
|
|
|
await waitForSelector(browser, "#altTextSettingsDialog");
|
|
|
|
for (const [id, record, name] of [
|
|
[
|
|
"createModelButton",
|
|
Glean.pdfjsImageAltText.settingsAiGenerationCheck,
|
|
"settings_ai_generation_check",
|
|
],
|
|
[
|
|
"showAltTextDialogButton",
|
|
Glean.pdfjsImageAltText.settingsEditAltTextCheck,
|
|
"settings_edit_alt_text_check",
|
|
],
|
|
]) {
|
|
telemetryPromise = getPromise(name);
|
|
await clickOn(browser, `#${id}`);
|
|
await telemetryPromise;
|
|
|
|
await testTelemetryEventExtra(record, [{ status: "false" }]);
|
|
|
|
telemetryPromise = getPromise(name);
|
|
await clickOn(browser, `#${id}`);
|
|
await telemetryPromise;
|
|
await Services.fog.testFlushAllChildren();
|
|
await testTelemetryEventExtra(record, [{ status: "true" }]);
|
|
}
|
|
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const a = content.document.querySelector("#altTextSettingsLearnMore");
|
|
a.href = "#";
|
|
a.target = "";
|
|
});
|
|
telemetryPromise = getPromise("info");
|
|
await clickOn(browser, `#altTextSettingsLearnMore`);
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.info, [
|
|
{ topic: "ai_generation" },
|
|
]);
|
|
|
|
telemetryPromise = getPromise("model_deleted");
|
|
await clickOn(browser, "#deleteModelButton");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.modelDeleted, [{}]);
|
|
|
|
telemetryPromise = getPromise("model_download_complete");
|
|
await clickOn(browser, "#downloadModelButton");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.modelDownloadStart,
|
|
[{}],
|
|
false
|
|
);
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.modelDownloadComplete,
|
|
[{}]
|
|
);
|
|
|
|
await clickOn(browser, "#altTextSettingsCloseButton");
|
|
|
|
await waitForPdfJSClose(browser);
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
);
|
|
});
|
|
|
|
add_task(async function test_telemetry_new_alt_text_dialog() {
|
|
makePDFJSHandler();
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{ gBrowser, url: "about:blank" },
|
|
async function (browser) {
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["pdfjs.annotationEditorMode", 0],
|
|
[altTextPref, true],
|
|
[guessAltTextPref, true],
|
|
[newFlowPref, true],
|
|
[browserMLPref, true],
|
|
],
|
|
});
|
|
|
|
await Services.fog.testFlushAllChildren();
|
|
Services.fog.testResetFOG();
|
|
|
|
// check that PDF is opened with internal viewer
|
|
await waitForPdfJSAllLayers(browser, TESTROOT + "file_empty_test.pdf", [
|
|
[
|
|
"annotationEditorLayer",
|
|
"annotationLayer",
|
|
"textLayer",
|
|
"canvasWrapper",
|
|
],
|
|
]);
|
|
|
|
telemetryPromise = getPromise("icon_click");
|
|
await enableEditor(browser, "Stamp", 0);
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImage.iconClick, [{}]);
|
|
|
|
// We test the telemetry for the alt-text dialog.
|
|
|
|
telemetryPromise = getPromise("add_image_click");
|
|
const imageSelectedPromise = getPromise("image_selected");
|
|
const modelResultPromise = getPromise("model_result");
|
|
await clickOn(browser, `#editorStampAddImage`);
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImage.addImageClick,
|
|
[{}],
|
|
false
|
|
);
|
|
|
|
await imageSelectedPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImage.imageSelected,
|
|
[{ alt_text_modal: "true" }],
|
|
false
|
|
);
|
|
|
|
await modelResultPromise;
|
|
await Services.fog.testFlushAllChildren();
|
|
let values = Glean.pdfjsImageAltText.modelResult.testGetValue();
|
|
Assert.equal(values.length, 1, "Should have 1 model result");
|
|
const extra = values[0].extra;
|
|
Assert.ok(extra.time > 0, "time must be a positive number");
|
|
Assert.ok(!!extra.length, "length must be a positive number");
|
|
|
|
await waitForSelector(browser, "#newAltTextDialog");
|
|
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const a = content.document.querySelector("#newAltTextLearnMore");
|
|
a.href = "#";
|
|
a.target = "";
|
|
});
|
|
telemetryPromise = getPromise("info");
|
|
await clickOn(browser, `#newAltTextLearnMore`);
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.info, [
|
|
{ topic: "alt_text" },
|
|
]);
|
|
|
|
await SpecialPowers.spawn(browser, [], async function () {
|
|
const { ContentTaskUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/ContentTaskUtils.sys.mjs"
|
|
);
|
|
const { document } = content;
|
|
await ContentTaskUtils.waitForCondition(
|
|
() =>
|
|
document.querySelector("#newAltTextDescriptionTextarea").value !==
|
|
"",
|
|
"Textarea mustn't be empty"
|
|
);
|
|
});
|
|
|
|
telemetryPromise = getPromise("image_added");
|
|
const savePromise = getPromise("save");
|
|
const statusPromise = getPromise("image_status_label_displayed");
|
|
await clickOn(browser, `#newAltTextSave`);
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImage.imageAdded,
|
|
[
|
|
{
|
|
alt_text_modal: "true",
|
|
alt_text_type: "present",
|
|
},
|
|
],
|
|
false
|
|
);
|
|
await savePromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.save,
|
|
[
|
|
{
|
|
alt_text_type: "present",
|
|
flow: "image_add",
|
|
},
|
|
],
|
|
false
|
|
);
|
|
await statusPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.imageStatusLabelDisplayed,
|
|
[
|
|
{
|
|
label: "added",
|
|
},
|
|
]
|
|
);
|
|
|
|
telemetryPromise = getPromise("image_status_label_clicked");
|
|
await clickOn(browser, ".altText.new");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.imageStatusLabelClicked,
|
|
[
|
|
{
|
|
label: "added",
|
|
},
|
|
]
|
|
);
|
|
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const textarea = content.document.querySelector(
|
|
"#newAltTextDescriptionTextarea"
|
|
);
|
|
textarea.value = "Hello Pdf.js World";
|
|
});
|
|
|
|
telemetryPromise = getPromise("image_status_label_displayed");
|
|
const userEditPromise = getPromise("user_edit");
|
|
await clickOn(browser, "#newAltTextSave");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.imageStatusLabelDisplayed,
|
|
[
|
|
{
|
|
label: "added",
|
|
},
|
|
],
|
|
false
|
|
);
|
|
await userEditPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.userEdit, [
|
|
{ total_words: 2, words_removed: 2, words_added: 4 },
|
|
]);
|
|
|
|
// Edit again in order to delete the alt text.
|
|
await clickOn(browser, ".altText.new");
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const textarea = content.document.querySelector(
|
|
"#newAltTextDescriptionTextarea"
|
|
);
|
|
textarea.value = "";
|
|
});
|
|
|
|
telemetryPromise = getPromise("image_status_label_displayed");
|
|
await clickOn(browser, "#newAltTextSave");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.imageStatusLabelDisplayed,
|
|
[
|
|
{
|
|
label: "missing",
|
|
},
|
|
]
|
|
);
|
|
|
|
// Remove the image.
|
|
await clickOn(browser, ".delete");
|
|
|
|
await clickOn(browser, `#editorStampAddImage`);
|
|
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const { ContentTaskUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/ContentTaskUtils.sys.mjs"
|
|
);
|
|
const { document } = content;
|
|
await ContentTaskUtils.waitForCondition(
|
|
() =>
|
|
!!document.querySelector("#newAltTextDescriptionTextarea")?.value,
|
|
"text area must be displayed"
|
|
);
|
|
});
|
|
Services.fog.testResetFOG();
|
|
|
|
telemetryPromise = getPromise("image_status_label_displayed");
|
|
const dismissPromise = getPromise("dismiss");
|
|
await clickOn(browser, "#newAltTextNotNow");
|
|
await telemetryPromise;
|
|
await testTelemetryEventExtra(
|
|
Glean.pdfjsImageAltText.imageStatusLabelDisplayed,
|
|
[
|
|
{
|
|
label: "review",
|
|
},
|
|
],
|
|
false
|
|
);
|
|
await dismissPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.dismiss, [
|
|
{
|
|
alt_text_type: "present",
|
|
flow: "image_add",
|
|
},
|
|
]);
|
|
|
|
await waitForPdfJSClose(browser);
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
);
|
|
});
|
|
|
|
add_task(async function test_telemetry_new_alt_text_count() {
|
|
makePDFJSHandler();
|
|
|
|
await BrowserTestUtils.withNewTab(
|
|
{ gBrowser, url: "about:blank" },
|
|
async function (browser) {
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["pdfjs.annotationEditorMode", 0],
|
|
[altTextPref, true],
|
|
[guessAltTextPref, true],
|
|
[newFlowPref, true],
|
|
[browserMLPref, true],
|
|
],
|
|
});
|
|
|
|
await Services.fog.testFlushAllChildren();
|
|
Services.fog.testResetFOG();
|
|
|
|
// check that PDF is opened with internal viewer
|
|
await waitForPdfJSAllLayers(browser, TESTROOT + "file_empty_test.pdf", [
|
|
[
|
|
"annotationEditorLayer",
|
|
"annotationLayer",
|
|
"textLayer",
|
|
"canvasWrapper",
|
|
],
|
|
]);
|
|
|
|
await enableEditor(browser, "Stamp", 0);
|
|
await clickOn(browser, `#editorStampAddImage`);
|
|
|
|
await SpecialPowers.spawn(browser, [], async () => {
|
|
const { ContentTaskUtils } = ChromeUtils.importESModule(
|
|
"resource://testing-common/ContentTaskUtils.sys.mjs"
|
|
);
|
|
const { document } = content;
|
|
await ContentTaskUtils.waitForCondition(
|
|
() =>
|
|
!!document.querySelector("#newAltTextDescriptionTextarea")?.value,
|
|
"text area must be displayed"
|
|
);
|
|
});
|
|
Services.fog.testResetFOG();
|
|
|
|
telemetryPromise = getPromise("alt_text_edit");
|
|
const aiGenCheckPromise = getPromise("ai_generation_check");
|
|
await clickOn(browser, "#newAltTextCreateAutomaticallyButton");
|
|
await telemetryPromise;
|
|
|
|
await Services.fog.testFlushAllChildren();
|
|
let value = Glean.pdfjsImage.altTextEdit.ai_generation.testGetValue();
|
|
Assert.ok(!value, "Should have ai_generation disabled");
|
|
|
|
await aiGenCheckPromise;
|
|
await testTelemetryEventExtra(Glean.pdfjsImageAltText.aiGenerationCheck, [
|
|
{ status: "false" },
|
|
]);
|
|
|
|
await clickOn(browser, "#newAltTextNotNow");
|
|
|
|
// Delete the editor and create a new one but without AI.
|
|
await clickOn(browser, ".delete");
|
|
Services.fog.testResetFOG();
|
|
|
|
for (const string of ["Hello", "", "World", "", ""]) {
|
|
info("Adding image with alt text: " + (string || "(empty)"));
|
|
await clickOn(browser, `#editorStampAddImage`);
|
|
await waitForSelector(browser, "#newAltTextDescriptionTextarea");
|
|
await SpecialPowers.spawn(browser, [string], async text => {
|
|
content.document.querySelector(
|
|
"#newAltTextDescriptionTextarea"
|
|
).value = text;
|
|
});
|
|
await clickOn(browser, `#newAltTextSave`);
|
|
}
|
|
|
|
await clickOn(browser, "#printButton");
|
|
|
|
await waitForPreviewVisible();
|
|
await hitKey(browser, "VK_ESCAPE");
|
|
|
|
await Services.fog.testFlushAllChildren();
|
|
value = Glean.pdfjsImage.added.with_alt_text.testGetValue();
|
|
Assert.equal(value, 2, "Should have 2 images with alt text");
|
|
|
|
value = Glean.pdfjsImage.added.with_no_alt_text.testGetValue();
|
|
Assert.equal(value, 3, "Should have 3 images without alt text");
|
|
|
|
await waitForPdfJSClose(browser);
|
|
await SpecialPowers.popPrefEnv();
|
|
}
|
|
);
|
|
});
|