| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/strings/string16.h" | 6 #include "base/strings/string16.h" |
| 7 #include "base/strings/string_split.h" | 7 #include "base/strings/string_split.h" |
| 8 #include "base/task_scheduler/post_task.h" | 8 #include "base/task_scheduler/post_task.h" |
| 9 #include "chrome/browser/prerender/prerender_manager.h" | 9 #include "chrome/browser/prerender/prerender_manager.h" |
| 10 #include "chrome/browser/prerender/prerender_manager_factory.h" | 10 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 28 | 28 |
| 29 using prerender::test_utils::CreateCountingInterceptorOnIO; | 29 using prerender::test_utils::CreateCountingInterceptorOnIO; |
| 30 using prerender::test_utils::DestructionWaiter; | 30 using prerender::test_utils::DestructionWaiter; |
| 31 using prerender::test_utils::RequestCounter; | 31 using prerender::test_utils::RequestCounter; |
| 32 using prerender::test_utils::TestPrerender; | 32 using prerender::test_utils::TestPrerender; |
| 33 using prerender::test_utils::TestPrerenderContents; | 33 using prerender::test_utils::TestPrerenderContents; |
| 34 using task_manager::browsertest_util::WaitForTaskManagerRows; | 34 using task_manager::browsertest_util::WaitForTaskManagerRows; |
| 35 | 35 |
| 36 namespace { | |
| 37 // Fetches a boolean value from javascript. Returns whether the fetch | |
| 38 // succeeded; the value of the variable is returned in value. If | |
| 39 // javascript_variable does not exist, this returns false and value is | |
| 40 // unchanged. The function checks that script execution works. | |
| 41 bool GetJavascriptBoolean(const std::string& javascript_variable, | |
| 42 content::WebContents* web_contents, | |
| 43 bool* value) { | |
| 44 // In order to detect unknown variables a three-valued return is needed. | |
| 45 int result; | |
| 46 EXPECT_TRUE(content::ExecuteScriptAndExtractInt( | |
| 47 web_contents, | |
| 48 "try { if (" + javascript_variable + ") { " + | |
| 49 "window.domAutomationController.send(1) } else { " + | |
| 50 "window.domAutomationController.send(0); } } catch(err) {" + | |
| 51 "window.domAutomationController.send(2) }", | |
| 52 &result)); | |
| 53 if (result == 2) { | |
| 54 // This means an exception was caught, usually because of a missing | |
| 55 // variable. | |
| 56 return false; | |
| 57 } | |
| 58 *value = (result == 1); | |
| 59 return true; | |
| 60 } | |
| 61 | |
| 62 // As above, but just checks for a missing variable. | |
| 63 bool JavascriptVariableMissing(const std::string& javascript_variable, | |
| 64 content::WebContents* web_contents) { | |
| 65 bool unused; | |
| 66 return !GetJavascriptBoolean(javascript_variable, web_contents, &unused); | |
| 67 } | |
| 68 | |
| 69 } // namespace | |
| 70 | |
| 71 namespace prerender { | 36 namespace prerender { |
| 72 | 37 |
| 73 // These URLs used for test resources must be relative with the exception of | 38 // These URLs used for test resources must be relative with the exception of |
| 74 // |PrefetchLoaderPath|, which is only used in |PrerenderTestURLImpl()|. | 39 // |PrefetchLoaderPath|, which is only used in |PrerenderTestURLImpl()|. |
| 75 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; | 40 const char kPrefetchImagePage[] = "prerender/prefetch_image.html"; |
| 76 const char kPrefetchJpeg[] = "prerender/image.jpeg"; | 41 const char kPrefetchJpeg[] = "prerender/image.jpeg"; |
| 77 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; | 42 const char kPrefetchLoaderPath[] = "/prerender/prefetch_loader.html"; |
| 78 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; | 43 const char kPrefetchLoopPage[] = "prerender/prefetch_loop.html"; |
| 79 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; | 44 const char kPrefetchMetaCSP[] = "prerender/prefetch_meta_csp.html"; |
| 80 const char kPrefetchPage[] = "prerender/prefetch_page.html"; | 45 const char kPrefetchPage[] = "prerender/prefetch_page.html"; |
| 81 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; | 46 const char kPrefetchPage2[] = "prerender/prefetch_page2.html"; |
| 82 const char kPrefetchPng[] = "prerender/image.png"; | 47 const char kPrefetchPng[] = "prerender/image.png"; |
| 83 const char kPrefetchResponseHeaderCSP[] = | 48 const char kPrefetchResponseHeaderCSP[] = |
| 84 "prerender/prefetch_response_csp.html"; | 49 "prerender/prefetch_response_csp.html"; |
| 85 const char kPrefetchScript[] = "prerender/prefetch.js"; | 50 const char kPrefetchScript[] = "prerender/prefetch.js"; |
| 86 const char kPrefetchScript2[] = "prerender/prefetch2.js"; | 51 const char kPrefetchScript2[] = "prerender/prefetch2.js"; |
| 87 const char kPrefetchSubresourceRedirectPage[] = | 52 const char kPrefetchSubresourceRedirectPage[] = |
| 88 "prerender/prefetch_subresource_redirect.html"; | 53 "prerender/prefetch_subresource_redirect.html"; |
| 89 | 54 |
| 90 const char kPageBool[] = "pageBool"; | |
| 91 const char kScriptBool[] = "scriptBool"; | |
| 92 | |
| 93 class NoStatePrefetchBrowserTest | 55 class NoStatePrefetchBrowserTest |
| 94 : public test_utils::PrerenderInProcessBrowserTest { | 56 : public test_utils::PrerenderInProcessBrowserTest { |
| 95 public: | 57 public: |
| 96 class BrowserTestTime : public PrerenderManager::TimeOverride { | 58 class BrowserTestTime : public PrerenderManager::TimeOverride { |
| 97 public: | 59 public: |
| 98 BrowserTestTime() {} | 60 BrowserTestTime() {} |
| 99 | 61 |
| 100 base::Time GetCurrentTime() const override { | 62 base::Time GetCurrentTime() const override { |
| 101 if (delta_.is_zero()) { | 63 if (delta_.is_zero()) { |
| 102 return base::Time::Now(); | 64 return base::Time::Now(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); | 153 EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status()); |
| 192 } | 154 } |
| 193 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads()); | 155 EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads()); |
| 194 | 156 |
| 195 return prerenders; | 157 return prerenders; |
| 196 } | 158 } |
| 197 | 159 |
| 198 BrowserTestTime* browser_test_time_; | 160 BrowserTestTime* browser_test_time_; |
| 199 }; | 161 }; |
| 200 | 162 |
| 201 // Performs a full load of the target page and check that javascript values are | |
| 202 // set as expected. This confirms that our test system is working correctly, so | |
| 203 // that when the target page is prefetched it can be confirmed that javascript | |
| 204 // is not executed. | |
| 205 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, CheckJavascript) { | |
| 206 ui_test_utils::NavigateToURL( | |
| 207 current_browser(), src_server()->GetURL(MakeAbsolute(kPrefetchPage))); | |
| 208 content::WebContents* web_contents = | |
| 209 current_browser()->tab_strip_model()->GetActiveWebContents(); | |
| 210 | |
| 211 // Confirms that true and false values can appear. | |
| 212 bool value = false; | |
| 213 EXPECT_TRUE(GetJavascriptBoolean(kPageBool, web_contents, &value)); | |
| 214 EXPECT_TRUE(value); | |
| 215 value = true; | |
| 216 EXPECT_TRUE(GetJavascriptBoolean("pageAntiBool", web_contents, &value)); | |
| 217 EXPECT_FALSE(value); | |
| 218 | |
| 219 // Confirm a value from the script is plumbed through. | |
| 220 value = false; | |
| 221 EXPECT_TRUE(GetJavascriptBoolean(kScriptBool, web_contents, &value)); | |
| 222 EXPECT_TRUE(value); | |
| 223 | |
| 224 // Confirm that the expected happens when a value doesn't exist. | |
| 225 EXPECT_TRUE(JavascriptVariableMissing("iDontExist", web_contents)); | |
| 226 } | |
| 227 | |
| 228 // Checks that a page is correctly prefetched in the case of a | 163 // Checks that a page is correctly prefetched in the case of a |
| 229 // <link rel=prerender> tag and then loaded into a tab in response to a | 164 // <link rel=prerender> tag and the JavaScript on the page is not executed. |
| 230 // navigation, when NoState Prefetch is enabled, but that the page is not loaded | |
| 231 // (which confirmed by checking that javascript is not executed). | |
| 232 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) { | 165 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimple) { |
| 166 RequestCounter main_counter; |
| 167 CountRequestFor(kPrefetchPage, &main_counter); |
| 233 RequestCounter script_counter; | 168 RequestCounter script_counter; |
| 234 CountRequestFor(kPrefetchScript, &script_counter); | 169 CountRequestFor(kPrefetchScript, &script_counter); |
| 235 RequestCounter main_counter; | 170 RequestCounter script2_counter; |
| 236 CountRequestFor(kPrefetchPage, &main_counter); | 171 CountRequestFor(kPrefetchScript2, &script2_counter); |
| 237 | 172 |
| 238 std::unique_ptr<TestPrerender> test_prerender = | 173 std::unique_ptr<TestPrerender> test_prerender = |
| 239 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); | 174 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_APP_TERMINATING, 1); |
| 240 main_counter.WaitForCount(1); | 175 main_counter.WaitForCount(1); |
| 241 script_counter.WaitForCount(1); | 176 script_counter.WaitForCount(1); |
| 242 | 177 script2_counter.WaitForCount(0); |
| 243 content::WebContents* contents = | |
| 244 test_prerender->contents()->prerender_contents(); | |
| 245 content::WebContents* active_contents = | |
| 246 current_browser()->tab_strip_model()->GetActiveWebContents(); | |
| 247 EXPECT_TRUE(JavascriptVariableMissing(kPageBool, contents)); | |
| 248 EXPECT_TRUE(JavascriptVariableMissing(kScriptBool, contents)); | |
| 249 EXPECT_TRUE(JavascriptVariableMissing(kPageBool, active_contents)); | |
| 250 EXPECT_TRUE(JavascriptVariableMissing(kScriptBool, active_contents)); | |
| 251 } | 178 } |
| 252 | 179 |
| 253 // Checks the prefetch of an img tag. | 180 // Checks the prefetch of an img tag. |
| 254 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { | 181 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchImage) { |
| 255 RequestCounter image_counter; | 182 RequestCounter image_counter; |
| 256 CountRequestFor(kPrefetchJpeg, &image_counter); | 183 CountRequestFor(kPrefetchJpeg, &image_counter); |
| 257 base::StringPairs replacement_text; | 184 base::StringPairs replacement_text; |
| 258 replacement_text.push_back( | 185 replacement_text.push_back( |
| 259 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); | 186 std::make_pair("REPLACE_WITH_IMAGE_URL", MakeAbsolute(kPrefetchJpeg))); |
| 260 std::string main_page_path; | 187 std::string main_page_path; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { | 253 IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchSimultaneous) { |
| 327 RequestCounter first_main_counter; | 254 RequestCounter first_main_counter; |
| 328 CountRequestFor(kPrefetchPage, &first_main_counter); | 255 CountRequestFor(kPrefetchPage, &first_main_counter); |
| 329 RequestCounter second_main_counter; | 256 RequestCounter second_main_counter; |
| 330 CountRequestFor(kPrefetchPage2, &second_main_counter); | 257 CountRequestFor(kPrefetchPage2, &second_main_counter); |
| 331 RequestCounter first_script_counter; | 258 RequestCounter first_script_counter; |
| 332 CountRequestFor(kPrefetchScript, &first_script_counter); | 259 CountRequestFor(kPrefetchScript, &first_script_counter); |
| 333 RequestCounter second_script_counter; | 260 RequestCounter second_script_counter; |
| 334 CountRequestFor(kPrefetchScript2, &second_script_counter); | 261 CountRequestFor(kPrefetchScript2, &second_script_counter); |
| 335 | 262 |
| 336 // The first prerender is marked as canceled as when the second starts, it | 263 // The first prerender is marked as canceled. When the second prerender |
| 337 // sees that the first has been abandoned (presumably because it is detached | 264 // starts, it sees that the first has been abandoned (because the earlier |
| 338 // immediately and so dies quickly). | 265 // prerender is detached immediately and so dies quickly). |
| 339 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_CANCELLED, 1); | 266 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_CANCELLED, 1); |
| 340 PrerenderTestURL(kPrefetchPage2, FINAL_STATUS_APP_TERMINATING, 1); | 267 PrerenderTestURL(kPrefetchPage2, FINAL_STATUS_APP_TERMINATING, 1); |
| 341 first_main_counter.WaitForCount(1); | 268 first_main_counter.WaitForCount(1); |
| 342 second_main_counter.WaitForCount(1); | 269 second_main_counter.WaitForCount(1); |
| 343 first_script_counter.WaitForCount(1); | 270 first_script_counter.WaitForCount(1); |
| 344 second_script_counter.WaitForCount(1); | 271 second_script_counter.WaitForCount(1); |
| 345 } | 272 } |
| 346 | 273 |
| 347 // Checks a prefetch to a nonexisting page. | 274 // Checks a prefetch to a nonexisting page. |
| 348 // TODO(mattcary): disabled as prefetch process teardown is racey with prerender | 275 // TODO(mattcary): disabled as prefetch process teardown is racey with prerender |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // special way. | 459 // special way. |
| 533 // TODO(mattcary): since the prerender will count itself as loaded even if the | 460 // TODO(mattcary): since the prerender will count itself as loaded even if the |
| 534 // fetch of the main resource fails, the test doesn't actually confirm what we | 461 // fetch of the main resource fails, the test doesn't actually confirm what we |
| 535 // want it to confirm. This may be fixed by planned changes to the prerender | 462 // want it to confirm. This may be fixed by planned changes to the prerender |
| 536 // lifecycle. | 463 // lifecycle. |
| 537 std::unique_ptr<TestPrerender> prerender = | 464 std::unique_ptr<TestPrerender> prerender = |
| 538 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_SAFE_BROWSING, 1); | 465 PrerenderTestURL(kPrefetchPage, FINAL_STATUS_SAFE_BROWSING, 1); |
| 539 } | 466 } |
| 540 | 467 |
| 541 } // namespace prerender | 468 } // namespace prerender |
| OLD | NEW |