Bug 1741793 part 6: Add tests to exercise RemoteAccessible text selection retrieval. r=eeejay

Differential Revision: https://phabricator.services.mozilla.com/D139345
This commit is contained in:
James Teh 2022-02-26 23:01:56 +00:00
Родитель 35ebd00b30
Коммит 8c2cca9320
1 изменённых файлов: 230 добавлений и 0 удалений

Просмотреть файл

@ -677,3 +677,233 @@ addAccessibleTask(
},
{ chrome: true, topLevel: true, iframe: true, remoteIframe: true }
);
function waitForSelectionChange(selectionAcc, caretAcc) {
if (!caretAcc) {
caretAcc = selectionAcc;
}
return waitForEvents(
[
[EVENT_TEXT_SELECTION_CHANGED, selectionAcc],
// We must swallow the caret events as well to avoid confusion with later,
// unrelated caret events.
[EVENT_TEXT_CARET_MOVED, caretAcc],
],
true
);
}
function changeDomSelection(
browser,
anchorId,
anchorOffset,
focusId,
focusOffset
) {
return invokeContentTask(
browser,
[anchorId, anchorOffset, focusId, focusOffset],
(
contentAnchorId,
contentAnchorOffset,
contentFocusId,
contentFocusOffset
) => {
// We want the text node, so we use firstChild.
content.window
.getSelection()
.setBaseAndExtent(
content.document.getElementById(contentAnchorId).firstChild,
contentAnchorOffset,
content.document.getElementById(contentFocusId).firstChild,
contentFocusOffset
);
}
);
}
function testSelectionRange(
browser,
root,
startContainer,
startOffset,
endContainer,
endOffset
) {
if (browser.isRemoteBrowser && !isCacheEnabled) {
todo(
false,
"selectionRanges not implemented for non-cached RemoteAccessible"
);
return;
}
let selRange = root.selectionRanges.queryElementAt(0, nsIAccessibleTextRange);
testTextRange(
selRange,
getAccessibleDOMNodeID(root),
startContainer,
startOffset,
endContainer,
endOffset
);
}
/**
* Test text selection.
*/
addAccessibleTask(
`
<textarea id="textarea">ab</textarea>
<div id="editable" contenteditable>
<p id="p1">a</p>
<p id="p2">bc</p>
<p id="pWithLink">d<a id="link" href="https://example.com/">e</a><span id="textAfterLink">f</span></p>
</div>
`,
async function(browser, docAcc) {
const textarea = findAccessibleChildByID(docAcc, "textarea", [
nsIAccessibleText,
]);
info("Focusing textarea");
let caretMoved = waitForEvent(EVENT_TEXT_CARET_MOVED, textarea);
textarea.takeFocus();
await caretMoved;
testSelectionRange(browser, textarea, textarea, 0, textarea, 0);
is(textarea.selectionCount, 0, "textarea selectionCount is 0");
info("Selecting a in textarea");
let selChanged = waitForSelectionChange(textarea);
EventUtils.synthesizeKey("KEY_ArrowRight", { shiftKey: true });
await selChanged;
testSelectionRange(browser, textarea, textarea, 0, textarea, 1);
testTextGetSelection(textarea, 0, 1, 0);
info("Selecting b in textarea");
selChanged = waitForSelectionChange(textarea);
EventUtils.synthesizeKey("KEY_ArrowRight", { shiftKey: true });
await selChanged;
testSelectionRange(browser, textarea, textarea, 0, textarea, 2);
testTextGetSelection(textarea, 0, 2, 0);
info("Unselecting b in textarea");
selChanged = waitForSelectionChange(textarea);
EventUtils.synthesizeKey("KEY_ArrowLeft", { shiftKey: true });
await selChanged;
testSelectionRange(browser, textarea, textarea, 0, textarea, 1);
testTextGetSelection(textarea, 0, 1, 0);
info("Unselecting a in textarea");
// We don't fire selection changed when the selection collapses.
caretMoved = waitForEvent(EVENT_TEXT_CARET_MOVED, textarea);
EventUtils.synthesizeKey("KEY_ArrowLeft", { shiftKey: true });
await caretMoved;
testSelectionRange(browser, textarea, textarea, 0, textarea, 0);
is(textarea.selectionCount, 0, "textarea selectionCount is 0");
const editable = findAccessibleChildByID(docAcc, "editable", [
nsIAccessibleText,
]);
const p1 = findAccessibleChildByID(docAcc, "p1", [nsIAccessibleText]);
info("Focusing editable, caret to start");
caretMoved = waitForEvent(EVENT_TEXT_CARET_MOVED, p1);
await changeDomSelection(browser, "p1", 0, "p1", 0);
await caretMoved;
testSelectionRange(browser, editable, p1, 0, p1, 0);
is(editable.selectionCount, 0, "editable selectionCount is 0");
is(p1.selectionCount, 0, "p1 selectionCount is 0");
info("Selecting a in editable");
selChanged = waitForSelectionChange(p1);
await changeDomSelection(browser, "p1", 0, "p1", 1);
await selChanged;
testSelectionRange(browser, editable, p1, 0, p1, 1);
testTextGetSelection(editable, 0, 1, 0);
testTextGetSelection(p1, 0, 1, 0);
const p2 = findAccessibleChildByID(docAcc, "p2", [nsIAccessibleText]);
// Selecting across two Accessibles with only a partial selection in the
// second.
info("Selecting ab in editable");
selChanged = waitForSelectionChange(editable, p2);
await changeDomSelection(browser, "p1", 0, "p2", 1);
await selChanged;
testSelectionRange(browser, editable, p1, 0, p2, 1);
testTextGetSelection(editable, 0, 2, 0);
testTextGetSelection(p1, 0, 1, 0);
testTextGetSelection(p2, 0, 1, 0);
const pWithLink = findAccessibleChildByID(docAcc, "pWithLink", [
nsIAccessibleText,
]);
const link = findAccessibleChildByID(docAcc, "link", [nsIAccessibleText]);
// Selecting both text and a link.
info("Selecting de in editable");
selChanged = waitForSelectionChange(pWithLink, link);
await changeDomSelection(browser, "pWithLink", 0, "link", 1);
await selChanged;
testSelectionRange(browser, editable, pWithLink, 0, link, 1);
testTextGetSelection(editable, 2, 3, 0);
testTextGetSelection(pWithLink, 0, 2, 0);
testTextGetSelection(link, 0, 1, 0);
// Selecting a link and text on either side.
info("Selecting def in editable");
selChanged = waitForSelectionChange(pWithLink, pWithLink);
await changeDomSelection(browser, "pWithLink", 0, "textAfterLink", 1);
await selChanged;
testSelectionRange(browser, editable, pWithLink, 0, pWithLink, 3);
testTextGetSelection(editable, 2, 3, 0);
testTextGetSelection(pWithLink, 0, 3, 0);
testTextGetSelection(link, 0, 1, 0);
// Noncontiguous selection.
info("Selecting a in editable");
selChanged = waitForSelectionChange(p1);
await changeDomSelection(browser, "p1", 0, "p1", 1);
await selChanged;
info("Adding c to selection in editable");
selChanged = waitForSelectionChange(p2);
await invokeContentTask(browser, [], () => {
const r = content.document.createRange();
const p2text = content.document.getElementById("p2").firstChild;
r.setStart(p2text, 0);
r.setEnd(p2text, 1);
content.window.getSelection().addRange(r);
});
await selChanged;
if (browser.isRemoteBrowser && !isCacheEnabled) {
todo(
false,
"selectionRanges not implemented for non-cached RemoteAccessible"
);
} else {
let selRanges = editable.selectionRanges;
is(selRanges.length, 2, "2 selection ranges");
testTextRange(
selRanges.queryElementAt(0, nsIAccessibleTextRange),
"range 0",
p1,
0,
p1,
1
);
testTextRange(
selRanges.queryElementAt(1, nsIAccessibleTextRange),
"range 1",
p2,
0,
p2,
1
);
}
is(editable.selectionCount, 2, "editable selectionCount is 2");
testTextGetSelection(editable, 0, 1, 0);
testTextGetSelection(editable, 1, 2, 1);
},
{
chrome: true,
topLevel: !isWinNoCache,
iframe: !isWinNoCache,
remoteIframe: !isWinNoCache,
}
);