#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>
#include "base/base64.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/repeating_test_future.h"
#include "base/test/with_feature_override.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/accessibility/accessibility_state_utils.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/pdf/pdf_extension_test_base.h"
#include "chrome/browser/pdf/pdf_extension_test_util.h"
#include "chrome/browser/pdf/test_pdf_viewer_stream_manager.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_user_data.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/tabs/public/tab_features.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toasts/toast_controller.h"
#include "chrome/browser/ui/toasts/toast_features.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_command_scheduler.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_render_frame.mojom.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/mixin_based_in_process_browser_test.h"
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/supervised_user/embedded_test_server_setup_mixin.h"
#include "chrome/test/supervised_user/supervision_mixin.h"
#include "components/compose/buildflags.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/lens/buildflags.h"
#include "components/lens/lens_features.h"
#include "components/lens/lens_metadata.mojom.h"
#include "components/lens/lens_testing_utils.h"
#include "components/pdf/browser/pdf_frame_util.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_attestations/privacy_sandbox_attestations.h"
#include "components/privacy_sandbox/privacy_sandbox_attestations/scoped_privacy_sandbox_attestations.h"
#include "components/search_engines/template_url_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/supervised_user/core/browser/supervised_user_preferences.h"
#include "components/supervised_user/core/browser/supervised_user_service.h"
#include "components/supervised_user/core/browser/supervised_user_url_filter.h"
#include "components/supervised_user/core/common/pref_names.h"
#include "components/supervised_user/core/common/supervised_user_constants.h"
#include "components/supervised_user/test_support/kids_management_api_server_mock.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "components/webapps/browser/uninstall_result_code.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/context_menu_params.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "net/base/load_flags.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_util.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "pdf/buildflags.h"
#include "pdf/pdf_features.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/context_menu_data/context_menu_data.h"
#include "third_party/blink/public/common/context_menu_data/edit_flags.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/page_state/page_state.h"
#include "third_party/blink/public/common/page_state/page_state_serialization.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
#include "third_party/libwebp/src/src/webp/decode.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/emoji/emoji_panel_helper.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#if BUILDFLAG(ENABLE_COMPOSE)
#include "chrome/browser/compose/mock_chrome_compose_client.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ui/chromeos/window_pin_util.h"
#include "ui/aura/window.h"
#endif
#if defined(USE_AURA)
#include "ui/aura/window.h"
#endif
#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
#include "base/test/run_until.h"
#include "chrome/browser/ui/lens/lens_overlay_controller.h"
#include "chrome/browser/ui/views/lens/lens_side_panel_helper.h"
#include "components/lens/lens_overlay_permission_utils.h"
#include "ui/events/test/event_generator.h"
#endif
WebContents;
MimeHandlerViewGuest;
TestMimeHandlerViewGuest;
WebAppProvider;
AppId;
_;
Return;
TestWithParam;
namespace {
const char kAppUrl1[] = …;
const char kAppUrl2[] = …;
class AllowPreCommitInputFlagMixin : public InProcessBrowserTestMixin { … };
class ContextMenuBrowserTestBase : public MixinBasedInProcessBrowserTest { … };
class ContextMenuBrowserTest
: public ContextMenuBrowserTestBase,
public ::testing::WithParamInterface< bool> { … };
INSTANTIATE_TEST_SUITE_P(…);
class PdfPluginContextMenuBrowserTest : public PDFExtensionTestBase { … };
class PdfPluginContextMenuBrowserTestWithOopifOverride
: public base::test::WithFeatureOverride,
public PdfPluginContextMenuBrowserTest { … };
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
NonExtensionMenuItemsAlwaysVisible) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
SaveLinkAsEntryIsDisabledForBlockedUrls) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
SaveAsEntryIsDisabledForBlockedUrls) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
SaveAsEntryIsNotDisabledForNonBlockedUrls) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
SaveImageAsEntryIsDisabledForBlockedUrls) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
SaveVideoAsEntryIsDisabledForBlockedUrls) { … }
class ContextMenuForSupervisedUsersBrowserTest
: public ContextMenuBrowserTestBase { … };
IN_PROC_BROWSER_TEST_F(ContextMenuForSupervisedUsersBrowserTest,
SaveLinkAsEntryIsDisabledForUrlsNotAccessibleForChild) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuForSupervisedUsersBrowserTest,
SaveLinkAsEntryIsDisabledForUrlsBlockedByAsyncCheckerForChild) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuForSupervisedUsersBrowserTest,
SaveLinkAsEntryIsEnabledForUrlsAllowedByAsyncCheckerForChild) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuEntriesAreDisabledInLockedFullscreen) {
int entries_to_test[] = {
IDC_VIEW_SOURCE,
IDC_CONTENT_CONTEXT_OPENLINKNEWTAB,
IDC_CONTENT_CONTEXT_INSPECTELEMENT,
};
std::unique_ptr<TestRenderViewContextMenu> menu =
CreateContextMenuMediaTypeNone(GURL("http://www.google.com/"),
GURL("http://www.google.com/"));
for (auto entry : entries_to_test)
EXPECT_TRUE(menu->IsCommandIdEnabled(entry));
PinWindow(browser()->window()->GetNativeWindow(), true);
for (auto entry : entries_to_test)
EXPECT_FALSE(menu->IsCommandIdEnabled(entry));
}
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenEntryPresentForNormalURLs) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenInAppPresentForURLsInScopeOfWebApp) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenInAppAbsentForURLsInScopeOfNonWindowedWebApp) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenEntryInAppAbsentForURLsOutOfScopeOfWebApp) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenInAppAbsentForURLsInNonLocallyInstalledApp) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
InAppOpenEntryPresentForRegularURLs) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenInAppAbsentForIncognito) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
InAppOpenEntryPresentForSameAppURLs) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
InAppOpenEntryPresentForOtherAppURLs) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenEntryAbsentForFilteredURLs) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, ContextMenuForCanvas) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForEmojiPanel_Editable) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForEmojiPanel_NonEditable) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, ShowsToastOnLinkCopied) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, ShowsToastOnImageCopied) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForEmojiPanel_NullBrowserCrash) {
ui::SetShowEmojiKeyboardCallback(base::BindLambdaForTesting(
[](ui::EmojiPickerCategory unused, ui::EmojiPickerFocusBehavior,
const std::string&) { ui::ShowTabletModeEmojiPanel(); }));
std::unique_ptr<content::WebContents> detached_web_contents =
content::WebContents::Create(
content::WebContents::CreateParams(browser()->profile()));
TestRenderViewContextMenu menu(*detached_web_contents->GetPrimaryMainFrame(),
{});
menu.Init();
menu.ExecuteCommand(IDC_CONTENT_CONTEXT_EMOJI, 0);
}
#else
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForEmojiPanel_NullBrowserCrash) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForEmojiPanel_NoCallback) {
ui::SetShowEmojiKeyboardCallback(
base::RepeatingCallback<void(ui::EmojiPickerCategory,
ui::EmojiPickerFocusBehavior,
const std::string&)>());
content::ContextMenuParams params;
params.is_editable = true;
auto menu = CreateContextMenuFromParams(params);
EXPECT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_EMOJI));
}
#endif
#if BUILDFLAG(ENABLE_COMPOSE)
struct ContextMenuForComposeTestCase { … };
class ContextMenuForComposeBrowserTest
: public ContextMenuBrowserTestBase,
public ::testing::WithParamInterface<ContextMenuForComposeTestCase> { … };
IN_PROC_BROWSER_TEST_P(ContextMenuForComposeBrowserTest,
TestComposeItemPresent) { … }
INSTANTIATE_TEST_SUITE_P(…);
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, CopyLinkTextMouse) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, CopyLinkTextTouchNoText) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, CopyLinkTextTouchTextOnly) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, CopyLinkTextTouchTextImage) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, RealMenu) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenNewTabInChromeFromWebAppWithAnOpenBrowser) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
OpenNewTabInChromeFromWebAppWithoutAnOpenBrowser) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenAboutBlankInNewTab) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenDataURLInNewTab) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenInNewTabReferrer) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenIncognitoNoneReferrer) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, SuggestedFileName) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
MenuContentsVerification_MainFrame) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
MenuContentsVerification_Subframe) { … }
#if !BUILDFLAG(IS_MAC)
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
NonLocatedContextMenuOnLargeImageElement) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
NonLocatedContextMenuOnAnchorElement) { … }
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, SuggestedFileNameCrossOrigin) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenImageInNewTab) { … }
#if !BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenLinkInProfileEntryPresent) { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_LINUX)
#define MAYBE_OpenLinkInProfile …
#else
#define MAYBE_OpenLinkInProfile …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_OpenLinkInProfile) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenProfileNoneReferrer) { … }
#endif
class InterestGroupContentBrowserClient : public ChromeContentBrowserClient { … };
class ContextMenuFencedFrameTest : public ContextMenuBrowserTestBase { … };
#if BUILDFLAG(IS_MAC)
#define MAYBE_MenuContentsVerification_Fencedframe …
#else
#define MAYBE_MenuContentsVerification_Fencedframe …
#endif
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
MAYBE_MenuContentsVerification_Fencedframe) { … }
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
SaveLinkAsEntryIsDisabledAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuFencedFrameTest,
SaveLinkAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
SaveAudioAsEntryIsDisabledAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuFencedFrameTest,
SaveAudioAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
SaveVideoAsEntryIsDisabledAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuFencedFrameTest,
SaveVideoAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
SaveImageAsEntryIsDisabledAfterNetworkCutoff) { … }
IN_PROC_BROWSER_TEST_F(
ContextMenuFencedFrameTest,
SaveImageAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) { … }
class ContextMenuFencedFrameTestNoTestingConfig
: public ContextMenuFencedFrameTest { … };
IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTestNoTestingConfig,
AutomaticBeaconSentAfterContextMenuNavigation) { … }
#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
class SearchByRegionBrowserBaseTest : public InProcessBrowserTest {
protected:
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
CreateAndSetEventGenerator();
}
void CreateAndSetEventGenerator() {
gfx::NativeWindow window = browser()->window()->GetNativeWindow();
#if defined(USE_AURA)
window = window->GetRootWindow();
#endif
event_generator_ = std::make_unique<ui::test::EventGenerator>(window);
event_generator_->set_target(ui::test::EventGenerator::Target::APPLICATION);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
}
void SetupAndLoadPage(const std::string& page_path) {
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), GURL(embedded_test_server()->GetURL(page_path))));
}
void AttemptFullscreenLensRegionSearch() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, 0,
base::BindOnce(
&SearchByRegionBrowserBaseTest::SimulateDragAndVerifyOverlayUI,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
void AttemptLensRegionSearchNewTab() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, ui::EF_MOUSE_BUTTON,
base::BindOnce(
&SearchByRegionBrowserBaseTest::SimulateDragAndVerifyOverlayUI,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
void AttemptNonGoogleRegionSearch() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_WEB_REGION_SEARCH, ui::EF_MOUSE_BUTTON,
base::BindOnce(
&SearchByRegionBrowserBaseTest::SimulateDragAndVerifyOverlayUI,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
GURL GetNonGoogleRegionSearchURL() {
static const char kImageSearchURL[] = "/imagesearch";
return embedded_test_server()->GetURL(kImageSearchURL);
}
GURL GetLensRegionSearchURL() {
static const std::string kLensRegionSearchURL =
lens::features::GetHomepageURLForLens() + "upload?ep=crs";
return GURL(kLensRegionSearchURL);
}
void RightClickToOpenContextMenu() {
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
content::SimulateMouseClick(tab, 0, blink::WebMouseEvent::Button::kRight);
}
void SimulateDrag() {
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
gfx::Point center = tab->GetContainerBounds().CenterPoint();
event_generator_->MoveMouseTo(center);
event_generator_->DragMouseBy(100, 100);
}
void SimulateDragAndVerifyOverlayUI(RenderViewContextMenu* menu) {
lens::LensRegionSearchController* controller =
menu->GetLensRegionSearchControllerForTesting();
ASSERT_NE(controller, nullptr);
ASSERT_TRUE(controller->IsOverlayUIVisibleForTesting());
SimulateDrag();
ASSERT_FALSE(controller->IsOverlayUIVisibleForTesting());
}
void AssertOverlayUIHidden(RenderViewContextMenu* menu) {
lens::LensRegionSearchController* controller =
menu->GetLensRegionSearchControllerForTesting();
ASSERT_NE(controller, nullptr);
ASSERT_FALSE(controller->IsOverlayUIVisibleForTesting());
}
void VerifyLensUrl(std::string content, std::string expected_content) {
std::size_t query_start_pos = content.find("?");
EXPECT_THAT(content,
testing::MatchesRegex(
expected_content.substr(0, query_start_pos) +
".*ep=crs&re=dcsp&s=4&st=\\d+&lm=.+&sideimagesearch=1"));
if (quit_closure_)
quit_closure_.Run();
}
void ExpectThatRequestContainsImageData(content::WebContents* web_contents) {
auto* last_entry = web_contents->GetController().GetLastCommittedEntry();
EXPECT_TRUE(last_entry);
EXPECT_TRUE(last_entry->GetHasPostData());
std::string post_data = last_entry->GetPageState().ToEncodedData();
std::string image_bytes = lens::GetImageBytesFromEncodedPostData(post_data);
EXPECT_FALSE(image_bytes.empty());
}
void SetupNonGoogleRegionSearchEngine(
bool with_side_image_search_param = true) {
static const char16_t kShortName[] = u"test";
static const char kRegionSearchPostParams[] =
"thumb={google:imageThumbnail}";
TemplateURLService* model =
TemplateURLServiceFactory::GetForProfile(browser()->profile());
ASSERT_NE(model, nullptr);
search_test_utils::WaitForTemplateURLServiceToLoad(model);
ASSERT_TRUE(model->loaded());
TemplateURLData data;
data.SetShortName(kShortName);
data.SetKeyword(data.short_name());
data.SetURL(GetNonGoogleRegionSearchURL().spec());
data.image_url = GetNonGoogleRegionSearchURL().spec();
data.image_url_post_params = kRegionSearchPostParams;
if (with_side_image_search_param)
data.side_image_search_param = "sideimagesearch";
TemplateURL* template_url = model->Add(std::make_unique<TemplateURL>(data));
ASSERT_TRUE(template_url);
model->SetUserSelectedDefaultSearchProvider(template_url);
}
void TearDownInProcessBrowserTestFixture() override {
menu_observer_.reset();
event_generator_.reset();
}
std::unique_ptr<ui::test::EventGenerator> event_generator_;
std::unique_ptr<ContextMenuNotificationObserver> menu_observer_;
base::RepeatingClosure quit_closure_;
};
class SearchByRegionWithUnifiedSidePanelBrowserTest
: public SearchByRegionBrowserBaseTest {
protected:
void SetUp() override {
ASSERT_TRUE(embedded_test_server()->Start());
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeaturesAndParameters(
{
{lens::features::kLensStandalone,
{{lens::features::kHomepageURLForLens.name,
GetLensRegionSearchURL().spec()}}},
},
{});
InProcessBrowserTest::SetUp();
}
void SimulateFullscreenSearchAndVerifyLensUrl(RenderViewContextMenu* menu) {
AssertOverlayUIHidden(menu);
content::WebContents* contents =
GetLensUnifiedSidePanelWebContentsAfterNavigation();
std::string expected_content = GetLensRegionSearchURL().GetContent();
std::string side_panel_content =
contents->GetLastCommittedURL().GetContent();
VerifyLensUrl(side_panel_content, expected_content);
}
void SimulateDragAndVerifyLensRequest(RenderViewContextMenu* menu) {
SearchByRegionBrowserBaseTest::SimulateDragAndVerifyOverlayUI(menu);
content::WebContents* contents =
GetLensUnifiedSidePanelWebContentsAfterNavigation();
std::string expected_content = GetLensRegionSearchURL().GetContent();
std::string side_panel_content =
contents->GetLastCommittedURL().GetContent();
VerifyLensUrl(side_panel_content, expected_content);
ExpectThatRequestContainsImageData(contents);
}
void SimulateDragAndVerifyNonGoogleUrlForSidePanel(
RenderViewContextMenu* menu) {
SearchByRegionBrowserBaseTest::SimulateDragAndVerifyOverlayUI(menu);
content::WebContents* contents =
GetLensUnifiedSidePanelWebContentsAfterNavigation();
std::string side_panel_content =
contents->GetLastCommittedURL().GetContent();
std::string expected_content = GetNonGoogleRegionSearchURL().GetContent();
std::size_t query_start_pos = side_panel_content.find("?");
EXPECT_THAT(
side_panel_content,
testing::MatchesRegex(expected_content.substr(0, query_start_pos) +
".*sideimagesearch=1&vpw=\\d+&vph=\\d+"));
ExpectThatRequestContainsImageData(contents);
quit_closure_.Run();
}
void AttemptFullscreenLensRegionSearchWithUnifiedSidePanel() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, 0,
base::BindOnce(&SearchByRegionWithUnifiedSidePanelBrowserTest::
SimulateFullscreenSearchAndVerifyLensUrl,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
void AttemptLensRegionSearchWithUnifiedSidePanel() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, ui::EF_MOUSE_BUTTON,
base::BindOnce(&SearchByRegionWithUnifiedSidePanelBrowserTest::
SimulateDragAndVerifyLensRequest,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
void AttemptNonGoogleRegionSearchWithUnifiedSidePanel() {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_WEB_REGION_SEARCH, ui::EF_MOUSE_BUTTON,
base::BindOnce(&SearchByRegionWithUnifiedSidePanelBrowserTest::
SimulateDragAndVerifyNonGoogleUrlForSidePanel,
base::Unretained(this)));
RightClickToOpenContextMenu();
}
content::WebContents* GetLensUnifiedSidePanelWebContentsAfterNavigation() {
content::WebContents* contents =
lens::GetLensUnifiedSidePanelWebContentsForTesting(browser());
EXPECT_TRUE(contents);
content::TestNavigationObserver nav_observer(contents);
nav_observer.WaitForNavigationFinished();
return contents;
}
GURL GetLensRegionSearchURL() {
static const char kLensRegionSearchURL[] = "/imagesearch";
return embedded_test_server()->GetURL(kLensRegionSearchURL);
}
void SetupUnifiedSidePanel() {
SetupAndLoadPage("/empty.html");
lens::CreateLensUnifiedSidePanelEntryForTesting(browser());
content::WebContents* contents =
lens::GetLensUnifiedSidePanelWebContentsForTesting(browser());
content::TestNavigationObserver nav_observer(contents);
nav_observer.WaitForNavigationFinished();
}
};
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
#define MAYBE_ValidLensRegionSearchWithUnifiedSidePanel …
#else
#define MAYBE_ValidLensRegionSearchWithUnifiedSidePanel …
#endif
IN_PROC_BROWSER_TEST_F(SearchByRegionWithUnifiedSidePanelBrowserTest,
MAYBE_ValidLensRegionSearchWithUnifiedSidePanel) {
SetupUnifiedSidePanel();
base::RunLoop loop;
quit_closure_ = base::BindRepeating(loop.QuitClosure());
AttemptLensRegionSearchWithUnifiedSidePanel();
loop.Run();
}
IN_PROC_BROWSER_TEST_F(SearchByRegionWithUnifiedSidePanelBrowserTest,
ProgressiveWebAppValidLensRegionSearch) {
Browser* pwa_browser = InProcessBrowserTest::CreateBrowserForApp(
"test_app", browser()->profile());
CloseBrowserSynchronously(browser());
SelectFirstBrowser();
ASSERT_EQ(pwa_browser, browser());
SearchByRegionBrowserBaseTest::CreateAndSetEventGenerator();
SetupAndLoadPage("/empty.html");
ui_test_utils::AllBrowserTabAddedWaiter add_tab;
SearchByRegionBrowserBaseTest::AttemptLensRegionSearchNewTab();
content::WebContents* new_tab = add_tab.Wait();
content::WaitForLoadStop(new_tab);
std::string new_tab_content = new_tab->GetLastCommittedURL().GetContent();
std::string expected_content = GetLensRegionSearchURL().GetContent();
std::size_t query_start_pos = new_tab_content.find("?");
EXPECT_THAT(new_tab_content, testing::MatchesRegex(
expected_content.substr(0, query_start_pos) +
".*ep=crs&re=df&s=4&st=\\d+&lm=.+"));
}
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
#define MAYBE_ValidFullscreenLensRegionSearchWithUnifiedSidePanel …
#else
#define MAYBE_ValidFullscreenLensRegionSearchWithUnifiedSidePanel …
#endif
IN_PROC_BROWSER_TEST_F(
SearchByRegionWithUnifiedSidePanelBrowserTest,
MAYBE_ValidFullscreenLensRegionSearchWithUnifiedSidePanel) {
SetupUnifiedSidePanel();
base::RunLoop loop;
quit_closure_ = base::BindRepeating(loop.QuitClosure());
AttemptFullscreenLensRegionSearchWithUnifiedSidePanel();
loop.Run();
}
IN_PROC_BROWSER_TEST_F(
SearchByRegionWithUnifiedSidePanelBrowserTest,
ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch) {
SetupNonGoogleRegionSearchEngine();
SetupUnifiedSidePanel();
base::RunLoop loop;
quit_closure_ = base::BindRepeating(loop.QuitClosure());
AttemptNonGoogleRegionSearchWithUnifiedSidePanel();
loop.Run();
}
IN_PROC_BROWSER_TEST_F(
SearchByRegionWithUnifiedSidePanelBrowserTest,
ValidNonGoogleRegionSearchWithUnifiedSidePanelAndNoSideImageSearch) {
SetupAndLoadPage("/empty.html");
SetupNonGoogleRegionSearchEngine(false);
ui_test_utils::AllBrowserTabAddedWaiter add_tab;
AttemptNonGoogleRegionSearch();
content::WebContents* new_tab = add_tab.Wait();
content::WaitForLoadStop(new_tab);
std::string new_tab_content = new_tab->GetLastCommittedURL().GetContent();
std::string expected_content = GetNonGoogleRegionSearchURL().GetContent();
EXPECT_EQ(new_tab_content, expected_content);
}
class LensOverlayBrowserTest : public SearchByRegionBrowserBaseTest {
protected:
void SetUp() override {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({lens::features::kLensOverlay}, {});
InProcessBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(lens::prefs::kLensSharingPageScreenshotEnabled, true);
}
void TearDownOnMainThread() override {
InProcessBrowserTest::TearDownOnMainThread();
PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(lens::prefs::kLensSharingPageScreenshotEnabled, false);
}
void OpenContextMenuAndSelectRegionSearchEntrypoint(
int event_flags,
ContextMenuNotificationObserver::MenuShownCallback callback) {
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH, event_flags,
std::move(callback));
RightClickToOpenContextMenu();
}
void OpenImagePageAndContextMenuForLensImageSearch(
std::string image_path,
int event_flags,
ContextMenuNotificationObserver::MenuShownCallback callback) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL image_url(embedded_test_server()->GetURL(image_path));
GURL page("data:text/html,<img src='" + image_url.spec() + "'>");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), page));
menu_observer_ = std::make_unique<ContextMenuNotificationObserver>(
IDC_CONTENT_CONTEXT_SEARCHLENSFORIMAGE, event_flags,
std::move(callback));
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
content::SimulateMouseClickAt(tab, 0, blink::WebMouseEvent::Button::kRight,
gfx::Point(15, 15));
}
};
IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest,
RegionSearchContextMenuOpensLensOverlay) {
auto* controller = browser()
->tab_strip_model()
->GetActiveTab()
->tab_features()
->lens_overlay_controller();
ASSERT_EQ(controller->state(), LensOverlayController::State::kOff);
OpenContextMenuAndSelectRegionSearchEntrypoint(ui::EF_MOUSE_BUTTON,
base::NullCallback());
ASSERT_TRUE(base::test::RunUntil([&]() {
return controller->state() == LensOverlayController::State::kOverlay;
}));
}
IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest,
RegionSearchContextMenuDoesNotOpenRegionSearch) {
bool run = false;
OpenContextMenuAndSelectRegionSearchEntrypoint(
ui::EF_MOUSE_BUTTON,
base::BindLambdaForTesting([&](RenderViewContextMenu* menu) {
lens::LensRegionSearchController* controller =
menu->GetLensRegionSearchControllerForTesting();
ASSERT_EQ(controller, nullptr);
run = true;
}));
ASSERT_TRUE(base::test::RunUntil([&]() { return run == true; }));
}
IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest,
RegionSearchContextMenuOpensRegionSearchForKeyboard) {
bool run = false;
OpenContextMenuAndSelectRegionSearchEntrypoint(
ui::EF_NONE,
base::BindLambdaForTesting([&](RenderViewContextMenu* menu) {
lens::LensRegionSearchController* controller =
menu->GetLensRegionSearchControllerForTesting();
ASSERT_NE(controller, nullptr);
run = true;
}));
ASSERT_TRUE(base::test::RunUntil([&]() { return run == true; }));
}
IN_PROC_BROWSER_TEST_F(LensOverlayBrowserTest,
ImageSearchContextMenuDoesNotOpenImageSearch) {
bool run = false;
int starting_tab_index = browser()->tab_strip_model()->active_index();
OpenImagePageAndContextMenuForLensImageSearch(
"/google/logo.gif", ui::EF_MOUSE_BUTTON,
base::BindLambdaForTesting([&](RenderViewContextMenu* menu) {
lens::LensRegionSearchController* controller =
menu->GetLensRegionSearchControllerForTesting();
ASSERT_EQ(controller, nullptr);
run = true;
}));
ASSERT_TRUE(base::test::RunUntil([&]() { return run == true; }));
ASSERT_EQ(browser()->tab_strip_model()->active_index(), starting_tab_index);
}
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
#define MAYBE_ImageSearchContextMenuOpensImageSearchForKeyboard …
#else
#define MAYBE_ImageSearchContextMenuOpensImageSearchForKeyboard …
#endif
IN_PROC_BROWSER_TEST_F(
LensOverlayBrowserTest,
MAYBE_ImageSearchContextMenuOpensImageSearchForKeyboard) {
bool run = false;
int starting_tab_index = browser()->tab_strip_model()->active_index();
OpenImagePageAndContextMenuForLensImageSearch(
"/google/logo.gif", ui::EF_NONE,
base::BindLambdaForTesting(
[&](RenderViewContextMenu* menu) { run = true; }));
ASSERT_TRUE(base::test::RunUntil([&]() { return run == true; }));
ASSERT_NE(browser()->tab_strip_model()->active_index(), starting_tab_index);
}
#endif
#if BUILDFLAG(ENABLE_PDF)
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
FullPagePdfHasPageItems) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
FullPagePdfFullscreenItems) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
CopyWithoutText) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
CopyText) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
CopyTextWithRestriction) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
IframedPdfHasNoPageItems) { … }
IN_PROC_BROWSER_TEST_P(PdfPluginContextMenuBrowserTestWithOopifOverride,
RotateInFullPagePdf) { … }
class OopifPdfPluginContextMenuBrowserTest
: public PdfPluginContextMenuBrowserTest { … };
IN_PROC_BROWSER_TEST_F(OopifPdfPluginContextMenuBrowserTest,
RotateInEmbeddedPdf) { … }
INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(…);
#endif
class LoadImageRequestObserver : public content::WebContentsObserver { … };
class LoadImageBrowserTest : public InProcessBrowserTest { … };
IN_PROC_BROWSER_TEST_F(LoadImageBrowserTest, LoadImage) { … }
IN_PROC_BROWSER_TEST_F(LoadImageBrowserTest, LoadImageWithMap) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, ContextMenuForVideo) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForVideoWithBlobLink) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForVideoWithReadableFrame) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForVideoWithoutReadableFrame) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, ContextMenuForEncryptedVideo) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForVideoNotInPictureInPicture) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
ContextMenuForVideoInPictureInPicture) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, BrowserlessWebContentsCrash) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, GifImageShare) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, GifImageDownscaleToJpeg) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_RequestPngForGifImage …
#else
#define MAYBE_RequestPngForGifImage …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_RequestPngForGifImage) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_PngImageDownscaleToPng …
#else
#define MAYBE_PngImageDownscaleToPng …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_PngImageDownscaleToPng) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, PngImageOriginalDownscaleToPng) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_JpgImageDownscaleToJpg …
#else
#define MAYBE_JpgImageDownscaleToJpg …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_JpgImageDownscaleToJpg) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, JpgImageDownscaleToWebp) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_PngImageDownscaleToWebp …
#else
#define MAYBE_PngImageDownscaleToWebp …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_PngImageDownscaleToWebp) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_GifImageDownscaleToWebp …
#else
#define MAYBE_GifImageDownscaleToWebp …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_GifImageDownscaleToWebp) { … }
#if BUILDFLAG(IS_MAC)
#define MAYBE_WebpImageDownscaleToWebp …
#else
#define MAYBE_WebpImageDownscaleToWebp …
#endif
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, MAYBE_WebpImageDownscaleToWebp) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest,
CopyLinkToTextDisabledWithScrollToTextPolicyDisabled) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenInReadingMode) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, BackAfterBackEntryRemoved) { … }
static std::string BuildCrossOriginChildFrameHTML(const GURL& link) { … }
IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, SubframeNewTabInitiator) { … }
}