| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/accessibility/browser_accessibility.h" |
| #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| #include "content/browser/renderer_host/render_view_host_impl.h" |
| #include "content/browser/renderer_host/render_widget_host_impl.h" |
| #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/render_widget_host.h" |
| #include "content/public/browser/render_widget_host_view.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/test/content_browser_test.h" |
| #include "content/public/test/content_browser_test_utils.h" |
| #include "content/shell/browser/shell.h" |
| #include "content/test/accessibility_browser_test_utils.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/accessibility/ax_modes.h" |
| |
| namespace content { |
| |
| const char kMinimalPageDataURL[] = |
| "data:text/html,<html><head></head><body>Hello, world</body></html>"; |
| |
| class AccessibilityModeTest : public ContentBrowserTest { |
| protected: |
| WebContentsImpl* web_contents() { |
| return static_cast<WebContentsImpl*>(shell()->web_contents()); |
| } |
| |
| protected: |
| const BrowserAccessibility* FindNode(ax::mojom::Role role, |
| const std::string& name) { |
| const BrowserAccessibility* root = GetManager()->GetRoot(); |
| CHECK(root); |
| return FindNodeInSubtree(*root, role, name); |
| } |
| |
| BrowserAccessibilityManager* GetManager() { |
| WebContentsImpl* web_contents = |
| static_cast<WebContentsImpl*>(shell()->web_contents()); |
| return web_contents->GetRootBrowserAccessibilityManager(); |
| } |
| |
| private: |
| const BrowserAccessibility* FindNodeInSubtree( |
| const BrowserAccessibility& node, |
| ax::mojom::Role role, |
| const std::string& name) { |
| if (node.GetRole() == role && |
| node.GetStringAttribute(ax::mojom::StringAttribute::kName) == name) |
| return &node; |
| for (unsigned int i = 0; i < node.PlatformChildCount(); ++i) { |
| const BrowserAccessibility* result = FindNodeInSubtree( |
| *node.PlatformGetChild(i), role, name); |
| if (result) |
| return result; |
| } |
| return nullptr; |
| } |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AccessibilityModeOff) { |
| NavigateToURL(shell(), GURL(kMinimalPageDataURL)); |
| EXPECT_TRUE(web_contents()->GetAccessibilityMode().is_mode_off()); |
| EXPECT_EQ(nullptr, GetManager()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AccessibilityModeComplete) { |
| NavigateToURL(shell(), GURL(kMinimalPageDataURL)); |
| ASSERT_TRUE(web_contents()->GetAccessibilityMode().is_mode_off()); |
| |
| AccessibilityNotificationWaiter waiter(shell()->web_contents()); |
| web_contents()->AddAccessibilityMode(ui::kAXModeComplete); |
| EXPECT_TRUE(web_contents()->GetAccessibilityMode() == ui::kAXModeComplete); |
| waiter.WaitForNotification(); |
| EXPECT_NE(nullptr, GetManager()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, |
| AccessibilityModeWebContentsOnly) { |
| NavigateToURL(shell(), GURL(kMinimalPageDataURL)); |
| ASSERT_TRUE(web_contents()->GetAccessibilityMode().is_mode_off()); |
| |
| AccessibilityNotificationWaiter waiter(shell()->web_contents()); |
| web_contents()->AddAccessibilityMode(ui::kAXModeWebContentsOnly); |
| EXPECT_TRUE(web_contents()->GetAccessibilityMode() == |
| ui::kAXModeWebContentsOnly); |
| waiter.WaitForNotification(); |
| // No BrowserAccessibilityManager expected for this mode. |
| EXPECT_EQ(nullptr, GetManager()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AddingModes) { |
| NavigateToURL(shell(), GURL(kMinimalPageDataURL)); |
| |
| AccessibilityNotificationWaiter waiter(shell()->web_contents()); |
| web_contents()->AddAccessibilityMode(ui::kAXModeWebContentsOnly); |
| EXPECT_TRUE(web_contents()->GetAccessibilityMode() == |
| ui::kAXModeWebContentsOnly); |
| waiter.WaitForNotification(); |
| EXPECT_EQ(nullptr, GetManager()); |
| |
| AccessibilityNotificationWaiter waiter2(shell()->web_contents()); |
| web_contents()->AddAccessibilityMode(ui::kAXModeComplete); |
| EXPECT_TRUE(web_contents()->GetAccessibilityMode() == ui::kAXModeComplete); |
| waiter2.WaitForNotification(); |
| EXPECT_NE(nullptr, GetManager()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, |
| FullAccessibilityHasInlineTextBoxes) { |
| // TODO(dmazzoni): On Android we use an ifdef to disable inline text boxes, |
| // we should do it with accessibility flags instead. http://crbug.com/672205 |
| #if !defined(OS_ANDROID) |
| NavigateToURL(shell(), GURL(url::kAboutBlankURL)); |
| |
| AccessibilityNotificationWaiter waiter(shell()->web_contents(), |
| ui::kAXModeComplete, |
| ax::mojom::Event::kLoadComplete); |
| GURL url("data:text/html,<p>Para</p>"); |
| NavigateToURL(shell(), url); |
| waiter.WaitForNotification(); |
| |
| const BrowserAccessibility* text = |
| FindNode(ax::mojom::Role::kStaticText, "Para"); |
| ASSERT_NE(nullptr, text); |
| ASSERT_EQ(1U, text->InternalChildCount()); |
| BrowserAccessibility* inline_text = text->InternalGetChild(0); |
| ASSERT_NE(nullptr, inline_text); |
| EXPECT_EQ(ax::mojom::Role::kInlineTextBox, inline_text->GetRole()); |
| #endif // !defined(OS_ANDROID) |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, |
| MinimalAccessibilityModeHasNoInlineTextBoxes) { |
| // TODO(dmazzoni): On Android we use an ifdef to disable inline text boxes, |
| // we should do it with accessibility flags instead. http://crbug.com/672205 |
| #if !defined(OS_ANDROID) |
| NavigateToURL(shell(), GURL(url::kAboutBlankURL)); |
| |
| AccessibilityNotificationWaiter waiter( |
| shell()->web_contents(), |
| ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents, |
| ax::mojom::Event::kLoadComplete); |
| GURL url("data:text/html,<p>Para</p>"); |
| NavigateToURL(shell(), url); |
| waiter.WaitForNotification(); |
| |
| const BrowserAccessibility* text = |
| FindNode(ax::mojom::Role::kStaticText, "Para"); |
| ASSERT_NE(nullptr, text); |
| EXPECT_EQ(0U, text->InternalChildCount()); |
| #endif // !defined(OS_ANDROID) |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AddScreenReaderModeFlag) { |
| NavigateToURL(shell(), GURL(url::kAboutBlankURL)); |
| |
| AccessibilityNotificationWaiter waiter( |
| shell()->web_contents(), |
| ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents, |
| ax::mojom::Event::kLoadComplete); |
| GURL url("data:text/html,<input aria-label=Foo placeholder=Bar>"); |
| NavigateToURL(shell(), url); |
| waiter.WaitForNotification(); |
| |
| const BrowserAccessibility* textbox = |
| FindNode(ax::mojom::Role::kTextField, "Foo"); |
| ASSERT_NE(nullptr, textbox); |
| EXPECT_FALSE( |
| textbox->HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)); |
| int original_id = textbox->GetId(); |
| |
| AccessibilityNotificationWaiter waiter2(shell()->web_contents(), ui::AXMode(), |
| ax::mojom::Event::kLoadComplete); |
| BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags( |
| ui::AXMode::kScreenReader); |
| waiter2.WaitForNotification(); |
| |
| const BrowserAccessibility* textbox2 = |
| FindNode(ax::mojom::Role::kTextField, "Foo"); |
| ASSERT_NE(nullptr, textbox2); |
| EXPECT_TRUE( |
| textbox2->HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)); |
| EXPECT_EQ(original_id, textbox2->GetId()); |
| } |
| |
| } // namespace content |