#include <algorithm>
#include <array>
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_mock_time_message_loop_task_runner.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/features.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/scoped_accessibility_mode_override.h"
#include "content/shell/browser/shell.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
class ProgressiveAccessibilityTest
: public ContentBrowserTest,
public testing::WithParamInterface<
features::ProgressiveAccessibilityMode> {
protected:
ProgressiveAccessibilityTest() {
feature_list_.InitAndEnableFeatureWithParameters(
features::kProgressiveAccessibility,
{{"progressive_accessibility_mode",
GetParam() == features::ProgressiveAccessibilityMode::kDisableOnHide
? "disable_on_hide"
: "only_enable"}});
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_P(ProgressiveAccessibilityTest, AccessibilityOnReveal) {
Shell* shell_2 =
Shell::CreateNewWindow(shell()->web_contents()->GetBrowserContext(),
GURL(), nullptr, gfx::Size());
shell_2->web_contents()->WasHidden();
ScopedAccessibilityModeOverride basic(ui::kAXModeBasic);
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
EXPECT_EQ(shell_2->web_contents()->GetAccessibilityMode(), ui::AXMode());
shell_2->web_contents()->WasShown();
EXPECT_EQ(shell_2->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
}
IN_PROC_BROWSER_TEST_P(ProgressiveAccessibilityTest, DisableAfterHide) {
base::ScopedMockTimeMessageLoopTaskRunner mock_time_runner;
ScopedAccessibilityModeOverride basic(ui::kAXModeBasic);
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
std::array<Shell*, BrowserAccessibilityStateImpl::kMaxPreservedWebContents>
shells;
std::ranges::generate(
shells,
[browser_context = shell()->web_contents()->GetBrowserContext()]() {
auto* shell = Shell::CreateNewWindow(browser_context, GURL(), nullptr,
gfx::Size());
EXPECT_EQ(shell->web_contents()->GetAccessibilityMode(),
ui::kAXModeBasic);
return shell;
});
shell()->web_contents()->WasHidden();
std::ranges::for_each(
shells, [](Shell* shell) { shell->web_contents()->WasHidden(); });
mock_time_runner->FastForwardBy(
BrowserAccessibilityStateImpl::GetMaxDisableDelay());
std::ranges::for_each(shells, [](Shell* shell) {
EXPECT_EQ(shell->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
});
switch (GetParam()) {
case features::ProgressiveAccessibilityMode::kOnlyEnable:
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(),
ui::kAXModeBasic);
break;
case features::ProgressiveAccessibilityMode::kDisableOnHide:
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), ui::AXMode());
break;
}
}
IN_PROC_BROWSER_TEST_P(ProgressiveAccessibilityTest, DestroyAfterHide) {
ScopedAccessibilityModeOverride basic(ui::kAXModeBasic);
shell()->web_contents()->WasHidden();
shell()->Close();
}
IN_PROC_BROWSER_TEST_P(ProgressiveAccessibilityTest,
NoDisableWithScreenReader) {
base::ScopedMockTimeMessageLoopTaskRunner mock_time_runner;
const ui::AXMode mode = ui::kAXModeBasic | ui::AXMode::kScreenReader;
ScopedAccessibilityModeOverride basic(mode);
std::array<Shell*, BrowserAccessibilityStateImpl::kMaxPreservedWebContents>
shells;
std::ranges::generate(
shells,
[browser_context = shell()->web_contents()->GetBrowserContext()]() {
return Shell::CreateNewWindow(browser_context, GURL(), nullptr,
gfx::Size());
});
shell()->web_contents()->WasHidden();
std::ranges::for_each(
shells, [](Shell* shell) { shell->web_contents()->WasHidden(); });
mock_time_runner->FastForwardBy(
BrowserAccessibilityStateImpl::GetMaxDisableDelay());
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), mode);
}
IN_PROC_BROWSER_TEST_P(ProgressiveAccessibilityTest,
NoDisableWithScreenReaderLater) {
base::ScopedMockTimeMessageLoopTaskRunner mock_time_runner;
ScopedAccessibilityModeOverride basic(ui::kAXModeBasic);
std::array<Shell*, BrowserAccessibilityStateImpl::kMaxPreservedWebContents>
shells;
std::ranges::generate(
shells,
[browser_context = shell()->web_contents()->GetBrowserContext()]() {
return Shell::CreateNewWindow(browser_context, GURL(), nullptr,
gfx::Size());
});
shell()->web_contents()->WasHidden();
std::ranges::for_each(
shells, [](Shell* shell) { shell->web_contents()->WasHidden(); });
ScopedAccessibilityModeOverride screen_reader(ui::AXMode::kScreenReader);
mock_time_runner->FastForwardBy(
BrowserAccessibilityStateImpl::GetMaxDisableDelay());
std::ranges::for_each(shells, [](Shell* shell) {
EXPECT_EQ(shell->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
});
EXPECT_EQ(shell()->web_contents()->GetAccessibilityMode(), ui::kAXModeBasic);
}
INSTANTIATE_TEST_SUITE_P(
OnlyEnable,
ProgressiveAccessibilityTest,
testing::Values(features::ProgressiveAccessibilityMode::kOnlyEnable));
INSTANTIATE_TEST_SUITE_P(
DisableOnHide,
ProgressiveAccessibilityTest,
testing::Values(features::ProgressiveAccessibilityMode::kDisableOnHide));
}
}