chromium/third_party/blink/web_tests/accessibility/set-selection-whitespace.html

<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>

<div id="editable1" contenteditable="true">Hello1</div>

<div id="editable2" contenteditable="true">  Hello2  </div>

<h2 id="heading">  Hello2  </h2>

<script>
  test(() => {
    const editable1 = document.getElementById('editable1');
    assert_class_string(editable1, 'HTMLDivElement');
    const textNode1 = editable1.firstChild;
    assert_class_string(textNode1, 'Text');

    const axEditable1 = accessibilityController.accessibleElementById('editable1');
    const axTextNode1 = axEditable1.childAtIndex(0);
    assert_equals(axTextNode1.role, 'AXRole: AXStaticText');
    assert_equals(axTextNode1.name, 'Hello1');

    axTextNode1.setSelection(axTextNode1, 0, axTextNode1, 6);

    const selection = getSelection();
    // "Before object" positions at a text node are always adjusted to be before
    // the first character of the text node itself.
    // This ensures that to otherwise identical AX positions will have the same
    // DOM position.
    assert_equals(selection.anchorNode, textNode1, 'anchorNode');
    assert_equals(selection.anchorOffset, 0, 'anchorOffset');
    assert_equals(selection.focusNode, textNode1, 'focusNode');
    assert_equals(selection.focusOffset, 6, 'focusOffset');
    assert_equals(selection.toString(), 'Hello1', 'getSelection.toString()');
  }, 'Using accessible APIs to set selection works when there is no extra whitespace.');

test(() => {
    const editable2 = document.getElementById('editable2');
    assert_class_string(editable2, 'HTMLDivElement');
    const textNode2 = editable2.firstChild;
    assert_class_string(textNode2, 'Text');

    const axEditable2 = accessibilityController.accessibleElementById('editable2');
    const axTextNode2 = axEditable2.childAtIndex(0);
    assert_equals(axTextNode2.role, 'AXRole: AXStaticText');
    assert_equals(axTextNode2.name, 'Hello2');

    axTextNode2.setSelection(axTextNode2, 0, axTextNode2, 6);

    const selection = getSelection();
    // Anchor and focus offsets are DOM base and are therefore adjusted to
    // account for whitespace.
    assert_equals(selection.anchorNode, textNode2, 'anchorNode');
    assert_equals(selection.anchorOffset, 2, 'anchorOffset');
    assert_equals(selection.focusNode, textNode2, 'focusNode');
    assert_equals(selection.focusOffset, 8, 'focusOffset');
    assert_equals(selection.toString(), 'Hello2', 'getSelection.toString()');
  }, 'Using accessible APIs to set selection works even with non-visible whitespace.');

  test(() => {
    const heading = document.getElementById('heading');
    assert_class_string(heading, 'HTMLHeadingElement');
    const headingText = heading.firstChild;
    assert_class_string(headingText, 'Text');

    const axHeading = accessibilityController.accessibleElementById('heading');
    assert_equals(axHeading.role, 'AXRole: AXHeading');

    // Select all the children in the heading.
    axHeading.setSelection(axHeading, 0, axHeading, 1);

    const selection = getSelection();
    assert_equals(selection.anchorNode, headingText, 'anchorNode');
    assert_equals(selection.anchorOffset, 2, 'anchorOffset');
    assert_equals(selection.focusNode, heading, 'focusNode');
    assert_equals(selection.focusOffset, 1, 'focusOffset');
    assert_equals(selection.toString(), 'Hello2', 'getSelection.toString()');
  }, 'Use accessible APIs to set selection on all the children of an element rather than a static text node.');
</script>