Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / web_navigation / web_navigation_apitest.cc
blob09a26804aa8fbe50f47fc2271818d480ec801138
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()->ExecuteJavaScriptWithUserGestureForTests(
214 base::UTF8ToUTF16(script_));
215 } else {
216 rvh_->GetMainFrame()->ExecuteJavaScriptForTests(
217 base::UTF8ToUTF16(script_));
219 script_was_executed_ = true;
222 void DidCommitProvisionalLoadForFrame(
223 content::RenderFrameHost* render_frame_host,
224 const GURL& url,
225 ui::PageTransition transition_type) override {
226 if (script_was_executed_ &&
227 base::EndsWith(url.spec(), until_url_suffix_,
228 base::CompareCase::SENSITIVE)) {
229 content::WebContentsObserver::Observe(NULL);
230 test_navigation_listener_->ResumeAll();
232 rvh_ = render_frame_host->GetRenderViewHost();
235 void set_has_user_gesture(bool has_user_gesture) {
236 has_user_gesture_ = has_user_gesture;
239 private:
240 content::NotificationRegistrar registrar_;
242 scoped_refptr<TestNavigationListener> test_navigation_listener_;
244 GURL delay_url_;
245 std::string until_url_suffix_;
246 std::string script_;
247 bool has_user_gesture_;
248 bool script_was_executed_;
249 content::RenderViewHost* rvh_;
251 DISALLOW_COPY_AND_ASSIGN(DelayLoadStartAndExecuteJavascript);
254 class StartProvisionalLoadObserver : public content::WebContentsObserver {
255 public:
256 StartProvisionalLoadObserver(WebContents* web_contents,
257 const GURL& expected_url)
258 : content::WebContentsObserver(web_contents),
259 url_(expected_url),
260 url_seen_(false),
261 message_loop_runner_(new content::MessageLoopRunner) {}
262 ~StartProvisionalLoadObserver() override {}
264 void DidStartProvisionalLoadForFrame(
265 content::RenderFrameHost* render_frame_host,
266 const GURL& validated_url,
267 bool is_error_page,
268 bool is_iframe_srcdoc) override {
269 if (validated_url == url_) {
270 url_seen_ = true;
271 message_loop_runner_->Quit();
275 // Run a nested message loop until navigation to the expected URL has started.
276 void Wait() {
277 if (url_seen_)
278 return;
280 message_loop_runner_->Run();
283 private:
284 GURL url_;
285 bool url_seen_;
287 // The MessageLoopRunner used to spin the message loop during Wait().
288 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
290 DISALLOW_COPY_AND_ASSIGN(StartProvisionalLoadObserver);
293 // A ResourceDispatcherHostDelegate that adds a TestNavigationObserver.
294 class TestResourceDispatcherHostDelegate
295 : public ChromeResourceDispatcherHostDelegate {
296 public:
297 explicit TestResourceDispatcherHostDelegate(
298 TestNavigationListener* test_navigation_listener)
299 : test_navigation_listener_(test_navigation_listener) {
301 ~TestResourceDispatcherHostDelegate() override {}
303 void RequestBeginning(
304 net::URLRequest* request,
305 content::ResourceContext* resource_context,
306 content::AppCacheService* appcache_service,
307 ResourceType resource_type,
308 ScopedVector<content::ResourceThrottle>* throttles) override {
309 ChromeResourceDispatcherHostDelegate::RequestBeginning(
310 request,
311 resource_context,
312 appcache_service,
313 resource_type,
314 throttles);
315 content::ResourceThrottle* throttle =
316 test_navigation_listener_->CreateResourceThrottle(request->url(),
317 resource_type);
318 if (throttle)
319 throttles->push_back(throttle);
322 private:
323 scoped_refptr<TestNavigationListener> test_navigation_listener_;
325 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
328 } // namespace
330 class WebNavigationApiTest : public ExtensionApiTest {
331 public:
332 WebNavigationApiTest() {}
333 ~WebNavigationApiTest() override {}
335 void SetUpInProcessBrowserTestFixture() override {
336 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
338 FrameNavigationState::set_allow_extension_scheme(true);
340 base::CommandLine::ForCurrentProcess()->AppendSwitch(
341 switches::kAllowLegacyExtensionManifests);
343 host_resolver()->AddRule("*", "127.0.0.1");
346 void SetUpOnMainThread() override {
347 ExtensionApiTest::SetUpOnMainThread();
348 test_navigation_listener_ = new TestNavigationListener();
349 resource_dispatcher_host_delegate_.reset(
350 new TestResourceDispatcherHostDelegate(
351 test_navigation_listener_.get()));
352 content::ResourceDispatcherHost::Get()->SetDelegate(
353 resource_dispatcher_host_delegate_.get());
356 TestNavigationListener* test_navigation_listener() {
357 return test_navigation_listener_.get();
360 private:
361 scoped_refptr<TestNavigationListener> test_navigation_listener_;
362 scoped_ptr<TestResourceDispatcherHostDelegate>
363 resource_dispatcher_host_delegate_;
365 DISALLOW_COPY_AND_ASSIGN(WebNavigationApiTest);
368 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Api) {
369 ASSERT_TRUE(StartEmbeddedTestServer());
370 ASSERT_TRUE(RunExtensionTest("webnavigation/api")) << message_;
373 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, GetFrame) {
374 ASSERT_TRUE(StartEmbeddedTestServer());
375 ASSERT_TRUE(RunExtensionTest("webnavigation/getFrame")) << message_;
378 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ClientRedirect) {
379 ASSERT_TRUE(StartEmbeddedTestServer());
380 ASSERT_TRUE(RunExtensionTest("webnavigation/clientRedirect"))
381 << message_;
384 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirect) {
385 ASSERT_TRUE(StartEmbeddedTestServer());
386 ASSERT_TRUE(RunExtensionTest("webnavigation/serverRedirect"))
387 << message_;
390 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Download) {
391 base::ScopedTempDir download_directory;
392 ASSERT_TRUE(download_directory.CreateUniqueTempDir());
393 DownloadPrefs* download_prefs =
394 DownloadPrefs::FromBrowserContext(browser()->profile());
395 download_prefs->SetDownloadPath(download_directory.path());
397 DownloadTestObserverNotInProgress download_observer(
398 content::BrowserContext::GetDownloadManager(profile()), 1);
399 download_observer.StartObserving();
400 ASSERT_TRUE(StartEmbeddedTestServer());
401 ASSERT_TRUE(RunExtensionTest("webnavigation/download"))
402 << message_;
403 download_observer.WaitForFinished();
406 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirectSingleProcess) {
407 ASSERT_TRUE(StartEmbeddedTestServer());
409 // Set max renderers to 1 to force running out of processes.
410 content::RenderProcessHost::SetMaxRendererProcessCount(1);
412 // Wait for the extension to set itself up and return control to us.
413 ASSERT_TRUE(
414 RunExtensionTest("webnavigation/serverRedirectSingleProcess"))
415 << message_;
417 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
418 content::WaitForLoadStop(tab);
420 ResultCatcher catcher;
421 GURL url(base::StringPrintf(
422 "http://www.a.com:%u/"
423 "extensions/api_test/webnavigation/serverRedirectSingleProcess/a.html",
424 embedded_test_server()->port()));
426 ui_test_utils::NavigateToURL(browser(), url);
428 url = GURL(base::StringPrintf(
429 "http://www.b.com:%u/server-redirect?http://www.b.com:%u/",
430 embedded_test_server()->port(),
431 embedded_test_server()->port()));
433 ui_test_utils::NavigateToURL(browser(), url);
435 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
438 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ForwardBack) {
439 ASSERT_TRUE(StartEmbeddedTestServer());
440 ASSERT_TRUE(RunExtensionTest("webnavigation/forwardBack")) << message_;
443 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, IFrame) {
444 ASSERT_TRUE(StartEmbeddedTestServer());
445 ASSERT_TRUE(RunExtensionTest("webnavigation/iframe")) << message_;
448 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SrcDoc) {
449 ASSERT_TRUE(StartEmbeddedTestServer());
450 ASSERT_TRUE(RunExtensionTest("webnavigation/srcdoc")) << message_;
453 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, OpenTab) {
454 ASSERT_TRUE(StartEmbeddedTestServer());
455 ASSERT_TRUE(RunExtensionTest("webnavigation/openTab")) << message_;
458 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ReferenceFragment) {
459 ASSERT_TRUE(StartEmbeddedTestServer());
460 ASSERT_TRUE(RunExtensionTest("webnavigation/referenceFragment"))
461 << message_;
464 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SimpleLoad) {
465 ASSERT_TRUE(StartEmbeddedTestServer());
466 ASSERT_TRUE(RunExtensionTest("webnavigation/simpleLoad")) << message_;
469 #if defined(OS_WIN) // http://crbug.com/477840
470 #define MAYBE_Failures DISABLED_Failures
471 #else
472 #define MAYBE_Failures Failures
473 #endif
474 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Failures) {
475 ASSERT_TRUE(StartEmbeddedTestServer());
476 ASSERT_TRUE(RunExtensionTest("webnavigation/failures")) << message_;
479 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, FilteredTest) {
480 ASSERT_TRUE(StartEmbeddedTestServer());
481 ASSERT_TRUE(RunExtensionTest("webnavigation/filtered")) << message_;
484 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, UserAction) {
485 ASSERT_TRUE(StartEmbeddedTestServer());
487 // Wait for the extension to set itself up and return control to us.
488 ASSERT_TRUE(RunExtensionTest("webnavigation/userAction")) << message_;
490 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
491 content::WaitForLoadStop(tab);
493 ResultCatcher catcher;
495 ExtensionService* service = extensions::ExtensionSystem::Get(
496 browser()->profile())->extension_service();
497 const extensions::Extension* extension =
498 service->GetExtensionById(last_loaded_extension_id(), false);
499 GURL url = extension->GetResourceURL("a.html");
501 ui_test_utils::NavigateToURL(browser(), url);
503 // This corresponds to "Open link in new tab".
504 content::ContextMenuParams params;
505 params.is_editable = false;
506 params.media_type = blink::WebContextMenuData::MediaTypeNone;
507 params.page_url = url;
508 params.link_url = extension->GetResourceURL("b.html");
510 TestRenderViewContextMenu menu(tab->GetMainFrame(), params);
511 menu.Init();
512 menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
514 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
517 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, RequestOpenTab) {
518 ASSERT_TRUE(StartEmbeddedTestServer());
520 // Wait for the extension to set itself up and return control to us.
521 ASSERT_TRUE(RunExtensionTest("webnavigation/requestOpenTab"))
522 << message_;
524 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
525 content::WaitForLoadStop(tab);
527 ResultCatcher catcher;
529 ExtensionService* service = extensions::ExtensionSystem::Get(
530 browser()->profile())->extension_service();
531 const extensions::Extension* extension =
532 service->GetExtensionById(last_loaded_extension_id(), false);
533 GURL url = extension->GetResourceURL("a.html");
535 ui_test_utils::NavigateToURL(browser(), url);
537 // There's a link on a.html. Middle-click on it to open it in a new tab.
538 blink::WebMouseEvent mouse_event;
539 mouse_event.type = blink::WebInputEvent::MouseDown;
540 mouse_event.button = blink::WebMouseEvent::ButtonMiddle;
541 mouse_event.x = 7;
542 mouse_event.y = 7;
543 mouse_event.clickCount = 1;
544 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
545 mouse_event.type = blink::WebInputEvent::MouseUp;
546 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
548 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
551 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, TargetBlank) {
552 ASSERT_TRUE(StartEmbeddedTestServer());
554 // Wait for the extension to set itself up and return control to us.
555 ASSERT_TRUE(RunExtensionTest("webnavigation/targetBlank")) << message_;
557 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
558 content::WaitForLoadStop(tab);
560 ResultCatcher catcher;
562 GURL url = embedded_test_server()->GetURL(
563 "/extensions/api_test/webnavigation/targetBlank/a.html");
565 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
566 ui_test_utils::NavigateToURL(&params);
568 // There's a link with target=_blank on a.html. Click on it to open it in a
569 // new tab.
570 blink::WebMouseEvent mouse_event;
571 mouse_event.type = blink::WebInputEvent::MouseDown;
572 mouse_event.button = blink::WebMouseEvent::ButtonLeft;
573 mouse_event.x = 7;
574 mouse_event.y = 7;
575 mouse_event.clickCount = 1;
576 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
577 mouse_event.type = blink::WebInputEvent::MouseUp;
578 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
580 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
583 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, TargetBlankIncognito) {
584 ASSERT_TRUE(StartEmbeddedTestServer());
586 // Wait for the extension to set itself up and return control to us.
587 ASSERT_TRUE(RunExtensionTestIncognito("webnavigation/targetBlank"))
588 << message_;
590 ResultCatcher catcher;
592 GURL url = embedded_test_server()->GetURL(
593 "/extensions/api_test/webnavigation/targetBlank/a.html");
595 Browser* otr_browser = OpenURLOffTheRecord(browser()->profile(), url);
596 WebContents* tab = otr_browser->tab_strip_model()->GetActiveWebContents();
598 // There's a link with target=_blank on a.html. Click on it to open it in a
599 // new tab.
600 blink::WebMouseEvent mouse_event;
601 mouse_event.type = blink::WebInputEvent::MouseDown;
602 mouse_event.button = blink::WebMouseEvent::ButtonLeft;
603 mouse_event.x = 7;
604 mouse_event.y = 7;
605 mouse_event.clickCount = 1;
606 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
607 mouse_event.type = blink::WebInputEvent::MouseUp;
608 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
610 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
613 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, History) {
614 ASSERT_TRUE(StartEmbeddedTestServer());
615 ASSERT_TRUE(RunExtensionTest("webnavigation/history")) << message_;
618 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcess) {
619 ASSERT_TRUE(StartEmbeddedTestServer());
621 LoadExtension(test_data_dir_.AppendASCII("webnavigation").AppendASCII("app"));
623 // See crossProcess/d.html.
624 DelayLoadStartAndExecuteJavascript call_script(
625 test_navigation_listener(),
626 embedded_test_server()->GetURL("/test1"),
627 "navigate2()",
628 "empty.html");
630 DelayLoadStartAndExecuteJavascript call_script_user_gesture(
631 test_navigation_listener(),
632 embedded_test_server()->GetURL("/test2"),
633 "navigate2()",
634 "empty.html");
635 call_script_user_gesture.set_has_user_gesture(true);
637 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcess")) << message_;
640 // This test verifies proper events for the following navigation sequence:
641 // * Site A commits
642 // * Slow cross-site navigation to site B starts
643 // * Slow same-site navigation to different page in site A starts
644 // * The slow cross-site navigation commits, cancelling the slow same-site
645 // navigation
646 // Slow navigations are simulated by deferring an URL request, which fires
647 // an onBeforeNavigate event, but doesn't reach commit. The URL request can
648 // later be resumed to allow it to commit and load.
649 // This test cannot use DelayLoadStartAndExecuteJavascript, as that class
650 // resumes all URL requests. Instead, the test explicitly delays each URL
651 // and resumes manually at the required time.
652 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessAbort) {
653 ASSERT_TRUE(StartEmbeddedTestServer());
655 // Add the cross-site URL delay early on, as loading the extension will
656 // cause the cross-site navigation to start.
657 GURL cross_site_url = embedded_test_server()->GetURL("/title1.html");
658 test_navigation_listener()->DelayRequestsForURL(cross_site_url);
660 // Load the extension manually, as its base URL is needed later on to
661 // construct a same-site URL to delay.
662 const Extension* extension =
663 LoadExtension(test_data_dir_.AppendASCII("webnavigation")
664 .AppendASCII("crossProcessAbort"));
666 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
667 ResultCatcher catcher;
668 StartProvisionalLoadObserver cross_site_load(tab, cross_site_url);
670 GURL same_site_url =
671 extension->GetResourceURL(extension->url(), "empty.html");
672 test_navigation_listener()->DelayRequestsForURL(same_site_url);
673 StartProvisionalLoadObserver same_site_load(tab, same_site_url);
675 // Ensure the cross-site navigation has started, then execute JavaScript
676 // to cause the renderer-initiated, non-user navigation.
677 cross_site_load.Wait();
678 tab->GetMainFrame()->ExecuteJavaScriptForTests(
679 base::UTF8ToUTF16("navigate2()"));
681 // Wait for the same-site navigation to start and resume the cross-site
682 // one, allowing it to commit.
683 same_site_load.Wait();
684 test_navigation_listener()->Resume(cross_site_url);
686 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
689 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessFragment) {
690 ASSERT_TRUE(StartEmbeddedTestServer());
692 // See crossProcessFragment/f.html.
693 DelayLoadStartAndExecuteJavascript call_script3(
694 test_navigation_listener(),
695 embedded_test_server()->GetURL("/test3"),
696 "updateFragment()",
697 base::StringPrintf("f.html?%u#foo", embedded_test_server()->port()));
699 // See crossProcessFragment/g.html.
700 DelayLoadStartAndExecuteJavascript call_script4(
701 test_navigation_listener(),
702 embedded_test_server()->GetURL("/test4"),
703 "updateFragment()",
704 base::StringPrintf("g.html?%u#foo", embedded_test_server()->port()));
706 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcessFragment"))
707 << message_;
710 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessHistory) {
711 ASSERT_TRUE(StartEmbeddedTestServer());
713 // See crossProcessHistory/e.html.
714 DelayLoadStartAndExecuteJavascript call_script2(
715 test_navigation_listener(),
716 embedded_test_server()->GetURL("/test2"),
717 "updateHistory()",
718 "empty.html");
720 // See crossProcessHistory/h.html.
721 DelayLoadStartAndExecuteJavascript call_script5(
722 test_navigation_listener(),
723 embedded_test_server()->GetURL("/test5"),
724 "updateHistory()",
725 "empty.html");
727 // See crossProcessHistory/i.html.
728 DelayLoadStartAndExecuteJavascript call_script6(
729 test_navigation_listener(),
730 embedded_test_server()->GetURL("/test6"),
731 "updateHistory()",
732 "empty.html");
734 ASSERT_TRUE(RunExtensionTest("webnavigation/crossProcessHistory"))
735 << message_;
738 // TODO(jam): http://crbug.com/350550
739 #if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER))
740 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Crash) {
741 ASSERT_TRUE(StartEmbeddedTestServer());
743 // Wait for the extension to set itself up and return control to us.
744 ASSERT_TRUE(RunExtensionTest("webnavigation/crash")) << message_;
746 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
747 content::WaitForLoadStop(tab);
749 ResultCatcher catcher;
751 GURL url(base::StringPrintf(
752 "http://www.a.com:%u/"
753 "extensions/api_test/webnavigation/crash/a.html",
754 embedded_test_server()->port()));
755 ui_test_utils::NavigateToURL(browser(), url);
757 ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL));
759 url = GURL(base::StringPrintf(
760 "http://www.a.com:%u/"
761 "extensions/api_test/webnavigation/crash/b.html",
762 embedded_test_server()->port()));
763 ui_test_utils::NavigateToURL(browser(), url);
765 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
768 #endif
770 } // namespace extensions