chromium/ash/wm/overview/overview_focus_cycler_unittest.cc

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/overview/overview_focus_cycler.h"

#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/shell.h"
#include "ash/test/ash_test_util.h"
#include "ash/wm/desks/desk_action_button.h"
#include "ash/wm/desks/desk_action_view.h"
#include "ash/wm/desks/desk_name_view.h"
#include "ash/wm/desks/desk_preview_view.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_test_util.h"
#include "ash/wm/desks/overview_desk_bar_view.h"
#include "ash/wm/desks/templates/saved_desk_save_desk_button.h"
#include "ash/wm/overview/overview_item_view.h"
#include "ash/wm/overview/overview_test_base.h"
#include "ash/wm/overview/overview_test_util.h"
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
#include "ash/wm/window_util.h"
#include "base/test/scoped_feature_list.h"
#include "overview_focus_cycler.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/test/display_manager_test_api.h"

namespace ash {

class OverviewFocusCyclerTest : public OverviewTestBase,
                                public testing::WithParamInterface<bool> {
 public:
  OverviewFocusCyclerTest() = default;
  OverviewFocusCyclerTest(const OverviewFocusCyclerTest&) = delete;
  OverviewFocusCyclerTest& operator=(const OverviewFocusCyclerTest&) = delete;
  ~OverviewFocusCyclerTest() override = default;

  // Helper to make tests more readable.
  bool AreDeskTemplatesEnabled() const { return GetParam(); }

  views::View* GetFocusedView() {
    return GetOverviewSession()->focus_cycler()->GetOverviewFocusedView();
  }

  // OverviewTestBase:
  void SetUp() override {
    scoped_feature_list_.InitWithFeatureStates(
        {{features::kDesksTemplates, AreDeskTemplatesEnabled()},
         {features::kSnapGroup, true},
         {features::kDeskBarWindowOcclusionOptimization, true}});
    OverviewTestBase::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Tests traversing some windows in overview mode with the tab key.
TEST_P(OverviewFocusCyclerTest, BasicTabKeyNavigation) {
  std::unique_ptr<aura::Window> window2 = CreateAppWindow();
  std::unique_ptr<aura::Window> window1 = CreateAppWindow();

  ToggleOverview();
  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
      GetOverviewItemsForRoot(0);
  auto* event_generator = GetEventGenerator();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
  EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
}

// Same as above but for tablet mode.
TEST_P(OverviewFocusCyclerTest, BasicTabKeyNavigationTablet) {
  std::unique_ptr<aura::Window> window1 = CreateAppWindow();
  std::unique_ptr<aura::Window> window2 = CreateAppWindow();
  std::unique_ptr<aura::Window> window3 = CreateAppWindow();

  TabletModeControllerTestApi().EnterTabletMode();
  ToggleOverview();
  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
      GetOverviewItemsForRoot(0);
  auto* event_generator = GetEventGenerator();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(overview_windows[0]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_windows[2]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
  EXPECT_EQ(overview_windows[1]->item_widget()->GetNativeWindow(),
            window_util::GetFocusedWindow());
}

// Tests that pressing Ctrl+W while a window is selected in overview closes it.
TEST_P(OverviewFocusCyclerTest, CloseWindowWithKey) {
  std::unique_ptr<aura::Window> window = CreateAppWindow();
  ToggleOverview();

  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, GetEventGenerator());
  PressAndReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  EXPECT_TRUE(
      views::Widget::GetWidgetForNativeWindow(window.get())->IsClosed());
}

// Tests traversing some windows in overview mode with the arrow keys in every
// possible direction.
TEST_P(OverviewFocusCyclerTest, BasicArrowKeyNavigation) {
  const size_t test_windows = 9;
  std::vector<std::unique_ptr<aura::Window>> windows;
  for (size_t i = test_windows; i > 0; --i) {
    std::unique_ptr<aura::Window> window = CreateAppWindow();
    window->SetId(i);
    windows.push_back(std::move(window));
  }

  struct TestData {
    ui::KeyboardCode key_code;
    std::string msg;
    std::vector<int> expected_ids;
  };

  // The rows contain variable number of items making vertical navigation not
  // feasible. [Down] is equivalent to [Right] and [Up] is equivalent to [Left].
  std::vector<TestData> test_data = {
      {ui::VKEY_RIGHT, "right", {1, 2, 3, 4, 5, 6, 7, 8, 9, 1}},
      {ui::VKEY_DOWN, "down", {1, 2, 3, 4, 5, 6, 7, 8, 9, 1}},
      {ui::VKEY_LEFT, "left", {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}},
      {ui::VKEY_UP, "up", {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}}};

  // In this test, the original windows are assigned id's. However, when focus
  // traversing, the window that gets focused is the overview item widget
  // window. This helper gets the id of the original window associated with
  // the current focused window, if the focused window is an overview item
  // widget window.
  auto get_id_for_focused_window =
      [](const std::vector<std::unique_ptr<OverviewItemBase>>& items) -> int {
    aura::Window* window = window_util::GetFocusedWindow();
    if (!window) {
      return aura::Window::kInitialId;
    }
    for (const auto& item : items) {
      if (window == item->item_widget()->GetNativeWindow()) {
        return item->GetWindow()->GetId();
      }
    }
    return aura::Window::kInitialId;
  };

  auto* event_generator = GetEventGenerator();
  for (const TestData& test_case : test_data) {
    SCOPED_TRACE("Using " + test_case.msg + " key.");

    ToggleOverview();
    const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
        GetOverviewItemsForRoot(0);
    std::vector<int> actual_ids;
    for (size_t i = 0; i < test_windows + 1; ++i) {
      SendKeyUntilOverviewItemIsFocused(test_case.key_code, event_generator);
      actual_ids.push_back(get_id_for_focused_window(overview_windows));
    }
    EXPECT_THAT(test_case.expected_ids, actual_ids);
    ToggleOverview();
  }
}

// Tests basic selection across multiple monitors.
TEST_P(OverviewFocusCyclerTest, BasicMultiMonitorArrowKeyNavigation) {
  UpdateDisplay("500x400,500x400");

  // Create two windows on each display.
  const gfx::Rect bounds1(100, 100);
  const gfx::Rect bounds2(550, 0, 100, 100);
  std::unique_ptr<aura::Window> window4 = CreateAppWindow(bounds2);
  std::unique_ptr<aura::Window> window3 = CreateAppWindow(bounds2);
  std::unique_ptr<aura::Window> window2 = CreateAppWindow(bounds1);
  std::unique_ptr<aura::Window> window1 = CreateAppWindow(bounds1);

  ToggleOverview();

  auto* event_generator = GetEventGenerator();
  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root1 =
      GetOverviewItemsForRoot(0);
  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root2 =
      GetOverviewItemsForRoot(1);
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_root1[0]->item_widget(), GetFocusedView()->GetWidget());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_root1[1]->item_widget(), GetFocusedView()->GetWidget());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_root2[0]->item_widget(), GetFocusedView()->GetWidget());
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(overview_root2[1]->item_widget(), GetFocusedView()->GetWidget());
}

// Tests first monitor when display order doesn't match left to right screen
// positions.
TEST_P(OverviewFocusCyclerTest, MultiMonitorReversedOrder) {
  UpdateDisplay("500x400,500x400");
  Shell::Get()->display_manager()->SetLayoutForCurrentDisplays(
      display::test::CreateDisplayLayout(display_manager(),
                                         display::DisplayPlacement::LEFT, 0));
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  std::unique_ptr<aura::Window> window2 = CreateAppWindow(gfx::Rect(100, 100));
  std::unique_ptr<aura::Window> window1 =
      CreateAppWindow(gfx::Rect(-450, 0, 100, 100));
  ASSERT_EQ(root_windows[1], window1->GetRootWindow());
  ASSERT_EQ(root_windows[0], window2->GetRootWindow());

  ToggleOverview();

  // Coming from the left to right, we should select `window1` first being on
  // the display to the left.
  auto* event_generator = GetEventGenerator();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(GetOverviewItemForWindow(window1.get())->item_widget(),
            GetFocusedView()->GetWidget());

  // Exit and reenter overview.
  ToggleOverview();
  ToggleOverview();

  // Coming from right to left, we should select window2 first being on the
  // display on the right.
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_LEFT, event_generator);
  EXPECT_EQ(GetOverviewItemForWindow(window2.get())->item_widget(),
            GetFocusedView()->GetWidget());
}

// Tests three monitors where the grid becomes empty on one of the monitors.
TEST_P(OverviewFocusCyclerTest, ThreeMonitors) {
  UpdateDisplay("500x400,500x400,500x400");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  std::unique_ptr<aura::Window> window3 =
      CreateAppWindow(gfx::Rect(1000, 0, 100, 100));
  std::unique_ptr<aura::Window> window2 =
      CreateAppWindow(gfx::Rect(500, 0, 100, 100));
  std::unique_ptr<aura::Window> window1 = CreateAppWindow(gfx::Rect(100, 100));
  EXPECT_EQ(root_windows[0], window1->GetRootWindow());
  EXPECT_EQ(root_windows[1], window2->GetRootWindow());
  EXPECT_EQ(root_windows[2], window3->GetRootWindow());

  ToggleOverview();

  auto* event_generator = GetEventGenerator();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
            GetFocusedView()->GetWidget());

  // If the selected window is closed, then something should be selected.
  // Closing a window is done on a post task.
  window3.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(GetFocusedView());
  ToggleOverview();

  window3 = CreateTestWindow(gfx::Rect(1000, 0, 100, 100));
  ToggleOverview();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_RIGHT, event_generator);

  // If the window on the second display is removed, the selected window should
  // remain window3.
  EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
            GetFocusedView()->GetWidget());
  window2.reset();
  EXPECT_EQ(GetOverviewItemForWindow(window3.get())->item_widget(),
            GetFocusedView()->GetWidget());
}

// Tests selecting a window in overview mode with the return key.
TEST_P(OverviewFocusCyclerTest, FocusOverviewWindowWithReturnKey) {
  std::unique_ptr<aura::Window> window2 = CreateAppWindow();
  std::unique_ptr<aura::Window> window1 = CreateAppWindow();
  ToggleOverview();

  // Pressing the return key on an item that is not focused should not do
  // anything.
  PressAndReleaseKey(ui::VKEY_RETURN);
  OverviewController* overview_controller = OverviewController::Get();
  EXPECT_TRUE(overview_controller->InOverviewSession());

  // Focus and select the first window.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_RETURN);
  EXPECT_FALSE(overview_controller->InOverviewSession());
  EXPECT_TRUE(wm::IsActiveWindow(window1.get()));

  // Focus and select the second window.
  ToggleOverview();
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_RETURN);
  EXPECT_FALSE(OverviewController::Get()->InOverviewSession());
  EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
}

// Tests that the location of the overview focus ring is as expected while
// dragging an overview item.
TEST_P(OverviewFocusCyclerTest, FocusLocationWhileDragging) {
  std::unique_ptr<aura::Window> window1 = CreateAppWindow();
  std::unique_ptr<aura::Window> window2 = CreateAppWindow();
  std::unique_ptr<aura::Window> window3 = CreateAppWindow();

  ToggleOverview();

  // Tab once to show the focus ring.
  auto* event_generator = GetEventGenerator();
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  OverviewItemBase* item3 = GetOverviewItemForWindow(window3.get());
  EXPECT_EQ(item3->item_widget()->GetContentsView(), GetFocusedView());

  // Tests that the there is no focused view while dragging. Drag the item in a
  // way which does not enter splitview, or close overview.
  DragItemToPoint(item3, gfx::Point(20, 20), event_generator,
                  /*by_touch_gestures=*/false, /*drop=*/false);
  EXPECT_FALSE(GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_FALSE(GetFocusedView());

  DragItemToPoint(item3, gfx::Point(300, 200), event_generator,
                  /*by_touch_gestures=*/false, /*drop=*/true);
  EXPECT_FALSE(GetFocusedView());

  // Tests that tabbing after dragging works as expected.
  SendKeyUntilOverviewItemIsFocused(ui::VKEY_TAB, event_generator);
  EXPECT_EQ(item3->item_widget()->GetContentsView(), GetFocusedView());
}

// ----------------------------------------------------------------------------
// DesksOverviewFocusCyclerTest:

class DesksOverviewFocusCyclerTest : public OverviewFocusCyclerTest {
 public:
  DesksOverviewFocusCyclerTest()
      : saved_desk_ui_revamp_enabled_(features::IsSavedDeskUiRevampEnabled()) {}
  DesksOverviewFocusCyclerTest(const DesksOverviewFocusCyclerTest&) = delete;
  DesksOverviewFocusCyclerTest& operator=(const DesksOverviewFocusCyclerTest&) =
      delete;
  ~DesksOverviewFocusCyclerTest() override = default;

  const OverviewDeskBarView* GetDesksBarViewForRoot(aura::Window* root_window) {
    OverviewGrid* grid =
        GetOverviewSession()->GetGridWithRootWindow(root_window);
    const OverviewDeskBarView* bar_view = grid->desks_bar_view();
    CHECK(bar_view->IsZeroState() ^ grid->IsDesksBarViewActive());
    return bar_view;
  }

  // OverviewFocusCyclerOldTest:
  void SetUp() override {
    OverviewFocusCyclerTest::SetUp();

    // All tests in this suite require the desks bar to be visible in overview,
    // which requires at least two desks.
    auto* desk_controller = DesksController::Get();
    desk_controller->NewDesk(DesksCreationRemovalSource::kButton);
    ASSERT_EQ(2u, desk_controller->desks().size());

    // Give the second desk a name. The desk name gets exposed as the accessible
    // name. And the focusable views that are painted in these tests will fail
    // the accessibility paint checker checks if they lack an accessible name.
    desk_controller->GetDeskAtIndex(1)->SetName(u"Desk 2", false);
  }

 protected:
  static void CheckDeskBarViewSize(const OverviewDeskBarView* view,
                                   const std::string& scope) {
    SCOPED_TRACE(scope);
    EXPECT_EQ(view->bounds().height(),
              view->GetWidget()->GetWindowBoundsInScreen().height());
  }

  const bool saved_desk_ui_revamp_enabled_;
};

// Tests that we can tab through the desk mini views, new desk button and other
// desk items in the correct order.
TEST_P(DesksOverviewFocusCyclerTest, TabbingBasic) {
  base::AutoReset<bool> disable_app_id_check =
      OverviewController::Get()->SetDisableAppIdCheckForTests();

  std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
  std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));

  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());

  CheckDeskBarViewSize(desk_bar_view, "initial");
  ASSERT_EQ(2u, desk_bar_view->mini_views().size());

  // Tests that the overview item gets focused first.
  PressAndReleaseKey(ui::VKEY_TAB);
  auto* item2 = GetOverviewItemForWindow(window2.get())
                    ->GetLeafItemForWindow(window2.get());
  EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
  CheckDeskBarViewSize(desk_bar_view, "overview item");

  // Tests that the first focused desk item is the first desk preview view.
  DeskMiniView* first_mini_view = desk_bar_view->mini_views()[0];
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(first_mini_view->desk_preview(), GetFocusedView());
  CheckDeskBarViewSize(desk_bar_view, "first mini view");

  // Tests that the context menu/combine desks and close all buttons of the
  // first desk preview is focused next.
  PressAndReleaseKey(ui::VKEY_TAB);
  const DeskActionView* desk_action_view = first_mini_view->desk_action_view();
  EXPECT_EQ(saved_desk_ui_revamp_enabled_
                ? desk_action_view->context_menu_button()
                : desk_action_view->combine_desks_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_action_view->close_all_button(), GetFocusedView());

  // Test that one more tab focuses the desks name view.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(first_mini_view->desk_name_view(), GetFocusedView());

  // Tab three times through the second mini view (it has no windows so there is
  // no combine desks button). The next tab should focus the new desk button.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());
  CheckDeskBarViewSize(desk_bar_view, "new desk button");

  // With forest, there are is no saved desk save desk container.
  if (saved_desk_ui_revamp_enabled_) {
    return;
  }

  // Tests that tabbing past the new desk button, we focus the save to a new
  // desk template. The templates button is not in the tab traversal since it is
  // hidden when we have no templates.
  if (AreDeskTemplatesEnabled()) {
    PressAndReleaseKey(ui::VKEY_TAB);
    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
              GetFocusedView());
  }

  // Tests that after the save desk as template button (if the feature was
  // enabled), focus goes to the save desk for later button.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskForLaterButton(),
            GetFocusedView());
}

// Tests that we can reverse tab through the desk mini views, new desk button
// and overview items in the correct order.
TEST_P(DesksOverviewFocusCyclerTest, TabbingReverse) {
  base::AutoReset<bool> disable_app_id_check =
      OverviewController::Get()->SetDisableAppIdCheckForTests();

  std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
  std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));

  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  ASSERT_EQ(2u, desk_bar_view->mini_views().size());

  if (!saved_desk_ui_revamp_enabled_) {
    // Tests that the first focused item when reversing is the save desk for
    // later button.
    PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskForLaterButton(),
              GetFocusedView());

    // Tests that after the save desk for later button, we get the save desk as
    // template button, if the feature is enabled.
    if (AreDeskTemplatesEnabled()) {
      PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
      EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
                GetFocusedView());
    }
  }

  // Tests that after the desks templates button (if the feature was enabled),
  // we get to the new desk button.
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());

  // Tests that after the new desk button comes the preview views, desk action
  // buttons, and the desk name views in reverse order.
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  DeskMiniView* second_mini_view = desk_bar_view->mini_views()[1];
  EXPECT_EQ(second_mini_view->desk_name_view(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(second_mini_view->desk_action_view()->close_all_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(second_mini_view->desk_preview(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  DeskMiniView* first_mini_view = desk_bar_view->mini_views()[0];
  DeskActionView* first_action_view = first_mini_view->desk_action_view();
  EXPECT_EQ(first_mini_view->desk_name_view(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(first_action_view->close_all_button(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(saved_desk_ui_revamp_enabled_
                ? first_action_view->context_menu_button()
                : first_action_view->combine_desks_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(first_mini_view->desk_preview(), GetFocusedView());

  // Tests that the next focused item when reversing is the last overview item.
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  auto* item1 = GetOverviewItemForWindow(window1.get())
                    ->GetLeafItemForWindow(window1.get());
  EXPECT_EQ(item1->overview_item_view(), GetFocusedView());

  // With forest, there are is no saved desk save desk container.
  if (saved_desk_ui_revamp_enabled_) {
    return;
  }

  // Tests that the next focused item when reversing is the save desk for later
  // button.
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskForLaterButton(),
            GetFocusedView());

  // Tests that we return to the save desk as template button after reverse
  // tabbing through the save desk for later button if the feature is enabled.
  if (AreDeskTemplatesEnabled()) {
    PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
    EXPECT_EQ(desk_bar_view->overview_grid()->GetSaveDeskAsTemplateButton(),
              GetFocusedView());
  }
}

// Tests that tabbing with desk items and multiple displays works as expected.
TEST_P(DesksOverviewFocusCyclerTest, TabbingMultiDisplay) {
  base::AutoReset<bool> disable_app_id_check =
      OverviewController::Get()->SetDisableAppIdCheckForTests();

  UpdateDisplay("600x400,600x400,600x400");
  aura::Window::Windows roots = Shell::GetAllRootWindows();
  ASSERT_EQ(3u, roots.size());

  // Create two windows on the first display, and one each on the second and
  // third displays.
  std::unique_ptr<aura::Window> window1(CreateAppWindow(gfx::Rect(200, 200)));
  std::unique_ptr<aura::Window> window2(CreateAppWindow(gfx::Rect(200, 200)));
  std::unique_ptr<aura::Window> window3(
      CreateAppWindow(gfx::Rect(600, 0, 200, 200)));
  std::unique_ptr<aura::Window> window4(
      CreateAppWindow(gfx::Rect(1200, 0, 200, 200)));
  ASSERT_EQ(roots[0], window1->GetRootWindow());
  ASSERT_EQ(roots[0], window2->GetRootWindow());
  ASSERT_EQ(roots[1], window3->GetRootWindow());
  ASSERT_EQ(roots[2], window4->GetRootWindow());

  ToggleOverview();
  const auto* desk_bar_view1 = GetDesksBarViewForRoot(roots[0]);
  EXPECT_EQ(2u, desk_bar_view1->mini_views().size());

  // Tests that tabbing initially will go through the two overview items on the
  // first display.
  PressAndReleaseKey(ui::VKEY_TAB);
  auto* item2 = GetOverviewItemForWindow(window2.get())
                    ->GetLeafItemForWindow(window2.get());
  EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  auto* item1 = GetOverviewItemForWindow(window1.get())
                    ->GetLeafItemForWindow(window1.get());
  EXPECT_EQ(item1->overview_item_view(), GetFocusedView());

  // Tests that further tabbing will go through the desk preview views, desk
  // name views, the new desk button, and finally the desks templates button on
  // the first display.
  PressAndReleaseKey(ui::VKEY_TAB);
  DeskMiniView* mini_view1 = desk_bar_view1->mini_views()[0];
  DeskActionView* action_view1 = mini_view1->desk_action_view();
  EXPECT_EQ(mini_view1->desk_preview(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(saved_desk_ui_revamp_enabled_
                ? action_view1->context_menu_button()
                : action_view1->combine_desks_button(),
            GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(action_view1->close_all_button(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(mini_view1->desk_name_view(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  DeskMiniView* mini_view2 = desk_bar_view1->mini_views()[1];
  EXPECT_EQ(mini_view2->desk_preview(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(mini_view2->desk_action_view()->close_all_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(mini_view2->desk_name_view(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_bar_view1->new_desk_button(), GetFocusedView());

  if (!saved_desk_ui_revamp_enabled_) {
    if (AreDeskTemplatesEnabled()) {
      PressAndReleaseKey(ui::VKEY_TAB);
      EXPECT_EQ(desk_bar_view1->overview_grid()->GetSaveDeskAsTemplateButton(),
                GetFocusedView());
    }
    PressAndReleaseKey(ui::VKEY_TAB);
    EXPECT_EQ(desk_bar_view1->overview_grid()->GetSaveDeskForLaterButton(),
              GetFocusedView());
  }

  // Tests that the next tab will bring us to the first overview item on the
  // second display.
  PressAndReleaseKey(ui::VKEY_TAB);
  auto* item3 = GetOverviewItemForWindow(window3.get())
                    ->GetLeafItemForWindow(window3.get());
  EXPECT_EQ(item3->overview_item_view(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  const auto* desk_bar_view2 = GetDesksBarViewForRoot(roots[1]);
  EXPECT_EQ(desk_bar_view2->mini_views()[0]->desk_preview(), GetFocusedView());

  // Tab through all items on the second display.
  SendKey(ui::VKEY_TAB, GetEventGenerator(), ui::EF_NONE, /*count=*/7);
  EXPECT_EQ(desk_bar_view2->new_desk_button(), GetFocusedView());

  if (!saved_desk_ui_revamp_enabled_) {
    if (AreDeskTemplatesEnabled()) {
      PressAndReleaseKey(ui::VKEY_TAB);
      EXPECT_EQ(desk_bar_view2->overview_grid()->GetSaveDeskAsTemplateButton(),
                GetFocusedView());
    }
    PressAndReleaseKey(ui::VKEY_TAB);
    EXPECT_EQ(desk_bar_view2->overview_grid()->GetSaveDeskForLaterButton(),
              GetFocusedView());
  }

  // Tests that after tabbing through the items on the second display, the
  // next tab will bring us to the first overview item on the third display.
  PressAndReleaseKey(ui::VKEY_TAB);
  auto* item4 = GetOverviewItemForWindow(window4.get())
                    ->GetLeafItemForWindow(window4.get());
  EXPECT_EQ(item4->overview_item_view(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_TAB);
  const auto* desk_bar_view3 = GetDesksBarViewForRoot(roots[2]);
  EXPECT_EQ(desk_bar_view3->mini_views()[0]->desk_preview(), GetFocusedView());

  // Tab through all items on the third display.
  SendKey(ui::VKEY_TAB, GetEventGenerator(), ui::EF_NONE, /*count=*/7);
  EXPECT_EQ(desk_bar_view3->new_desk_button(), GetFocusedView());

  if (!saved_desk_ui_revamp_enabled_) {
    if (AreDeskTemplatesEnabled()) {
      PressAndReleaseKey(ui::VKEY_TAB);
      EXPECT_EQ(desk_bar_view3->overview_grid()->GetSaveDeskAsTemplateButton(),
                GetFocusedView());
    }
    PressAndReleaseKey(ui::VKEY_TAB);
    EXPECT_EQ(desk_bar_view3->overview_grid()->GetSaveDeskForLaterButton(),
              GetFocusedView());
  }

  // Tests that after tabbing through the items on the third display, the next
  // tab will bring us to the first overview item on the first display.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(item2->overview_item_view(), GetFocusedView());
}

// Tests that we can tab and chromevox interchangeably through the desk mini
// views and new desk button in the correct order.
TEST_P(DesksOverviewFocusCyclerTest, TabbingChromevox) {
  Shell::Get()->accessibility_controller()->spoken_feedback().SetEnabled(true);
  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  EXPECT_EQ(2u, desk_bar_view->mini_views().size());

  auto* mini_view1 = desk_bar_view->mini_views()[0].get();
  auto* mini_view2 = desk_bar_view->mini_views()[1].get();

  // Alternate between tabbing and chromevoxing through the 2 desk preview views
  // and name views.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(mini_view1->desk_preview(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
  EXPECT_EQ(mini_view1->desk_action_view()->close_all_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
  EXPECT_EQ(mini_view1->desk_name_view(), GetFocusedView());

  PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
  EXPECT_EQ(mini_view2->desk_preview(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
  EXPECT_EQ(mini_view2->desk_action_view()->close_all_button(),
            GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(mini_view2->desk_name_view(), GetFocusedView());

  // Check for the new desk button.
  PressAndReleaseKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN);
  EXPECT_EQ(desk_bar_view->new_desk_button(), GetFocusedView());
}

TEST_P(DesksOverviewFocusCyclerTest, MiniViewAccelerator) {
  // We are initially on desk 1.
  const auto* desks_controller = DesksController::Get();
  auto& desks = desks_controller->desks();
  ASSERT_EQ(desks_controller->active_desk(), desks[0].get());

  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());

  // Use keyboard to navigate to the preview view associated with desk 2.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  ASSERT_EQ(desk_bar_view->mini_views()[1]->desk_preview(), GetFocusedView());

  // Tests that after hitting the space key on the focused preview view
  // associated with desk 2, we switch to desk 2.
  PressAndReleaseKey(ui::VKEY_SPACE);
  DeskSwitchAnimationWaiter().Wait();
  EXPECT_EQ(desks_controller->active_desk(), desks[1].get());
}

TEST_P(DesksOverviewFocusCyclerTest, CloseDeskWithMiniViewAccelerator) {
  const auto* desks_controller = DesksController::Get();
  ASSERT_EQ(2u, desks_controller->desks().size());
  auto* desk1 = desks_controller->GetDeskAtIndex(0);
  auto* desk2 = desks_controller->GetDeskAtIndex(1);
  ASSERT_EQ(desk1, desks_controller->active_desk());

  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  auto* mini_view2 = desk_bar_view->mini_views()[1].get();

  // Use keyboard to navigate to the miniview associated with desk 2.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  ASSERT_EQ(mini_view2->desk_preview(), GetFocusedView());

  // Tests that after hitting ctrl-w on the focused preview view associated with
  // `desk2`, `desk2` is destroyed.
  PressAndReleaseKey(ui::VKEY_W, ui::EF_CONTROL_DOWN);
  EXPECT_EQ(1u, desks_controller->desks().size());
  EXPECT_NE(desk2, desks_controller->GetDeskAtIndex(0));

  // Desks bar never goes back to zero state after it's initialized.
  EXPECT_FALSE(desk_bar_view->IsZeroState());
  EXPECT_FALSE(desk_bar_view->mini_views().empty());
}

TEST_P(DesksOverviewFocusCyclerTest, DeskNameView) {
  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  auto* desk_name_view_1 = desk_bar_view->mini_views()[0]->desk_name_view();

  auto* desk_1 = DesksController::Get()->GetDeskAtIndex(0);
  const std::u16string original_name = desk_1->name();

  // Tab until the desk name view of the first desk is focused. Verify that the
  // desk name is being edited.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_name_view_1, GetFocusedView());
  EXPECT_TRUE(desk_name_view_1->HasFocus());
  EXPECT_TRUE(desk_bar_view->IsDeskNameBeingModified());

  // The whole name starts off selected.
  EXPECT_TRUE(desk_name_view_1->HasSelection());
  EXPECT_EQ(original_name, desk_name_view_1->GetSelectedText());

  // Left and right arrow keys should not change neither the focus as they need
  // to move the text caret.
  PressAndReleaseKey(ui::VKEY_RIGHT);
  PressAndReleaseKey(ui::VKEY_LEFT);
  EXPECT_EQ(desk_name_view_1, GetFocusedView());
  EXPECT_TRUE(desk_name_view_1->HasFocus());

  // Tests ctrl + A and backspace to select all and delete.
  PressAndReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
  PressAndReleaseKey(ui::VKEY_BACK);
  EXPECT_EQ(u"", desk_name_view_1->GetText());

  // Type "code" into the desk name textfield. It should update, but the desk
  // name has not change.
  PressAndReleaseKey(ui::VKEY_C);
  PressAndReleaseKey(ui::VKEY_O);
  PressAndReleaseKey(ui::VKEY_D);
  PressAndReleaseKey(ui::VKEY_E);
  EXPECT_EQ(u"code", desk_name_view_1->GetText());
  EXPECT_EQ(original_name, desk_1->name());

  // Tests that pressing tab will advance focus and commit the desk name
  // changes.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_FALSE(desk_name_view_1->HasFocus());
  EXPECT_EQ(u"code", desk_1->name());
  EXPECT_TRUE(desk_1->is_name_set_by_user());
}

TEST_P(DesksOverviewFocusCyclerTest, RemoveDeskWhileNameFocused) {
  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  auto* desk_name_view_1 = desk_bar_view->mini_views()[0]->desk_name_view();

  // Tab until the desk name view of the first desk is focused.
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desk_name_view_1, GetFocusedView());

  // Desks bar never goes back to zero state after it's initialized.
  const auto* desks_controller = DesksController::Get();
  auto* desk_1 = desks_controller->GetDeskAtIndex(0);
  RemoveDesk(desk_1);
  RunScheduledLayoutForAllOverviewDeskBars();
  EXPECT_EQ(nullptr, GetFocusedView());
  EXPECT_FALSE(desk_bar_view->IsZeroState());

  // Tabbing again should cause no crashes.
  PressAndReleaseKey(ui::VKEY_TAB);
  RunScheduledLayoutForAllOverviewDeskBars();
  EXPECT_EQ(desk_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());
}

// Tests the overview focus cycler behavior when a user uses the new desk
// button.
TEST_P(DesksOverviewFocusCyclerTest, NewDesksWithKeyboard) {
  // Make sure the display is large enough to hold the max number of desks.
  UpdateDisplay("1200x800");

  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  ASSERT_FALSE(desk_bar_view->IsZeroState());
  const views::LabelButton* new_desk_button = desk_bar_view->new_desk_button();
  const auto* desks_controller = DesksController::Get();

  auto check_name_view_at_index = [this, desks_controller](
                                      const auto* desk_bar_view, int index) {
    const auto* desk_name_view =
        desk_bar_view->mini_views()[index]->desk_name_view();
    EXPECT_TRUE(desk_name_view->HasFocus());
    if (desks_controller->CanCreateDesks()) {
      EXPECT_EQ(desk_name_view, GetFocusedView());
    }
    EXPECT_EQ(std::u16string(), desk_name_view->GetText());
  };

  // Tab seven times, three times for each desk (preview, close button, name),
  // and then one more time to focus the new desk button.
  for (int i = 0; i < 7; ++i) {
    PressAndReleaseKey(ui::VKEY_TAB);
  }
  ASSERT_EQ(new_desk_button, GetFocusedView());

  // Keep adding new desks until we reach the maximum allowed amount. Verify the
  // amount of desks is indeed the maximum allowed and that the new desk button
  // is disabled.
  while (desks_controller->CanCreateDesks()) {
    PressAndReleaseKey(ui::VKEY_SPACE);
    RunScheduledLayoutForAllOverviewDeskBars();
    check_name_view_at_index(desk_bar_view,
                             desks_controller->desks().size() - 1);
    PressAndReleaseKey(ui::VKEY_TAB);
  }
  EXPECT_FALSE(new_desk_button->GetEnabled());
  EXPECT_EQ(desks_util::GetMaxNumberOfDesks(),
            desks_controller->desks().size());
}

TEST_P(DesksOverviewFocusCyclerTest, ZeroStateOfDesksBar) {
  ToggleOverview();
  auto* desks_bar_view = GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  ASSERT_FALSE(desks_bar_view->IsZeroState());
  ASSERT_EQ(2u, desks_bar_view->mini_views().size());

  // Remove one desk to enter zero state desks bar.
  auto* mini_view = desks_bar_view->mini_views()[1].get();
  GetEventGenerator()->MoveMouseTo(
      mini_view->GetBoundsInScreen().CenterPoint());
  EXPECT_TRUE(GetDeskActionVisibilityForMiniView(mini_view));
  LeftClickOn(GetCloseDeskButtonForMiniView(mini_view));

  // Desks bar never goes back to zero state after it's initialized.
  ASSERT_FALSE(desks_bar_view->IsZeroState());

  // Exit and reenter overview to show the zero state desks bar.
  ToggleOverview();
  ToggleOverview();
  ASSERT_TRUE(OverviewController::Get()->InOverviewSession());

  // Tab through and verify the zero state desk bar views.
  desks_bar_view = GetOverviewSession()
                       ->GetGridWithRootWindow(Shell::GetPrimaryRootWindow())
                       ->desks_bar_view();
  ASSERT_TRUE(desks_bar_view->IsZeroState());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desks_bar_view->default_desk_button(), GetFocusedView());
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_EQ(desks_bar_view->new_desk_button(), GetFocusedView());

  // Test that when we create a new desk, we focus the desk name view of that
  // desk.
  PressAndReleaseKey(ui::VKEY_SPACE);
  EXPECT_EQ(desks_bar_view->mini_views()[1]->desk_name_view(),
            GetFocusedView());
}

TEST_P(DesksOverviewFocusCyclerTest, ClickingNameViewMovesFocus) {
  ToggleOverview();
  const auto* desk_bar_view =
      GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  CheckDeskBarViewSize(desk_bar_view, "initial");
  ASSERT_EQ(2u, desk_bar_view->mini_views().size());

  // Tab to first mini desk view's preview view.
  PressAndReleaseKey(ui::VKEY_TAB);
  ASSERT_EQ(desk_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());
  CheckDeskBarViewSize(desk_bar_view, "tabbed once");

  // Click on the second mini desk item's name view.
  auto* event_generator = GetEventGenerator();
  auto* desk_name_view_1 = desk_bar_view->mini_views()[1]->desk_name_view();
  event_generator->MoveMouseTo(
      desk_name_view_1->GetBoundsInScreen().CenterPoint());
  event_generator->ClickLeftButton();
  EXPECT_FALSE(desk_bar_view->IsZeroState());

  // Verify that focus has moved to the clicked desk item.
  EXPECT_EQ(desk_name_view_1, GetFocusedView());
}

// Tests that there is no crash when tabbing after we switch to the zero state
// desks bar. Regression test for https://crbug.com/1301134.
TEST_P(DesksOverviewFocusCyclerTest, SwitchingToZeroStateWhileTabbing) {
  ToggleOverview();
  auto* desks_bar_view = GetDesksBarViewForRoot(Shell::GetPrimaryRootWindow());
  ASSERT_FALSE(desks_bar_view->IsZeroState());
  ASSERT_EQ(2u, desks_bar_view->mini_views().size());

  // Tab to first mini desk view's preview view.
  PressAndReleaseKey(ui::VKEY_TAB);
  ASSERT_EQ(desks_bar_view->mini_views()[0]->desk_preview(), GetFocusedView());

  // Remove one desk to have only one desk left.
  auto* mini_view = desks_bar_view->mini_views()[1].get();
  GetEventGenerator()->MoveMouseTo(
      mini_view->GetBoundsInScreen().CenterPoint());
  ASSERT_TRUE(GetDeskActionVisibilityForMiniView(mini_view));
  LeftClickOn(GetCloseDeskButtonForMiniView(mini_view));

  // Desks bar never goes back to zero state after it's initialized.
  ASSERT_FALSE(desks_bar_view->IsZeroState());

  // Try tabbing after removing the second desk triggers us to transition to
  // zero state desks bar. There should not be a crash.
  PressAndReleaseKey(ui::VKEY_TAB);
}

INSTANTIATE_TEST_SUITE_P(All, OverviewFocusCyclerTest, testing::Bool());
INSTANTIATE_TEST_SUITE_P(All, DesksOverviewFocusCyclerTest, testing::Bool());

}  // namespace ash