Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Errors
- This test gets skipped with pattern: tsan
- This test failed 19 times in the preceding 30 days. quicksearch this test
- Manifest: layout/base/tests/mochitest.toml
<!DOCTYPE HTML>
<title>Reftests with caret drawing</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
<style>
iframe {
border: none;
width: 600px;
height: 400px;
}
</style>
<script>
SimpleTest.waitForExplicitFinish();
SimpleTest.requestLongerTimeout(3);
const { AppConstants } = SpecialPowers.ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
var iframes = [];
function callbackTestIframe(iframe)
{
iframes.push(iframe);
if (iframes.length != 2)
return;
var result = iframes[0];
var reference = iframes[1];
const shouldBeEqual = true;
// Using assertSnapshots is important to get the data-URIs of failing tests
// dumped into the log in a format that reftest-analyzer.xhtml can process.
var passed = assertSnapshots(result.snapshot, reference.snapshot,
shouldBeEqual, null /*no fuzz*/, result.src,
reference.src);
// Remove the iframes if the test was successful
if (passed) {
result.remove();
reference.remove();
}
iframes = [];
SimpleTest.waitForFocus(nextTest);
}
function doSnapShot(iframe) {
iframe.snapshot = snapshotWindow(iframe.contentWindow, true);
callbackTestIframe(iframe);
};
function remotePageLoaded(callback) {
var iframe = this;
setTimeout(function(){
doSnapShot(iframe);
callback();
}, 0);
};
const MAX_ITERATIONS = 1000;
function createIframe(url,next) {
var iframe = document.createElement("iframe");
iframe.remotePageLoaded = remotePageLoaded;
var me = this;
var currentIteration = 0;
function iframeLoadCompleted() {
let loc = iframe.contentWindow.location;
if (loc && loc.href == "about:blank") {
return;
}
var docEl = iframe.contentDocument.documentElement;
if (docEl.className.includes("reftest-wait")) {
if (currentIteration++ > MAX_ITERATIONS) {
ok(false, "iframe load for " + url + " timed out");
endTest();
} else {
setTimeout(iframeLoadCompleted, 0);
}
return;
}
iframe.remotePageLoaded(function() {
if (next) {
setTimeout(function(){createIframe(next,null);}, 0)
}
});
}
iframe.addEventListener("load", iframeLoadCompleted);
window.document.body.appendChild(iframe);
iframe.clientHeight; // flush layout.
iframe.src = url;
iframe.focus();
};
function refTest(test, ref) {
createIframe(test, ref);
};
var caretBlinkTime = null;
async function endTest() {
await SpecialPowers.spawn(window.parent, [], () => {
content.document.styleSheets[content.document.styleSheets.length-1].deleteRule(0);
});
// finish(), yet let the test actually end first, to be safe.
SimpleTest.executeSoon(SimpleTest.finish);
}
var tests = [
// The following test cases uses mouse events. We need to make
// AccessibleCaret unhide for them.
function() {SpecialPowers.pushPrefEnv({'set': [['layout.accessiblecaret.hide_carets_for_mouse_input', false]]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.accessiblecaret.hide_carets_for_mouse_input']]}, nextTest);} ,
// The following test cases are all involving with one sending
// synthesizeKey(), the other without. They fail when accessiblecaret
// is enabled. Test them with the preference off.
function() {SpecialPowers.pushPrefEnv({'set': [['layout.accessiblecaret.enabled_on_touch', false]]}, nextTest);} ,
[ 'input-maxlength-valid-before-change.html', 'input-valid-ref.html'] ,
[ 'input-maxlength-valid-change.html', 'input-valid-ref.html'] ,
[ 'input-maxlength-invalid-change.html', 'input-invalid-ref.html'] ,
[ 'input-minlength-valid-before-change.html', 'input-valid-ref.html'] ,
[ 'input-minlength-valid-change.html', 'input-valid-ref.html'] ,
[ 'input-minlength-invalid-change.html', 'input-invalid-ref.html'] ,
[ 'input-maxlength-ui-valid-change.html', 'input-valid-ref.html'] ,
[ 'input-maxlength-ui-invalid-change.html', 'input-invalid-ref.html'] ,
[ 'input-minlength-ui-valid-change.html', 'input-valid-ref.html'] ,
[ 'input-minlength-ui-invalid-change.html', 'input-invalid-ref.html'] ,
function() {SpecialPowers.pushPrefEnv({'set': [['layout.forms.reveal-password-button.enabled', false]]}, nextTest);} ,
[ 'input-password-remask.html', 'input-password-remask-ref.html' ],
// The following hash means language.
function() {SpecialPowers.pushPrefEnv({'set': [['editor.password.mask_delay', 0]]}, nextTest);} ,
[ 'input-password-RTL-input.html#arabic', 'input-password-RTL-input-ref.html'],
[ 'input-password-RTL-input.html#hebrew', 'input-password-RTL-input-ref.html'],
function() {SpecialPowers.pushPrefEnv({'clear': [['editor.password.mask_delay']]}, nextTest);} ,
// The following hash means "text ('_' is a space)" - unmarsk start - unmask end - selection start - selection end[ - text-transform].
[ 'input-password-unmask.html#abc_def-0-7-7-7', 'input-password-unmask-ref.html#abc_def-0-7-7-7'],
[ 'input-password-unmask.html#abc_def-0-7-7-7-capitalize', 'input-password-unmask-ref.html#Abc_Def-0-7-7-7'],
[ 'input-password-unmask.html#abc_def-0-7-7-7-uppercase', 'input-password-unmask-ref.html#ABC_DEF-0-7-7-7'],
[ 'input-password-unmask.html#ABC_DEF-0-7-7-7-lowercase', 'input-password-unmask-ref.html#abc_def-0-7-7-7'],
[ 'input-password-unmask.html#abc_def-0-1-1-1', 'input-password-unmask-ref.html#abc_def-0-1-1-1'],
[ 'input-password-unmask.html#abc_def-2-4-1-5', 'input-password-unmask-ref.html#abc_def-2-4-1-5'],
[ 'input-password-unmask.html#abc_def-6-7-7-7', 'input-password-unmask-ref.html#abc_def-6-7-7-7'],
// The following hash means unmarsk start - unmask end - selection start - selection end.
// The value is "a🤔b" so that the range is 0-4.
[ 'input-password-unmask-around-emoji.html#0-4-4-4', 'input-password-unmask-around-emoji-ref.html#0-4-4-4'],
[ 'input-password-unmask-around-emoji.html#0-3-3-3', 'input-password-unmask-around-emoji-ref.html#0-3-3-3'],
[ 'input-password-unmask-around-emoji.html#0-1-3-3', 'input-password-unmask-around-emoji-ref.html#0-1-3-3'],
[ 'input-password-unmask-around-emoji.html#1-2-3-3', 'input-password-unmask-around-emoji-ref.html#1-2-3-3'],
[ 'input-password-unmask-around-emoji.html#1-3-3-3', 'input-password-unmask-around-emoji-ref.html#1-3-3-3'],
[ 'input-password-unmask-around-emoji.html#2-3-3-3', 'input-password-unmask-around-emoji-ref.html#2-3-3-3'],
[ 'input-password-unmask-around-emoji.html#3-4-4-4', 'input-password-unmask-around-emoji-ref.html#3-4-4-4'],
[ 'input-password-unmask-around-emoji.html#1-4-4-4', 'input-password-unmask-around-emoji-ref.html#1-4-4-4'],
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.forms.reveal-password-button.enabled']]}, nextTest);} ,
// The following tests something in editable elements so that we need to disable zoom to focused editor.
function() {SpecialPowers.pushPrefEnv({'set': [['apz.zoom-to-focused-input.enabled', false]]}, nextTest);} ,
[ 'bug1097242-1.html', 'bug1097242-1-ref.html'] , // Clicks non-editable and non-selectable element in an editing host
function() {SpecialPowers.pushPrefEnv({'clear': [['apz.zoom-to-focused-input.enabled']]}, nextTest);} ,
[ 'input-stoppropagation.html', 'input-stoppropagation-ref.html'] ,
[ 'textarea-maxlength-valid-before-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-maxlength-valid-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-maxlength-invalid-change.html', 'textarea-invalid-ref.html'] ,
[ 'textarea-minlength-valid-before-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-minlength-valid-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-minlength-invalid-change.html', 'textarea-invalid-ref.html'] ,
[ 'textarea-maxlength-ui-valid-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-maxlength-ui-invalid-change.html', 'textarea-invalid-ref.html'] ,
[ 'textarea-minlength-ui-valid-change.html', 'textarea-valid-ref.html'] ,
[ 'textarea-minlength-ui-invalid-change.html', 'textarea-invalid-ref.html'] ,
function() {SpecialPowers.pushPrefEnv({'set': [['bidi.browser.ui', true]]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'clear': [['bidi.browser.ui']]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'set': [['layout.css.overflow-clip-box.enabled', true]]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.css.overflow-clip-box.enabled']]}, nextTest);} ,
// Checks that the caret isn't occluded by children background content.
// Caret on contenteditable with abspos and / or empty content.
// TODO(emilio): This fails because nsInlineFrame::GetCaretBaseline doesn't
// return one line-height for an empty inline, and it probably should..
// Caret + line-height + pseudo-element only.
// shift+arrow key should select non-editable only
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.accessiblecaret.enabled_on_touch']]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'set': [['accessibility.browsewithcaret', true]]}, nextTest);} ,
function() {SpecialPowers.pushPrefEnv({'clear': [['accessibility.browsewithcaret']]}, nextTest);} ,
[ 'interlinePosition-after-Selection-addRange.html', 'interlinePosition-after-Selection-addRange-ref.html' ] ,
[ 'collapse-selection-into-editing-host-during-blur-of-input.html', 'collapse-selection-into-editing-host-during-blur-of-input-ref.html' ] ,
];
if (AppConstants.platform != "android") {
} else {
is(SpecialPowers.getIntPref("layout.spellcheckDefault"), 0, "Spellcheck should be turned off for this platform or this if..else check removed");
}
if (AppConstants.platform == "linux") {
tests = tests.concat([
// Turn off accessiblecaret to prevent it from interfering with the
// multi-range selection.
function() {SpecialPowers.pushPrefEnv({'set': [['layout.accessiblecaret.enabled_on_touch', false]]}, nextTest);} ,
// eDirPrevious, Shift+click
[ 'multi-range-user-select.html#prev1S_' , 'multi-range-user-select-ref.html#prev1S_' ] ,
[ 'multi-range-user-select.html#prev2S_' , 'multi-range-user-select-ref.html#prev2S_' ] ,
[ 'multi-range-user-select.html#prev3S_' , 'multi-range-user-select-ref.html#prev3S_' ] ,
[ 'multi-range-user-select.html#prev4S_' , 'multi-range-user-select-ref.html#prev4S_' ] ,
[ 'multi-range-user-select.html#prev5S_' , 'multi-range-user-select-ref.html#prev5S_' ] ,
[ 'multi-range-user-select.html#prev6S_' , 'multi-range-user-select-ref.html#prev6S_' ] ,
[ 'multi-range-user-select.html#prev7S_' , 'multi-range-user-select-ref.html#prev7S_' ] ,
// eDirPrevious, Shift+Accel+click
[ 'multi-range-user-select.html#prev1SA' , 'multi-range-user-select-ref.html#prev1SA' ] ,
[ 'multi-range-user-select.html#prev2SA' , 'multi-range-user-select-ref.html#prev2SA' ] ,
[ 'multi-range-user-select.html#prev3SA' , 'multi-range-user-select-ref.html#prev3SA' ] ,
[ 'multi-range-user-select.html#prev4SA' , 'multi-range-user-select-ref.html#prev4SA' ] ,
[ 'multi-range-user-select.html#prev5SA' , 'multi-range-user-select-ref.html#prev5SA' ] ,
[ 'multi-range-user-select.html#prev6SA' , 'multi-range-user-select-ref.html#prev6SA' ] ,
[ 'multi-range-user-select.html#prev7SA' , 'multi-range-user-select-ref.html#prev7SA' ] ,
// eDirPrevious, Accel+drag-select (adding an additional range)
[ 'multi-range-user-select.html#prev1AD' , 'multi-range-user-select-ref.html#prev1AD' ] ,
[ 'multi-range-user-select.html#prev7AD' , 'multi-range-user-select-ref.html#prev7AD' ] ,
[ 'multi-range-user-select.html#prev8AD' , 'multi-range-user-select-ref.html#prev8AD' ] ,
// eDirPrevious, VK_RIGHT / LEFT
[ 'multi-range-user-select.html#prev1SR' , 'multi-range-user-select-ref.html#prev1SR' ] ,
[ 'multi-range-user-select.html#prev1SL' , 'multi-range-user-select-ref.html#prev1SL' ] ,
// eDirNext, Shift+click
[ 'multi-range-user-select.html#next1S_' , 'multi-range-user-select-ref.html#next1S_' ] ,
[ 'multi-range-user-select.html#next2S_' , 'multi-range-user-select-ref.html#next2S_' ] ,
[ 'multi-range-user-select.html#next3S_' , 'multi-range-user-select-ref.html#next3S_' ] ,
[ 'multi-range-user-select.html#next4S_' , 'multi-range-user-select-ref.html#next4S_' ] ,
[ 'multi-range-user-select.html#next5S_' , 'multi-range-user-select-ref.html#next5S_' ] ,
[ 'multi-range-user-select.html#next6S_' , 'multi-range-user-select-ref.html#next6S_' ] ,
[ 'multi-range-user-select.html#next7S_' , 'multi-range-user-select-ref.html#next7S_' ] ,
// eDirNext, Shift+Accel+click
[ 'multi-range-user-select.html#next1SA' , 'multi-range-user-select-ref.html#next1SA' ] ,
[ 'multi-range-user-select.html#next2SA' , 'multi-range-user-select-ref.html#next2SA' ] ,
[ 'multi-range-user-select.html#next3SA' , 'multi-range-user-select-ref.html#next3SA' ] ,
[ 'multi-range-user-select.html#next4SA' , 'multi-range-user-select-ref.html#next4SA' ] ,
[ 'multi-range-user-select.html#next5SA' , 'multi-range-user-select-ref.html#next5SA' ] ,
[ 'multi-range-user-select.html#next6SA' , 'multi-range-user-select-ref.html#next6SA' ] ,
[ 'multi-range-user-select.html#next7SA' , 'multi-range-user-select-ref.html#next7SA' ] ,
// eDirNext, Accel+drag-select (adding an additional range)
[ 'multi-range-user-select.html#next1AD' , 'multi-range-user-select-ref.html#next1AD' ] ,
[ 'multi-range-user-select.html#next7AD' , 'multi-range-user-select-ref.html#next7AD' ] ,
[ 'multi-range-user-select.html#next8AD' , 'multi-range-user-select-ref.html#next8AD' ] ,
// eDirNext, VK_RIGHT / LEFT
[ 'multi-range-user-select.html#next1SR' , 'multi-range-user-select-ref.html#next1SR' ] ,
[ 'multi-range-user-select.html#next1SL' , 'multi-range-user-select-ref.html#next1SL' ] ,
// eDirPrevious, Shift+click
[ 'multi-range-script-select.html#prev1S_' , 'multi-range-script-select-ref.html#prev1S_' ] ,
[ 'multi-range-script-select.html#prev2S_' , 'multi-range-script-select-ref.html#prev2S_' ] ,
[ 'multi-range-script-select.html#prev3S_' , 'multi-range-script-select-ref.html#prev3S_' ] ,
[ 'multi-range-script-select.html#prev4S_' , 'multi-range-script-select-ref.html#prev4S_' ] ,
[ 'multi-range-script-select.html#prev5S_' , 'multi-range-script-select-ref.html#prev5S_' ] ,
[ 'multi-range-script-select.html#prev6S_' , 'multi-range-script-select-ref.html#prev6S_' ] ,
[ 'multi-range-script-select.html#prev7S_' , 'multi-range-script-select-ref.html#prev7S_' ] ,
// eDirPrevious, Shift+Accel+click
[ 'multi-range-script-select.html#prev1SA' , 'multi-range-script-select-ref.html#prev1SA' ] ,
[ 'multi-range-script-select.html#prev2SA' , 'multi-range-script-select-ref.html#prev2SA' ] ,
[ 'multi-range-script-select.html#prev3SA' , 'multi-range-script-select-ref.html#prev3SA' ] ,
[ 'multi-range-script-select.html#prev4SA' , 'multi-range-script-select-ref.html#prev4SA' ] ,
[ 'multi-range-script-select.html#prev5SA' , 'multi-range-script-select-ref.html#prev5SA' ] ,
[ 'multi-range-script-select.html#prev6SA' , 'multi-range-script-select-ref.html#prev6SA' ] ,
[ 'multi-range-script-select.html#prev7SA' , 'multi-range-script-select-ref.html#prev7SA' ] ,
// eDirPrevious, Accel+drag-select (adding an additional range)
[ 'multi-range-script-select.html#prev1AD' , 'multi-range-script-select-ref.html#prev1AD' ] ,
[ 'multi-range-script-select.html#prev7AD' , 'multi-range-script-select-ref.html#prev7AD' ] ,
// eDirPrevious, VK_RIGHT / LEFT
[ 'multi-range-script-select.html#prev1SR' , 'multi-range-script-select-ref.html#prev1SR' ] ,
[ 'multi-range-script-select.html#prev1SL' , 'multi-range-script-select-ref.html#prev1SL' ] ,
// eDirNext, Shift+click
[ 'multi-range-script-select.html#next1S_' , 'multi-range-script-select-ref.html#next1S_' ] ,
[ 'multi-range-script-select.html#next2S_' , 'multi-range-script-select-ref.html#next2S_' ] ,
[ 'multi-range-script-select.html#next3S_' , 'multi-range-script-select-ref.html#next3S_' ] ,
[ 'multi-range-script-select.html#next4S_' , 'multi-range-script-select-ref.html#next4S_' ] ,
[ 'multi-range-script-select.html#next5S_' , 'multi-range-script-select-ref.html#next5S_' ] ,
[ 'multi-range-script-select.html#next6S_' , 'multi-range-script-select-ref.html#next6S_' ] ,
[ 'multi-range-script-select.html#next7S_' , 'multi-range-script-select-ref.html#next7S_' ] ,
// eDirNext, Shift+Accel+click
[ 'multi-range-script-select.html#next1SA' , 'multi-range-script-select-ref.html#next1SA' ] ,
[ 'multi-range-script-select.html#next2SA' , 'multi-range-script-select-ref.html#next2SA' ] ,
[ 'multi-range-script-select.html#next3SA' , 'multi-range-script-select-ref.html#next3SA' ] ,
[ 'multi-range-script-select.html#next4SA' , 'multi-range-script-select-ref.html#next4SA' ] ,
[ 'multi-range-script-select.html#next5SA' , 'multi-range-script-select-ref.html#next5SA' ] ,
[ 'multi-range-script-select.html#next6SA' , 'multi-range-script-select-ref.html#next6SA' ] ,
[ 'multi-range-script-select.html#next7SA' , 'multi-range-script-select-ref.html#next7SA' ] ,
// eDirNext, Accel+drag-select (adding an additional range)
[ 'multi-range-script-select.html#next1AD' , 'multi-range-script-select-ref.html#next1AD' ] ,
[ 'multi-range-script-select.html#next7AD' , 'multi-range-script-select-ref.html#next7AD' ] ,
// eDirNext, VK_RIGHT / LEFT
[ 'multi-range-script-select.html#next1SR' , 'multi-range-script-select-ref.html#next1SR' ] ,
[ 'multi-range-script-select.html#next1SL' , 'multi-range-script-select-ref.html#next1SL' ] ,
// Tries to select and delete non-selectable content in a user-select subtree.
// Tries to select and delete non-editable content in a user-select subtree.
// Tries to edit an <input type="number"> with arrows inside a user-select: none element.
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.accessiblecaret.enabled_on_touch']]}, nextTest);} ,
]);
}
var testIndex = 0;
// debugging easier...
const DEBUG_TEST_FILTER = null;
function isTestSkipped(test) {
if (DEBUG_TEST_FILTER) {
return !DEBUG_TEST_FILTER.test(test[0]);
}
if (AppConstants.platform == "android") {
return [
].includes(test[0]);
}
if (AppConstants.platform == "win" || AppConstants.platform == "macosx") {
return [
].includes(test[0]);
}
return false;
}
function nextTest() {
// Move the mouse out of the way so that :hover doesn't interact with tests.
synthesizeMouse(document.body, 1, 1, { type: "mousemove" });
if (testIndex < tests.length) {
let test = tests[testIndex];
if (typeof(test) == 'function') {
test();
} else if (!isTestSkipped(test)) {
refTest(test[0], test[1]);
} else {
info("Skipping " + test[0]);
setTimeout(nextTest, 0);
}
++testIndex;
} else {
endTest();
}
}
async function runTests() {
try {
if (window.parent) {
await SpecialPowers.spawn(window.parent, [], () => {
content.document.styleSheets[content.document.styleSheets.length-1]
.insertRule("iframe#testframe{width:600px;height:400px}",0);
});
}
try {
caretBlinkTime = SpecialPowers.getIntPref("ui.caretBlinkTime");
} catch (e) {}
SpecialPowers.pushPrefEnv({'set': [['ui.caretBlinkTime', -1]]}, nextTest);
} catch(e) {
endTest();
}
}
SimpleTest.waitForFocus(runTests);
</script>
<body>
</body>