Bug 1129078 - part 5, Test suite for multi-range selections involving user-select:none.
☠☠ backed out by 7afbf9ebc89b ☠ ☠
authorMats Palmgren <mats@mozilla.com>
Fri, 20 Feb 2015 17:34:21 +0000
changeset 258780 9830ab1a2028aab1c1a1ff865704908b56a37722
parent 258779 ce5cb876af9ab955878f61367262c33cc9971ef4
child 258781 275d27c2dba06b7103f16fee39515a06ca187063
push id721
push userjlund@mozilla.com
push dateTue, 21 Apr 2015 23:03:33 +0000
treeherdermozilla-release@d27c9211ebb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1129078
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1129078 - part 5, Test suite for multi-range selections involving user-select:none.
layout/base/tests/Ahem.ttf
layout/base/tests/mochitest.ini
layout/base/tests/multi-range-user-select-ref.html
layout/base/tests/multi-range-user-select.html
layout/base/tests/selection-utils.js
layout/base/tests/test_reftests_with_caret.html
copy from layout/reftests/fonts/Ahem.ttf
copy to layout/base/tests/Ahem.ttf
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -1,12 +1,13 @@
 [DEFAULT]
 # Android: SLOW_DIRECTORY; Mulet: bug 1048441, bug 1087611, bug 1112988, etc.
 skip-if = toolkit == 'android' || buildapp == 'mulet'
 support-files =
+  Ahem.ttf
   border_radius_hit_testing_iframe.html
   preserve3d_sorting_hit_testing_iframe.html
   image_rgrg-256x256.png
   image_rrgg-256x256.png
   bug369950-subframe.xml
   file_bug842853.sjs
   file_bug842853.html
   enableTestPlugin.js
@@ -64,16 +65,19 @@ support-files =
   bug1109968-1-ref.html
   bug1109968-1.html
   bug1109968-2-ref.html
   bug1109968-2.html
   bug1123067-1.html
   bug1123067-2.html
   bug1123067-3.html
   bug1123067-ref.html
+  selection-utils.js
+  multi-range-user-select.html
+  multi-range-user-select-ref.html
 
 [test_preserve3d_sorting_hit_testing.html]
 [test_after_paint_pref.html]
 [test_bug993936.html]
 skip-if = e10s
 [test_border_radius_hit_testing.html]
 [test_bug66619.html]
 [test_bug93077-1.html]
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/multi-range-user-select-ref.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+    <meta charset="utf-8">
+    <title>Testcase #1 for bug 1129078</title>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <script src="selection-utils.js"></script>
+
+<style type="text/css">
+@font-face {
+  font-family: Ahem;
+  src: url("Ahem.ttf");
+}
+html,body { margin:0; padding: 0; }
+body,pre { font-family: Ahem; font-size: 20px; }
+</style>
+</head>
+<body>
+
+<pre id="select">
+2af45494-ak7e-11e4-a0c6-a7e7
+38222880-bj6d-11e4-8064-fb7b
+3d649ae4-ci5c-11e4-995d-17b2
+434351bc-dh4b-11e4-9971-4fc8
+4dc0e0b4-eg4a-11e4-8c28-5319
+a96319c8-ad7d-11e4-b312-039c
+</pre>
+
+<pre id="log" style="border:1px solid green"></pre>
+
+<script>
+
+var sel = window.getSelection();
+var e = document.querySelector('#select');
+function setupSelectionPrev3() {
+  addChildRanges([[0,150,0,160], [0,65,0,70], [0,15,0,15]], e);
+  sel.extend(e.firstChild, 10);  // to get eDirPrevious direction
+}
+function setupSelectionPrev2() {
+  addChildRanges([[0,150,0,160], [0,70,0,70]], e);
+  sel.extend(e.firstChild, 65);  // to get eDirPrevious direction
+}
+function setupSelectionPrev1() {
+  addChildRanges([[0,160,0,160]], e);
+  sel.extend(e.firstChild, 150);  // to get eDirPrevious direction
+}
+
+function setupSelectionNext3() {
+  addChildRanges([[0,10,0,15], [0,65,0,70], [0,150,0,160]], e);
+}
+function setupSelectionNext2() {
+  addChildRanges([[0,10,0,15], [0,65,0,70]], e);
+}
+function setupSelectionNext2b() {
+  addChildRanges([[0,15,0,80], [0,150,0,160]], e);
+}
+function setupSelectionNext1() {
+  addChildRanges([[0,10,0,15]], e);
+}
+function setupSelectionNext1b() {
+  addChildRanges([[0,15,0,170]], e);
+}
+function setupSelectionNext1c() {
+  addChildRanges([[0,150,0,160]], e);
+}
+
+function runTest() {
+  sel = window.getSelection();
+  sel.removeAllRanges();
+  document.body.offsetHeight;
+  var hash = window.location.hash
+  var op = hash.substring(6,8);
+  var test = hash.substring(0,6);
+  if (hash.substring(0,5) == "#prev") {
+    if (test == "#prev1") {
+      setupSelectionPrev3();
+      if (op == "SL") {
+        sel.extend(e.firstChild, 8);
+      } else if (op == "SR") {
+        sel.extend(e.firstChild, 12);
+      } else if (op == "AD") {
+        addChildRanges([[0,1,0,2]], e);
+      } else {
+        sel.extend(e.firstChild, 1);
+      }
+    } else if (test == "#prev2") {
+      setupSelectionPrev3();
+      sel.extend(e.firstChild, 14); // now eDirNext
+      sel.extend(e.firstChild, 13); // now eDirPrevious again
+    } else if (test == "#prev3") {
+      setupSelectionPrev2();
+      sel.extend(e.firstChild, 20);
+    } else if (test == "#prev4") {
+      setupSelectionPrev2();
+      sel.extend(e.firstChild, 68); // now eDirNext
+      sel.extend(e.firstChild, 67); // now eDirPrevious again
+    } else if (test == "#prev5") {
+      setupSelectionPrev1();
+      sel.extend(e.firstChild, 80);
+    } else if (test == "#prev6") {
+      setupSelectionPrev1();
+      sel.extend(e.firstChild, 153); // now eDirNext
+      sel.extend(e.firstChild, 152); // now eDirPrevious again
+    } else if (test == "#prev7") {
+      if (op == "AD") {
+        setupSelectionPrev3();
+        addChildRanges([[0,168,0,170]], e);
+      } else {
+        addChildRanges([[0,160,0,170]], e);
+      }
+    }
+  } else {
+    if (test == "#next1") {
+      if (op == "SL") {
+        setupSelectionNext3();
+        sel.extend(e.firstChild, 158);
+      } else if (op == "SR") {
+        setupSelectionNext3();
+        sel.extend(e.firstChild, 162);
+      } else if (op == "AD") {
+       setupSelectionNext3();
+       addChildRanges([[0,1,0,2]], e);
+      } else {
+        setupSelectionNext1();
+        sel.extend(e.firstChild, 1);
+      }
+    } else if (test == "#next2") {
+      setupSelectionNext1();
+      sel.extend(e.firstChild, 13);
+    } else if (test == "#next3") {
+      setupSelectionNext1();
+      sel.extend(e.firstChild, 20);
+    } else if (test == "#next4") {
+      setupSelectionNext2();
+      sel.extend(e.firstChild, 67);
+    } else if (test == "#next5") {
+      setupSelectionNext2();
+      sel.extend(e.firstChild, 80);
+    } else if (test == "#next6") {
+      setupSelectionNext3();
+      sel.extend(e.firstChild, 152);
+    } else if (test == "#next7") {
+      setupSelectionNext3();
+      if (op == "AD") {
+        addChildRanges([[0,168,0,170]], e);
+      } else {
+        sel.extend(e.firstChild, 170);
+      }
+    }
+  }
+  document.documentElement.removeAttribute("class");
+}
+
+SimpleTest.waitForFocus(function(){setTimeout(runTest,0)});
+
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/multi-range-user-select.html
@@ -0,0 +1,198 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+    <meta charset="utf-8">
+    <title>Testcase #1 for bug 1129078</title>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+    <script src="selection-utils.js"></script>
+
+<style type="text/css">
+@font-face {
+  font-family: Ahem;
+  src: url("Ahem.ttf");
+}
+html,body { margin:0; padding: 0; }
+body,pre { font-family: Ahem; font-size: 20px; }
+span { -moz-user-select:none; }
+x { -moz-user-select:text; }
+</style>
+</head>
+<body>
+
+<pre id="select">
+2af45494-a<x>k7e-1</x><span id="span2">1e4-a0c6-a7e7
+38222880-bj6d-11e4-8064-fb7b
+3d649ae</span><x>4-ci5</x><span id="span3">c-11e4-995d-17b2
+434351bc-dh4b-11e4-9971-4fc8
+4dc0e0b4-eg4a-11e4-8c28-5319
+a9631</span><x>9c8-ad7d-1</x>1e4-b312-039c
+</pre>
+
+<pre id="log" style="border:1px solid green"></pre>
+
+<script>
+window.info = parent.info;
+window.is = parent.is;
+window.isnot = parent.isnot;
+window.ok = parent.ok;
+
+var sel = window.getSelection();
+
+function enableSelection(id) {
+  var span = document.getElementById(id);
+  span.style.MozUserSelect = 'text';
+}
+
+function setupPrevSelection() {
+  var e = document.querySelector('#select');
+  dragSelectPoints(e, 300, 125, 200, 5);
+}
+
+function setupNextSelection() {
+  var e = document.querySelector('#select');
+  dragSelectPoints(e, 199, 5, 300, 125);
+}
+
+var ops = {
+  S_ : shiftClick,
+  SA : shiftAccelClick,
+  AD : accelDragSelect,
+  SL : keyLeft,
+  SR : keyRight
+}
+
+function runTest() {
+  sel = window.getSelection();
+  sel.removeAllRanges();
+  document.body.offsetHeight;
+  var e = document.querySelector('#select');
+  var hash = window.location.hash
+  if (hash.substring(0,5)=="#prev")
+    setupPrevSelection();
+  else
+    setupNextSelection();
+  var op = hash.substring(6,8);
+  var action = ops[op];
+  var test = hash.substring(0,6);
+  if (hash.substring(0,5) == "#prev") {
+    if (test == "#prev1") {
+      if (action == keyLeft) {
+        keyLeft({shiftKey:true}, 2)
+        checkRanges([[0,8,-1,2], [3,0,-1,4], [5,0,6,0]], e);
+      } else if (action == keyRight) {
+        keyRight({shiftKey:true}, 2)
+        checkRanges([[e.childNodes[1].firstChild,2,-1,2], [3,0,-1,4], [5,0,6,0]], e);
+      } else if (action == accelDragSelect) {
+        accelDragSelect(e, 30, 50);
+        checkRanges([[0,1,0,2], [e.childNodes[1].firstChild,0,-1,2], [3,0,-1,4], [5,0,6,0]], e);
+      } else {
+        action(e, 30);
+        checkRanges([[0,1,-1,2], [3,0,-1,4], [5,0,6,0]], e);
+      }
+    } else if (test == "#prev2") {
+      action(e, 260);
+      checkRangeCount(3, e);
+      checkRange(0, [0,3,-2,2], e.childNodes[1]);
+      checkRange(1, [3,0,-1,4], e);
+      checkRange(2, [5,0,6,0], e);
+    } else if (test == "#prev3") {
+      enableSelection('span2');
+      action(e, 400);
+      checkRangeCount(2, e);
+      checkRange(0, [0,5,-2,4], e.childNodes[2]);
+      checkRange(1, [5,0,6,0], e);
+    } else if (test == "#prev4") {
+      action(e, 180, 65);
+      checkRangeCount(2, e);
+      checkRange(0, [0,2,-2,4], e.childNodes[3]);
+      checkRange(1, [5,0,6,0], e);
+    } else if (test == "#prev5") {
+      enableSelection('span3');
+      action(e, 440, 65);
+      checkRangeCount(1, e);
+      var r = sel.getRangeAt(0);
+      checkRangePoints(r, [e.childNodes[4].firstChild,10,e.childNodes[6],0], e);
+    } else if (test == "#prev6") {
+      action(e, 140, 125);
+      checkRangeCount(1, e);
+      var r = sel.getRangeAt(0);
+      checkRangePoints(r, [e.childNodes[5].firstChild,2,e.childNodes[6],0], e);
+    } else if (test == "#prev7") {
+      if (action == accelDragSelect) {
+        accelDragSelect(e, 460, 500, 125);
+        checkRanges([[e.childNodes[1].firstChild,0,-1,2], [3,0,-1,4], [5,0,6,0], [6,8,6,10]], e);
+      } else {
+        action(e, 500, 125);
+        checkRanges([[6,0,6,10]], e);
+      }
+    }
+  } else {
+    if (test == "#next1") {
+      if (action == keyLeft) {
+        keyLeft({shiftKey:true}, 2)
+        checkRanges([[0,10,-1,2], [3,0,-1,4], [5,0,e.childNodes[5].firstChild,8]], e);
+      } else if (action == keyRight) {
+        keyRight({shiftKey:true}, 2)
+        checkRanges([[0,10,-1,2], [3,0,-1,4], [5,0,6,2]], e);
+      } else if (action == accelDragSelect) {
+        accelDragSelect(e, 30, 50);
+        checkRanges([[0,1,0,2], [0,10,-1,2], [3,0,-1,4], [5,0,e.childNodes[5].firstChild,10]], e);
+      } else {
+        action(e, 30);
+        checkRanges([[0,1,0,10]], e);
+      }
+    } else if (test == "#next2") {
+      action(e, 260);
+      checkRangeCount(1, e);
+      var r = sel.getRangeAt(0);
+      checkRangePoints(r, [e.childNodes[0],10,e.childNodes[1].firstChild,3], e);
+    } else if (test == "#next3") {
+      enableSelection('span2');
+      action(e, 400);
+      checkRangeCount(1, e);
+      var r = sel.getRangeAt(0);
+      checkRangePoints(r, [e.childNodes[0],10,e.childNodes[2].firstChild,5], e);
+    } else if (test == "#next4") {
+      action(e, 180, 65);
+      checkRangeCount(2, e);
+      checkRange(0, [0,10,-1,2], e);
+      checkRange(1, [-1,0,0,2], e.childNodes[3]);
+    } else if (test == "#next5") {
+      enableSelection('span3');
+      action(e, 440, 65);
+      checkRangeCount(2, e);
+      checkRange(0, [0,10,-1,2], e);
+      var r = sel.getRangeAt(1);
+      checkRangePoints(r, [e.childNodes[3],0,e.childNodes[4].firstChild,10], e);
+    } else if (test == "#next6") {
+      action(e, 140, 125);
+      checkRangeCount(3, e);
+      checkRange(0, [0,10,-1,2], e);
+      checkRange(1, [3,0,-1,4], e);
+      checkRange(2, [-1,0,0,2], e.childNodes[5]);
+    } else if (test == "#next7") {
+      if (action == keyRight) {
+        keyRight({shiftKey:true}, 2)
+        checkRanges([[0,10,-1,2], [3,0,-1,4], [5,0,6,2]], e);
+      } else if (action == accelDragSelect) {
+        accelDragSelect(e, 460, 500, 125);
+        checkRanges([[0,10,-1,2], [3,0,-1,4], [5,0,e.childNodes[5].firstChild,10], [6,8,6,10]], e);
+      } else {
+        action(e, 500, 125);
+        checkRangeCount(3, e);
+        checkRange(0, [0,10,-1,2], e);
+        checkRange(1, [3,0,-1,4], e);
+        var r = sel.getRangeAt(2);
+        checkRangePoints(r, [e.childNodes[5],0,e.childNodes[6],10], e);
+      }
+    }
+  }
+  document.documentElement.removeAttribute("class");
+}
+
+SimpleTest.waitForFocus(function(){setTimeout(runTest,0)});
+
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/selection-utils.js
@@ -0,0 +1,151 @@
+// -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
+// vim: set ts=2 sw=2 et tw=78:
+function clearSelection(w)
+{
+  var sel = (w ? w : window).getSelection();
+  sel.removeAllRanges();
+}
+
+function getNode(e, index) { 
+  if (!(typeof index==='number')) return index;
+  if (index >= 0) return e.childNodes[index];
+  while (++index != 0) e = e.parentNode;
+  return e;
+}
+
+function dragSelectPointsWithData()
+{
+  var event = arguments[0];
+  var e = arguments[1];
+  var x1 = arguments[2];
+  var y1 = arguments[3];
+  var x2 = arguments[4];
+  var y2 = arguments[5];
+  dir = x2 > x1 ? 1 : -1;
+  event['type'] = "mousedown";
+  synthesizeMouse(e, x1, y1, event);
+  event['type'] = "mousemove";
+  synthesizeMouse(e, x1 + dir, y1, event);
+  for (var i = 6; i < arguments.length; ++i)
+    synthesizeMouse(e, arguments[i], y1, event);
+  synthesizeMouse(e, x2 - dir, y2, event);
+  event['type'] = "mouseup";
+  synthesizeMouse(e, x2, y2, event);
+}
+
+function dragSelectPoints()
+{
+  var args = Array.prototype.slice.call(arguments);
+  dragSelectPointsWithData.apply(this, [{}].concat(args));
+}
+
+function dragSelect()
+{
+  var args = Array.prototype.slice.call(arguments);
+  var e = args.shift();
+  var x1 = args.shift();
+  var x2 = args.shift();
+  dragSelectPointsWithData.apply(this, [{},e,x1,5,x2,5].concat(args));
+}
+
+function accelDragSelect()
+{
+  var args = Array.prototype.slice.call(arguments);
+  var e = args.shift();
+  var x1 = args.shift();
+  var x2 = args.shift();
+  var y = args.length != 0 ? args.shift() : 5;
+  dragSelectPointsWithData.apply(this, [{accelKey: true},e,x1,y,x2,y].concat(args));
+}
+
+function shiftClick(e, x, y)
+{
+  function pos(p) { return (typeof p === "undefined") ? 5 : p }
+  synthesizeMouse(e, pos(x), pos(y), { shiftKey: true });
+}
+
+function keyRepeat(key,data,repeat)
+{
+  while (repeat-- > 0)
+    synthesizeKey(key, data);
+}
+
+function keyRight(data)
+{
+  var repeat = arguments.length > 1 ? arguments[1] : 1;
+  keyRepeat("VK_RIGHT", data, repeat);
+}
+
+function keyLeft(data)
+{
+  var repeat = arguments.length > 1 ? arguments[1] : 1;
+  keyRepeat("VK_LEFT", data, repeat);
+}
+
+function shiftAccelClick(e, x, y)
+{
+  function pos(p) { return (typeof p === "undefined") ? 5 : p }
+  synthesizeMouse(e, pos(x), pos(y), { shiftKey: true, accelKey: true });
+}
+
+function accelClick(e, x, y)
+{
+  function pos(p) { return (typeof p === "undefined") ? 5 : p }
+  synthesizeMouse(e, pos(x), pos(y), { accelKey: true });
+}
+
+function addChildRanges(arr, e)
+{
+  var sel = window.getSelection();
+  for (i = 0; i < arr.length; ++i) {
+    var data = arr[i];
+    var r = new Range()
+    r.setStart(getNode(e, data[0]), data[1]);
+    r.setEnd(getNode(e, data[2]), data[3]);
+    sel.addRange(r);
+  }
+}
+
+function checkText(text, e)
+{
+  var sel = window.getSelection();
+  is(sel.toString(), text, e.id + ": selected text")
+}
+
+function checkRangeText(text, index)
+{
+  var r = window.getSelection().getRangeAt(index);
+  is(r.toString(), text, e.id + ": range["+index+"].toString()")
+}
+
+function checkRangeCount(n, e)
+{
+  var sel = window.getSelection();
+  is(sel.rangeCount, n, e.id + ": Selection range count");
+}
+
+function checkRangePoints(r, expected, e) {
+  is(r.startContainer, expected[0], e.id + ": range.startContainer");
+  is(r.startOffset, expected[1], e.id + ": range.startOffset");
+  is(r.endContainer, expected[2], e.id + ": range.endContainer");
+  is(r.endOffset, expected[3], e.id + ": range.endOffset");
+}
+
+function checkRange(i, expected, e) {
+  var sel = window.getSelection();
+  if (i >= sel.rangeCount) return;
+  var r = sel.getRangeAt(i);
+  is(r.startContainer, getNode(e, expected[0]), e.id + ": range["+i+"].startContainer");
+  is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset");
+  is(r.endContainer, getNode(e, expected[2]), e.id + ": range["+i+"].endContainer");
+  is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset");
+}
+
+function checkRanges(arr, e)
+{
+  checkRangeCount(arr.length, e);
+  for (i = 0; i < arr.length; ++i) {
+    var expected = arr[i];
+    checkRange(i, expected, e);
+  }
+}
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -3,18 +3,19 @@
 <head>
   <title>Reftests with caret drawing</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <style>
     iframe {
+      border: none;
       width: 600px;
-      height: 600px;
+      height: 400px;
     }
   </style>
 <script type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout("untriaged");
 
 var iframes = [];
@@ -87,16 +88,18 @@ function createIframe(url,next) {
 };
 
 function refTest(test,ref) {
   createIframe(test,ref);
 };
 
 var caretBlinkTime = null;
 function endTest() {
+  var parentDoc = window.parent.document;
+  parentDoc.styleSheets[parentDoc.styleSheets.length-1].deleteRule(0);
   // finish(), yet let the test actually end first, to be safe.
   SimpleTest.executeSoon(SimpleTest.finish);
 }
 
 var tests = [
     [ 'bug106855-1.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug106855-2.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug389321-2.html' , 'bug389321-2-ref.html' ] ,
@@ -163,32 +166,90 @@ if (navigator.appVersion.indexOf("Androi
   tests.push([ 'bug966992-1.html' , 'bug966992-1-ref.html' ]);
   tests.push([ 'bug966992-2.html' , 'bug966992-2-ref.html' ]);
   tests.push([ 'bug966992-3.html' , 'bug966992-3-ref.html' ]);
   tests.push(function() {SpecialPowers.pushPrefEnv({'clear': [['layout.css.overflow-clip-box.enabled']]}, nextTest);});
 } else {
   is(SpecialPowers.getIntPref("layout.spellcheckDefault"), 0, "Spellcheck should be turned off for this platrom or this if..else check removed");
 }
 
+if ((navigator.platform.indexOf("Mac") >= 0 ||
+     navigator.platform.indexOf("Linux") >= 0) &&
+    SpecialPowers.Services.appinfo.name != "B2G") {
+  tests = tests.concat([
+    function() {SpecialPowers.pushPrefEnv({'set': [['touchcaret.enabled', 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'  ] ,
+    // 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'  ] ,
+    // 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'  ] ,
+    function() {SpecialPowers.pushPrefEnv({'clear': [['touchcaret.enabled']]}, nextTest);} ,
+  ]);
+}
+
 var testIndex = 0;
 
 function nextTest() {
   if (testIndex < tests.length) {
     if (typeof(tests[testIndex]) == 'function') {
       tests[testIndex]();
     } else {
       refTest(tests[testIndex][0],tests[testIndex][1]);
     }
     ++testIndex;
   } else {
     endTest();
   }
 }
 function runTests() {
   try {
+    if (window.parent) {
+      var parentDoc = window.parent.document;
+      extraCSSRule = parentDoc.styleSheets[parentDoc.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();
   }
 }