chromium/chrome/browser/ui/ash/shelf/shelf_integration_test.cc

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

#include <memory>

#include "ash/public/cpp/shelf_model.h"
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_app_button.h"
#include "ash/shelf/shelf_view_test_api.h"
#include "ash/shell.h"
#include "ash/wm/window_util.h"
#include "base/test/gtest_tags.h"
#include "chrome/browser/ash/file_manager/app_id.h"
#include "chrome/browser/ui/ash/shelf/shelf_context_menu.h"
#include "chrome/browser/web_applications/web_app_id_constants.h"
#include "chrome/test/base/chromeos/crosier/ash_integration_test.h"
#include "chrome/test/base/chromeos/crosier/aura_window_title_observer.h"
#include "components/app_constants/constants.h"
#include "content/public/test/browser_test.h"
#include "ui/aura/env.h"
#include "ui/aura/test/find_window.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/gfx/geometry/rect.h"

namespace ash {
namespace {

// The title of a window at the new tab page varies based on branding.
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
const char16_t kBrowserWindowTitle[] = u"Chrome - New Tab";
#else
const char16_t kBrowserWindowTitle[] = u"Chromium - New Tab";
#endif

class ShelfIntegrationTest : public AshIntegrationTest {
 public:
  ShelfIntegrationTest()
      : zero_duration_scoped_animation_scale_mode_(
            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) {}

  ~ShelfIntegrationTest() override = default;

 private:
  // Ensure shelf icon positions are stable. This needs to be created before the
  // test starts for the shelf view's bounds animator.
  ui::ScopedAnimationDurationScaleMode
      zero_duration_scoped_animation_scale_mode_;
};

IN_PROC_BROWSER_TEST_F(ShelfIntegrationTest, OpenCloseSwitchApps) {
  base::AddFeatureIdTagToTestResult(
      "screenplay-441c1034-bfff-42c0-ad81-79332c9e2304");

  SetupContextWidget();

  InstallSystemApps();  // For files app.

  // Get the primary display's shelf view.
  Shelf* shelf = Shell::GetPrimaryRootWindowController()->shelf();
  ASSERT_TRUE(shelf);
  ShelfView* shelf_view = shelf->GetShelfViewForTesting();
  ASSERT_TRUE(shelf_view);
  ShelfViewTestAPI test_api(shelf_view);

  // The shelf starts with at least the browser and Files apps pinned. Some
  // builds also have the Discover app, but not all.
  ASSERT_GE(test_api.GetButtonCount(), 2u);
  auto* shelf_model = ShelfModel::Get();
  ASSERT_TRUE(shelf_model->IsAppPinned(app_constants::kChromeAppId));
  ASSERT_TRUE(shelf_model->IsAppPinned(file_manager::kFileManagerSwaAppId));

  ShelfAppButton* chrome_button = test_api.GetButton(0);
  ASSERT_TRUE(chrome_button);
  ShelfAppButton* files_app_button = test_api.GetButton(1);
  ASSERT_TRUE(files_app_button);

  aura::Env* env = aura::Env::GetInstance();
  ASSERT_TRUE(env);

  // Define our own AuraWindowTitleObservers because we wait for window titles
  // more than once, and hence can't use the WaitForWindowWithTitle() helper.
  DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(AuraWindowTitleObserver,
                                      kBrowserTitleObserver);
  DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(AuraWindowTitleObserver,
                                      kFilesAppTitleObserver);

  RunTestSequence(
      Log("Clicking the chrome shelf button"),
      ObserveState(
          kBrowserTitleObserver,
          std::make_unique<AuraWindowTitleObserver>(env, kBrowserWindowTitle)),
      MoveMouseTo(chrome_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(),

      Log("Waiting for Chrome window to open"),
      WaitForState(kBrowserTitleObserver, true),

      Log("Clicking the files app shelf button"),
      ObserveState(kFilesAppTitleObserver,
                   std::make_unique<AuraWindowTitleObserver>(env, u"Files")),
      MoveMouseTo(files_app_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(),

      Log("Waiting for files app window to open"),
      WaitForState(kFilesAppTitleObserver, true),

      // Wait for files app to move to foreground.

      Log("Clicking the chrome shelf button again"),
      MoveMouseTo(chrome_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(),

      Log("Verifying the browser window is activated"), Check([&]() {
        aura::Window* browser_window =
            aura::test::FindWindowWithTitle(env, kBrowserWindowTitle);
        CHECK(browser_window);
        aura::Window* active_window = window_util::GetActiveWindow();
        CHECK(active_window);
        return browser_window == active_window;
      }),

      Log("Clicking the files app shelf button again"),
      MoveMouseTo(files_app_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(),

      Log("Verifying the files app window is activated"), Check([&]() {
        aura::Window* files_window =
            aura::test::FindWindowWithTitle(env, u"Files");
        CHECK(files_window);
        aura::Window* active_window = window_util::GetActiveWindow();
        CHECK(active_window);
        return files_window == active_window;
      }),

      Log("Closing Chrome via right-click menu"),
      MoveMouseTo(chrome_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(ui_controls::RIGHT), SelectMenuItem(kShelfCloseMenuItem),

      Log("Verifying the browser window is gone"), Check([&]() {
        return !aura::test::FindWindowWithTitle(env, kBrowserWindowTitle);
      }),

      Log("Closing files app via right-click menu"),
      MoveMouseTo(files_app_button->GetBoundsInScreen().CenterPoint()),
      ClickMouse(ui_controls::RIGHT), SelectMenuItem(kShelfCloseMenuItem),

      Log("Verifying the files app window is gone"),
      Check([&]() { return !aura::test::FindWindowWithTitle(env, u"Files"); }),

      Log("Test completed"));
}

}  // namespace
}  // namespace ash