Bug 1797393 - P2: Robustify spelling error text test. r=Jamie

Layout can trigger several text attribute changed events. We need to
wait until we get the correct one before continuing the test.

Differential Revision: https://phabricator.services.mozilla.com/D160300
This commit is contained in:
Eitan Isaacson 2022-10-28 18:30:01 +00:00
parent 4c3297aee9
commit 9706b711cc

View File

@ -345,6 +345,48 @@ addAccessibleTask(
}
);
/*
* Given a text accessible and a list of ranges
* check if those ranges match the misspelled ranges in the accessible.
*/
function misspelledRangesMatch(acc, ranges) {
let offset = 0;
let expectedRanges = [...ranges];
let charCount = acc.characterCount;
while (offset < charCount) {
let start = {};
let end = {};
let attributes = acc.getTextAttributes(false, offset, start, end);
offset = end.value;
try {
if (attributes.getStringProperty("invalid") == "spelling") {
let expected = expectedRanges.shift();
if (
!expected ||
expected[0] != start.value ||
expected[1] != end.value
) {
return false;
}
}
} catch (err) {}
}
return !expectedRanges.length;
}
/*
* Returns a promise that resolves after a text attribute changed event
* brings us to a state where the misspelled ranges match.
*/
function waitForMisspelledRanges(acc, ranges) {
return waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, () =>
misspelledRangesMatch(acc, ranges)
).then(() => {
ok(true, `Misspelled ranges match: ${JSON.stringify(ranges)}`);
});
}
/**
* Test spelling errors.
*/
@ -354,24 +396,22 @@ addAccessibleTask(
<div contenteditable id="editable" spellcheck="true">plain<span> ts</span>et <b>bold</b></div>
`,
async function(browser, docAcc) {
const misspelledAttrs = { invalid: "spelling" };
const textarea = findAccessibleChildByID(docAcc, "textarea");
const textarea = findAccessibleChildByID(docAcc, "textarea", [
nsIAccessibleText,
]);
info("Focusing textarea");
let spellingChanged = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, textarea);
let spellingChanged = waitForMisspelledRanges(textarea, [
[5, 9],
[10, 14],
]);
textarea.takeFocus();
await spellingChanged;
testTextAttrs(textarea, 0, {}, {}, 0, 5, true); // "test "
testTextAttrs(textarea, 5, misspelledAttrs, {}, 5, 9, true); // "tset"
testTextAttrs(textarea, 9, {}, {}, 9, 10, true); // " "
testTextAttrs(textarea, 10, misspelledAttrs, {}, 10, 14, true); // "tset"
testTextAttrs(textarea, 14, {}, {}, 14, 19, true); // " test"
// Test removal of a spelling error.
info('textarea: Changing first "tset" to "test"');
// setTextRange fires multiple EVENT_TEXT_ATTRIBUTE_CHANGED, so replace by
// selecting and typing instead.
spellingChanged = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, textarea);
spellingChanged = waitForMisspelledRanges(textarea, [[10, 14]]);
await invokeContentTask(browser, [], () => {
content.document.getElementById("textarea").setSelectionRange(5, 9);
});
@ -379,24 +419,19 @@ addAccessibleTask(
// Move the cursor to trigger spell check.
EventUtils.synthesizeKey("KEY_ArrowRight");
await spellingChanged;
testTextAttrs(textarea, 0, {}, {}, 0, 10, true); // "test test "
testTextAttrs(textarea, 10, misspelledAttrs, {}, 10, 14, true); // "tset"
testTextAttrs(textarea, 14, {}, {}, 14, 19, true); // " test"
// Test addition of a spelling error.
info('textarea: Changing it back to "tset"');
spellingChanged = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, textarea);
spellingChanged = waitForMisspelledRanges(textarea, [
[5, 9],
[10, 14],
]);
await invokeContentTask(browser, [], () => {
content.document.getElementById("textarea").setSelectionRange(5, 9);
});
EventUtils.sendString("tset");
EventUtils.synthesizeKey("KEY_ArrowRight");
await spellingChanged;
testTextAttrs(textarea, 0, {}, {}, 0, 5, true); // "test "
testTextAttrs(textarea, 5, misspelledAttrs, {}, 5, 9, true); // "tset"
testTextAttrs(textarea, 9, {}, {}, 9, 10, true); // " "
testTextAttrs(textarea, 10, misspelledAttrs, {}, 10, 14, true); // "tset"
testTextAttrs(textarea, 14, {}, {}, 14, 19, true); // " test"
// Ensure that changing the text without changing any spelling errors
// correctly updates offsets.
@ -413,14 +448,21 @@ addAccessibleTask(
let selected = waitForEvent(EVENT_TEXT_SELECTION_CHANGED, textarea);
EventUtils.synthesizeKey("KEY_ArrowRight", { shiftKey: true });
await selected;
testTextAttrs(textarea, 0, {}, {}, 0, 4, true); // "the "
testTextAttrs(textarea, 4, misspelledAttrs, {}, 4, 8, true); // "tset"
testTextAttrs(textarea, 8, {}, {}, 8, 9, true); // " "
testTextAttrs(textarea, 9, misspelledAttrs, {}, 9, 13, true); // "tset"
testTextAttrs(textarea, 13, {}, {}, 13, 18, true); // " test"
const expectedRanges = [
[4, 8],
[9, 13],
];
if (!misspelledRangesMatch(textarea, expectedRanges)) {
// XXX: Sometimes the attributes do get updated after all.
await waitForMisspelledRanges(textarea, expectedRanges);
}
const editable = findAccessibleChildByID(docAcc, "editable");
const editable = findAccessibleChildByID(docAcc, "editable", [
nsIAccessibleText,
]);
info("Focusing editable");
spellingChanged = waitForMisspelledRanges(editable, [[6, 10]]);
spellingChanged = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, editable);
editable.takeFocus();
await spellingChanged;
@ -428,7 +470,7 @@ addAccessibleTask(
testTextAttrs(editable, 0, {}, {}, 0, 6, true); // "plain "
// Ensure we detect the spelling error even though there is a style change
// after it.
testTextAttrs(editable, 6, misspelledAttrs, {}, 6, 10, true); // "tset"
testTextAttrs(editable, 6, { invalid: "spelling" }, {}, 6, 10, true); // "tset"
testTextAttrs(editable, 10, {}, {}, 10, 11, true); // " "
// Ensure a style change is still detected in the presence of a spelling
// error.