Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Editor] Add a first test to test the new alt text flow #18581

Merged
merged 1 commit into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions test/integration/stamp_editor_spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import {
applyFunctionToEditor,
awaitPromise,
clearInput,
closePages,
copy,
copyToClipboard,
Expand All @@ -24,6 +25,7 @@ import {
getFirstSerialized,
getRect,
getSerialized,
isVisible,
kbBigMoveDown,
kbBigMoveRight,
kbSelectAll,
Expand All @@ -39,6 +41,7 @@ import {
waitForSelectedEditor,
waitForSerialized,
waitForStorageEntries,
waitForUnselectedEditor,
} from "./test_utils.mjs";
import { fileURLToPath } from "url";
import fs from "fs";
Expand Down Expand Up @@ -835,4 +838,228 @@ describe("Stamp Editor", () => {
}
});
});

describe("New alt-text flow", () => {
let pages;

beforeAll(async () => {
pages = await loadAndWait(
"empty.pdf",
".annotationEditorLayer",
null,
null,
{
enableAltText: true,
enableUpdatedAddImage: true,
enableGuessAltText: true,
}
);
});

afterEach(async () => {
for (const [, page] of pages) {
if (await isVisible(page, "#newAltTextDialog")) {
await page.keyboard.press("Escape");
await page.waitForSelector("#newAltTextDisclaimer", {
visible: false,
});
}
await page.evaluate(() => {
window.uiManager.reset();
});
// Disable editing mode.
await switchToStamp(page, /* disable */ true);
}
});

afterAll(async () => {
await closePages(pages);
});

it("must check the new alt text flow (part 1)", async () => {
// Run sequentially to avoid clipboard issues.
for (const [browserName, page] of pages) {
await switchToStamp(page);

// Add an image.
await copyImage(page, "../images/firefox_logo.png", 0);
const editorSelector = getEditorSelector(0);
await page.waitForSelector(editorSelector);
await waitForSerialized(page, 1);

// Wait for the dialog to be visible.
await page.waitForSelector("#newAltTextDialog", { visible: true });
// Wait for the spinner to be visible.
await page.waitForSelector("#newAltTextDescriptionContainer.loading");
// Check we've the disclaimer.
await page.waitForSelector("#newAltTextDisclaimer", { visible: true });

// Check that the dialog has the correct title: "Edit..."
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Edit')"
);

// Check that AI guessed the correct alt text.
await page.waitForFunction(
`document.getElementById("newAltTextDescriptionTextarea").value ===
"Fake alt text"`
);

// Check that the dialog has the correct title: "Edit..."
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Edit')"
);

// Check we've the disclaimer.
await page.waitForSelector("#newAltTextDisclaimer", { visible: true });

// Clear the input and check that the title changes to "Add..."
await clearInput(
page,
"#newAltTextDescriptionTextarea",
/* waitForInputEvent = */ true
calixteman marked this conversation as resolved.
Show resolved Hide resolved
);
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Add')"
);

// Check we haven't the disclaimer.
await page.waitForSelector("#newAltTextDisclaimer", { visible: false });

// Add a new alt text and check that the title changes to "Edit..."
await page.type("#newAltTextDescriptionTextarea", "Hello World");
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Edit')"
);

// Check we haven't the disclaimer after the modification.
await page.waitForSelector("#newAltTextDisclaimer", { visible: false });

// Click on the Not Now button.
await page.click("#newAltTextNotNow");
await page.waitForSelector("#newAltTextDialog", { visible: false });
await waitForSelectedEditor(page, editorSelector);

// Wait for the alt-text button to be visible.
const buttonSelector = `${editorSelector} button.altText.new`;
await page.waitForSelector(buttonSelector, { visible: true });

// Check the text in the button.
let text = await page.evaluate(
sel => document.querySelector(sel).textContent,
buttonSelector
);
let ariaLabel = await page.evaluate(
sel => document.querySelector(sel).getAttribute("aria-label"),
buttonSelector
);
expect(text === ariaLabel && text)
.withContext(`In ${browserName}`)
.toEqual("Review alt text");

// Unselect and select the editor and check that the badge is visible.
await page.keyboard.press("Escape");
await waitForUnselectedEditor(page, editorSelector);
await page.waitForSelector(".editToolbar", { visible: false });
await page.waitForSelector(".noAltTextBadge", { visible: true });

await page.evaluate(() => {
window.uiManager.selectAll();
});
await waitForSelectedEditor(page, editorSelector);
await page.waitForSelector(".editToolbar", { visible: true });
await page.waitForSelector(".noAltTextBadge", { visible: false });

// Click on the Review button.
await page.click(buttonSelector);
await page.waitForSelector("#newAltTextDialog", { visible: true });

// Check that the dialog has the correct title: "Edit..."
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Edit')"
);

// Click on create automatically toggle button.
await page.click("#newAltTextCreateAutomaticallyButton");
calixteman marked this conversation as resolved.
Show resolved Hide resolved
await clearInput(
page,
"#newAltTextDescriptionTextarea",
/* waitForInputEvent = */ true
);

// Save the empty text.
await page.click("#newAltTextSave");
await page.waitForSelector("#newAltTextDialog", { visible: false });
await waitForSelectedEditor(page, editorSelector);
await page.waitForSelector(buttonSelector, { visible: true });

// Check the text in the button.
text = await page.evaluate(
sel => document.querySelector(sel).textContent,
buttonSelector
);
ariaLabel = await page.evaluate(
sel => document.querySelector(sel).getAttribute("aria-label"),
buttonSelector
);
expect(text === ariaLabel && text)
.withContext(`In ${browserName}`)
.toEqual("Missing alt text");

// Unselect and select the editor and check that the badge is visible.
await page.keyboard.press("Escape");
await waitForUnselectedEditor(page, editorSelector);
await page.waitForSelector(".editToolbar", { visible: false });
await page.waitForSelector(".noAltTextBadge", { visible: true });
await page.evaluate(() => {
window.uiManager.selectAll();
});
await waitForSelectedEditor(page, editorSelector);
await page.waitForSelector(".editToolbar", { visible: true });
await page.waitForSelector(".noAltTextBadge", { visible: false });

// Click on the Review button.
await page.click(buttonSelector);
await page.waitForSelector("#newAltTextDialog", { visible: true });

await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Add')"
);
// Add a new alt text and check that the title changes to "Edit..."
await page.type("#newAltTextDescriptionTextarea", "Hello World");
await page.waitForFunction(
"document.getElementById('newAltTextTitle').textContent.startsWith('Edit')"
);

// Click on the Save button.
await page.click("#newAltTextSave");
await page.waitForSelector("#newAltTextDialog", { visible: false });

// Check the text in the button.
text = await page.evaluate(
sel => document.querySelector(sel).firstChild.textContent,
buttonSelector
);
ariaLabel = await page.evaluate(
sel => document.querySelector(sel).getAttribute("aria-label"),
buttonSelector
);
expect(text === ariaLabel && text)
.withContext(`In ${browserName}`)
.toEqual("Alt text added");

await page.hover(buttonSelector);

// Wait for the tooltip to be visible.
const tooltipSelector = `${buttonSelector} .tooltip`;
await page.waitForSelector(tooltipSelector, { visible: true });

const tooltipText = await page.evaluate(
sel => document.querySelector(`${sel}`).textContent,
tooltipSelector
);
expect(tooltipText).toEqual("Hello World");
}
});
});
});
32 changes: 25 additions & 7 deletions test/integration/test_utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ function closePages(pages) {
return Promise.all(pages.map(([_, page]) => closeSinglePage(page)));
}

function isVisible(page, selector) {
return page.evaluate(
sel => document.querySelector(sel)?.checkVisibility(),
selector
);
}

async function closeSinglePage(page) {
// Avoid to keep something from a previous test.
await page.evaluate(async () => {
Expand Down Expand Up @@ -119,13 +126,23 @@ function waitForTimeout(milliseconds) {
});
}

async function clearInput(page, selector) {
await page.click(selector);
await kbSelectAll(page);
await page.keyboard.press("Backspace");
await page.waitForFunction(
`document.querySelector('${selector}').value === ""`
);
async function clearInput(page, selector, waitForInputEvent = false) {
const action = async () => {
await page.click(selector);
await kbSelectAll(page);
await page.keyboard.press("Backspace");
await page.waitForFunction(
`document.querySelector('${selector}').value === ""`
);
};
return waitForInputEvent
? waitForEvent({
page,
eventName: "input",
action,
selector,
})
: action();
}

function getSelector(id) {
Expand Down Expand Up @@ -711,6 +728,7 @@ export {
getSerialized,
getSpanRectFromText,
hover,
isVisible,
kbBigMoveDown,
kbBigMoveLeft,
kbBigMoveRight,
Expand Down
15 changes: 15 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,21 @@ const PDFViewerApplication = {
parseInt(params.get("spreadmodeonload"))
);
}
if (params.has("enablealttext")) {
AppOptions.set("enableAltText", params.get("enablealttext") === "true");
}
if (params.has("enableupdatedaddimage")) {
AppOptions.set(
"enableUpdatedAddImage",
params.get("enableupdatedaddimage") === "true"
);
}
if (params.has("enableguessalttext")) {
AppOptions.set(
"enableGuessAltText",
params.get("enableguessalttext") === "true"
);
}
}
},

Expand Down