Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / web_navigation / web_navigation_apitest.cc
blob501248d1231533f2351788e9a139763105fb5e3b
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.
5 #include <list>
6 #include <set>
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chrome_browser_main.h"
17 #include "chrome/browser/chrome_browser_main_extra_parts.h"
18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/download/download_browsertest.h"
21 #include "chrome/browser/download/download_prefs.h"
22 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
23 #include "chrome/browser/extensions/extension_apitest.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
27 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
28 #include "chrome/browser/ui/browser.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/test/base/ui_test_utils.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/browser/render_process_host.h"
34 #include "content/public/browser/render_view_host.h"
35 #include "content/public/browser/resource_controller.h"
36 #include "content/public/browser/resource_dispatcher_host.h"
37 #include "content/public/browser/resource_throttle.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/common/context_menu_params.h"
40 #include "content/public/common/resource_type.h"
41 #include "content/public/common/url_constants.h"
42 #include "content/public/test/browser_test_utils.h"
43 #include "extensions/browser/extension_system.h"
44 #include "extensions/common/switches.h"
45 #include "extensions/test/result_catcher.h"
46 #include "net/dns/mock_host_resolver.h"
47 #include "net/test/embedded_test_server/embedded_test_server.h"
48 #include "third_party/WebKit/public/web/WebContextMenuData.h"
49 #include "third_party/WebKit/public/web/WebInputEvent.h"
51 using content::ResourceType;
52 using content::WebContents;
54 namespace extensions {
56 namespace {
58 // This class can defer requests for arbitrary URLs.
59 class TestNavigationListener
60 : public base::RefCountedThreadSafe<TestNavigationListener> {
61 public:
62 TestNavigationListener() {}
64 // Add |url| to the set of URLs we should delay.
65 void DelayRequestsForURL(const GURL& url) {
66 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
67 content::BrowserThread::PostTask(
68 content::BrowserThread::IO,
69 FROM_HERE,
70 base::Bind(&TestNavigationListener::DelayRequestsForURL, this, url));
71 return;
73 urls_to_delay_.insert(url);
76 // Resume all deferred requests.
77 void ResumeAll() {
78 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
79 content::BrowserThread::PostTask(
80 content::BrowserThread::IO,
81 FROM_HERE,
82 base::Bind(&TestNavigationListener::ResumeAll, this));
83 return;
85 WeakThrottleList::const_iterator it;
86 for (it = throttles_.begin(); it != throttles_.end(); ++it) {
87 if (it->get())
88 (*it)->Resume();
90 throttles_.clear();
93 // Resume a specific request.
94 void Resume(const GURL& url) {
95 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
96 content::BrowserThread::PostTask(
97 content::BrowserThread::IO, FROM_HERE,
98 base::Bind(&TestNavigationListener::Resume, this, url));
99 return;
101 WeakThrottleList::iterator it;
102 for (it = throttles_.begin(); it != throttles_.end(); ++it) {
103 if (it->get() && it->get()->url() == url) {
104 (*it)->Resume();
105 throttles_.erase(it);
106 break;
111 // Constructs a ResourceThrottle if the request for |url| should be held.
113 // Needs to be invoked on the IO thread.
114 content::ResourceThrottle* CreateResourceThrottle(
115 const GURL& url,
116 ResourceType resource_type) {
117 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
118 if (urls_to_delay_.find(url) == urls_to_delay_.end())
119 return NULL;
121 Throttle* throttle = new Throttle();
122 throttle->set_url(url);
123 throttles_.push_back(throttle->AsWeakPtr());
124 return throttle;
127 private:
128 friend class base::RefCountedThreadSafe<TestNavigationListener>;
130 virtual ~TestNavigationListener() {}
132 // Stores a throttle per URL request that we have delayed.
133 class Throttle : public content::ResourceThrottle,
134 public base::SupportsWeakPtr<Throttle> {
135 public:
136 void Resume() {
137 controller()->Resume();
140 // content::ResourceThrottle implementation.
141 void WillStartRequest(bool* defer) override { *defer = true; }
143 const char* GetNameForLogging() const override {
144 return "TestNavigationListener::Throttle";
147 void set_url(const GURL& url) { url_ = url; }
148 const GURL& url() { return url_; }
150 private:
151 GURL url_;
153 typedef base::WeakPtr<Throttle> WeakThrottle;
154 typedef std::list<WeakThrottle> WeakThrottleList;
155 WeakThrottleList throttles_;
157 // The set of URLs to be delayed.
158 std::set<GURL> urls_to_delay_;
160 DISALLOW_COPY_AND_ASSIGN(TestNavigationListener);
163 // Waits for a WC to be created. Once it starts loading |delay_url| (after at
164 // least the first navigation has committed), it delays the load, executes
165 // |script| in the last committed RVH and resumes the load when a URL ending in
166 // |until_url_suffix| commits. This class expects |script| to trigger the load
167 // of an URL ending in |until_url_suffix|.
168 class DelayLoadStartAndExecuteJavascript
169 : public content::NotificationObserver,
170 public content::WebContentsObserver {
171 public:
172 DelayLoadStartAndExecuteJavascript(
173 TestNavigationListener* test_navigation_listener,
174 const GURL& delay_url,
175 const std::string& script,
176 const std::string& until_url_suffix)
177 : content::WebContentsObserver(),
178 test_navigation_listener_(test_navigation_listener),
179 delay_url_(delay_url),
180 until_url_suffix_(until_url_suffix),
181 script_(script),
182 has_user_gesture_(false),
183 script_was_executed_(false),
184 rvh_(NULL) {
185 registrar_.Add(this,
186 chrome::NOTIFICATION_TAB_ADDED,
187 content::NotificationService::AllSources());
188 test_navigation_listener_->DelayRequestsForURL(delay_url_);
190 ~DelayLoadStartAndExecuteJavascript() override {}
192 void Observe(int type,
193 const content::NotificationSource& source,
194 const content::NotificationDetails& details) override {
195 if (type != chrome::NOTIFICATION_TAB_ADDED) {
196 NOTREACHED();
197 return;
199 content::WebContentsObserver::Observe(
200 content::Details<content::WebContents>(details).ptr());
201 registrar_.RemoveAll();
204 void DidStartProvisionalLoadForFrame(
205 content::RenderFrameHost* render_frame_host,
206 const GURL& validated_url,
207 bool is_error_page,
208 bool is_iframe_srcdoc) override {
209 if (validated_url != delay_url_ || !rvh_)
210 return;
212 if (has_user_gesture_) {
213 rvh_->GetMainFrame()->ExecuteJavaScriptForTests(
214 base::UTF8ToUTF16(script_));
215 } else {
216 rvh_->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(script_));
218 script_was_executed_ = true;
221 void DidCommitProvisionalLoadForFrame(
222 content::RenderFrameHost* render_frame_host,
223 const GURL& url,
224 ui::PageTransition transition_type) override {
225 if (script_was_executed_ && EndsWith(url.spec(), until_url_suffix_, true)) {
226 content::WebContentsObserver::Observe(NULL);
227 test_navigation_listener_->ResumeAll();
229 rvh_ = render_frame_host->GetRenderViewHost();
232 void set_has_user_gesture(bool has_user_gesture) {
233 has_user_gesture_ = has_user_gesture;
236 private:
237 content::NotificationRegistrar registrar_;
239 scoped_refptr<TestNavigationListener> test_navigation_listener_;
241 GURL delay_url_;
242 std::string until_url_suffix_;
243 std::string script_;
244 bool has_user_gesture_;
245 bool script_was_executed_;
246 content::RenderViewHost* rvh_;
248 DISALLOW_COPY_AND_ASSIGN(DelayLoadStartAndExecuteJavascript);
251 class StartProvisionalLoadObserver : public content::WebContentsObserver {
252 public:
253 StartProvisionalLoadObserver(WebContents* web_contents,
254 const GURL& expected_url)
255 : content::WebContentsObserver(web_contents),
256 url_(expected_url),
257 url_seen_(false),
258 message_loop_runner_(new content::MessageLoopRunner) {}
259 ~StartProvisionalLoadObserver() override {}
261 void DidStartProvisionalLoadForFrame(
262 content::RenderFrameHost* render_frame_host,
263 const GURL& validated_url,
264 bool is_error_page,
265 bool is_iframe_srcdoc) override {
266 if (validated_url == url_) {
267 url_seen_ = true;
268 message_loop_runner_->Quit();
272 // Run a nested message loop until navigation to the expected URL has started.
273 void Wait() {
274 if (url_seen_)
275 return;
277 message_loop_runner_->Run();
280 private:
281 GURL url_;
282 bool url_seen_;
284 // The MessageLoopRunner used to spin the message loop during Wait().
285 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
287 DISALLOW_COPY_AND_ASSIGN(StartProvisionalLoadObserver);
290 // A ResourceDispatcherHostDelegate that adds a TestNavigationObserver.
291 class TestResourceDispatcherHostDelegate
292 : public ChromeResourceDispatcherHostDelegate {
293 public:
294 explicit TestResourceDispatcherHostDelegate(
295 TestNavigationListener* test_navigation_listener)
296 : test_navigation_listener_(test_navigation_listener) {
298 ~TestResourceDispatcherHostDelegate() override {}
300 void RequestBeginning(
301 net::URLRequest* request,
302 content::ResourceContext* resource_context,
303 content::AppCacheService* appcache_service,
304 ResourceType resource_type,
305 ScopedVector<content::ResourceThrottle>* throttles) override {
306 ChromeResourceDispatcherHostDelegate::RequestBeginning(
307 request,
308 resource_context,
309 appcache_service,
310 resource_type,
311 throttles);
312 content::ResourceThrottle* throttle =
313 test_navigation_listener_->CreateResourceThrottle(request->url(),
314 resource_type);
315 if (throttle)
316 throttles->push_back(throttle);
319 private:
320 scoped_refptr<TestNavigationListener> test_navigation_listener_;
322 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
325 } // namespace
327 class WebNavigationApiTest : public ExtensionApiTest {
328 public:
329 WebNavigationApiTest() {}
330 ~WebNavigationApiTest() override {}
332 void SetUpInProcessBrowserTestFixture() override {
333 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
335 FrameNavigationState::set_allow_extension_scheme(true);
337 base::CommandLine::ForCurrentProcess()->AppendSwitch(
338 switches::kAllowLegacyExtensionManifests);
340 host_resolver()->AddRule("*", "127.0.0.1");
343 void SetUpOnMainThread() override {
344 ExtensionApiTest::SetUpOnMainThread();
345 test_navigation_listener_ = new TestNavigationListener();
346 resource_dispatcher_host_delegate_.reset(
347 new TestResourceDispatcherHostDelegate(
348 test_navigation_listener_.get()));
349 content::ResourceDispatcherHost::Get()->SetDelegate(
350 resource_dispatcher_host_delegate_.get());
353 TestNavigationListener* test_navigation_listener() {
354 return test_navigation_listener_.get();
357 private:
358 scoped_refptr<TestNavigationListener> test_navigation_listener_;
359 scoped_ptr<TestResourceDispatcherHostDelegate>
360 resource_dispatcher_host_delegate_;
362 DISALLOW_COPY_AND_ASSIGN(WebNavigationApiTest);
365 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Api) {
366 ASSERT_TRUE(StartEmbeddedTestServer());
367 ASSERT_TRUE(RunExtensionTest("webnavigation/api")) << message_;
370 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, GetFrame) {
371 ASSERT_TRUE(StartEmbeddedTestServer());
372 ASSERT_TRUE(RunExtensionTest("webnavigation/getFrame")) << message_;
375 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ClientRedirect) {
376 ASSERT_TRUE(StartEmbeddedTestServer());
377 ASSERT_TRUE(RunExtensionTest("webnavigation/clientRedirect"))
378 << message_;
381 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirect) {
382 ASSERT_TRUE(StartEmbeddedTestServer());
383 ASSERT_TRUE(RunExtensionTest("webnavigation/serverRedirect"))
384 << message_;
387 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Download) {
388 base::ScopedTempDir download_directory;
389 ASSERT_TRUE(download_directory.CreateUniqueTempDir());
390 DownloadPrefs* download_prefs =
391 DownloadPrefs::FromBrowserContext(browser()->profile());
392 download_prefs->SetDownloadPath(download_directory.path());
394 DownloadTestObserverNotInProgress download_observer(
395 content::BrowserContext::GetDownloadManager(profile()), 1);
396 download_observer.StartObserving();
397 ASSERT_TRUE(StartEmbeddedTestServer());
398 ASSERT_TRUE(RunExtensionTest("webnavigation/download"))
399 << message_;
400 download_observer.WaitForFinished();
403 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirectSingleProcess) {
404 ASSERT_TRUE(StartEmbeddedTestServer());
406 // Set max renderers to 1 to force running out of processes.
407 content::RenderProcessHost::SetMaxRendererProcessCount(1);
409 // Wait for the extension to set itself up and return control to us.
410 ASSERT_TRUE(
411 RunExtensionTest("webnavigation/serverRedirectSingleProcess"))
412 << message_;
414 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
415 content::WaitForLoadStop(tab);
417 ResultCatcher catcher;
418 GURL url(base::StringPrintf(
419 "http://www.a.com:%u/"
420 "extensions/api_test/webnavigation/serverRedirectSingleProcess/a.html",
421 embedded_test_server()->port()));
423 ui_test_utils::NavigateToURL(browser(), url);
425 url = GURL(base::StringPrintf(
426 "http://www.b.com:%u/server-redirect?http://www.b.com:%u/",
427 embedded_test_server()->port(),
428 embedded_test_server()->port()));
430 ui_test_utils::NavigateToURL(browser(), url);
432 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
435 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ForwardBack) {
436 ASSERT_TRUE(StartEmbeddedTestServer());
437 ASSERT_TRUE(RunExtensionTest("webnavigation/forwardBack")) << message_;
440 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, IFrame) {
441 ASSERT_TRUE(StartEmbeddedTestServer());
442 ASSERT_TRUE(RunExtensionTest("webnavigation/iframe")) << message_;
445 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SrcDoc) {
446 ASSERT_TRUE(StartEmbeddedTestServer());
447 ASSERT_TRUE(RunExtensionTest("webnavigation/srcdoc")) << message_;
450 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, OpenTab) {
451 ASSERT_TRUE(StartEmbeddedTestServer());
452 ASSERT_TRUE(RunExtensionTest("webnavigation/openTab")) << message_;
455 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ReferenceFragment) {
456 ASSERT_TRUE(StartEmbeddedTestServer());
457 ASSERT_TRUE(RunExtensionTest("webnavigation/referenceFragment"))
458 << message_;
461 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SimpleLoad) {
462 ASSERT_TRUE(StartEmbeddedTestServer());
463 ASSERT_TRUE(RunExtensionTest("webnavigation/simpleLoad")) << message_;
466 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Failures) {
467 ASSERT_TRUE(StartEmbeddedTestServer());
468 ASSERT_TRUE(RunExtensionTest("webnavigation/failures")) << message_;
471 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, FilteredTest) {
472 ASSERT_TRUE(StartEmbeddedTestServer());
473 ASSERT_TRUE(RunExtensionTest("webnavigation/filtered")) << message_;
476 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, UserAction) {
477 ASSERT_TRUE(StartEmbeddedTestServer());
479 // Wait for the extension to set itself up and return control to us.
480 ASSERT_TRUE(RunExtensionTest("webnavigation/userAction")) << message_;
482 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
483 content::WaitForLoadStop(tab);
485 ResultCatcher catcher;
487 ExtensionService* service = extensions::ExtensionSystem::Get(
488 browser()->profile())->extension_service();
489 const extensions::Extension* extension =
490 service->GetExtensionById(last_loaded_extension_id(), false);
491 GURL url = extension->GetResourceURL("a.html");
493 ui_test_utils::NavigateToURL(browser(), url);
495 // This corresponds to "Open link in new tab".
496 content::ContextMenuParams params;
497 params.is_editable = false;
498 params.media_type = blink::WebContextMenuData::MediaTypeNone;
499 params.page_url = url;
500 params.link_url = extension->GetResourceURL("b.html");
502 TestRenderViewContextMenu menu(tab->GetMainFrame(), params);
503 menu.Init();
504 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
506 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
509 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, RequestOpenTab) {
510 ASSERT_TRUE(StartEmbeddedTestServer());
512 // Wait for the extension to set itself up and return control to us.
513 ASSERT_TRUE(RunExtensionTest("webnavigation/requestOpenTab"))
514 << message_;
516 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
517 content::WaitForLoadStop(tab);
519 ResultCatcher catcher;
521 ExtensionService* service = extensions::ExtensionSystem::Get(
522 browser()->profile())->extension_service();
523 const extensions::Extension* extension =
524 service->GetExtensionById(last_loaded_extension_id(), false);
525 GURL url = extension->GetResourceURL("a.html");
527 ui_test_utils::NavigateToURL(browser(), url);
529 // There's a link on a.html. Middle-click on it to open it in a new tab.
530 blink::WebMouseEvent mouse_event;
531 mouse_event.type = blink::WebInputEvent::MouseDown;
532 mouse_event.button = blink::WebMouseEvent::ButtonMiddle;
533 mouse_event.x = 7;
534 mouse_event.y = 7;
535 mouse_event.clickCount = 1;
536 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
537 mouse_event.type = blink::WebInputEvent::MouseUp;
538 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
540 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
543 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, TargetBlank) {
544 ASSERT_TRUE(StartEmbeddedTestServer());
546 // Wait for the extension to set itself up and return control to us.
547 ASSERT_TRUE(RunExtensionTest("webnavigation/targetBlank")) << message_;
549 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
550 content::WaitForLoadStop(tab);
552 ResultCatcher catcher;
554 GURL url = embedded_test_server()->GetURL(
555 "/extensions/api_test/webnavigation/targetBlank/a.html");
557 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
558 ui_test_utils::NavigateToURL(&params);
560 // There's a link with target=_blank on a.html. Click on it to open it in a
561 // new tab.
562 blink::WebMouseEvent mouse_event;
563 mouse_event.type = blink::WebInputEvent::MouseDown;
564 mouse_event.button = blink::WebMouseEvent::ButtonLeft;
565 mouse_event.x = 7;
566 mouse_event.y = 7;
567 mouse_event.clickCount = 1;
568 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
569 mouse_event.type = blink::WebInputEvent::MouseUp;
570 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
572 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
575 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, TargetBlankIncognito) {
576 ASSERT_TRUE(StartEmbeddedTestServer());
578 // Wait for the extension to set itself up and return control to us.
579 ASSERT_TRUE(RunExtensionTestIncognito("webnavigation/targetBlank"))
580 << message_;
582 ResultCatcher catcher;
584 GURL url = embedded_test_server()->GetURL(
585 "/extensions/api_test/webnavigation/targetBlank/a.html");
587 Browser* otr_browser = ui_test_utils::OpenURLOffTheRecord(
588 browser()->profile(), url);
589 WebContents* tab = otr_browser->tab_strip_model()->GetActiveWebContents();
591 // There's a link with target=_blank on a.html. Click on it to open it in a
592 // new tab.
593 blink::WebMouseEvent mouse_event;
594 mouse_event.type = blink::WebInputEvent::MouseDown;
595 mouse_event.button = blink::WebMouseEvent::ButtonLeft;
596 mouse_event.x = 7;
597 mouse_event.y = 7;
598 mouse_event.clickCount = 1;
599 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
600 mouse_event.type = blink::WebInputEvent::MouseUp;
601 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
603 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
606 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, History) {
607 ASSERT_TRUE(StartEmbeddedTestServer());
608 ASSERT_TRUE(RunExtensionTest("webnavigation/history")) << message_;
611 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcess) {
612 ASSERT_TRUE(StartEmbeddedTestServer());
614 LoadExtension(test_data_dir_.AppendASCII("webnavigation").AppendASCII("app"));
616 // See crossProcess/d.html.
617 DelayLoadStartAndExecuteJavascript call_script(
618 test_navigation_listener(),
619 embedded_test_server()->GetURL("/test1"),
620 "navigate2()",
621 "empty.html");
623 DelayLoadStartAndExecuteJavascript call_script_user_gesture(
624 test_navigation_listener(),
625 embedded_test_server()->GetURL("/test2"),
626 "navigate2()",
627 "empty.html");
628 call_script_user_gesture.set_has_user_gesture(true);
630 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcess")) << message_;
633 // This test verifies proper events for the following navigation sequence:
634 // * Site A commits
635 // * Slow cross-site navigation to site B starts
636 // * Slow same-site navigation to different page in site A starts
637 // * The slow cross-site navigation commits, cancelling the slow same-site
638 // navigation
639 // Slow navigations are simulated by deferring an URL request, which fires
640 // an onBeforeNavigate event, but doesn't reach commit. The URL request can
641 // later be resumed to allow it to commit and load.
642 // This test cannot use DelayLoadStartAndExecuteJavascript, as that class
643 // resumes all URL requests. Instead, the test explicitly delays each URL
644 // and resumes manually at the required time.
645 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessAbort) {
646 ASSERT_TRUE(StartEmbeddedTestServer());
648 // Add the cross-site URL delay early on, as loading the extension will
649 // cause the cross-site navigation to start.
650 GURL cross_site_url = embedded_test_server()->GetURL("/title1.html");
651 test_navigation_listener()->DelayRequestsForURL(cross_site_url);
653 // Load the extension manually, as its base URL is needed later on to
654 // construct a same-site URL to delay.
655 const Extension* extension =
656 LoadExtension(test_data_dir_.AppendASCII("webnavigation")
657 .AppendASCII("crossProcessAbort"));
659 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
660 ResultCatcher catcher;
661 StartProvisionalLoadObserver cross_site_load(tab, cross_site_url);
663 GURL same_site_url =
664 extension->GetResourceURL(extension->url(), "empty.html");
665 test_navigation_listener()->DelayRequestsForURL(same_site_url);
666 StartProvisionalLoadObserver same_site_load(tab, same_site_url);
668 // Ensure the cross-site navigation has started, then execute JavaScript
669 // to cause the renderer-initiated, non-user navigation.
670 cross_site_load.Wait();
671 tab->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16("navigate2()"));
673 // Wait for the same-site navigation to start and resume the cross-site
674 // one, allowing it to commit.
675 same_site_load.Wait();
676 test_navigation_listener()->Resume(cross_site_url);
678 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
681 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessFragment) {
682 ASSERT_TRUE(StartEmbeddedTestServer());
684 // See crossProcessFragment/f.html.
685 DelayLoadStartAndExecuteJavascript call_script3(
686 test_navigation_listener(),
687 embedded_test_server()->GetURL("/test3"),
688 "updateFragment()",
689 base::StringPrintf("f.html?%u#foo", embedded_test_server()->port()));
691 // See crossProcessFragment/g.html.
692 DelayLoadStartAndExecuteJavascript call_script4(
693 test_navigation_listener(),
694 embedded_test_server()->GetURL("/test4"),
695 "updateFragment()",
696 base::StringPrintf("g.html?%u#foo", embedded_test_server()->port()));
698 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcessFragment"))
699 << message_;
702 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessHistory) {
703 ASSERT_TRUE(StartEmbeddedTestServer());
705 // See crossProcessHistory/e.html.
706 DelayLoadStartAndExecuteJavascript call_script2(
707 test_navigation_listener(),
708 embedded_test_server()->GetURL("/test2"),
709 "updateHistory()",
710 "empty.html");
712 // See crossProcessHistory/h.html.
713 DelayLoadStartAndExecuteJavascript call_script5(
714 test_navigation_listener(),
715 embedded_test_server()->GetURL("/test5"),
716 "updateHistory()",
717 "empty.html");
719 // See crossProcessHistory/i.html.
720 DelayLoadStartAndExecuteJavascript call_script6(
721 test_navigation_listener(),
722 embedded_test_server()->GetURL("/test6"),
723 "updateHistory()",
724 "empty.html");
726 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcessHistory"))
727 << message_;
730 // TODO(jam): http://crbug.com/350550
731 #if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER))
732 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Crash) {
733 ASSERT_TRUE(StartEmbeddedTestServer());
735 // Wait for the extension to set itself up and return control to us.
736 ASSERT_TRUE(RunExtensionTest("webnavigation/crash")) << message_;
738 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
739 content::WaitForLoadStop(tab);
741 ResultCatcher catcher;
743 GURL url(base::StringPrintf(
744 "http://www.a.com:%u/"
745 "extensions/api_test/webnavigation/crash/a.html",
746 embedded_test_server()->port()));
747 ui_test_utils::NavigateToURL(browser(), url);
749 ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL));
751 url = GURL(base::StringPrintf(
752 "http://www.a.com:%u/"
753 "extensions/api_test/webnavigation/crash/b.html",
754 embedded_test_server()->port()));
755 ui_test_utils::NavigateToURL(browser(), url);
757 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
760 #endif
762 } // namespace extensions