Skip to content

Commit

Permalink
[Editor] Add a first test to test the new alt text flow
Browse files Browse the repository at this point in the history
  • Loading branch information
calixteman committed Aug 8, 2024
1 parent 40aa593 commit 0864aef
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 7 deletions.
232 changes: 232 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,233 @@ 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
);
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);

// 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.evaluate(() => {
window.uiManager.unselectAll();
});
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");
await clearInput(
page,
"#newAltTextDescriptionTextarea",
/* waitForInputEvent = */ true
);

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

// 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");
await waitForSelectedEditor(page, editorSelector);

// Unselect and select the editor and check that the badge is visible.
await page.evaluate(() => {
window.uiManager.unselectAll();
});
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}`).innerText,
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

0 comments on commit 0864aef

Please sign in to comment.