ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / renderer_context_menu / render_view_context_menu_browsertest.cc
blob7d50614d1f37f4ce32fa06a3e99d6308a5e839d6
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
7 #include "base/command_line.h"
8 #include "base/macros.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/app/chrome_command_ids.h"
14 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
16 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
17 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
18 #include "chrome/browser/search_engines/template_url_service_factory.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/render_messages.h"
22 #include "chrome/test/base/in_process_browser_test.h"
23 #include "chrome/test/base/ui_test_utils.h"
24 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
25 #include "components/search_engines/template_url_data.h"
26 #include "components/search_engines/template_url_service.h"
27 #include "content/public/browser/browser_message_filter.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/navigation_controller.h"
30 #include "content/public/browser/navigation_entry.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/render_process_host.h"
33 #include "content/public/browser/render_view_host.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/test/browser_test_utils.h"
36 #include "content/public/test/test_utils.h"
37 #include "third_party/WebKit/public/web/WebContextMenuData.h"
38 #include "third_party/WebKit/public/web/WebInputEvent.h"
40 using content::WebContents;
42 namespace {
44 class ContextMenuBrowserTest : public InProcessBrowserTest {
45 public:
46 ContextMenuBrowserTest() {}
48 TestRenderViewContextMenu* CreateContextMenu(
49 const GURL& unfiltered_url,
50 const GURL& url,
51 blink::WebContextMenuData::MediaType media_type) {
52 content::ContextMenuParams params;
53 params.media_type = media_type;
54 params.unfiltered_link_url = unfiltered_url;
55 params.link_url = url;
56 params.src_url = url;
57 WebContents* web_contents =
58 browser()->tab_strip_model()->GetActiveWebContents();
59 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL();
60 #if defined(OS_MACOSX)
61 params.writing_direction_default = 0;
62 params.writing_direction_left_to_right = 0;
63 params.writing_direction_right_to_left = 0;
64 #endif // OS_MACOSX
65 TestRenderViewContextMenu* menu = new TestRenderViewContextMenu(
66 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
67 params);
68 menu->Init();
69 return menu;
72 TestRenderViewContextMenu* CreateContextMenuMediaTypeNone(
73 const GURL& unfiltered_url,
74 const GURL& url) {
75 return CreateContextMenu(unfiltered_url, url,
76 blink::WebContextMenuData::MediaTypeNone);
80 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
81 OpenEntryPresentForNormalURLs) {
82 scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenuMediaTypeNone(
83 GURL("http://www.google.com/"), GURL("http://www.google.com/")));
85 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));
86 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW));
87 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION));
90 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
91 OpenEntryAbsentForFilteredURLs) {
92 scoped_ptr<TestRenderViewContextMenu> menu(
93 CreateContextMenuMediaTypeNone(GURL("chrome://history"), GURL()));
95 ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));
96 ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW));
97 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION));
100 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
101 ContextMenuForCanvas) {
102 content::ContextMenuParams params;
103 params.media_type = blink::WebContextMenuData::MediaTypeCanvas;
105 TestRenderViewContextMenu menu(
106 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
107 params);
108 menu.Init();
110 ASSERT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
111 ASSERT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_COPYIMAGE));
114 // Opens a link in a new tab via a "real" context menu.
115 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, RealMenu) {
116 ContextMenuNotificationObserver menu_observer(
117 IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
118 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
119 content::NotificationService::AllSources());
121 // Go to a page with a link
122 ui_test_utils::NavigateToURL(
123 browser(), GURL("data:text/html,<a href='about:blank'>link</a>"));
125 // Open a context menu.
126 blink::WebMouseEvent mouse_event;
127 mouse_event.type = blink::WebInputEvent::MouseDown;
128 mouse_event.button = blink::WebMouseEvent::ButtonRight;
129 mouse_event.x = 15;
130 mouse_event.y = 15;
131 content::WebContents* tab =
132 browser()->tab_strip_model()->GetActiveWebContents();
133 gfx::Rect offset = tab->GetContainerBounds();
134 mouse_event.globalX = 15 + offset.x();
135 mouse_event.globalY = 15 + offset.y();
136 mouse_event.clickCount = 1;
137 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
138 mouse_event.type = blink::WebInputEvent::MouseUp;
139 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
141 // The menu_observer will select "Open in new tab", wait for the new tab to
142 // be added.
143 tab_observer.Wait();
144 tab = tab_observer.GetTab();
145 content::WaitForLoadStop(tab);
147 // Verify that it's the correct tab.
148 EXPECT_EQ(GURL("about:blank"), tab->GetURL());
151 // Verify that "Open Link in New Tab" doesn't send URL fragment as referrer.
152 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenInNewTabReferrer) {
153 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
154 content::NotificationService::AllSources());
156 ASSERT_TRUE(test_server()->Start());
157 GURL echoheader(test_server()->GetURL("echoheader?Referer"));
159 // Go to a |page| with a link to echoheader URL.
160 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>");
161 ui_test_utils::NavigateToURL(browser(), page);
163 // Set up referrer URL with fragment.
164 const GURL kReferrerWithFragment("http://foo.com/test#fragment");
165 const std::string kCorrectReferrer("http://foo.com/test");
167 // Set up menu with link URL.
168 content::ContextMenuParams context_menu_params;
169 context_menu_params.page_url = kReferrerWithFragment;
170 context_menu_params.link_url = echoheader;
172 // Select "Open Link in New Tab" and wait for the new tab to be added.
173 TestRenderViewContextMenu menu(
174 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
175 context_menu_params);
176 menu.Init();
177 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
179 tab_observer.Wait();
180 content::WebContents* tab = tab_observer.GetTab();
181 content::WaitForLoadStop(tab);
183 // Verify that it's the correct tab.
184 ASSERT_EQ(echoheader, tab->GetURL());
185 // Verify that the text on the page matches |kCorrectReferrer|.
186 std::string actual_referrer;
187 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
188 tab,
189 "window.domAutomationController.send(window.document.body.textContent);",
190 &actual_referrer));
191 ASSERT_EQ(kCorrectReferrer, actual_referrer);
193 // Verify that the referrer on the page matches |kCorrectReferrer|.
194 std::string page_referrer;
195 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
196 tab,
197 "window.domAutomationController.send(window.document.referrer);",
198 &page_referrer));
199 ASSERT_EQ(kCorrectReferrer, page_referrer);
202 // Verify that "Open Link in Incognito Window " doesn't send referrer URL.
203 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenIncognitoNoneReferrer) {
204 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
205 content::NotificationService::AllSources());
207 ASSERT_TRUE(test_server()->Start());
208 GURL echoheader(test_server()->GetURL("echoheader?Referer"));
210 // Go to a |page| with a link to echoheader URL.
211 GURL page("data:text/html,<a href='" + echoheader.spec() + "'>link</a>");
212 ui_test_utils::NavigateToURL(browser(), page);
214 // Set up referrer URL with fragment.
215 const GURL kReferrerWithFragment("http://foo.com/test#fragment");
216 const std::string kNoneReferrer("None");
217 const std::string kEmptyReferrer("");
219 // Set up menu with link URL.
220 content::ContextMenuParams context_menu_params;
221 context_menu_params.page_url = kReferrerWithFragment;
222 context_menu_params.link_url = echoheader;
224 // Select "Open Link in Incognito Window" and wait for window to be added.
225 TestRenderViewContextMenu menu(
226 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
227 context_menu_params);
228 menu.Init();
229 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, 0);
231 tab_observer.Wait();
232 content::WebContents* tab = tab_observer.GetTab();
233 content::WaitForLoadStop(tab);
235 // Verify that it's the correct tab.
236 ASSERT_EQ(echoheader, tab->GetURL());
237 // Verify that the text on the page matches |kNoneReferrer|.
238 std::string actual_referrer;
239 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
240 tab,
241 "window.domAutomationController.send(window.document.body.textContent);",
242 &actual_referrer));
243 ASSERT_EQ(kNoneReferrer, actual_referrer);
245 // Verify that the referrer on the page matches |kEmptyReferrer|.
246 std::string page_referrer;
247 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
248 tab,
249 "window.domAutomationController.send(window.document.referrer);",
250 &page_referrer));
251 ASSERT_EQ(kEmptyReferrer, page_referrer);
254 // Check filename on clicking "Save Link As" via a "real" context menu.
255 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, SuggestedFileName) {
256 // Register observer.
257 SaveLinkAsContextMenuObserver menu_observer(
258 content::NotificationService::AllSources());
260 // Go to a page with a link having download attribute.
261 const std::string kSuggestedFilename("test_filename.png");
262 ui_test_utils::NavigateToURL(
263 browser(),
264 GURL("data:text/html,<a href='about:blank' download='" +
265 kSuggestedFilename + "'>link</a>"));
267 // Open a context menu.
268 blink::WebMouseEvent mouse_event;
269 mouse_event.type = blink::WebInputEvent::MouseDown;
270 mouse_event.button = blink::WebMouseEvent::ButtonRight;
271 mouse_event.x = 15;
272 mouse_event.y = 15;
273 content::WebContents* tab =
274 browser()->tab_strip_model()->GetActiveWebContents();
275 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
276 mouse_event.type = blink::WebInputEvent::MouseUp;
277 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
279 // Wait for context menu to be visible.
280 menu_observer.WaitForMenu();
282 // Compare filename.
283 base::string16 suggested_filename = menu_observer.GetSuggestedFilename();
284 ASSERT_EQ(kSuggestedFilename, base::UTF16ToUTF8(suggested_filename).c_str());
287 // Ensure that View Page Info won't crash if there is no visible entry.
288 // See http://crbug.com/370863.
289 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, ViewPageInfoWithNoEntry) {
290 // Create a new tab with no committed entry.
291 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
292 content::NotificationService::AllSources());
293 ASSERT_TRUE(content::ExecuteScript(
294 browser()->tab_strip_model()->GetActiveWebContents(), "window.open();"));
295 tab_observer.Wait();
296 content::WebContents* tab = tab_observer.GetTab();
297 EXPECT_FALSE(tab->GetController().GetLastCommittedEntry());
298 EXPECT_FALSE(tab->GetController().GetVisibleEntry());
300 // Create a context menu.
301 content::ContextMenuParams context_menu_params;
302 TestRenderViewContextMenu menu(tab->GetMainFrame(), context_menu_params);
303 menu.Init();
305 // The item shouldn't be enabled in the menu.
306 EXPECT_FALSE(menu.IsCommandIdEnabled(IDC_CONTENT_CONTEXT_VIEWPAGEINFO));
308 // Ensure that viewing page info doesn't crash even if you can get to it.
309 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_VIEWPAGEINFO, 0);
312 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, DataSaverOpenOrigImageInNewTab) {
313 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
314 command_line->AppendSwitch(
315 data_reduction_proxy::switches::kEnableDataReductionProxy);
317 scoped_ptr<TestRenderViewContextMenu> menu(
318 CreateContextMenu(GURL(), GURL("http://url.com/image.png"),
319 blink::WebContextMenuData::MediaTypeImage));
321 ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB));
322 ASSERT_TRUE(menu->IsItemPresent(
323 IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB));
326 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
327 DataSaverHttpsOpenImageInNewTab) {
328 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
329 command_line->AppendSwitch(
330 data_reduction_proxy::switches::kEnableDataReductionProxy);
332 scoped_ptr<TestRenderViewContextMenu> menu(
333 CreateContextMenu(GURL(), GURL("https://url.com/image.png"),
334 blink::WebContextMenuData::MediaTypeImage));
336 ASSERT_FALSE(
337 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB));
338 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB));
341 IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenImageInNewTab) {
342 scoped_ptr<TestRenderViewContextMenu> menu(
343 CreateContextMenu(GURL(), GURL("http://url.com/image.png"),
344 blink::WebContextMenuData::MediaTypeImage));
345 ASSERT_FALSE(
346 menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB));
347 ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB));
350 class ThumbnailResponseWatcher : public content::NotificationObserver {
351 public:
352 enum QuitReason {
353 STILL_RUNNING = 0,
354 THUMBNAIL_RECEIVED,
355 RENDER_PROCESS_GONE,
358 class MessageFilter : public content::BrowserMessageFilter {
359 public:
360 explicit MessageFilter(ThumbnailResponseWatcher* owner)
361 : content::BrowserMessageFilter(ChromeMsgStart), owner_(owner) {}
363 bool OnMessageReceived(const IPC::Message& message) override {
364 if (message.type() ==
365 ChromeViewHostMsg_RequestThumbnailForContextNode_ACK::ID) {
366 content::BrowserThread::PostTask(
367 content::BrowserThread::UI, FROM_HERE,
368 base::Bind(&MessageFilter::OnRequestThumbnailForContextNodeACK,
369 this));
371 return false;
374 void OnRequestThumbnailForContextNodeACK() {
375 if (owner_)
376 owner_->OnRequestThumbnailForContextNodeACK();
379 void Disown() { owner_ = nullptr; }
381 private:
382 ~MessageFilter() override {}
384 ThumbnailResponseWatcher* owner_;
386 DISALLOW_COPY_AND_ASSIGN(MessageFilter);
389 explicit ThumbnailResponseWatcher(
390 content::RenderProcessHost* render_process_host)
391 : message_loop_runner_(new content::MessageLoopRunner),
392 filter_(new MessageFilter(this)),
393 quit_reason_(STILL_RUNNING) {
394 notification_registrar_.Add(
395 this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
396 content::Source<content::RenderProcessHost>(render_process_host));
397 notification_registrar_.Add(
398 this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
399 content::Source<content::RenderProcessHost>(render_process_host));
400 render_process_host->AddFilter(filter_.get());
403 ~ThumbnailResponseWatcher() override { filter_->Disown(); }
405 QuitReason Wait() WARN_UNUSED_RESULT {
406 message_loop_runner_->Run();
407 DCHECK_NE(STILL_RUNNING, quit_reason_);
408 return quit_reason_;
411 void Observe(int type,
412 const content::NotificationSource& source,
413 const content::NotificationDetails& details) override {
414 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED ||
415 type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED);
416 quit_reason_ = RENDER_PROCESS_GONE;
417 message_loop_runner_->Quit();
420 void OnRequestThumbnailForContextNodeACK() {
421 quit_reason_ = THUMBNAIL_RECEIVED;
422 message_loop_runner_->Quit();
425 private:
426 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
427 scoped_refptr<MessageFilter> filter_;
428 content::NotificationRegistrar notification_registrar_;
429 QuitReason quit_reason_;
431 DISALLOW_COPY_AND_ASSIGN(ThumbnailResponseWatcher);
434 // Maintains image search test state. In particular, note that |menu_observer_|
435 // must live until the right-click completes asynchronously.
436 class SearchByImageBrowserTest : public InProcessBrowserTest {
437 protected:
438 void SetupAndLoadImagePage(const std::string& image_path) {
439 // The test server must start first, so that we know the port that the test
440 // server is using.
441 ASSERT_TRUE(test_server()->Start());
442 SetupImageSearchEngine();
444 // Go to a page with an image in it. The test server doesn't serve the image
445 // with the right MIME type, so use a data URL to make a page containing it.
446 GURL image_url(test_server()->GetURL(image_path));
447 GURL page("data:text/html,<img src='" + image_url.spec() + "'>");
448 ui_test_utils::NavigateToURL(browser(), page);
451 void AttemptImageSearch() {
452 // Right-click where the image should be.
453 // |menu_observer_| will cause the search-by-image menu item to be clicked.
454 menu_observer_.reset(new ContextMenuNotificationObserver(
455 IDC_CONTENT_CONTEXT_SEARCHWEBFORIMAGE));
456 content::WebContents* tab =
457 browser()->tab_strip_model()->GetActiveWebContents();
458 content::SimulateMouseClickAt(tab, 0, blink::WebMouseEvent::ButtonRight,
459 gfx::Point(15, 15));
462 GURL GetImageSearchURL() {
463 static const char kImageSearchURL[] = "imagesearch";
464 return test_server()->GetURL(kImageSearchURL);
467 private:
468 void SetupImageSearchEngine() {
469 static const char kShortName[] = "test";
470 static const char kSearchURL[] = "search?q={searchTerms}";
471 static const char kImageSearchPostParams[] =
472 "thumb={google:imageThumbnail}";
474 TemplateURLService* model =
475 TemplateURLServiceFactory::GetForProfile(browser()->profile());
476 ASSERT_TRUE(model);
477 ui_test_utils::WaitForTemplateURLServiceToLoad(model);
478 ASSERT_TRUE(model->loaded());
480 TemplateURLData data;
481 data.short_name = base::ASCIIToUTF16(kShortName);
482 data.SetKeyword(data.short_name);
483 data.SetURL(test_server()->GetURL(kSearchURL).spec());
484 data.image_url = GetImageSearchURL().spec();
485 data.image_url_post_params = kImageSearchPostParams;
487 // The model takes ownership of |template_url|.
488 TemplateURL* template_url = new TemplateURL(data);
489 ASSERT_TRUE(model->Add(template_url));
490 model->SetUserSelectedDefaultSearchProvider(template_url);
493 void TearDownInProcessBrowserTestFixture() override {
494 menu_observer_.reset();
497 scoped_ptr<ContextMenuNotificationObserver> menu_observer_;
500 IN_PROC_BROWSER_TEST_F(SearchByImageBrowserTest, ImageSearchWithValidImage) {
501 static const char kValidImage[] = "files/image_search/valid.png";
502 SetupAndLoadImagePage(kValidImage);
504 ui_test_utils::WindowedTabAddedNotificationObserver tab_observer(
505 content::NotificationService::AllSources());
506 AttemptImageSearch();
508 // The browser should open a new tab for an image search.
509 tab_observer.Wait();
510 content::WebContents* new_tab = tab_observer.GetTab();
511 content::WaitForLoadStop(new_tab);
512 EXPECT_EQ(GetImageSearchURL(), new_tab->GetURL());
515 IN_PROC_BROWSER_TEST_F(SearchByImageBrowserTest, ImageSearchWithCorruptImage) {
516 static const char kCorruptImage[] = "files/image_search/corrupt.png";
517 SetupAndLoadImagePage(kCorruptImage);
519 content::WebContents* tab =
520 browser()->tab_strip_model()->GetActiveWebContents();
521 ThumbnailResponseWatcher watcher(tab->GetRenderProcessHost());
522 AttemptImageSearch();
524 // The browser should receive a response from the renderer, because the
525 // renderer should not crash.
526 EXPECT_EQ(ThumbnailResponseWatcher::THUMBNAIL_RECEIVED, watcher.Wait());
529 } // namespace