Commit 3c88080a authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Enables writing selection tests using HTML files

Selection tests are stored under blink/renderer/modules/accessibility/testing/data/selection
There are three files per selection test:
<testname>.html - the actual HTML to be tested. AXSelection::SetSelection will be used to set the selection.
<test_name>_dom.html - The selection resulting from AXSelection::GetSelection on the selection that the first file has produced.
<test_name>-ax.txt - The resulting accessibility tree.
The test framework will use the embedded selection markers "^" and "|" in the HTML to:
A) set the selection specified in the first file and compare it with the selection in the "dom" file.
B) Dump the accessibility tree after applying the selection and compare it with the tree in the "ax" file.
R=dmazzoni@chromium.org

Change-Id: I7c3c9e3a1eb222aac0afb69d1c4ffa2247a9cd49
Reviewed-on: https://chromium-review.googlesource.com/c/1240633
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605382}
parent 769bb1f5
......@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
namespace test {
namespace {
......@@ -400,4 +401,5 @@ TEST_F(AccessibilityObjectModelTest, LabeledBy) {
} // namespace
} // namespace test
} // namespace blink
......@@ -3508,6 +3508,13 @@ const AXObject* AXObject::LowestCommonAncestor(const AXObject& first,
return common_ancestor;
}
String AXObject::ToString() const {
return AXObject::InternalRoleName(RoleValue())
.GetString()
.EncodeForDebugging() +
": " + ComputedName().EncodeForDebugging();
}
VisiblePosition AXObject::VisiblePositionForIndex(int) const {
return VisiblePosition();
}
......@@ -3563,8 +3570,7 @@ bool operator>=(const AXObject& first, const AXObject& second) {
}
std::ostream& operator<<(std::ostream& stream, const AXObject& obj) {
return stream << AXObject::InternalRoleName(obj.RoleValue()) << ": "
<< obj.ComputedName();
return stream << obj.ToString().Utf8().data();
}
void AXObject::Trace(blink::Visitor* visitor) {
......
......@@ -49,6 +49,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/accessibility/ax_enums.mojom-blink.h"
......@@ -1007,6 +1008,9 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
int* index_in_ancestor1,
int* index_in_ancestor2);
// Returns a string representation of this object.
String ToString() const;
protected:
AXID id_;
AXObjectVector children_;
......
......@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
namespace blink {
namespace test {
// TODO(nektar): Break test up into multiple tests.
TEST_F(AccessibilityTest, IsARIAWidget) {
......@@ -55,4 +56,5 @@ TEST_F(AccessibilityTest, IsARIAWidget) {
*root->getElementById("focusable-parent")));
}
} // namespace test
} // namespace blink
......@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
namespace blink {
namespace test {
TEST_F(AccessibilityTest, IsDescendantOf) {
SetBodyInnerHTML(R"HTML(<button id="button">button</button>)HTML");
......@@ -164,4 +165,5 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) {
EXPECT_EQ(GetAXObjectCache().InOrderTraversalBegin(), iter);
}
} // namespace test
} // namespace blink
......@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/modules/accessibility/ax_layout_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
......@@ -675,6 +676,26 @@ const PositionWithAffinity AXPosition::ToPositionWithAffinity(
return PositionWithAffinity(range.EndPosition(), affinity_);
}
String AXPosition::ToString() const {
if (!IsValid())
return "Invalid AXPosition";
StringBuilder builder;
if (IsTextPosition()) {
builder.Append("AX text position in ");
builder.Append(container_object_->ToString());
builder.Append(", ");
builder.Append(String::Format("%d", TextOffset()));
return builder.ToString();
}
builder.Append("AX object anchored position in ");
builder.Append(container_object_->ToString());
builder.Append(", ");
builder.Append(String::Format("%d", ChildIndex()));
return builder.ToString();
}
// static
const AXObject* AXPosition::FindNeighboringUnignoredObject(
const Document& document,
......@@ -805,15 +826,7 @@ bool operator>=(const AXPosition& a, const AXPosition& b) {
}
std::ostream& operator<<(std::ostream& ostream, const AXPosition& position) {
if (!position.IsValid())
return ostream << "Invalid AXPosition";
if (position.IsTextPosition()) {
return ostream << "AX text position in " << *position.ContainerObject()
<< ", " << position.TextOffset();
}
return ostream << "AX object anchored position in "
<< *position.ContainerObject() << ", "
<< position.ChildIndex();
return ostream << position.ToString().Utf8().data();
}
} // namespace blink
......@@ -5,15 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_POSITION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_POSITION_H_
#include <base/logging.h>
#include <stdint.h>
#include <ostream>
#include <base/logging.h>
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -145,6 +147,9 @@ class MODULES_EXPORT AXPosition final {
const AXPositionAdjustmentBehavior =
AXPositionAdjustmentBehavior::kMoveLeft) const;
// Returns a string representation of this object.
String ToString() const;
private:
// Only used by static Create... methods.
explicit AXPosition(const AXObject& container);
......
......@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
namespace test {
namespace {
......@@ -1393,4 +1394,5 @@ TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) {
EXPECT_EQ(ax_after, ax_position_after_from_dom.ChildAfterTreePosition());
}
} // namespace test
} // namespace blink
......@@ -70,6 +70,12 @@ AXRange AXRange::RangeOfContents(const AXObject& container) {
AXPosition::CreateLastPositionInObject(container));
}
String AXRange::ToString() const {
if (!IsValid())
return "Invalid AXRange";
return "AXRange from " + Start().ToString() + " to " + End().ToString();
}
bool operator==(const AXRange& a, const AXRange& b) {
DCHECK(a.IsValid() && b.IsValid());
return a.Start() == b.Start() && a.End() == b.End();
......@@ -80,9 +86,7 @@ bool operator!=(const AXRange& a, const AXRange& b) {
}
std::ostream& operator<<(std::ostream& ostream, const AXRange& range) {
if (!range.IsValid())
return ostream << "Invalid AXRange";
return ostream << "AXRange from " << range.Start() << " to " << range.End();
return ostream << range.ToString().Utf8().data();
}
} // namespace blink
......@@ -5,13 +5,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RANGE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RANGE_H_
#include <base/logging.h>
#include <stdint.h>
#include <ostream>
#include <base/logging.h>
#include "third_party/blink/renderer/modules/accessibility/ax_position.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -44,6 +46,9 @@ class MODULES_EXPORT AXRange final {
// Creates an |AXRange| encompassing the contents of the given |AXObject|.
static AXRange RangeOfContents(const AXObject&);
// Returns a string representation of this object.
String ToString() const;
private:
AXPosition start_;
AXPosition end_;
......
......@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
namespace blink {
namespace test {
TEST_F(AccessibilityTest, CommonAncestorContainerOfRange) {
SetBodyInnerHTML(R"HTML(<input id='input' type='text' value='value'>"
......@@ -79,4 +80,5 @@ TEST_F(AccessibilityTest, RangeOfContents) {
paragraph_range.End());
}
} // namespace test
} // namespace blink
......@@ -207,6 +207,12 @@ void AXSelection::Select(const AXSelectionBehavior selection_behavior) {
frame_selection.SetSelection(selection, SetSelectionOptions());
}
String AXSelection::ToString() const {
if (!IsValid())
return "Invalid AXSelection";
return "AXSelection from " + Base().ToString() + " to " + Extent().ToString();
}
bool operator==(const AXSelection& a, const AXSelection& b) {
DCHECK(a.IsValid() && b.IsValid());
return a.Base() == b.Base() && a.Extent() == b.Extent();
......@@ -217,10 +223,7 @@ bool operator!=(const AXSelection& a, const AXSelection& b) {
}
std::ostream& operator<<(std::ostream& ostream, const AXSelection& selection) {
if (!selection.IsValid())
return ostream << "Invalid AXSelection";
return ostream << "AXSelection from " << selection.Base() << " to "
<< selection.Extent();
return ostream << selection.ToString().Utf8().data();
}
} // namespace blink
......@@ -5,14 +5,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_SELECTION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_SELECTION_H_
#include <base/logging.h>
#include <stdint.h>
#include <ostream>
#include <base/logging.h>
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/modules/accessibility/ax_position.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -56,6 +58,9 @@ class MODULES_EXPORT AXSelection final {
void Select(
const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
// Returns a string representation of this object.
String ToString() const;
private:
AXSelection();
......
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/accessibility/ax_selection.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/position.h"
......@@ -15,6 +16,7 @@
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h"
namespace blink {
namespace test {
//
// Basic tests.
......@@ -43,8 +45,10 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInText) {
EXPECT_EQ(3, dom_selection.Base().OffsetInContainerNode());
EXPECT_EQ(text, dom_selection.Extent().AnchorNode());
EXPECT_EQ(5, dom_selection.Extent().OffsetInContainerNode());
EXPECT_EQ("<Paragraph: ><StaticText: Hel^lo|>",
GetSelectionText(ax_selection));
EXPECT_EQ(
"++<Paragraph>\n"
"++++<StaticText: Hel^lo|>\n",
GetSelectionText(ax_selection));
}
TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) {
......@@ -70,8 +74,10 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) {
EXPECT_EQ(8, dom_selection.Base().OffsetInContainerNode());
EXPECT_EQ(text, dom_selection.Extent().AnchorNode());
EXPECT_EQ(10, dom_selection.Extent().OffsetInContainerNode());
EXPECT_EQ("<Paragraph: ><StaticText: Hel^lo|>",
GetSelectionText(ax_selection));
EXPECT_EQ(
"++<Paragraph>\n"
"++++<StaticText: Hel^lo|>\n",
GetSelectionText(ax_selection));
}
//
......@@ -132,4 +138,17 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAroundListBullet) {
EXPECT_EQ("", GetSelectionText(ax_selection_extend));
}
//
// Declarative tests.
//
TEST_F(AccessibilitySelectionTest, List) {
RunSelectionTest("list");
}
TEST_F(AccessibilitySelectionTest, table) {
RunSelectionTest("table");
}
} // namespace test
} // namespace blink
......@@ -16,6 +16,8 @@ class AXObject;
class AXSelection;
class LocalFrameClient;
namespace test {
// Makes writing and debugging selection tests easier.
class AccessibilitySelectionTest : public AccessibilityTest {
USING_FAST_MALLOC(AccessibilitySelectionTest);
......@@ -24,12 +26,19 @@ class AccessibilitySelectionTest : public AccessibilityTest {
AccessibilitySelectionTest(LocalFrameClient* local_frame_client = nullptr);
protected:
// Gets the inner HTML of the accessibility tree and annotates it with markers
// indicating the anchor and focus of |selection|.
// Gets a text representation of the accessibility tree that is currently
// selected and annotates it with markers indicating the anchor and focus of
// |selection|.
std::string GetCurrentSelectionText() const;
// Gets a text representation of the accessibility tree encompassing
// |selection| and annotates it with markers indicating the anchor and focus
// of |selection|.
std::string GetSelectionText(const AXSelection& selection) const;
// Gets the inner HTML of the accessibility subtree rooted at |subtree| and
// annotates it with markers indicating the anchor and focus of |selection|.
// Gets a text representation of the accessibility subtree rooted at |subtree|
// and encompassing |selection|, and annotates it with markers indicating the
// anchor and focus of |selection|.
std::string GetSelectionText(const AXSelection& selection,
const AXObject& subtree) const;
......@@ -41,8 +50,15 @@ class AccessibilitySelectionTest : public AccessibilityTest {
// the accessibility subtree at |element|.
const AXSelection SetSelectionText(const std::string& selection_text,
HTMLElement& element) const;
// Compares two HTML files containing a DOM selection and the equivalent
// accessibility selection.
void RunSelectionTest(const std::string& test_name) const;
private:
};
} // namespace test
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_SELECTION_TEST_H_
......@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
namespace blink {
namespace test {
AccessibilityTest::AccessibilityTest(LocalFrameClient* local_frame_client)
: RenderingTest(local_frame_client) {}
......@@ -56,11 +57,12 @@ std::ostringstream& AccessibilityTest::PrintAXTreeHelper(
stream << std::string(level * 2, '+');
stream << *root << std::endl;
for (const Member<AXObject> child : root->Children()) {
for (const AXObject* child : root->Children()) {
DCHECK(child);
PrintAXTreeHelper(stream, child.Get(), level + 1);
PrintAXTreeHelper(stream, child, level + 1);
}
return stream;
}
} // namespace test
} // namespace blink
......@@ -19,6 +19,8 @@ class AXObject;
class AXObjectCacheImpl;
class LocalFrameClient;
namespace test {
class AccessibilityTest : public RenderingTest {
USING_FAST_MALLOC(AccessibilityTest);
......@@ -47,6 +49,7 @@ class AccessibilityTest : public RenderingTest {
std::unique_ptr<AXContext> ax_context_;
};
} // namespace test
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_TEST_H_
================================================================================
AXSelection from AX object anchored position in "List": "", 1 to AX object anchored position in "List": "", 3
================================================================================
++<List>
++++<ListItem>
++++++<ListMarker: 1. >
++++++<StaticText: tic>
^++++<ListItem>
++++++<ListMarker: 2. >
++++++<StaticText: tac>
++++<ListItem>
++++++<ListMarker: 3. >
++++++<StaticText: toe>
|++<List>
++++<ListItem>
++++++<StaticText: tic>
++++<StaticText: >
++++<ListItem>
++++++<StaticText: tac>
++++<StaticText: >
++++<ListItem>
++++++<StaticText: toe>
================================================================================
AXSelection from AX object anchored position in "WebArea": "", 1 to AX object anchored position in "WebArea": "", 2
================================================================================
++<List>
++++<ListItem>
++++++<ListMarker: 1. >
++++++<StaticText: tic>
++++<ListItem>
++++++<ListMarker: 2. >
++++++<StaticText: tac>
++++<ListItem>
++++++<ListMarker: 3. >
++++++<StaticText: toe>
^++<List>
++++<ListItem>
++++++<StaticText: tic>
++++<StaticText: >
++++<ListItem>
++++++<StaticText: tac>
++++<StaticText: >
++++<ListItem>
++++++<StaticText: toe>
|
\ No newline at end of file
================================================================================
AXSelection from AX object anchored position in "WebArea": "", 0 to AX object anchored position in "WebArea": "", 0
================================================================================
|++<Table>
++++<Row>
++++++<ColumnHeader: Sum>
++++++++<StaticText: Sum>
++++++<ColumnHeader: Subtraction>
++++++++<StaticText: Subtraction>
++++<Row>
++++++<Cell: 10>
++++++++<StaticText: 10>
++++++<Cell: 7>
++++++++<StaticText: 7>
++++<Row>
++++++<Cell: 2>
++++++++<StaticText: 2>
++++++<Cell: 4>
++++++++<StaticText: 4>
++++<Row>
++++++<Cell: 12>
++++++++<StaticText: 12>
++++++<Cell: 3>
++++++++<StaticText: 3>
================================================================================
AXSelection from AX object anchored position in "WebArea": "", 0 to AX object anchored position in "WebArea": "", 0
================================================================================
|++<Table>
++++<Row>
++++++<ColumnHeader: Sum>
++++++++<StaticText: Sum>
++++++<ColumnHeader: Subtraction>
++++++++<StaticText: Subtraction>
++++<Row>
++++++<Cell: 10>
++++++++<StaticText: 10>
++++++<Cell: 7>
++++++++<StaticText: 7>
++++<Row>
++++++<Cell: 2>
++++++++<StaticText: 2>
++++++<Cell: 4>
++++++++<StaticText: 4>
++++<Row>
++++++<Cell: 12>
++++++++<StaticText: 12>
++++++<Cell: 3>
++++++++<StaticText: 3>
================================================================================
AXSelection from AX object anchored position in "WebArea": "", 0 to AX object anchored position in "WebArea": "", 0
================================================================================
|++<Table>
++++<Row>
++++++<ColumnHeader: Sum>
++++++++<StaticText: Sum>
++++++<ColumnHeader: Subtraction>
++++++++<StaticText: Subtraction>
++++<Row>
++++++<Cell: 10>
++++++++<StaticText: 10>
++++++<Cell: 7>
++++++++<StaticText: 7>
++++<Row>
++++++<Cell: 2>
++++++++<StaticText: 2>
++++++<Cell: 4>
++++++++<StaticText: 4>
++++<Row>
++++++<Cell: 12>
++++++++<StaticText: 12>
++++++<Cell: 3>
++++++++<StaticText: 3>
================================================================================
AXSelection from AX text position in "StaticText": "Sum", 0 to AX text position in "StaticText": "Subtraction", 11
================================================================================
++<Table>
++++<Row>
++++++<ColumnHeader: Sum>
^++++++++<StaticText: ^Sum>
++++++<ColumnHeader: Subtraction>
++++++++<StaticText: Subtraction|>
++++<Row>
++++++<Cell: 10>
++++++++<StaticText: 10>
++++++<Cell: 7>
++++++++<StaticText: 7>
++++<Row>
++++++<Cell: 2>
++++++++<StaticText: 2>
++++++<Cell: 4>
++++++++<StaticText: 4>
++++<Row>
++++++<Cell: 12>
++++++++<StaticText: 12>
++++++<Cell: 3>
++++++++<StaticText: 3>
<!DOCTYPE html>
<html>
<body>
<table border="1">
<thead>
<tr>
<th>^Sum</th>
<th>Subtraction|</th>
</tr>
</thead>
<tfoot>
^<tr>
<td>12</td>
<td>3</td>
</tr>|
</tfoot>
<tbody>
<tr>
^<td>10</td>
<td>7</td>|
</tr>
^<tr>
<td>2</td>
<td>4</td>
</tr>|
</tbody>
</table>
</body>
</html>
......@@ -122,6 +122,14 @@ String PlatformTestDataPath(const String& relative_path) {
.Append(WebStringToFilePath(relative_path)));
}
String AccessibilityTestDataPath(const String& relative_path) {
return FilePathToWebString(
BlinkRootFilePath()
.Append(
FILE_PATH_LITERAL("renderer/modules/accessibility/testing/data"))
.Append(WebStringToFilePath(relative_path)));
}
scoped_refptr<SharedBuffer> ReadFromFile(const String& path) {
base::FilePath file_path = blink::WebStringToFilePath(path);
std::string buffer;
......
......@@ -70,6 +70,12 @@ String CoreTestDataPath(const String& relative_path = String());
// specified.
String PlatformTestDataPath(const String& relative_path = String());
// Returns test data absolute path for accessibility unittests, i.e.
// <blinkRootDir>/renderer/modules/accessibility/testing/data/<relativePath>. It
// returns the top accessibility test directory if |relativePath| was not
// specified.
String AccessibilityTestDataPath(const String& relative_path = String());
scoped_refptr<SharedBuffer> ReadFromFile(const String& path);
class LineReader {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment