kiosk: browsertest for OnAddGuestView

Add browser tests for web and chrome app kiosks to cover
KioskSystemSession::OnAddGuestView().

Bug: b/352490540
Test: browser_tests --gtest_filter="*KioskGuestViewTest*"
Change-Id: I8f9cd802f48469774b6a9419ebf38414414ff141
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5724352
Reviewed-by: Edman Anjos <edman@chromium.org>
Auto-Submit: Polina Bondarenko <pbond@chromium.org>
Commit-Queue: Polina Bondarenko <pbond@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1332942}
diff --git a/chrome/browser/ash/app_mode/BUILD.gn b/chrome/browser/ash/app_mode/BUILD.gn
index 05d26f4..3e7e889 100644
--- a/chrome/browser/ash/app_mode/BUILD.gn
+++ b/chrome/browser/ash/app_mode/BUILD.gn
@@ -240,6 +240,7 @@
     "kiosk_app_update_service_browsertest.cc",
     "kiosk_chrome_app_manager_browsertest.cc",
     "kiosk_crash_restore_browsertest.cc",
+    "kiosk_guest_view_browsertest.cc",
     "kiosk_system_web_app_browsertest.cc",
     "kiosk_troubleshooting_tools_browsertest.cc",
   ]
diff --git a/chrome/browser/ash/app_mode/kiosk_guest_view_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_guest_view_browsertest.cc
new file mode 100644
index 0000000..7a0972aa
--- /dev/null
+++ b/chrome/browser/ash/app_mode/kiosk_guest_view_browsertest.cc
@@ -0,0 +1,153 @@
+// 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 "apps/test/app_window_waiter.h"
+#include "base/check_deref.h"
+#include "chrome/browser/ash/app_mode/kiosk_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h"
+#include "chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h"
+#include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/login/test/login_manager_mixin.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/guest_view/browser/guest_view.h"
+#include "components/guest_view/browser/guest_view_manager_delegate.h"
+#include "components/guest_view/browser/test_guest_view_manager.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "extensions/browser/api/extensions_api_client.h"
+#include "extensions/browser/app_window/app_window.h"
+#include "extensions/browser/guest_view/web_view/web_view_guest.h"
+
+namespace ash {
+
+namespace {
+
+void NotifyKioskGuestAdded(content::WebContents* guest_web_contents) {
+  KioskSystemSession* system_session =
+      KioskController::Get().GetKioskSystemSession();
+  ASSERT_NE(system_session, nullptr);
+  system_session->OnGuestAdded(guest_web_contents);
+}
+
+Profile& GetProfile() {
+  return CHECK_DEREF(ProfileManager::GetPrimaryUserProfile());
+}
+
+void OpenWebUiWithGuestView() {
+  // Enable troubleshooting tools to access a Web Ui page with `<webview>` tag.
+  // Note: `<webview>` is a restricted tag and triggers guest view creation only
+  // for Chrome apps and allowlisted WebUi pages.
+  GetProfile().GetPrefs()->SetBoolean(prefs::kKioskTroubleshootingToolsEnabled,
+                                      true);
+
+  // Navigate to the WebUi page allowlisted here
+  // extensions/common/api/_api_features.json.
+  GURL signin_url{"chrome://chrome-signin/?reason=5"};
+  Browser::CreateParams params =
+      Browser::CreateParams(Browser::Type::TYPE_NORMAL,
+                            /*profile=*/&GetProfile(),
+                            /*user_gesture=*/true);
+  auto& new_browser = CHECK_DEREF(Browser::Create(params));
+  new_browser.window()->Show();
+  ui_test_utils::NavigateToURLWithDisposition(
+      &new_browser, signin_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+}
+
+guest_view::TestGuestViewManager& GetGuestViewManager(
+    guest_view::TestGuestViewManagerFactory& factory) {
+  return CHECK_DEREF(factory.GetOrCreateTestGuestViewManager(
+      &GetProfile(), extensions::ExtensionsAPIClient::Get()
+                         ->CreateGuestViewManagerDelegate()));
+}
+
+}  // namespace
+
+class WebKioskGuestViewBrowserTest : public WebKioskBaseTest {
+ public:
+  WebKioskGuestViewBrowserTest() = default;
+  WebKioskGuestViewBrowserTest(const WebKioskGuestViewBrowserTest&) = delete;
+  WebKioskGuestViewBrowserTest& operator=(const WebKioskGuestViewBrowserTest&) =
+      delete;
+
+  ~WebKioskGuestViewBrowserTest() override = default;
+
+ protected:
+  void SetUpOnMainThread() override {
+    WebKioskBaseTest::SetUpOnMainThread();
+    InitializeRegularOnlineKiosk();
+  }
+
+  guest_view::TestGuestViewManagerFactory& factory() { return factory_; }
+
+ private:
+  guest_view::TestGuestViewManagerFactory factory_;
+};
+
+IN_PROC_BROWSER_TEST_F(WebKioskGuestViewBrowserTest,
+                       AddingGuestViewDoesNotCrash) {
+  EXPECT_EQ(0ULL, GetGuestViewManager(factory()).GetCurrentGuestCount());
+  OpenWebUiWithGuestView();
+
+  auto* guest_view =
+      GetGuestViewManager(factory()).WaitForSingleGuestViewCreated();
+  ASSERT_NE(guest_view, nullptr);
+  ASSERT_NE(guest_view->web_contents(), nullptr);
+  EXPECT_NO_FATAL_FAILURE(NotifyKioskGuestAdded(guest_view->web_contents()));
+}
+
+class ChromeAppKioskGuestViewBrowserTest : public KioskBaseTest {
+ public:
+  ChromeAppKioskGuestViewBrowserTest() = default;
+  ChromeAppKioskGuestViewBrowserTest(
+      const ChromeAppKioskGuestViewBrowserTest&) = delete;
+  ChromeAppKioskGuestViewBrowserTest& operator=(
+      const ChromeAppKioskGuestViewBrowserTest&) = delete;
+
+  ~ChromeAppKioskGuestViewBrowserTest() override = default;
+
+ protected:
+  void LaunchApp() {
+    StartAppLaunchFromLoginScreen(NetworkStatus::kOnline);
+    WaitForAppLaunchWithOptions(/*check_launch_data=*/true,
+                                /*terminate_app=*/false,
+                                /*keep_app_open=*/true);
+  }
+
+  content::WebContents* WaitForAppWindowWebContents() {
+    extensions::AppWindowRegistry* app_window_registry =
+        extensions::AppWindowRegistry::Get(&GetProfile());
+    extensions::AppWindow& window = CHECK_DEREF(
+        apps::AppWindowWaiter(app_window_registry, test_app_id()).Wait());
+    return window.web_contents();
+  }
+
+  guest_view::TestGuestViewManagerFactory& factory() { return factory_; }
+
+ private:
+  ash::DeviceStateMixin device_state_{
+      &mixin_host_,
+      ash::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
+  LoginManagerMixin login_manager_{
+      &mixin_host_,
+      {{LoginManagerMixin::TestUserInfo{test_owner_account_id_}}}};
+
+  guest_view::TestGuestViewManagerFactory factory_;
+};
+
+IN_PROC_BROWSER_TEST_F(ChromeAppKioskGuestViewBrowserTest,
+                       AddingGuestViewDoesNotCrash) {
+  LaunchApp();
+  EXPECT_EQ(0ULL, GetGuestViewManager(factory()).GetCurrentGuestCount());
+  OpenWebUiWithGuestView();
+  auto* guest_view =
+      GetGuestViewManager(factory()).WaitForSingleGuestViewCreated();
+  ASSERT_NE(guest_view, nullptr);
+  ASSERT_NE(guest_view->web_contents(), nullptr);
+  EXPECT_NO_FATAL_FAILURE(NotifyKioskGuestAdded(guest_view->web_contents()));
+}
+
+}  // namespace ash