blob: c380b63fe2e0461936c023d05b4d6b1ad682b28f [file] [log] [blame]
// Copyright 2019 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 "base/win/scoped_variant.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views/accessibility/uia_accessibility_event_waiter.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/accessibility_notification_waiter.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/accessibility/ax_tree_manager_map.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "url/gurl.h"
namespace autofill {
class AutofillAccessibilityWinBrowserTest : public InProcessBrowserTest {
public:
AutofillAccessibilityWinBrowserTest() = default;
AutofillAccessibilityWinBrowserTest(
const AutofillAccessibilityWinBrowserTest&) = delete;
AutofillAccessibilityWinBrowserTest& operator=(
const AutofillAccessibilityWinBrowserTest&) = delete;
protected:
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(embedded_test_server()->Start());
content::WebContents* web_contents = GetWebContents();
web_contents->SetAccessibilityMode(ui::kAXModeComplete);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
content::WebContents* GetWebContents() const {
return browser()->tab_strip_model()->GetActiveWebContents();
}
HWND GetWebPageHwnd() const {
return browser()
->window()
->GetNativeWindow()
->GetHost()
->GetAcceleratedWidget();
}
// Show drop down based on the element id.
void ShowDropdown(const std::string& field_id) {
std::string js("document.getElementById('" + field_id + "').focus();");
ASSERT_TRUE(ExecuteScript(GetWebContents(), js));
SendKeyToPage(GetWebContents(), ui::DomKey::ARROW_DOWN);
}
void SendKeyToPage(content::WebContents* web_contents, const ui::DomKey key) {
ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key);
ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code);
SimulateKeyPress(web_contents, key, code, key_code, false, false, false,
false);
}
};
// The test is flaky on Windows. See https://crbug.com/1221273
#if BUILDFLAG(IS_WIN)
#define MAYBE_AutofillPopupControllerFor DISABLED_AutofillPopupControllerFor
#else
#define MAYBE_AutofillPopupControllerFor AutofillPopupControllerFor
#endif
IN_PROC_BROWSER_TEST_F(AutofillAccessibilityWinBrowserTest,
MAYBE_AutofillPopupControllerFor) {
content::AccessibilityNotificationWaiter waiter(
GetWebContents(), ui::kAXModeComplete, ax::mojom::Event::kLoadComplete);
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(),
embedded_test_server()->GetURL("/accessibility/input_datalist.html")));
waiter.WaitForNotification();
base::win::ScopedVariant result_variant;
content::FindAccessibilityNodeCriteria find_criteria;
find_criteria.role = ax::mojom::Role::kTextFieldWithComboBox;
// The autofill popup of the form input element has not shown yet. The form
// input element is the controller for the checkbox as indicated by the form
// input element's |aria-controls| attribute.
content::UiaGetPropertyValueVtArrayVtUnknownValidate(
UIA_ControllerForPropertyId,
FindAccessibilityNode(GetWebContents(), find_criteria), {"checkbox"});
UiaAccessibilityWaiterInfo info = {
GetWebPageHwnd(), base::ASCIIToWide("combobox"),
base::ASCIIToWide("input"), ax::mojom::Event::kControlsChanged};
std::unique_ptr<UiaAccessibilityEventWaiter> control_waiter =
std::make_unique<UiaAccessibilityEventWaiter>(info);
// Show popup and wait for UIA_ControllerForPropertyId event.
ShowDropdown("datalist");
control_waiter->Wait();
// The focus should remain on the input element.
EXPECT_EQ(content::GetFocusedAccessibilityNodeInfo(GetWebContents()).role,
ax::mojom::Role::kTextFieldWithComboBox);
// The autofill popup of the form input element is showing. The form input
// element is the controller for the checkbox and autofill popup as
// indicated by the form input element's |aria-controls| attribute and the
// existing popup.
content::UiaGetPropertyValueVtArrayVtUnknownValidate(
UIA_ControllerForPropertyId,
FindAccessibilityNode(GetWebContents(), find_criteria),
{"checkbox", "Autofill"});
control_waiter = std::make_unique<UiaAccessibilityEventWaiter>(info);
// Hide popup and wait for UIA_ControllerForPropertyId event.
SendKeyToPage(GetWebContents(), ui::DomKey::TAB);
control_waiter->Wait();
// The autofill popup of the form input element is hidden. The form
// input element is the controller for the checkbox as indicated by the form
// input element's |aria-controls| attribute.
content::UiaGetPropertyValueVtArrayVtUnknownValidate(
UIA_ControllerForPropertyId,
FindAccessibilityNode(GetWebContents(), find_criteria), {"checkbox"});
}
} // namespace autofill