blob: 3db580b54d5dbb6ecaa3229150d0c99812b4585f [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2018 The Chromium Authors
Mike Wasserman07e6c462018-03-31 01:15:502// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakjdb9ae7942020-11-11 16:01:355#include "base/callback_helpers.h"
Mike Wasserman07e6c462018-03-31 01:15:506#include "base/files/file_path.h"
Mike Wasserman07e6c462018-03-31 01:15:507#include "base/run_loop.h"
8#include "base/strings/utf_string_conversions.h"
9#include "build/build_config.h"
10#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
11#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/browser/ui/browser_window.h"
Mike Wasserman07e6c462018-03-31 01:15:5014#include "chrome/browser/ui/tabs/tab_strip_model.h"
15#include "chrome/test/base/in_process_browser_test.h"
16#include "chrome/test/base/interactive_test_utils.h"
17#include "chrome/test/base/ui_test_utils.h"
Evan Stade4b55d2022020-02-06 17:29:0618#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
Mike Wasserman07e6c462018-03-31 01:15:5019#include "content/public/browser/render_frame_host.h"
20#include "content/public/browser/web_contents.h"
Peter Kasting919ce652020-05-07 10:22:3621#include "content/public/test/browser_test.h"
Mike Wasserman07e6c462018-03-31 01:15:5022#include "content/public/test/browser_test_utils.h"
23#include "ui/base/test/ui_controls.h"
24
25namespace {
26
27// Integration test of browser event forwarding and web content event handling.
28class MouseEventsTest : public InProcessBrowserTest {
29 public:
Avi Drissman487275f2021-11-02 18:46:0030 MouseEventsTest() = default;
Mike Wasserman07e6c462018-03-31 01:15:5031
Peter Boströmfadb1752021-09-30 19:17:0132 MouseEventsTest(const MouseEventsTest&) = delete;
33 MouseEventsTest& operator=(const MouseEventsTest&) = delete;
34
Mike Wasserman07e6c462018-03-31 01:15:5035 // InProcessBrowserTest:
36 void SetUpOnMainThread() override {
37 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
38 }
39
40 content::WebContents* GetActiveWebContents() {
41 return browser()->tab_strip_model()->GetActiveWebContents();
42 }
43
44 // Wait for the active web contents title to match |title|.
45 void WaitForTitle(const std::string& title) {
46 // Logging added temporarily to track down flakiness cited below.
47 LOG(INFO) << "Waiting for title: " << title;
Jan Wilken Dörriedec99122021-03-11 18:02:3048 const std::u16string expected_title(base::ASCIIToUTF16(title));
Mike Wasserman07e6c462018-03-31 01:15:5049 content::TitleWatcher title_watcher(GetActiveWebContents(), expected_title);
50 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
51 }
52
53 // Load the test page and wait for onmouseover to be called.
54 void NavigateAndWaitForMouseOver() {
55 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
56
57 // Move the mouse 2px above the web contents; allows onmouseover after load.
58 const gfx::Rect bounds = GetActiveWebContents()->GetContainerBounds();
59 ui_controls::SendMouseMove(bounds.CenterPoint().x(), bounds.y() - 2);
60
61 // Navigate to the test page and wait for onload to be called.
62 const GURL url = ui_test_utils::GetTestUrl(
63 base::FilePath(),
64 base::FilePath(FILE_PATH_LITERAL("mouse_events_test.html")));
Lukasz Anforowiczb78290c2021-09-08 04:31:3865 ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
Mike Wasserman07e6c462018-03-31 01:15:5066 WaitForTitle("onload");
67
68 // Move the mouse over the div and wait for onmouseover to be called.
69 ui_controls::SendMouseMove(bounds.CenterPoint().x(), bounds.y() + 10);
70 WaitForTitle("onmouseover");
71 }
72
73 // Load the test page and wait for onmouseover then onmouseout to be called.
74 void NavigateAndWaitForMouseOverThenMouseOut() {
75 EXPECT_NO_FATAL_FAILURE(NavigateAndWaitForMouseOver());
76
77 // Moving the mouse outside the div should trigger onmouseout.
78 const gfx::Rect bounds = GetActiveWebContents()->GetContainerBounds();
79 ui_controls::SendMouseMove(bounds.CenterPoint().x(), bounds.y() - 10);
80 WaitForTitle("onmouseout");
81 }
Mike Wasserman07e6c462018-03-31 01:15:5082};
83
Xiaohan Wang55ae2c012022-01-20 21:49:1184#if BUILDFLAG(IS_MAC)
Avi Drissman487275f2021-11-02 18:46:0085// Flaky; http://crbug.com/133361.
Mike Wasserman07e6c462018-03-31 01:15:5086#define MAYBE_MouseOver DISABLED_MouseOver
87#else
88#define MAYBE_MouseOver MouseOver
89#endif
90
91IN_PROC_BROWSER_TEST_F(MouseEventsTest, MAYBE_MouseOver) {
92 NavigateAndWaitForMouseOver();
93}
94
Xiaohan Wang55ae2c012022-01-20 21:49:1195#if BUILDFLAG(IS_MAC)
Avi Drissman487275f2021-11-02 18:46:0096// Flaky; http://crbug.com/133361.
Mike Wasserman07e6c462018-03-31 01:15:5097#define MAYBE_ClickAndDoubleClick DISABLED_ClickAndDoubleClick
98#else
99#define MAYBE_ClickAndDoubleClick ClickAndDoubleClick
100#endif
101
102IN_PROC_BROWSER_TEST_F(MouseEventsTest, MAYBE_ClickAndDoubleClick) {
103 NavigateAndWaitForMouseOver();
104
105 ui_controls::SendMouseClick(ui_controls::LEFT);
106 WaitForTitle("onclick");
107
108 ui_controls::SendMouseClick(ui_controls::LEFT);
109 WaitForTitle("ondblclick");
110}
111
Xiaohan Wang55ae2c012022-01-20 21:49:11112#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
113 BUILDFLAG(IS_WIN)
Avi Drissman487275f2021-11-02 18:46:00114// Flaky; http://crbug.com/133361.
Mike Wasserman07e6c462018-03-31 01:15:50115#define MAYBE_TestOnMouseOut DISABLED_TestOnMouseOut
Mike Wasserman07e6c462018-03-31 01:15:50116#else
117#define MAYBE_TestOnMouseOut TestOnMouseOut
118#endif
119
120IN_PROC_BROWSER_TEST_F(MouseEventsTest, MAYBE_TestOnMouseOut) {
121 NavigateAndWaitForMouseOverThenMouseOut();
122}
123
Xiaohan Wang55ae2c012022-01-20 21:49:11124#if BUILDFLAG(IS_WIN)
Avi Drissman487275f2021-11-02 18:46:00125// Mac/Linux are flaky; http://crbug.com/133361.
Mike Wasserman07e6c462018-03-31 01:15:50126IN_PROC_BROWSER_TEST_F(MouseEventsTest, MouseDownOnBrowserCaption) {
127 gfx::Rect browser_bounds = browser()->window()->GetBounds();
128 ui_controls::SendMouseMove(browser_bounds.x() + 200, browser_bounds.y() + 10);
129 ui_controls::SendMouseClick(ui_controls::LEFT);
130
131 NavigateAndWaitForMouseOverThenMouseOut();
132}
133#endif
134
kylechar29fa9712022-11-04 00:47:47135#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_OZONE)
Mike Wasserman07e6c462018-03-31 01:15:50136// Test that a mouseleave is not triggered when showing the context menu.
137// If the test is failed, it means that Blink gets the mouseleave event
138// when showing the context menu and it could make the unexpecting
139// content behavior such as clearing the hover status.
140// Please refer to the below issue for understanding what happens .
Avi Drissman487275f2021-11-02 18:46:00141// Flaky; See http://crbug.com/656101.
Mike Wasserman07e6c462018-03-31 01:15:50142#define MAYBE_ContextMenu DISABLED_ContextMenu
143#else
144#define MAYBE_ContextMenu ContextMenu
145#endif
146
147IN_PROC_BROWSER_TEST_F(MouseEventsTest, MAYBE_ContextMenu) {
148 EXPECT_NO_FATAL_FAILURE(NavigateAndWaitForMouseOver());
149
Avi Drissman6b53a1d42018-04-09 18:19:43150 ContextMenuWaiter menu_observer;
Mike Wasserman07e6c462018-03-31 01:15:50151 ui_controls::SendMouseClick(ui_controls::RIGHT);
152 // Wait until the context menu is opened and closed.
153 menu_observer.WaitForMenuOpenAndClose();
154
155 content::WebContents* tab = GetActiveWebContents();
Dave Tapuska6aea6e22022-06-06 21:21:51156 tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"done()",
157 base::NullCallback());
Jan Wilken Dörrie78e88d82e2021-03-23 15:24:22158 const std::u16string success_title = u"without mouseleave";
159 const std::u16string failure_title = u"with mouseleave";
Mike Wasserman07e6c462018-03-31 01:15:50160 content::TitleWatcher done_title_watcher(tab, success_title);
161 done_title_watcher.AlsoWaitForTitle(failure_title);
162 EXPECT_EQ(success_title, done_title_watcher.WaitAndGetTitle());
163}
164
Xiaohan Wang55ae2c012022-01-20 21:49:11165#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
166 BUILDFLAG(IS_CHROMEOS)
Mike Wasserman07e6c462018-03-31 01:15:50167// Test that a mouseleave is not triggered when showing a modal dialog.
168// Sample regression: crbug.com/394672
Avi Drissman487275f2021-11-02 18:46:00169// Flaky; http://crbug.com/838120
Mike Wasserman07e6c462018-03-31 01:15:50170#define MAYBE_ModalDialog DISABLED_ModalDialog
171#else
172#define MAYBE_ModalDialog ModalDialog
173#endif
174
175IN_PROC_BROWSER_TEST_F(MouseEventsTest, MAYBE_ModalDialog) {
176 EXPECT_NO_FATAL_FAILURE(NavigateAndWaitForMouseOver());
177
178 content::WebContents* tab = GetActiveWebContents();
Evan Stade4b55d2022020-02-06 17:29:06179 auto* js_dialog_manager =
180 javascript_dialogs::TabModalDialogManager::FromWebContents(tab);
Mike Wasserman07e6c462018-03-31 01:15:50181 base::RunLoop dialog_wait;
Evan Stade4b55d2022020-02-06 17:29:06182 js_dialog_manager->SetDialogShownCallbackForTesting(
183 dialog_wait.QuitClosure());
Dave Tapuska6aea6e22022-06-06 21:21:51184 tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"alert()",
185 base::NullCallback());
Mike Wasserman07e6c462018-03-31 01:15:50186 dialog_wait.Run();
187
188 // Cancel the dialog.
Evan Stade4b55d2022020-02-06 17:29:06189 js_dialog_manager->HandleJavaScriptDialog(tab, false, nullptr);
Mike Wasserman07e6c462018-03-31 01:15:50190
Dave Tapuska6aea6e22022-06-06 21:21:51191 tab->GetPrimaryMainFrame()->ExecuteJavaScriptForTests(u"done()",
192 base::NullCallback());
Jan Wilken Dörrie78e88d82e2021-03-23 15:24:22193 const std::u16string success_title = u"without mouseleave";
194 const std::u16string failure_title = u"with mouseleave";
Mike Wasserman07e6c462018-03-31 01:15:50195 content::TitleWatcher done_title_watcher(tab, success_title);
196 done_title_watcher.AlsoWaitForTitle(failure_title);
197 EXPECT_EQ(success_title, done_title_watcher.WaitAndGetTitle());
198}
199
200} // namespace