Bug 1832353 - P2: Convert editable text tests to browser tests. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D178715
This commit is contained in:
Eitan Isaacson 2023-05-25 20:38:29 +00:00
Родитель e90263d66f
Коммит 6d1721c180
8 изменённых файлов: 318 добавлений и 619 удалений

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

@ -8,6 +8,7 @@ support-files =
prefs =
javascript.options.asyncstack_capture_debuggee_only=false
[browser_editabletext.js]
[browser_text.js]
[browser_text_caret.js]
[browser_text_paragraph_boundary.js]

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

@ -0,0 +1,173 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
async function testEditable(browser, acc, aBefore = "", aAfter = "") {
async function resetInput() {
if (acc.childCount <= 1) {
return;
}
let emptyInputEvent = waitForEvent(EVENT_TEXT_VALUE_CHANGE, "input");
await invokeContentTask(browser, [], async () => {
content.document.getElementById("input").innerHTML = "";
});
await emptyInputEvent;
}
// ////////////////////////////////////////////////////////////////////////
// insertText
await testInsertText(acc, "hello", 0, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hello", aAfter]);
await testInsertText(acc, "ma ", 0, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "ma hello", aAfter]);
await testInsertText(acc, "ma", 2, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "mama hello", aAfter]);
await testInsertText(acc, " hello", 10, aBefore.length);
await isFinalValueCorrect(browser, acc, [
aBefore,
"mama hello hello",
aAfter,
]);
// ////////////////////////////////////////////////////////////////////////
// deleteText
await testDeleteText(acc, 0, 5, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hello hello", aAfter]);
await testDeleteText(acc, 5, 6, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hellohello", aAfter]);
await testDeleteText(acc, 5, 10, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hello", aAfter]);
await testDeleteText(acc, 0, 5, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "", aAfter]);
// XXX: clipboard operation tests don't work well with editable documents.
if (acc.role == ROLE_DOCUMENT) {
return;
}
await resetInput();
// copyText and pasteText
await testInsertText(acc, "hello", 0, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hello", aAfter]);
await testCopyText(acc, 0, 1, aBefore.length, browser, "h");
await testPasteText(acc, 1, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hhello", aAfter]);
await testCopyText(acc, 5, 6, aBefore.length, browser, "o");
await testPasteText(acc, 6, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hhelloo", aAfter]);
await testCopyText(acc, 2, 3, aBefore.length, browser, "e");
await testPasteText(acc, 1, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "hehelloo", aAfter]);
// cut & paste
await testCutText(acc, 0, 1, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "ehelloo", aAfter]);
await testPasteText(acc, 2, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "ehhelloo", aAfter]);
await testCutText(acc, 3, 4, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "ehhlloo", aAfter]);
await testPasteText(acc, 6, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "ehhlloeo", aAfter]);
await testCutText(acc, 0, 8, aBefore.length);
await isFinalValueCorrect(browser, acc, [aBefore, "", aAfter]);
await resetInput();
// ////////////////////////////////////////////////////////////////////////
// setTextContents
await testSetTextContents(acc, "hello", aBefore.length, [
EVENT_TEXT_INSERTED,
]);
await isFinalValueCorrect(browser, acc, [aBefore, "hello", aAfter]);
await testSetTextContents(acc, "katze", aBefore.length, [
EVENT_TEXT_REMOVED,
EVENT_TEXT_INSERTED,
]);
await isFinalValueCorrect(browser, acc, [aBefore, "katze", aAfter]);
}
addAccessibleTask(
`<input id="input"/>`,
async function (browser, docAcc) {
await testEditable(browser, findAccessibleChildByID(docAcc, "input"));
},
{ chrome: true, topLevel: true }
);
addAccessibleTask(
`<style>
#input::after {
content: "pseudo element";
}
</style>
<div id="input" contenteditable="true" role="textbox"></div>`,
async function (browser, docAcc) {
await testEditable(
browser,
findAccessibleChildByID(docAcc, "input"),
"",
"pseudo element"
);
},
{ chrome: true, topLevel: false /* bug 1834129 */ }
);
addAccessibleTask(
`<style>
#input::before {
content: "pseudo element";
}
</style>
<div id="input" contenteditable="true" role="textbox"></div>`,
async function (browser, docAcc) {
await testEditable(
browser,
findAccessibleChildByID(docAcc, "input"),
"pseudo element"
);
},
{ chrome: true, topLevel: false /* bug 1834129 */ }
);
addAccessibleTask(
`<style>
#input::before {
content: "before";
}
#input::after {
content: "after";
}
</style>
<div id="input" contenteditable="true" role="textbox"></div>`,
async function (browser, docAcc) {
await testEditable(
browser,
findAccessibleChildByID(docAcc, "input"),
"before",
"after"
);
},
{ chrome: true, topLevel: false /* bug 1834129 */ }
);
addAccessibleTask(
``,
async function (browser, docAcc) {
await testEditable(browser, docAcc);
},
{
chrome: true,
topLevel: true,
contentDocBodyAttrs: { contentEditable: "true" },
}
);

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

@ -7,7 +7,9 @@
/* exported createTextLeafPoint, DIRECTION_NEXT, DIRECTION_PREVIOUS,
BOUNDARY_FLAG_DEFAULT, BOUNDARY_FLAG_INCLUDE_ORIGIN,
BOUNDARY_FLAG_STOP_IN_EDITABLE, BOUNDARY_FLAG_SKIP_LIST_ITEM_MARKER,
readablePoint, testPointEqual, textBoundaryGenerator, testBoundarySequence */
readablePoint, testPointEqual, textBoundaryGenerator, testBoundarySequence,
isFinalValueCorrect, isFinalValueCorrect, testInsertText, testDeleteText,
testCopyText, testPasteText, testCutText, testSetTextContents */
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
@ -17,9 +19,13 @@ Services.scriptloader.loadSubScript(
// Loading and common.js from accessible/tests/mochitest/ for all tests, as
// well as promisified-events.js.
/* import-globals-from ../../mochitest/role.js */
loadScripts(
{ name: "common.js", dir: MOCHITESTS_DIR },
{ name: "text.js", dir: MOCHITESTS_DIR },
{ name: "role.js", dir: MOCHITESTS_DIR },
{ name: "promisified-events.js", dir: MOCHITESTS_DIR }
);
@ -131,3 +137,140 @@ function testBoundarySequence(
msg
);
}
///////////////////////////////////////////////////////////////////////////////
// Editable text
async function waitForCopy(browser) {
await BrowserTestUtils.waitForContentEvent(browser, "copy", false, evt => {
return true;
});
let clipboardData = await invokeContentTask(browser, [], async () => {
let text = await content.navigator.clipboard.readText();
return text;
});
return clipboardData;
}
async function isFinalValueCorrect(
browser,
acc,
expectedTextLeafs,
msg = "Value is correct"
) {
let value =
acc.role == ROLE_ENTRY
? acc.value
: await invokeContentTask(browser, [], () => {
return content.document.body.textContent;
});
let [before, text, after] = expectedTextLeafs;
let finalValue =
before && after && !text
? [before, after].join(" ")
: [before, text, after].join("");
is(value.replace("\xa0", " "), finalValue, msg);
}
function waitForTextChangeEvents(acc, eventSeq) {
let events = eventSeq.map(eventType => {
return [eventType, acc];
});
if (acc.role == ROLE_ENTRY) {
events.push([EVENT_TEXT_VALUE_CHANGE, acc]);
}
return waitForEvents(events);
}
async function testSetTextContents(acc, text, staticContentOffset, events) {
acc.QueryInterface(nsIAccessibleEditableText);
let evtPromise = waitForTextChangeEvents(acc, events);
acc.setTextContents(text);
let evt = (await evtPromise)[0];
evt.QueryInterface(nsIAccessibleTextChangeEvent);
is(evt.start, staticContentOffset);
}
async function testInsertText(
acc,
textToInsert,
insertOffset,
staticContentOffset
) {
acc.QueryInterface(nsIAccessibleEditableText);
let evtPromise = waitForTextChangeEvents(acc, [EVENT_TEXT_INSERTED]);
acc.insertText(textToInsert, staticContentOffset + insertOffset);
let evt = (await evtPromise)[0];
evt.QueryInterface(nsIAccessibleTextChangeEvent);
is(evt.start, staticContentOffset + insertOffset);
}
async function testDeleteText(
acc,
startOffset,
endOffset,
staticContentOffset
) {
acc.QueryInterface(nsIAccessibleEditableText);
let evtPromise = waitForTextChangeEvents(acc, [EVENT_TEXT_REMOVED]);
acc.deleteText(
staticContentOffset + startOffset,
staticContentOffset + endOffset
);
let evt = (await evtPromise)[0];
evt.QueryInterface(nsIAccessibleTextChangeEvent);
is(evt.start, staticContentOffset + startOffset);
}
async function testCopyText(
acc,
startOffset,
endOffset,
staticContentOffset,
browser,
aExpectedClipboard = null
) {
acc.QueryInterface(nsIAccessibleEditableText);
let copied = waitForCopy(browser);
acc.copyText(
staticContentOffset + startOffset,
staticContentOffset + endOffset
);
let clipboardText = await copied;
if (aExpectedClipboard != null) {
is(clipboardText, aExpectedClipboard, "Correct text in clipboard");
}
}
async function testPasteText(acc, insertOffset, staticContentOffset) {
acc.QueryInterface(nsIAccessibleEditableText);
let evtPromise = waitForTextChangeEvents(acc, [EVENT_TEXT_INSERTED]);
acc.pasteText(staticContentOffset + insertOffset);
let evt = (await evtPromise)[0];
evt.QueryInterface(nsIAccessibleTextChangeEvent);
// XXX: In non-headless mode pasting text produces several text leaves
// and the offset is not what we expect.
// is(evt.start, staticContentOffset + insertOffset);
}
async function testCutText(acc, startOffset, endOffset, staticContentOffset) {
acc.QueryInterface(nsIAccessibleEditableText);
let evtPromise = waitForTextChangeEvents(acc, [EVENT_TEXT_REMOVED]);
acc.cutText(
staticContentOffset + startOffset,
staticContentOffset + endOffset
);
let evt = (await evtPromise)[0];
evt.QueryInterface(nsIAccessibleTextChangeEvent);
is(evt.start, staticContentOffset + startOffset);
}

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

@ -1,7 +0,0 @@
[DEFAULT]
support-files =
editabletext.js
!/accessible/tests/mochitest/*.js
[test_1.html]
[test_2.html]

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

@ -1,409 +0,0 @@
/* import-globals-from ../common.js */
/* import-globals-from ../events.js */
/**
* Perform all editable text tests.
*/
function editableTextTestRun() {
this.add = function add(aTest) {
this.seq.push(aTest);
};
this.run = function run() {
this.iterate();
};
this.index = 0;
this.seq = [];
this.iterate = function iterate() {
if (this.index < this.seq.length) {
this.seq[this.index++].startTest(this);
return;
}
this.seq = null;
SimpleTest.finish();
};
}
/**
* Used to test nsIEditableTextAccessible methods.
*/
function editableTextTest(aID) {
/**
* Schedule a test, the given function with its arguments will be executed
* when preceding test is complete.
*/
this.scheduleTest = function scheduleTest(aFunc, ...aFuncArgs) {
// A data container acts like a dummy invoker, it's never invoked but
// it's used to generate real invoker when previous invoker was handled.
var dataContainer = {
func: aFunc,
funcArgs: aFuncArgs,
};
this.mEventQueue.push(dataContainer);
if (!this.mEventQueueReady) {
this.unwrapNextTest();
this.mEventQueueReady = true;
}
};
/**
* setTextContents test.
*/
this.setTextContents = function setTextContents(aValue, aSkipStartOffset) {
var testID = "setTextContents '" + aValue + "' for " + prettyName(aID);
function setTextContentsInvoke() {
dump(`\nsetTextContents '${aValue}'\n`);
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.setTextContents(aValue);
}
aSkipStartOffset = aSkipStartOffset || 0;
var insertTripple = aValue
? [aSkipStartOffset, aSkipStartOffset + aValue.length, aValue]
: null;
var oldValue = getValue();
var removeTripple = oldValue
? [aSkipStartOffset, aSkipStartOffset + oldValue.length, oldValue]
: null;
this.generateTest(
removeTripple,
insertTripple,
setTextContentsInvoke,
getValueChecker(aValue),
testID
);
};
/**
* insertText test.
*/
this.insertText = function insertText(aStr, aPos, aResStr, aResPos) {
var testID =
"insertText '" + aStr + "' at " + aPos + " for " + prettyName(aID);
function insertTextInvoke() {
dump(`\ninsertText '${aStr}' at ${aPos} pos\n`);
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.insertText(aStr, aPos);
}
var resPos = aResPos != undefined ? aResPos : aPos;
this.generateTest(
null,
[resPos, resPos + aStr.length, aStr],
insertTextInvoke,
getValueChecker(aResStr),
testID
);
};
/**
* copyText test.
*/
this.copyText = function copyText(aStartPos, aEndPos, aClipboardStr) {
var testID =
"copyText from " +
aStartPos +
" to " +
aEndPos +
" for " +
prettyName(aID);
function copyTextInvoke() {
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.copyText(aStartPos, aEndPos);
}
this.generateTest(
null,
null,
copyTextInvoke,
getClipboardChecker(aClipboardStr),
testID
);
};
/**
* copyText and pasteText test.
*/
this.copyNPasteText = function copyNPasteText(
aStartPos,
aEndPos,
aPos,
aResStr
) {
var testID =
"copyText from " +
aStartPos +
" to " +
aEndPos +
"and pasteText at " +
aPos +
" for " +
prettyName(aID);
function copyNPasteTextInvoke() {
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.copyText(aStartPos, aEndPos);
acc.pasteText(aPos);
}
this.generateTest(
null,
[aStartPos, aEndPos, getTextFromClipboard],
copyNPasteTextInvoke,
getValueChecker(aResStr),
testID
);
};
/**
* cutText test.
*/
this.cutText = function cutText(
aStartPos,
aEndPos,
aResStr,
aResStartPos,
aResEndPos
) {
var testID =
"cutText from " +
aStartPos +
" to " +
aEndPos +
" for " +
prettyName(aID);
function cutTextInvoke() {
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.cutText(aStartPos, aEndPos);
}
var resStartPos = aResStartPos != undefined ? aResStartPos : aStartPos;
var resEndPos = aResEndPos != undefined ? aResEndPos : aEndPos;
this.generateTest(
[resStartPos, resEndPos, getTextFromClipboard],
null,
cutTextInvoke,
getValueChecker(aResStr),
testID
);
};
/**
* cutText and pasteText test.
*/
this.cutNPasteText = function copyNPasteText(
aStartPos,
aEndPos,
aPos,
aResStr
) {
var testID =
"cutText from " +
aStartPos +
" to " +
aEndPos +
" and pasteText at " +
aPos +
" for " +
prettyName(aID);
function cutNPasteTextInvoke() {
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.cutText(aStartPos, aEndPos);
acc.pasteText(aPos);
}
this.generateTest(
[aStartPos, aEndPos, getTextFromClipboard],
[aPos, -1, getTextFromClipboard],
cutNPasteTextInvoke,
getValueChecker(aResStr),
testID
);
};
/**
* pasteText test.
*/
this.pasteText = function pasteText(aPos, aResStr) {
var testID = "pasteText at " + aPos + " for " + prettyName(aID);
function pasteTextInvoke() {
var acc = getAccessible(aID, nsIAccessibleEditableText);
acc.pasteText(aPos);
}
this.generateTest(
null,
[aPos, -1, getTextFromClipboard],
pasteTextInvoke,
getValueChecker(aResStr),
testID
);
};
/**
* deleteText test.
*/
this.deleteText = function deleteText(aStartPos, aEndPos, aResStr) {
var testID =
"deleteText from " +
aStartPos +
" to " +
aEndPos +
" for " +
prettyName(aID);
var oldValue = getValue().substring(aStartPos, aEndPos);
var removeTripple = oldValue ? [aStartPos, aEndPos, oldValue] : null;
function deleteTextInvoke() {
var acc = getAccessible(aID, [nsIAccessibleEditableText]);
acc.deleteText(aStartPos, aEndPos);
}
this.generateTest(
removeTripple,
null,
deleteTextInvoke,
getValueChecker(aResStr),
testID
);
};
// ////////////////////////////////////////////////////////////////////////////
// Implementation details.
function getValue() {
var elm = getNode(aID);
var elmClass = ChromeUtils.getClassName(elm);
if (elmClass === "HTMLTextAreaElement" || elmClass === "HTMLInputElement") {
return elm.value;
}
if (elmClass === "HTMLDocument") {
return elm.body.textContent;
}
return elm.textContent;
}
/**
* Common checkers.
*/
function getValueChecker(aValue) {
var checker = {
check: function valueChecker_check() {
is(getValue(), aValue, "Wrong value " + aValue);
},
};
return checker;
}
function getClipboardChecker(aText) {
var checker = {
check: function clipboardChecker_check() {
is(getTextFromClipboard(), aText, "Wrong text in clipboard.");
},
};
return checker;
}
/**
* Process next scheduled test.
*/
this.unwrapNextTest = function unwrapNextTest() {
var data = this.mEventQueue.mInvokers[this.mEventQueue.mIndex + 1];
if (data) {
data.func.apply(this, data.funcArgs);
}
};
/**
* Used to generate an invoker object for the sheduled test.
*/
this.generateTest = function generateTest(
aRemoveTriple,
aInsertTriple,
aInvokeFunc,
aChecker,
aInvokerID
) {
var et = this;
var invoker = {
eventSeq: [],
invoke: aInvokeFunc,
finalCheck: function finalCheck() {
// dumpTree(aID, `'${aID}' tree:`);
aChecker.check();
et.unwrapNextTest(); // replace dummy invoker on real invoker object.
},
getID: function getID() {
return aInvokerID;
},
};
if (aRemoveTriple) {
let checker = new textChangeChecker(
aID,
aRemoveTriple[0],
aRemoveTriple[1],
aRemoveTriple[2],
false
);
invoker.eventSeq.push(checker);
}
if (aInsertTriple) {
let checker = new textChangeChecker(
aID,
aInsertTriple[0],
aInsertTriple[1],
aInsertTriple[2],
true
);
invoker.eventSeq.push(checker);
}
// Claim that we don't want to fail when no events are expected.
if (!aRemoveTriple && !aInsertTriple) {
invoker.noEventsOnAction = true;
}
this.mEventQueue.mInvokers[this.mEventQueue.mIndex + 1] = invoker;
};
/**
* Run the tests.
*/
this.startTest = function startTest(aTestRun) {
var testRunObj = aTestRun;
var thisObj = this;
this.mEventQueue.onFinish = function finishCallback() {
// Notify textRun object that all tests were finished.
testRunObj.iterate();
// Help GC to avoid leaks (refer to aTestRun from local variable, drop
// onFinish function).
thisObj.mEventQueue.onFinish = null;
return DO_NOT_FINISH_TEST;
};
this.mEventQueue.invoke();
};
this.mEventQueue = new eventQueue();
this.mEventQueueReady = false;
}

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

@ -1,140 +0,0 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=452161
-->
<head>
<title>nsIAccessibleEditableText chrome tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript"
src="editabletext.js"></script>
<script type="application/javascript">
// gA11yEventDumpToConsole = true;
// enableLogging("tree,verbose"); // debug
function addTestEditable(aID, aTestRun, aBeforeContent, aAfterContent) {
var et = new editableTextTest(aID);
var startOffset = aBeforeContent ? aBeforeContent.length : 0;
// XXX afterContent currently is not used
// ////////////////////////////////////////////////////////////////////////
// setTextContents
et.scheduleTest(et.setTextContents, "hello", startOffset);
et.scheduleTest(et.setTextContents, "katze", startOffset);
et.scheduleTest(et.setTextContents, "", startOffset);
// ////////////////////////////////////////////////////////////////////////
// insertText
et.scheduleTest(et.insertText, "hello", startOffset, "hello");
et.scheduleTest(et.insertText, "ma ", startOffset, "ma hello");
et.scheduleTest(et.insertText, "ma", startOffset + 2, "mama hello");
et.scheduleTest(et.insertText, " hello", startOffset + 10, "mama hello hello");
// XXX: bug 452584
// ////////////////////////////////////////////////////////////////////////
// deleteText
// et.deleteText(0, 5, "hello hello");
// et.deleteText(5, 6, "hellohello");
// et.deleteText(5, 10, "hello");
// et.deleteText(0, 5, "");
// ////////////////////////////////////////////////////////////////////////
// copyNPasteText
// et.copyNPasteText(0, 0, 0, "");
// et.insertText("hello", 0, "hello");
// et.copyNPasteText(0, 1, 0, "hhello");
// et.copyNPasteText(5, 6, 6, "hhelloo");
// et.copyNPasteText(3, 4, 1, "hehelloo");
// ////////////////////////////////////////////////////////////////////////
// // cutNPasteText
// et.cutNPasteText(0, 1, 1, "ehhelloo");
// et.cutNPasteText(1, 2, 0, "hehelloo");
// et.cutNPasteText(7, 8, 8, "hehelloo");
aTestRun.add(et);
}
// gA11yEventDumpToConsole = true; // debug stuff
function runTest() {
var testRun = new editableTextTestRun();
addTestEditable("input", testRun);
addTestEditable("div", testRun);
addTestEditable("divb", testRun, "pseudo element", "");
addTestEditable("diva", testRun, "", "pseudo element");
addTestEditable("divba", testRun, "before", "after");
addTestEditable(getNode("frame").contentDocument, testRun);
testRun.run(); // Will call SimpleTest.finish();
}
function doTest() {
// Prepare tested elements.
// Design mode on/off triggers an editable state change event on
// the document accessible.
var frame = getNode("frame");
waitForEvent(EVENT_STATE_CHANGE, frame.contentDocument, runTest);
frame.contentDocument.designMode = "on";
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
<style>
#divb::before,
#diva::after {
content: "pseudo element";
}
#divba::before {
content: "before";
}
#divba::after {
content: "after";
}
</style>
</head>
<body>
<a target="_blank"
title="nsIAccessibleEditableText chrome tests"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452161">
Bug 452161
</a>
<a target="_blank"
title="Cache rendered text on a11y side"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=626660">
Bug 626660
</a>
<a target="_blank"
title="Pseudo element support test"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1105611">
Bug 1105611
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input id="input"/>
<div id="div" contenteditable="true"></div>
<div id="divb" contenteditable="true"></div>
<div id="diva" contenteditable="true"></div>
<div id="divba" contenteditable="true"></div>
<iframe id="frame"/>
</body>
</html>

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

@ -1,61 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>nsIAccessibleEditableText chrome tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript"
src="editabletext.js"></script>
<script type="application/javascript">
function doTest() {
var et = new editableTextTest("input");
// 'ee' insertion/removal at 1 or 2 offset of 'hello'/'heeello' string
// reports 'ee' text was inserted/removed at 2 offset.
et.scheduleTest(et.insertText, "ee", 1, "heeello", 2);
et.scheduleTest(et.copyText, 1, 3, "ee");
et.scheduleTest(et.cutText, 1, 3, "hello", 2, 4);
et.scheduleTest(et.insertText, "ee", 2, "heeello", 2);
et.scheduleTest(et.cutText, 2, 4, "hello", 2, 4);
et.scheduleTest(et.deleteText, 1, 3, "hlo");
et.scheduleTest(et.pasteText, 1, "heelo");
var testRun = new editableTextTestRun();
testRun.add(et);
testRun.run(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="HyperText accessible should get focus when the caret is positioned inside of it, text is changed or copied into clipboard by ATs"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=524115">
Mozilla Bug 524115
</a>
<a target="_blank"
title="Cache rendered text on a11y side"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=626660">
Mozilla Bug 626660
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input id="input" value="hello"/>
</body>
</html>

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

@ -10,7 +10,6 @@ A11Y_MANIFESTS += [
"aom/a11y.ini",
"attributes/a11y.ini",
"bounds/a11y.ini",
"editabletext/a11y.ini",
"elm/a11y.ini",
"events/a11y.ini",
"events/docload/a11y.ini",