blob: b63b3ac6c6650be244185aed00bde15011dfe817 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/accessibility/ax_node_object.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
namespace blink {
namespace test {
TEST_F(AccessibilityTest, TextOffsetInFormattingContextWithLayoutReplaced) {
SetBodyInnerHTML(R"HTML(
<p>
Before <img id="replaced" alt="alt"> after.
</p>)HTML");
const AXObject* ax_replaced = GetAXObjectByElementId("replaced");
ASSERT_NE(nullptr, ax_replaced);
ASSERT_EQ(ax::mojom::Role::kImage, ax_replaced->RoleValue());
ASSERT_EQ("alt", ax_replaced->ComputedName());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_replaced->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_replaced->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest, TextOffsetInFormattingContextWithLayoutInline) {
SetBodyInnerHTML(R"HTML(
<p>
Before <a id="inline" href="#">link</a> after.
</p>)HTML");
const AXObject* ax_inline = GetAXObjectByElementId("inline");
ASSERT_NE(nullptr, ax_inline);
ASSERT_EQ(ax::mojom::Role::kLink, ax_inline->RoleValue());
ASSERT_EQ("link", ax_inline->ComputedName());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_inline->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_inline->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest,
TextOffsetInFormattingContextWithLayoutBlockFlowAtInlineLevel) {
SetBodyInnerHTML(R"HTML(
<p>
Before
<b id="block-flow" style="display: inline-block;">block flow</b>
after.
</p>)HTML");
const AXObject* ax_block_flow = GetAXObjectByElementId("block-flow");
ASSERT_NE(nullptr, ax_block_flow);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_block_flow->RoleValue());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_block_flow->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_block_flow->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest,
TextOffsetInFormattingContextWithLayoutBlockFlowAtBlockLevel) {
// OffsetMapping does not support block flow objects that are at
// block-level, so we do not support them as well.
SetBodyInnerHTML(R"HTML(
<p>
Before
<b id="block-flow" style="display: block;">block flow</b>
after.
</p>)HTML");
const AXObject* ax_block_flow = GetAXObjectByElementId("block-flow");
ASSERT_NE(nullptr, ax_block_flow);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_block_flow->RoleValue());
// Since block-level elements do not expose a count of the number of
// characters from the beginning of their formatting context, we return the
// same offset that was passed in.
EXPECT_EQ(0, ax_block_flow->TextOffsetInFormattingContext(0));
EXPECT_EQ(1, ax_block_flow->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest, TextOffsetInFormattingContextWithLayoutText) {
SetBodyInnerHTML(R"HTML(
<p>
Before <span id="span">text</span> after.
</p>)HTML");
const AXObject* ax_text =
GetAXObjectByElementId("span")->FirstChildIncludingIgnored();
ASSERT_NE(nullptr, ax_text);
ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue());
ASSERT_EQ("text", ax_text->ComputedName());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_text->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_text->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest, TextOffsetInFormattingContextWithLayoutBr) {
SetBodyInnerHTML(R"HTML(
<p>
Before <br id="br"> after.
</p>)HTML");
const AXObject* ax_br = GetAXObjectByElementId("br");
ASSERT_NE(nullptr, ax_br);
ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue());
ASSERT_EQ("\n", ax_br->ComputedName());
// After white space is compressed, the word "before" is of length 6.
EXPECT_EQ(6, ax_br->TextOffsetInFormattingContext(0));
EXPECT_EQ(7, ax_br->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest, TextOffsetInFormattingContextWithLayoutFirstLetter) {
SetBodyInnerHTML(R"HTML(
<style>
q::first-letter {
color: red;
}
</style>
<p>
Before
<q id="first-letter">1. Remaining part</q>
after.
</p>)HTML");
const AXObject* ax_first_letter = GetAXObjectByElementId("first-letter");
ASSERT_NE(nullptr, ax_first_letter);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_first_letter->RoleValue());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_first_letter->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_first_letter->TextOffsetInFormattingContext(1));
}
TEST_F(AccessibilityTest,
TextOffsetInFormattingContextWithCSSGeneratedContent) {
SetBodyInnerHTML(R"HTML(
<style>
q::before {
content: "<";
color: blue;
}
q::after {
content: ">";
color: red;
}
</style>
<p>
Before <q id="css-generated">CSS generated</q> after.
</p>)HTML");
const AXObject* ax_css_generated = GetAXObjectByElementId("css-generated");
ASSERT_NE(nullptr, ax_css_generated);
ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_css_generated->RoleValue());
// After white space is compressed, the word "before" plus a single white
// space is of length 7.
EXPECT_EQ(7, ax_css_generated->TextOffsetInFormattingContext(0));
EXPECT_EQ(8, ax_css_generated->TextOffsetInFormattingContext(1));
}
} // namespace test
} // namespace blink