1// Copyright (c) 2012 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.
4
5#include <list>
6#include <set>
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/weak_ptr.h"
10#include "base/strings/stringprintf.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/app/chrome_command_ids.h"
13#include "chrome/browser/browser_process.h"
14#include "chrome/browser/chrome_browser_main.h"
15#include "chrome/browser/chrome_browser_main_extra_parts.h"
16#include "chrome/browser/chrome_content_browser_client.h"
17#include "chrome/browser/chrome_notification_types.h"
18#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
19#include "chrome/browser/extensions/extension_apitest.h"
20#include "chrome/browser/extensions/extension_service.h"
21#include "chrome/browser/extensions/extension_system.h"
22#include "chrome/browser/profiles/profile.h"
23#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
24#include "chrome/browser/tab_contents/render_view_context_menu.h"
25#include "chrome/browser/ui/browser.h"
26#include "chrome/browser/ui/tabs/tab_strip_model.h"
27#include "chrome/test/base/ui_test_utils.h"
28#include "content/public/browser/browser_thread.h"
29#include "content/public/browser/render_process_host.h"
30#include "content/public/browser/render_view_host.h"
31#include "content/public/browser/resource_controller.h"
32#include "content/public/browser/resource_dispatcher_host.h"
33#include "content/public/browser/resource_throttle.h"
34#include "content/public/browser/web_contents.h"
35#include "content/public/common/context_menu_params.h"
36#include "content/public/common/url_constants.h"
37#include "content/public/test/browser_test_utils.h"
38#include "extensions/common/switches.h"
39#include "net/dns/mock_host_resolver.h"
40#include "net/test/embedded_test_server/embedded_test_server.h"
41#include "third_party/WebKit/public/web/WebContextMenuData.h"
42#include "third_party/WebKit/public/web/WebInputEvent.h"
43#include "webkit/common/resource_type.h"
44
45using content::WebContents;
46
47namespace extensions {
48
49namespace {
50
51// An UI-less RenderViewContextMenu.
52class TestRenderViewContextMenu : public RenderViewContextMenu {
53 public:
54  TestRenderViewContextMenu(WebContents* web_contents,
55                            const content::ContextMenuParams& params)
56      : RenderViewContextMenu(web_contents, params) {
57  }
58  virtual ~TestRenderViewContextMenu() {}
59
60 private:
61  virtual void PlatformInit() OVERRIDE {}
62  virtual void PlatformCancel() OVERRIDE {}
63  virtual bool GetAcceleratorForCommandId(int, ui::Accelerator*) OVERRIDE {
64    return false;
65  }
66
67  DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
68};
69
70
71// This class can defer requests for arbitrary URLs.
72class TestNavigationListener
73    : public base::RefCountedThreadSafe<TestNavigationListener> {
74 public:
75  TestNavigationListener() {}
76
77  // Add |url| to the set of URLs we should delay.
78  void DelayRequestsForURL(const GURL& url) {
79    if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
80      content::BrowserThread::PostTask(
81          content::BrowserThread::IO,
82          FROM_HERE,
83          base::Bind(&TestNavigationListener::DelayRequestsForURL, this, url));
84      return;
85    }
86    urls_to_delay_.insert(url);
87  }
88
89  // Resume all deferred requests.
90  void ResumeAll() {
91    if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
92      content::BrowserThread::PostTask(
93          content::BrowserThread::IO,
94          FROM_HERE,
95          base::Bind(&TestNavigationListener::ResumeAll, this));
96      return;
97    }
98    WeakThrottleList::const_iterator it;
99    for (it = throttles_.begin(); it != throttles_.end(); ++it) {
100      if (it->get())
101        (*it)->Resume();
102    }
103    throttles_.clear();
104  }
105
106  // Constructs a ResourceThrottle if the request for |url| should be held.
107  //
108  // Needs to be invoked on the IO thread.
109  content::ResourceThrottle* CreateResourceThrottle(
110      const GURL& url,
111      ResourceType::Type resource_type) {
112    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
113    if (urls_to_delay_.find(url) == urls_to_delay_.end())
114      return NULL;
115
116    Throttle* throttle = new Throttle();
117    throttles_.push_back(throttle->AsWeakPtr());
118    return throttle;
119  }
120
121 private:
122  friend class base::RefCountedThreadSafe<TestNavigationListener>;
123
124  virtual ~TestNavigationListener() {}
125
126  // Stores a throttle per URL request that we have delayed.
127  class Throttle : public content::ResourceThrottle,
128                   public base::SupportsWeakPtr<Throttle> {
129   public:
130    void Resume() {
131      controller()->Resume();
132    }
133
134    // content::ResourceThrottle implementation.
135    virtual void WillStartRequest(bool* defer) OVERRIDE {
136      *defer = true;
137    }
138  };
139  typedef base::WeakPtr<Throttle> WeakThrottle;
140  typedef std::list<WeakThrottle> WeakThrottleList;
141  WeakThrottleList throttles_;
142
143  // The set of URLs to be delayed.
144  std::set<GURL> urls_to_delay_;
145
146  DISALLOW_COPY_AND_ASSIGN(TestNavigationListener);
147};
148
149// Waits for a WC to be created. Once it starts loading |delay_url| (after at
150// least the first navigation has committed), it delays the load, executes
151// |script| in the last committed RVH and resumes the load when |until_url|
152// commits. This class expects |script| to trigger the load of |until_url|.
153class DelayLoadStartAndExecuteJavascript
154    : public content::NotificationObserver,
155      public content::WebContentsObserver {
156 public:
157  DelayLoadStartAndExecuteJavascript(
158      TestNavigationListener* test_navigation_listener,
159      const GURL& delay_url,
160      const std::string& script,
161      const GURL& until_url)
162      : content::WebContentsObserver(),
163        test_navigation_listener_(test_navigation_listener),
164        delay_url_(delay_url),
165        until_url_(until_url),
166        script_(script),
167        script_was_executed_(false),
168        rvh_(NULL) {
169    registrar_.Add(this,
170                   chrome::NOTIFICATION_TAB_ADDED,
171                   content::NotificationService::AllSources());
172    test_navigation_listener_->DelayRequestsForURL(delay_url_);
173  }
174  virtual ~DelayLoadStartAndExecuteJavascript() {}
175
176  virtual void Observe(int type,
177                       const content::NotificationSource& source,
178                       const content::NotificationDetails& details) OVERRIDE {
179    if (type != chrome::NOTIFICATION_TAB_ADDED) {
180      NOTREACHED();
181      return;
182    }
183    content::WebContentsObserver::Observe(
184        content::Details<content::WebContents>(details).ptr());
185    registrar_.RemoveAll();
186  }
187
188  virtual void DidStartProvisionalLoadForFrame(
189      int64 frame_id,
190      int64 parent_frame_id,
191      bool is_main_frame,
192      const GURL& validated_url,
193      bool is_error_page,
194      bool is_iframe_srcdoc,
195      content::RenderViewHost* render_view_host) OVERRIDE {
196    if (validated_url != delay_url_ || !rvh_)
197      return;
198
199    rvh_->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(script_));
200    script_was_executed_ = true;
201  }
202
203  virtual void DidCommitProvisionalLoadForFrame(
204      int64 frame_id,
205      bool is_main_frame,
206      const GURL& url,
207      content::PageTransition transition_type,
208      content::RenderViewHost* render_view_host) OVERRIDE {
209    if (script_was_executed_ && url == until_url_) {
210      content::WebContentsObserver::Observe(NULL);
211      test_navigation_listener_->ResumeAll();
212    }
213    rvh_ = render_view_host;
214  }
215
216 private:
217  content::NotificationRegistrar registrar_;
218
219  scoped_refptr<TestNavigationListener> test_navigation_listener_;
220
221  GURL delay_url_;
222  GURL until_url_;
223  std::string script_;
224  bool script_was_executed_;
225  content::RenderViewHost* rvh_;
226
227  DISALLOW_COPY_AND_ASSIGN(DelayLoadStartAndExecuteJavascript);
228};
229
230// A ResourceDispatcherHostDelegate that adds a TestNavigationObserver.
231class TestResourceDispatcherHostDelegate
232    : public ChromeResourceDispatcherHostDelegate {
233 public:
234  TestResourceDispatcherHostDelegate(
235      prerender::PrerenderTracker* prerender_tracker,
236      TestNavigationListener* test_navigation_listener)
237      : ChromeResourceDispatcherHostDelegate(prerender_tracker),
238        test_navigation_listener_(test_navigation_listener) {
239  }
240  virtual ~TestResourceDispatcherHostDelegate() {}
241
242  virtual void RequestBeginning(
243      net::URLRequest* request,
244      content::ResourceContext* resource_context,
245      appcache::AppCacheService* appcache_service,
246      ResourceType::Type resource_type,
247      int child_id,
248      int route_id,
249      bool is_continuation_of_transferred_request,
250      ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE {
251    ChromeResourceDispatcherHostDelegate::RequestBeginning(
252        request,
253        resource_context,
254        appcache_service,
255        resource_type,
256        child_id,
257        route_id,
258        is_continuation_of_transferred_request,
259        throttles);
260    content::ResourceThrottle* throttle =
261        test_navigation_listener_->CreateResourceThrottle(request->url(),
262                                                          resource_type);
263    if (throttle)
264      throttles->push_back(throttle);
265  }
266
267 private:
268  scoped_refptr<TestNavigationListener> test_navigation_listener_;
269
270  DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
271};
272
273// Used to manage the lifetime of the TestResourceDispatcherHostDelegate which
274// needs to be deleted before the threads are stopped.
275class TestBrowserMainExtraParts : public ChromeBrowserMainExtraParts {
276 public:
277  explicit TestBrowserMainExtraParts(
278      TestNavigationListener* test_navigation_listener)
279      : test_navigation_listener_(test_navigation_listener) {
280  }
281  virtual ~TestBrowserMainExtraParts() {}
282
283  TestResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() {
284    if (!resource_dispatcher_host_delegate_.get()) {
285      resource_dispatcher_host_delegate_.reset(
286          new TestResourceDispatcherHostDelegate(
287              g_browser_process->prerender_tracker(),
288              test_navigation_listener_.get()));
289    }
290    return resource_dispatcher_host_delegate_.get();
291  }
292
293  // ChromeBrowserMainExtraParts implementation.
294  virtual void PostMainMessageLoopRun() OVERRIDE {
295    resource_dispatcher_host_delegate_.reset();
296  }
297
298 private:
299  scoped_refptr<TestNavigationListener> test_navigation_listener_;
300  scoped_ptr<TestResourceDispatcherHostDelegate>
301      resource_dispatcher_host_delegate_;
302
303  DISALLOW_COPY_AND_ASSIGN(TestBrowserMainExtraParts);
304};
305
306// A ContentBrowserClient that doesn't forward the RDH created signal.
307class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
308 public:
309  explicit TestContentBrowserClient(
310      TestNavigationListener* test_navigation_listener)
311      : test_navigation_listener_(test_navigation_listener) {
312  }
313  virtual ~TestContentBrowserClient() {}
314
315  virtual void ResourceDispatcherHostCreated() OVERRIDE {
316    // Don't invoke ChromeContentBrowserClient::ResourceDispatcherHostCreated.
317    // It would notify BrowserProcessImpl which would create a
318    // ChromeResourceDispatcherHostDelegate and other objects. Not creating
319    // other objects might turn out to be a problem in the future.
320    content::ResourceDispatcherHost::Get()->SetDelegate(
321        browser_main_extra_parts_->resource_dispatcher_host_delegate());
322  }
323
324  virtual content::BrowserMainParts* CreateBrowserMainParts(
325      const content::MainFunctionParams& parameters) OVERRIDE {
326    ChromeBrowserMainParts* main_parts = static_cast<ChromeBrowserMainParts*>(
327        ChromeContentBrowserClient::CreateBrowserMainParts(parameters));
328
329    browser_main_extra_parts_ =
330        new TestBrowserMainExtraParts(test_navigation_listener_.get());
331    main_parts->AddParts(browser_main_extra_parts_);
332    return main_parts;
333  }
334
335 private:
336  scoped_refptr<TestNavigationListener> test_navigation_listener_;
337  TestBrowserMainExtraParts* browser_main_extra_parts_;
338
339  DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
340};
341
342}  // namespace
343
344class WebNavigationApiTest : public ExtensionApiTest {
345 public:
346  WebNavigationApiTest() {}
347  virtual ~WebNavigationApiTest() {}
348
349  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
350    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
351
352    test_navigation_listener_ = new TestNavigationListener();
353    content_browser_client_.reset(
354        new TestContentBrowserClient(test_navigation_listener_.get()));
355    original_content_browser_client_ = content::SetBrowserClientForTesting(
356        content_browser_client_.get());
357
358    FrameNavigationState::set_allow_extension_scheme(true);
359
360    CommandLine::ForCurrentProcess()->AppendSwitch(
361        switches::kAllowLegacyExtensionManifests);
362
363    host_resolver()->AddRule("*", "127.0.0.1");
364  }
365
366  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
367    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
368    content::SetBrowserClientForTesting(original_content_browser_client_);
369  }
370
371  TestNavigationListener* test_navigation_listener() {
372    return test_navigation_listener_.get();
373  }
374
375 private:
376  scoped_refptr<TestNavigationListener> test_navigation_listener_;
377  scoped_ptr<TestContentBrowserClient> content_browser_client_;
378  content::ContentBrowserClient* original_content_browser_client_;
379
380  DISALLOW_COPY_AND_ASSIGN(WebNavigationApiTest);
381};
382
383// Fails often on Windows dbg bots. http://crbug.com/177163
384#if defined(OS_WIN)
385#define MAYBE_Api DISABLED_Api
386#else
387#define MAYBE_Api Api
388#endif  // defined(OS_WIN)
389IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Api) {
390  ASSERT_TRUE(StartEmbeddedTestServer());
391  ASSERT_TRUE(
392      RunExtensionSubtest("webnavigation", "test_api.html")) << message_;
393}
394
395// Fails often on Windows dbg bots. http://crbug.com/177163
396#if defined(OS_WIN)
397#define MAYBE_GetFrame DISABLED_GetFrame
398#else
399#define MAYBE_GetFrame GetFrame
400#endif  // defined(OS_WIN)
401IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_GetFrame) {
402  ASSERT_TRUE(StartEmbeddedTestServer());
403  ASSERT_TRUE(
404      RunExtensionSubtest("webnavigation", "test_getFrame.html")) << message_;
405}
406
407IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ClientRedirect) {
408  ASSERT_TRUE(StartEmbeddedTestServer());
409  ASSERT_TRUE(
410      RunExtensionSubtest("webnavigation", "test_clientRedirect.html"))
411          << message_;
412}
413
414IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirect) {
415  ASSERT_TRUE(StartEmbeddedTestServer());
416  ASSERT_TRUE(
417      RunExtensionSubtest("webnavigation", "test_serverRedirect.html"))
418          << message_;
419}
420
421// http://crbug.com/235171 and http://crbug.com/177163
422#if (defined(OS_WIN) && !defined(NDEBUG)) || \
423    (defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(USE_AURA)))
424#define MAYBE_ServerRedirectSingleProcess DISABLED_ServerRedirectSingleProcess
425#else
426#define MAYBE_ServerRedirectSingleProcess ServerRedirectSingleProcess
427#endif
428IN_PROC_BROWSER_TEST_F(WebNavigationApiTest,
429                       MAYBE_ServerRedirectSingleProcess) {
430  ASSERT_TRUE(StartEmbeddedTestServer());
431
432  // Set max renderers to 1 to force running out of processes.
433  content::RenderProcessHost::SetMaxRendererProcessCount(1);
434
435  // Wait for the extension to set itself up and return control to us.
436  ASSERT_TRUE(RunExtensionSubtest(
437      "webnavigation", "test_serverRedirectSingleProcess.html"))
438          << message_;
439
440  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
441  content::WaitForLoadStop(tab);
442
443  ResultCatcher catcher;
444  GURL url(base::StringPrintf(
445      "http://www.a.com:%d/"
446          "extensions/api_test/webnavigation/serverRedirect/a.html",
447      embedded_test_server()->port()));
448
449  ui_test_utils::NavigateToURL(browser(), url);
450
451  url = GURL(base::StringPrintf(
452      "http://www.b.com:%d/server-redirect?http://www.b.com:%d/",
453      embedded_test_server()->port(),
454      embedded_test_server()->port()));
455
456  ui_test_utils::NavigateToURL(browser(), url);
457
458  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
459}
460
461IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ForwardBack) {
462  ASSERT_TRUE(StartEmbeddedTestServer());
463  ASSERT_TRUE(
464      RunExtensionSubtest("webnavigation", "test_forwardBack.html"))
465          << message_;
466}
467
468IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, IFrame) {
469  ASSERT_TRUE(StartEmbeddedTestServer());
470  ASSERT_TRUE(
471      RunExtensionSubtest("webnavigation", "test_iframe.html")) << message_;
472}
473
474IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SrcDoc) {
475  ASSERT_TRUE(StartEmbeddedTestServer());
476  ASSERT_TRUE(
477      RunExtensionSubtest("webnavigation", "test_srcdoc.html")) << message_;
478}
479
480IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, OpenTab) {
481  ASSERT_TRUE(StartEmbeddedTestServer());
482  ASSERT_TRUE(
483      RunExtensionSubtest("webnavigation", "test_openTab.html")) << message_;
484}
485
486IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ReferenceFragment) {
487  ASSERT_TRUE(StartEmbeddedTestServer());
488  ASSERT_TRUE(
489      RunExtensionSubtest("webnavigation", "test_referenceFragment.html"))
490          << message_;
491}
492
493IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SimpleLoad) {
494  ASSERT_TRUE(StartEmbeddedTestServer());
495  ASSERT_TRUE(
496      RunExtensionSubtest("webnavigation", "test_simpleLoad.html")) << message_;
497}
498
499// Fails often on Windows dbg bots. http://crbug.com/177163
500#if defined(OS_WIN)
501#define MAYBE_Failures DISABLED_Failures
502#else
503#define MAYBE_Failures Failures
504#endif  // defined(OS_WIN)
505IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Failures) {
506  ASSERT_TRUE(StartEmbeddedTestServer());
507  ASSERT_TRUE(
508      RunExtensionSubtest("webnavigation", "test_failures.html")) << message_;
509}
510
511IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, FilteredTest) {
512  ASSERT_TRUE(StartEmbeddedTestServer());
513  ASSERT_TRUE(
514      RunExtensionSubtest("webnavigation", "test_filtered.html")) << message_;
515}
516
517// Fails often on Windows dbg bots. http://crbug.com/177163
518#if defined(OS_WIN)
519#define MAYBE_UserAction DISABLED_UserAction
520#else
521#define MAYBE_UserAction UserAction
522#endif  // defined(OS_WIN)
523IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_UserAction) {
524  ASSERT_TRUE(StartEmbeddedTestServer());
525
526  // Wait for the extension to set itself up and return control to us.
527  ASSERT_TRUE(
528      RunExtensionSubtest("webnavigation", "test_userAction.html")) << message_;
529
530  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
531  content::WaitForLoadStop(tab);
532
533  ResultCatcher catcher;
534
535  ExtensionService* service = extensions::ExtensionSystem::Get(
536      browser()->profile())->extension_service();
537  const extensions::Extension* extension =
538      service->GetExtensionById(last_loaded_extension_id_, false);
539  GURL url = extension->GetResourceURL("userAction/a.html");
540
541  ui_test_utils::NavigateToURL(browser(), url);
542
543  // This corresponds to "Open link in new tab".
544  content::ContextMenuParams params;
545  params.is_editable = false;
546  params.media_type = WebKit::WebContextMenuData::MediaTypeNone;
547  params.page_url = url;
548  params.frame_id = WebNavigationTabObserver::Get(tab)->
549      frame_navigation_state().GetMainFrameID().frame_num;
550  params.link_url = extension->GetResourceURL("userAction/b.html");
551
552  TestRenderViewContextMenu menu(tab, params);
553  menu.Init();
554  menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
555
556  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
557}
558
559// http://crbug.com/177163
560#if defined(OS_WIN) && !defined(NDEBUG)
561#define MAYBE_RequestOpenTab DISABLED_RequestOpenTab
562#else
563#define MAYBE_RequestOpenTab RequestOpenTab
564#endif
565IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_RequestOpenTab) {
566  ASSERT_TRUE(StartEmbeddedTestServer());
567
568  // Wait for the extension to set itself up and return control to us.
569  ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_requestOpenTab.html"))
570      << message_;
571
572  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
573  content::WaitForLoadStop(tab);
574
575  ResultCatcher catcher;
576
577  ExtensionService* service = extensions::ExtensionSystem::Get(
578      browser()->profile())->extension_service();
579  const extensions::Extension* extension =
580      service->GetExtensionById(last_loaded_extension_id_, false);
581  GURL url = extension->GetResourceURL("requestOpenTab/a.html");
582
583  ui_test_utils::NavigateToURL(browser(), url);
584
585  // There's a link on a.html. Middle-click on it to open it in a new tab.
586  WebKit::WebMouseEvent mouse_event;
587  mouse_event.type = WebKit::WebInputEvent::MouseDown;
588  mouse_event.button = WebKit::WebMouseEvent::ButtonMiddle;
589  mouse_event.x = 7;
590  mouse_event.y = 7;
591  mouse_event.clickCount = 1;
592  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
593  mouse_event.type = WebKit::WebInputEvent::MouseUp;
594  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
595
596  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
597}
598
599// Fails often on Windows dbg bots. http://crbug.com/177163
600#if defined(OS_WIN)
601#define MAYBE_TargetBlank DISABLED_TargetBlank
602#else
603#define MAYBE_TargetBlank TargetBlank
604#endif  // defined(OS_WIN)
605IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_TargetBlank) {
606  ASSERT_TRUE(StartEmbeddedTestServer());
607
608  // Wait for the extension to set itself up and return control to us.
609  ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_targetBlank.html"))
610      << message_;
611
612  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
613  content::WaitForLoadStop(tab);
614
615  ResultCatcher catcher;
616
617  GURL url = embedded_test_server()->GetURL(
618      "/extensions/api_test/webnavigation/targetBlank/a.html");
619
620  chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_LINK);
621  ui_test_utils::NavigateToURL(&params);
622
623  // There's a link with target=_blank on a.html. Click on it to open it in a
624  // new tab.
625  WebKit::WebMouseEvent mouse_event;
626  mouse_event.type = WebKit::WebInputEvent::MouseDown;
627  mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
628  mouse_event.x = 7;
629  mouse_event.y = 7;
630  mouse_event.clickCount = 1;
631  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
632  mouse_event.type = WebKit::WebInputEvent::MouseUp;
633  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
634
635  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
636}
637
638// http://crbug.com/177163
639#if defined(OS_WIN) && !defined(NDEBUG)
640#define MAYBE_TargetBlankIncognito DISABLED_TargetBlankIncognito
641#else
642#define MAYBE_TargetBlankIncognito TargetBlankIncognito
643#endif
644IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_TargetBlankIncognito) {
645  ASSERT_TRUE(StartEmbeddedTestServer());
646
647  // Wait for the extension to set itself up and return control to us.
648  ASSERT_TRUE(RunExtensionSubtest(
649      "webnavigation", "test_targetBlank.html",
650      ExtensionApiTest::kFlagEnableIncognito)) << message_;
651
652  ResultCatcher catcher;
653
654  GURL url = embedded_test_server()->GetURL(
655      "/extensions/api_test/webnavigation/targetBlank/a.html");
656
657  Browser* otr_browser = ui_test_utils::OpenURLOffTheRecord(
658      browser()->profile(), url);
659  WebContents* tab = otr_browser->tab_strip_model()->GetActiveWebContents();
660
661  // There's a link with target=_blank on a.html. Click on it to open it in a
662  // new tab.
663  WebKit::WebMouseEvent mouse_event;
664  mouse_event.type = WebKit::WebInputEvent::MouseDown;
665  mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
666  mouse_event.x = 7;
667  mouse_event.y = 7;
668  mouse_event.clickCount = 1;
669  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
670  mouse_event.type = WebKit::WebInputEvent::MouseUp;
671  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
672
673  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
674}
675
676IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, History) {
677  ASSERT_TRUE(StartEmbeddedTestServer());
678  ASSERT_TRUE(
679      RunExtensionSubtest("webnavigation", "test_history.html"))
680          << message_;
681}
682
683IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcess) {
684  ASSERT_TRUE(StartEmbeddedTestServer());
685
686  LoadExtension(test_data_dir_.AppendASCII("webnavigation").AppendASCII("app"));
687  LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
688
689  ExtensionService* service = extensions::ExtensionSystem::Get(
690      browser()->profile())->extension_service();
691  const extensions::Extension* extension =
692      service->GetExtensionById(last_loaded_extension_id_, false);
693
694  // See crossProcess/d.html.
695  DelayLoadStartAndExecuteJavascript call_script(
696      test_navigation_listener(),
697      embedded_test_server()->GetURL("/test1"),
698      "navigate2()",
699      extension->GetResourceURL("crossProcess/empty.html"));
700
701  ASSERT_TRUE(RunPageTest(
702      extension->GetResourceURL("test_crossProcess.html").spec()))
703          << message_;
704}
705
706IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessFragment) {
707  ASSERT_TRUE(StartEmbeddedTestServer());
708
709  LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
710
711  ExtensionService* service = extensions::ExtensionSystem::Get(
712      browser()->profile())->extension_service();
713  const extensions::Extension* extension =
714      service->GetExtensionById(last_loaded_extension_id_, false);
715
716  // See crossProcess/f.html.
717  DelayLoadStartAndExecuteJavascript call_script3(
718      test_navigation_listener(),
719      embedded_test_server()->GetURL("/test3"),
720      "updateFragment()",
721      extension->GetResourceURL(base::StringPrintf(
722          "crossProcess/f.html?%d#foo",
723          embedded_test_server()->port())));
724
725  // See crossProcess/g.html.
726  DelayLoadStartAndExecuteJavascript call_script4(
727      test_navigation_listener(),
728      embedded_test_server()->GetURL("/test4"),
729      "updateFragment()",
730      extension->GetResourceURL(base::StringPrintf(
731          "crossProcess/g.html?%d#foo",
732          embedded_test_server()->port())));
733
734  ASSERT_TRUE(RunPageTest(
735      extension->GetResourceURL("test_crossProcessFragment.html").spec()))
736          << message_;
737}
738
739IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessHistory) {
740  ASSERT_TRUE(StartEmbeddedTestServer());
741
742  LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
743
744  ExtensionService* service = extensions::ExtensionSystem::Get(
745      browser()->profile())->extension_service();
746  const extensions::Extension* extension =
747      service->GetExtensionById(last_loaded_extension_id_, false);
748
749  // See crossProcess/e.html.
750  DelayLoadStartAndExecuteJavascript call_script2(
751      test_navigation_listener(),
752      embedded_test_server()->GetURL("/test2"),
753      "updateHistory()",
754      extension->GetResourceURL("crossProcess/empty.html"));
755
756  // See crossProcess/h.html.
757  DelayLoadStartAndExecuteJavascript call_script5(
758      test_navigation_listener(),
759      embedded_test_server()->GetURL("/test5"),
760      "updateHistory()",
761      extension->GetResourceURL("crossProcess/empty.html"));
762
763  // See crossProcess/i.html.
764  DelayLoadStartAndExecuteJavascript call_script6(
765      test_navigation_listener(),
766      embedded_test_server()->GetURL("/test6"),
767      "updateHistory()",
768      extension->GetResourceURL("crossProcess/empty.html"));
769
770  ASSERT_TRUE(RunPageTest(
771      extension->GetResourceURL("test_crossProcessHistory.html").spec()))
772          << message_;
773}
774
775// http://crbug.com/177163
776#if defined(OS_WIN) && !defined(NDEBUG)
777#define MAYBE_Crash DISABLED_Crash
778#else
779#define MAYBE_Crash Crash
780#endif
781IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Crash) {
782  ASSERT_TRUE(StartEmbeddedTestServer());
783
784  // Wait for the extension to set itself up and return control to us.
785  ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_crash.html"))
786      << message_;
787
788  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
789  content::WaitForLoadStop(tab);
790
791  ResultCatcher catcher;
792
793  GURL url(base::StringPrintf(
794      "http://www.a.com:%d/"
795          "extensions/api_test/webnavigation/crash/a.html",
796      embedded_test_server()->port()));
797  ui_test_utils::NavigateToURL(browser(), url);
798
799  ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL));
800
801  url = GURL(base::StringPrintf(
802      "http://www.a.com:%d/"
803          "extensions/api_test/webnavigation/crash/b.html",
804      embedded_test_server()->port()));
805  ui_test_utils::NavigateToURL(browser(), url);
806
807  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
808}
809
810}  // namespace extensions
811