OLD | NEW |
---|---|
(Empty) | |
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 "base/command_line.h" | |
6 #include "base/strings/string16.h" | |
7 #include "base/strings/string_split.h" | |
8 #include "base/task_scheduler/post_task.h" | |
9 #include "base/threading/platform_thread.h" // For |Sleep()|. | |
10 #include "chrome/browser/prerender/prerender_manager.h" | |
11 #include "chrome/browser/prerender/prerender_manager_factory.h" | |
12 #include "chrome/browser/prerender/prerender_test_utils.h" | |
13 #include "chrome/browser/profiles/profile.h" | |
14 #include "chrome/browser/task_manager/task_manager_browsertest_util.h" | |
15 #include "chrome/browser/ui/browser.h" | |
16 #include "chrome/browser/ui/browser_commands.h" | |
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
18 #include "chrome/common/chrome_switches.h" | |
19 #include "chrome/grit/generated_resources.h" | |
20 #include "chrome/test/base/ui_test_utils.h" | |
21 #include "content/public/common/content_switches.h" | |
22 #include "content/public/common/url_constants.h" | |
23 #include "content/public/test/browser_test_utils.h" | |
24 #include "net/base/escape.h" | |
25 #include "net/dns/mock_host_resolver.h" | |
26 #include "net/test/embedded_test_server/request_handler_util.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 #include "ui/base/l10n/l10n_util.h" | |
29 | |
30 using prerender::test_utils::CreateCountingInterceptorOnIO; | |
31 using prerender::test_utils::DestructionWaiter; | |
32 using prerender::test_utils::RequestCounter; | |
33 using prerender::test_utils::TestPrerender; | |
34 using prerender::test_utils::TestPrerenderContents; | |
35 using task_manager::browsertest_util::WaitForTaskManagerRows; | |
36 | |
37 namespace { | |
38 const int kMetricsSendDelayMillis = 1500; | |
39 | |
40 // Fetches a boolean value from javascript. Returns whether the fetch | |
41 // succeeded; the value of the variable is returned in value. If | |
42 // javascript_variable does not exist, this returns false and value is | |
43 // unchanged. The function checks that script execution works. | |
44 bool GetJavascriptBoolean(const std::string& javascript_variable, | |
45 content::WebContents* web_contents, | |
46 bool* value) { | |
47 // In order to detect unknown variables a three-valued return is needed. | |
48 int result; | |
49 EXPECT_TRUE(content::ExecuteScriptAndExtractInt( | |
50 web_contents, | |
51 "try { if (" + javascript_variable + ") { " + | |
52 "window.domAutomationController.send(1) } else { " + | |
53 "window.domAutomationController.send(0); } } catch(err) {" + | |
54 "window.domAutomationController.send(2) }", | |
55 &result)); | |
56 if (result == 2) { | |
57 // This means an exception was caught, usually because of a missing | |
58 // variable. | |
59 return false; | |
60 } | |
61 *value = (result == 1); | |
62 return true; | |
63 } | |
64 | |
65 // As above, but just checks for a missing variable. | |
66 bool JavascriptVariableMissing(const std::string& javascript_variable, | |
67 content::WebContents* web_contents) { | |
68 bool unused; | |
69 return !GetJavascriptBoolean(javascript_variable, web_contents, &unused); | |
70 } | |
71 | |
72 } // namespace | |
73 | |
74 namespace prerender { | |
75 | |
76 // These URLs used for test resources must be relative with the exception of | |
77 // |PrefetchLoaderPath|, which is only used in |PrerenderTestURLImpl()|. | |
78 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; | |
79 const char kPrefetchJpeg[] = "prerender/image.jpeg"; | |
80 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; | |
81 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; | |
82 const char kPrefetchPage[] = "prerender/prefetch_page.html"; | |
83 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; | |
84 const char kPrefetchPng[] = "prerender/image.png"; | |
85 const char kPrefetchScript[] = "prerender/prefetch.js"; | |
86 const char kPrefetchScript2[] = "prerender/prefetch2.js"; | |
87 const char kPrefetchSubresourceRedirectPage[] = | |
88 "prerender/prefetch_subresource_redirect.html"; | |
89 | |
90 const char kPageBool[] = "pageBool"; | |
91 const char kScriptBool[] = "scriptBool"; | |
92 | |
93 class NoStatePrefetchBrowserTest | |
94 : public test_utils::PrerenderInProcessBrowserTest { | |
95 public: | |
96 class BrowserTestTime : public PrerenderManager::TimeOverride { | |
97 public: | |
98 BrowserTestTime() {} | |
99 | |
100 base::Time GetCurrentTime() const override { | |
101 if (delta_.is_zero()) { | |
102 return base::Time::Now(); | |
103 } | |
104 return time_ + delta_; | |
105 } | |
106 | |
107 base::TimeTicks GetCurrentTimeTicks() const override { | |
108 if (delta_.is_zero()) { | |
109 return base::TimeTicks::Now(); | |
110 } | |
111 return time_ticks_ + delta_; | |
112 } | |
113 | |
114 void AdvanceTime(base::TimeDelta delta) { | |
115 if (delta_.is_zero()) { | |
116 time_ = base::Time::Now(); | |
117 time_ticks_ = base::TimeTicks::Now(); | |
118 delta_ = delta; | |
119 } else { | |
120 delta_ += delta; | |
121 } | |
122 } | |
123 | |
124 private: | |
125 base::Time time_; | |
126 base::TimeTicks time_ticks_; | |
127 base::TimeDelta delta_; | |
128 }; | |
129 | |
130 NoStatePrefetchBrowserTest() {} | |
131 | |
132 void SetUpCommandLine(base::CommandLine* command_line) override { | |
133 PrerenderInProcessBrowserTest::SetUpCommandLine(command_line); | |
134 command_line->AppendSwitchASCII( | |
135 switches::kPrerenderMode, switches::kPrerenderModeSwitchValuePrefetch); | |
136 } | |
137 | |
138 void SetUpOnMainThread() override { | |
139 PrerenderInProcessBrowserTest::SetUpOnMainThread(); | |
140 std::unique_ptr<BrowserTestTime> test_time = | |
141 base::MakeUnique<BrowserTestTime>(); | |
142 browser_test_time_ = test_time.get(); | |
143 GetPrerenderManager()->SetTimeOverride(std::move(test_time)); | |
144 } | |
145 | |
146 // Set up a request counter for |path|, which is also the location of the data | |
147 // served by the request. | |
148 void CountRequestFor(const std::string& path_str, RequestCounter* counter) { | |
149 url::StringPieceReplacements<base::FilePath::StringType> replacement; | |
150 replacement.SetPathStr(base::FilePath::FromUTF8Unsafe(path_str).value()); | |
151 const GURL url = src_server()->base_url().ReplaceComponents(replacement); | |
152 base::FilePath url_file = ui_test_utils::GetTestFilePath( | |
153 base::FilePath(), base::FilePath::FromUTF8Unsafe(path_str)); | |
154 content::BrowserThread::PostTask( | |
155 content::BrowserThread::IO, FROM_HERE, | |
156 base::Bind(&CreateCountingInterceptorOnIO, url, url_file, | |
157 counter->AsWeakPtr())); | |
158 } | |
159 | |
160 BrowserTestTime* GetTimeOverride() const { return browser_test_time_; } | |
161 | |
162 // Paint metrics do not reliably show until the page produces a frame. | |
163 void WaitForPaint() { | |
164 bool loaded = false; | |
165 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
166 current_browser()->tab_strip_model()->GetActiveWebContents(), | |
167 "requestAnimationFrame(function() {" | |
168 " window.domAutomationController.send(true);" | |
169 "});", | |
170 &loaded)); | |
171 ASSERT_TRUE(loaded); | |
172 // There can be a delay of up to a second to send performance stats. See | |
173 // PageTimingMetricsSender::Send. | |
174 base::PlatformThread::Sleep( | |
175 base::TimeDelta::FromMilliseconds(kMetricsSendDelayMillis)); | |
176 // Pump the message loop as timing updates are sent from the renderer to the | |
177 // browser. | |
178 base::RunLoop loop; | |
mattcary
2016/10/13 13:40:38
+pasko
Is this the right way to pump message loop
pasko
2016/10/13 14:00:44
Yes. One caveat: when starting this pump we need t
| |
179 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
180 loop.QuitClosure()); | |
181 loop.Run(); | |
182 } | |
183 | |
184 private: | |
185 ScopedVector<TestPrerender> PrerenderTestURLImpl( | |
186 const GURL& prerender_url, | |
187 const std::vector<FinalStatus>& expected_final_status_queue, | |
188 int expected_number_of_loads) override { | |
189 base::StringPairs replacement_text; | |
190 replacement_text.push_back( | |
191 make_pair("REPLACE_WITH_PREFETCH_URL", prerender_url.spec())); | |
192 std::string replacement_path; | |
193 net::test_server::GetFilePathWithReplacements( | |
194 kPrefetchLoaderPath, replacement_text, &replacement_path); | |
195 GURL loader_url = src_server()->GetURL(replacement_path); | |
196 | |
197 ScopedVector<TestPrerender> prerenders = NavigateWithPrerenders( | |
198 loader_url, expected_final_status_queue, expected_number_of_loads); | |
199 | |
200 TestPrerenderContents* prerender_contents = prerenders[0]->contents(); | |
201 CHECK(prerender_contents); | |
202 // Checks that the prerender contents final status is unchanged from its | |
203 // default value, meaning that the contents has not been destroyed. | |
204 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); | |
205 | |
206 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads()); | |
207 | |
208 return prerenders; | |
209 } | |
210 | |
211 BrowserTestTime* browser_test_time_; | |
212 }; | |
213 | |
214 // Performs a full load of the target page and check that javascript values are | |
215 // set as expected. This confirms that our test system is working correctly, so | |
216 // that when the target page is prefetched it can be confirmed that javascript | |
217 // is not executed. | |
218 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, CheckJavascript) { | |
219 ui_test_utils::NavigateToURL( | |
220 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage))); | |
221 content::WebContents* web_contents = | |
222 current_browser()->tab_strip_model()->GetActiveWebContents(); | |
223 | |
224 // Confirms that true and false values can appear. | |
225 bool value = false; | |
226 EXPECT_TRUE(GetJavascriptBoolean(kPageBool, web_contents, &value)); | |
227 EXPECT_TRUE(value); | |
228 value = true; | |
229 EXPECT_TRUE(GetJavascriptBoolean("pageAntiBool", web_contents, &value)); | |
230 EXPECT_FALSE(value); | |
231 | |
232 // Confirm a value from the script is plumbed through. | |
233 value = false; | |
234 EXPECT_TRUE(GetJavascriptBoolean(kScriptBool, web_contents, &value)); | |
235 EXPECT_TRUE(value); | |
236 | |
237 // Confirm that the expected happens when a value doesn't exist. | |
238 EXPECT_TRUE(JavascriptVariableMissing("iDontExist", web_contents)); | |
239 } | |
240 | |
241 // Checks that a page is correctly prefetched in the case of a | |
242 // <link rel=prerender> tag and then loaded into a tab in response to a | |
243 // navigation, when NoState Prefetch is enabled, but that the page is not loaded | |
244 // (which confirmed by checking that javascript is not executed). | |
245 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) { | |
246 RequestCounter script_counter; | |
247 CountRequestFor(kPrefetchScript, &script_counter); | |
248 RequestCounter main_counter; | |
249 CountRequestFor(kPrefetchPage, &main_counter); | |
250 | |
251 std::unique_ptr<TestPrerender> test_prerender = | |
252 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | |
253 main_counter.WaitForCount(1); | |
254 script_counter.WaitForCount(1); | |
255 | |
256 content::WebContents* contents = | |
257 test_prerender->contents()->prerender_contents(); | |
258 content::WebContents* active_contents = | |
259 current_browser()->tab_strip_model()->GetActiveWebContents(); | |
260 EXPECT_TRUE(JavascriptVariableMissing(kPageBool, contents)); | |
261 EXPECT_TRUE(JavascriptVariableMissing(kScriptBool, contents)); | |
262 EXPECT_TRUE(JavascriptVariableMissing(kPageBool, active_contents)); | |
263 EXPECT_TRUE(JavascriptVariableMissing(kScriptBool, active_contents)); | |
264 histogram_tester().ExpectTotalCount("Prerender.PerceivedPLT", 1); | |
265 histogram_tester().ExpectBucketCount( | |
266 "Prerender.websame_NoStatePrefetchResponseTypes", | |
267 4 /* cacheable, main resource */, 1); | |
268 histogram_tester().ExpectBucketCount( | |
269 "Prerender.websame_NoStatePrefetchResponseTypes", | |
270 0 /* cacheable, non-main resource */, 1); | |
271 histogram_tester().ExpectTotalCount("Prerender.none_MainResourceRedirects", | |
272 0); | |
273 histogram_tester().ExpectTotalCount("Prerender.none_SubResourceRedirects", 0); | |
274 } | |
275 | |
276 // Checks the TTFCP histograms on fast reuse of a prefetch. | |
277 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchReusedWarm) { | |
278 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | |
279 GetTimeOverride()->AdvanceTime(base::TimeDelta::FromSeconds(10)); | |
280 ui_test_utils::NavigateToURL( | |
281 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage))); | |
282 WaitForPaint(); | |
283 histogram_tester().ExpectTotalCount( | |
284 "Prerender.websame_NoStatePrefetchTTFCP.Warm.Cacheable", 1); | |
285 histogram_tester().ExpectTotalCount( | |
286 "Prerender.websame_NoStatePrefetchTTFCP.Cold.Cacheable", 0); | |
287 } | |
288 | |
289 // Checks the histograms on slow reuse of a prefetch. | |
290 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchReusedCold) { | |
291 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_TIMED_OUT, 1); | |
292 GetTimeOverride()->AdvanceTime(base::TimeDelta::FromSeconds(600)); | |
293 ui_test_utils::NavigateToURL( | |
294 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage))); | |
295 WaitForPaint(); | |
296 | |
297 histogram_tester().ExpectTotalCount( | |
298 "Prerender.websame_NoStatePrefetchTTFCP.Warm.Cacheable", 0); | |
299 histogram_tester().ExpectTotalCount( | |
300 "Prerender.websame_NoStatePrefetchTTFCP.Cold.Cacheable", 1); | |
301 } | |
302 | |
303 // Checks the prefetch of an img tag. | |
304 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { | |
305 RequestCounter image_counter; | |
306 CountRequestFor(kPrefetchJpeg, &image_counter); | |
307 base::StringPairs replacement_text; | |
308 replacement_text.push_back( | |
309 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); | |
310 std::string main_page_path; | |
311 net::test_server::GetFilePathWithReplacements( | |
312 kPrefetchImagePage, replacement_text, &main_page_path); | |
313 // Note CountRequestFor cannot be used on the main page as the test server | |
314 // must handling the image url replacement. | |
315 PrerenderTestURL(main_page_path, FINAL_STATUS_APP_TERMINATING, 1); | |
316 image_counter.WaitForCount(1); | |
317 } | |
318 | |
319 // Checks that a cross-domain prefetching works correctly by looking at | |
320 // histograms. | |
321 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchCrossDomain) { | |
322 static const std::string secondary_domain = "www.foo.com"; | |
323 host_resolver()->AddRule(secondary_domain, "127.0.0.1"); | |
324 GURL cross_domain_url(base::StringPrintf( | |
325 "http://%s:%d/%s", secondary_domain.c_str(), | |
326 embedded_test_server()->host_port_pair().port(), kPrefetchPage)); | |
327 PrerenderTestURL(cross_domain_url, FINAL_STATUS_APP_TERMINATING, 1); | |
328 // TODO(mattcary): remove PLT histograms (here and elsewhere). | |
329 histogram_tester().ExpectTotalCount("Prerender.PerceivedPLT", 1); | |
330 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 1); | |
331 histogram_tester().ExpectTotalCount( | |
332 "Prerender.webcross_PrerenderNotSwappedInPLT", 1); | |
333 } | |
334 | |
335 // Checks simultaneous prefetch. | |
336 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { | |
337 RequestCounter first_main_counter; | |
338 CountRequestFor(kPrefetchPage, &first_main_counter); | |
339 RequestCounter second_main_counter; | |
340 CountRequestFor(kPrefetchPage2, &second_main_counter); | |
341 RequestCounter first_script_counter; | |
342 CountRequestFor(kPrefetchScript, &first_script_counter); | |
343 RequestCounter second_script_counter; | |
344 CountRequestFor(kPrefetchScript2, &second_script_counter); | |
345 | |
346 // The first prerender is marked as canceled as when the second starts, it | |
347 // sees that the first has been abandoned (presumably because it is detached | |
348 // immediately and so dies quickly). | |
349 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_CANCELLED, 1); | |
350 PrerenderTestURL(kPrefetchPage2, FINAL_STATUS_APP_TERMINATING, 1); | |
351 first_main_counter.WaitForCount(1); | |
352 second_main_counter.WaitForCount(1); | |
353 first_script_counter.WaitForCount(1); | |
354 second_script_counter.WaitForCount(1); | |
355 histogram_tester().ExpectTotalCount("Prerender.PerceivedPLT", 2); | |
356 histogram_tester().ExpectTotalCount("Prerender.none_PerceivedPLT", 2); | |
357 } | |
358 | |
359 // Checks a prefetch to a nonexisting page. | |
360 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchNonexisting) { | |
361 PrerenderTestURL("nonexisting-page.html", FINAL_STATUS_APP_TERMINATING, 0); | |
362 // TODO(mattcary): we fire up a prerenderer before we discover that the main | |
363 // page doesn't exist, we still count this as a prerender. Also we don't fail | |
364 // the renderer (presumably because we've detached the resource, etc). Is this | |
365 // what we want? | |
366 histogram_tester().ExpectTotalCount("Prerender.PerceivedPLT", 1); | |
367 } | |
368 | |
369 // Checks that a 301 redirect is followed. | |
370 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Redirect) { | |
371 RequestCounter script_counter; | |
372 CountRequestFor(kPrefetchScript, &script_counter); | |
373 PrerenderTestURL( | |
374 "/server-redirect/?" + | |
375 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), | |
376 FINAL_STATUS_APP_TERMINATING, 1); | |
377 script_counter.WaitForCount(1); | |
378 histogram_tester().ExpectTotalCount( | |
379 "Prerender.websame_NoStatePrefetchMainResourceRedirects", 1); | |
380 } | |
381 | |
382 // Checks that a subresource 301 redirect is followed. | |
383 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301Subresource) { | |
384 RequestCounter script_counter; | |
385 CountRequestFor(kPrefetchScript, &script_counter); | |
386 PrerenderTestURL(kPrefetchSubresourceRedirectPage, | |
387 FINAL_STATUS_APP_TERMINATING, 1); | |
388 script_counter.WaitForCount(1); | |
389 histogram_tester().ExpectTotalCount( | |
390 "Prerender.websame_NoStatePrefetchMainResourceRedirects", 1); | |
391 } | |
392 | |
393 // Checks a client redirect is not followed. | |
394 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchClientRedirect) { | |
395 RequestCounter script_counter; | |
396 CountRequestFor(kPrefetchScript, &script_counter); | |
397 // A complete load of kPrefetchPage2 is used as a sentinal. Otherwise the test | |
398 // ends before script_counter would reliably see the load of kPrefetchScript, | |
399 // were it to happen. | |
400 RequestCounter sentinel_counter; | |
401 CountRequestFor(kPrefetchScript2, &sentinel_counter); | |
402 PrerenderTestURL( | |
403 "/client-redirect/?" + | |
404 net::EscapeQueryParamValue(MakeAbsolute(kPrefetchPage), false), | |
405 FINAL_STATUS_APP_TERMINATING, 1); | |
406 ui_test_utils::NavigateToURL( | |
407 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage2))); | |
408 WaitForPaint(); | |
409 sentinel_counter.WaitForCount(1); | |
410 script_counter.WaitForCount(0); | |
411 } | |
412 | |
413 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchHttps) { | |
414 UseHttpsSrcServer(); | |
415 RequestCounter main_counter; | |
416 CountRequestFor(kPrefetchPage, &main_counter); | |
417 RequestCounter script_counter; | |
418 CountRequestFor(kPrefetchScript, &script_counter); | |
419 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | |
420 main_counter.WaitForCount(1); | |
421 script_counter.WaitForCount(1); | |
422 } | |
423 | |
424 // Checks that an SSL error prevents prefetch. | |
425 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLError) { | |
426 // Only send the loaded page, not the loader, through SSL. | |
427 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); | |
428 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); | |
429 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); | |
430 ASSERT_TRUE(https_server.Start()); | |
431 std::unique_ptr<TestPrerender> prerender = | |
432 PrerenderTestURL(https_server.GetURL(MakeAbsolute(kPrefetchPage)), | |
433 FINAL_STATUS_SSL_ERROR, 0); | |
434 DestructionWaiter waiter(prerender->contents(), FINAL_STATUS_SSL_ERROR); | |
435 EXPECT_TRUE(waiter.WaitForDestroy()); | |
436 } | |
437 | |
438 // Checks that a subresource failing SSL does not prevent prefetch on the rest | |
439 // of the page. | |
440 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, SSLSubresourceError) { | |
441 // First confirm that the image loads as expected. | |
442 | |
443 // A separate HTTPS server is started for the subresource; src_server() is | |
444 // non-HTTPS. | |
445 net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); | |
446 https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME); | |
447 https_server.ServeFilesFromSourceDirectory("chrome/test/data"); | |
448 ASSERT_TRUE(https_server.Start()); | |
449 GURL https_url = https_server.GetURL("/prerender/image.jpeg"); | |
450 base::StringPairs replacement_text; | |
451 replacement_text.push_back( | |
452 std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec())); | |
453 std::string main_page_path; | |
454 net::test_server::GetFilePathWithReplacements( | |
455 kPrefetchImagePage, replacement_text, &main_page_path); | |
456 RequestCounter script_counter; | |
457 CountRequestFor(kPrefetchScript, &script_counter); | |
458 | |
459 std::unique_ptr<TestPrerender> prerender = | |
460 PrerenderTestURL(main_page_path, FINAL_STATUS_APP_TERMINATING, 1); | |
461 // Checks that the presumed failure of the image load didn't affect the script | |
462 // fetch. This assumes waiting for the script load is enough to see any error | |
463 // from the image load. | |
464 script_counter.WaitForCount(1); | |
465 } | |
466 | |
467 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Loop) { | |
468 RequestCounter script_counter; | |
469 CountRequestFor(kPrefetchScript, &script_counter); | |
470 RequestCounter main_counter; | |
471 CountRequestFor(kPrefetchLoopPage, &main_counter); | |
472 | |
473 std::unique_ptr<TestPrerender> test_prerender = | |
474 PrerenderTestURL(kPrefetchLoopPage, FINAL_STATUS_APP_TERMINATING, 1); | |
475 main_counter.WaitForCount(1); | |
476 script_counter.WaitForCount(1); | |
477 } | |
478 | |
479 #if defined(ENABLE_TASK_MANAGER) | |
480 | |
481 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, | |
482 OpenTaskManagerBeforePrefetch) { | |
483 const base::string16 any_prerender = MatchTaskManagerPrerender("*"); | |
484 const base::string16 any_tab = MatchTaskManagerTab("*"); | |
485 const base::string16 original = MatchTaskManagerTab("Prefetch Loader"); | |
486 // The page title is not visible in the task manager, presumably because the | |
487 // page has not been fully parsed. | |
488 const base::string16 prerender = | |
489 MatchTaskManagerPrerender("*prefetch_page.html*"); | |
490 | |
491 // Show the task manager. This populates the model. | |
492 chrome::OpenTaskManager(current_browser()); | |
493 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); | |
494 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender)); | |
495 | |
496 // Prerender a page in addition to the original tab. | |
497 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | |
498 | |
499 // A TaskManager entry should appear like "Prerender: Prerender Page" | |
500 // alongside the original tab entry. There should be just these two entries. | |
501 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender)); | |
502 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original)); | |
503 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender)); | |
504 ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab)); | |
505 } | |
506 | |
507 #endif // defined(ENABLE_TASK_MANAGER) | |
508 | |
509 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, RendererCrash) { | |
510 std::unique_ptr<TestPrerender> prerender = | |
511 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_RENDERER_CRASHED, 1); | |
512 prerender->contents()->prerender_contents()->GetController().LoadURL( | |
513 GURL(content::kChromeUICrashURL), content::Referrer(), | |
514 ui::PAGE_TRANSITION_TYPED, std::string()); | |
515 prerender->WaitForStop(); | |
516 } | |
517 | |
518 // Checks that the prefetch of png correctly loads the png. | |
519 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Png) { | |
520 RequestCounter counter; | |
521 CountRequestFor(kPrefetchPng, &counter); | |
522 PrerenderTestURL(kPrefetchPng, FINAL_STATUS_APP_TERMINATING, 1); | |
523 counter.WaitForCount(1); | |
524 } | |
525 | |
526 // Checks that the prefetch of png correctly loads the jpeg. | |
527 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Jpeg) { | |
528 RequestCounter counter; | |
529 CountRequestFor(kPrefetchJpeg, &counter); | |
530 PrerenderTestURL(kPrefetchJpeg, FINAL_STATUS_APP_TERMINATING, 1); | |
531 counter.WaitForCount(1); | |
532 } | |
533 | |
534 // Checks that nothing is prefetched from malware sites. | |
535 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, | |
536 PrerenderSafeBrowsingTopLevel) { | |
537 GURL url = src_server()->GetURL(MakeAbsolute(kPrefetchPage)); | |
538 GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl( | |
539 url, safe_browsing::SB_THREAT_TYPE_URL_MALWARE); | |
540 // Prefetch resources are blocked, but the prerender is not killed in any | |
541 // special way. | |
542 // TODO(mattcary): since the prerender will count itself as loaded even if the | |
543 // fetch of the main resource fails, the test doesn't actually confirm what we | |
544 // want it to confirm. This may be fixed by planned changes to the prerender | |
545 // lifecycle. | |
546 std::unique_ptr<TestPrerender> prerender = | |
547 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_TESTING_IGNORE, 1); | |
548 } | |
549 | |
550 } // namespace prerender | |
OLD | NEW |