OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/memory/weak_ptr.h" | 5 #include "base/memory/weak_ptr.h" |
6 #include "base/path_service.h" | 6 #include "base/path_service.h" |
7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "components/dom_distiller/content/distiller_page_web_contents.h" | 9 #include "components/dom_distiller/content/distiller_page_web_contents.h" |
| 10 #include "components/dom_distiller/content/web_contents_main_frame_observer.h" |
10 #include "components/dom_distiller/core/distiller_page.h" | 11 #include "components/dom_distiller/core/distiller_page.h" |
11 #include "content/public/browser/browser_context.h" | 12 #include "content/public/browser/browser_context.h" |
| 13 #include "content/public/browser/navigation_controller.h" |
| 14 #include "content/public/browser/render_frame_host.h" |
| 15 #include "content/public/browser/web_contents_observer.h" |
12 #include "content/public/test/content_browser_test.h" | 16 #include "content/public/test/content_browser_test.h" |
13 #include "content/shell/browser/shell.h" | 17 #include "content/shell/browser/shell.h" |
14 #include "grit/component_resources.h" | 18 #include "grit/component_resources.h" |
15 #include "net/test/embedded_test_server/embedded_test_server.h" | 19 #include "net/test/embedded_test_server/embedded_test_server.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
18 | 22 |
19 using content::ContentBrowserTest; | 23 using content::ContentBrowserTest; |
20 using testing::ContainsRegex; | 24 using testing::ContainsRegex; |
21 using testing::HasSubstr; | 25 using testing::HasSubstr; |
22 using testing::Not; | 26 using testing::Not; |
23 | 27 |
24 namespace dom_distiller { | 28 namespace dom_distiller { |
25 | 29 |
| 30 const char* kSimpleArticlePath = "/simple_article.html"; |
| 31 |
26 class DistillerPageWebContentsTest : public ContentBrowserTest { | 32 class DistillerPageWebContentsTest : public ContentBrowserTest { |
27 public: | 33 public: |
28 // ContentBrowserTest: | 34 // ContentBrowserTest: |
29 virtual void SetUpOnMainThread() OVERRIDE { | 35 virtual void SetUpOnMainThread() OVERRIDE { |
30 AddComponentsResources(); | 36 AddComponentsResources(); |
31 SetUpTestServer(); | 37 SetUpTestServer(); |
32 ContentBrowserTest::SetUpOnMainThread(); | 38 ContentBrowserTest::SetUpOnMainThread(); |
33 } | 39 } |
34 | 40 |
35 void DistillPage(const base::Closure& quit_closure, const std::string& url) { | 41 void DistillPage(const base::Closure& quit_closure, const std::string& url) { |
(...skipping 23 matching lines...) Expand all Loading... |
59 | 65 |
60 void SetUpTestServer() { | 66 void SetUpTestServer() { |
61 base::FilePath path; | 67 base::FilePath path; |
62 PathService::Get(base::DIR_SOURCE_ROOT, &path); | 68 PathService::Get(base::DIR_SOURCE_ROOT, &path); |
63 path = path.AppendASCII("components/test/data/dom_distiller"); | 69 path = path.AppendASCII("components/test/data/dom_distiller"); |
64 embedded_test_server()->ServeFilesFromDirectory(path); | 70 embedded_test_server()->ServeFilesFromDirectory(path); |
65 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 71 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
66 } | 72 } |
67 | 73 |
68 protected: | 74 protected: |
| 75 void RunUseCurrentWebContentsTest(const std::string& url, |
| 76 bool expect_new_web_contents, |
| 77 bool setup_main_frame_observer, |
| 78 bool wait_for_document_loaded); |
| 79 |
69 DistillerPageWebContents* distiller_page_; | 80 DistillerPageWebContents* distiller_page_; |
70 base::Closure quit_closure_; | 81 base::Closure quit_closure_; |
71 scoped_ptr<DistilledPageInfo> page_info_; | 82 scoped_ptr<DistilledPageInfo> page_info_; |
72 }; | 83 }; |
73 | 84 |
| 85 // Use this class to be able to leak the WebContents, which is needed for when |
| 86 // the current WebContents is used for distillation. |
| 87 class TestDistillerPageWebContents : public DistillerPageWebContents { |
| 88 public: |
| 89 TestDistillerPageWebContents( |
| 90 content::BrowserContext* browser_context, |
| 91 scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle, |
| 92 bool expect_new_web_contents) |
| 93 : DistillerPageWebContents(browser_context, |
| 94 optional_web_contents_handle.Pass()), |
| 95 expect_new_web_contents_(expect_new_web_contents), |
| 96 new_web_contents_created_(false) {} |
| 97 |
| 98 virtual void CreateNewWebContents(const GURL& url) OVERRIDE { |
| 99 ASSERT_EQ(true, expect_new_web_contents_); |
| 100 new_web_contents_created_ = true; |
| 101 // DistillerPageWebContents::CreateNewWebContents resets the scoped_ptr to |
| 102 // the WebContents, so intentionally leak WebContents here, since it is |
| 103 // owned by the shell. |
| 104 content::WebContents* web_contents = web_contents_.release(); |
| 105 web_contents->GetLastCommittedURL(); |
| 106 DistillerPageWebContents::CreateNewWebContents(url); |
| 107 } |
| 108 |
| 109 virtual ~TestDistillerPageWebContents() { |
| 110 if (!expect_new_web_contents_) { |
| 111 // Intentionally leaking WebContents, since it is owned by the shell. |
| 112 content::WebContents* web_contents = web_contents_.release(); |
| 113 web_contents->GetLastCommittedURL(); |
| 114 } |
| 115 } |
| 116 |
| 117 bool new_web_contents_created() { return new_web_contents_created_; } |
| 118 |
| 119 private: |
| 120 bool expect_new_web_contents_; |
| 121 bool new_web_contents_created_; |
| 122 }; |
| 123 |
| 124 // Helper class to know how far in the loading process the current WebContents |
| 125 // has come. It will call the callback either after |
| 126 // DidCommitProvisionalLoadForFrame or DocumentLoadedInFrame is called for the |
| 127 // main frame, based on the value of |wait_for_document_loaded|. |
| 128 class WebContentsMainFrameHelper : public content::WebContentsObserver { |
| 129 public: |
| 130 WebContentsMainFrameHelper(content::WebContents* web_contents, |
| 131 const base::Closure& callback, |
| 132 bool wait_for_document_loaded) |
| 133 : web_contents_(web_contents), |
| 134 callback_(callback), |
| 135 wait_for_document_loaded_(wait_for_document_loaded) { |
| 136 content::WebContentsObserver::Observe(web_contents); |
| 137 } |
| 138 |
| 139 virtual void DidCommitProvisionalLoadForFrame( |
| 140 int64 frame_id, |
| 141 const base::string16& frame_unique_name, |
| 142 bool is_main_frame, |
| 143 const GURL& url, |
| 144 content::PageTransition transition_type, |
| 145 content::RenderViewHost* render_view_host) OVERRIDE { |
| 146 if (wait_for_document_loaded_) |
| 147 return; |
| 148 if (is_main_frame) |
| 149 callback_.Run(); |
| 150 } |
| 151 |
| 152 virtual void DocumentLoadedInFrame( |
| 153 int64 frame_id, |
| 154 content::RenderViewHost* render_view_host) OVERRIDE { |
| 155 if (wait_for_document_loaded_) { |
| 156 if (web_contents_ && |
| 157 frame_id == web_contents_->GetMainFrame()->GetRoutingID()) { |
| 158 callback_.Run(); |
| 159 } |
| 160 } |
| 161 } |
| 162 |
| 163 private: |
| 164 content::WebContents* web_contents_; |
| 165 base::Closure callback_; |
| 166 bool wait_for_document_loaded_; |
| 167 }; |
| 168 |
74 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { | 169 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { |
75 DistillerPageWebContents distiller_page( | 170 DistillerPageWebContents distiller_page( |
76 shell()->web_contents()->GetBrowserContext()); | 171 shell()->web_contents()->GetBrowserContext(), |
| 172 scoped_ptr<SourcePageHandleWebContents>()); |
77 distiller_page_ = &distiller_page; | 173 distiller_page_ = &distiller_page; |
78 | 174 |
79 base::RunLoop run_loop; | 175 base::RunLoop run_loop; |
80 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); | 176 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
81 run_loop.Run(); | 177 run_loop.Run(); |
82 | 178 |
83 EXPECT_EQ("Test Page Title", page_info_.get()->title); | 179 EXPECT_EQ("Test Page Title", page_info_.get()->title); |
84 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); | 180 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); |
85 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("questionable content"))); | 181 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("questionable content"))); |
86 EXPECT_EQ("", page_info_.get()->next_page_url); | 182 EXPECT_EQ("", page_info_.get()->next_page_url); |
87 EXPECT_EQ("", page_info_.get()->prev_page_url); | 183 EXPECT_EQ("", page_info_.get()->prev_page_url); |
88 } | 184 } |
89 | 185 |
90 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { | 186 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { |
91 DistillerPageWebContents distiller_page( | 187 DistillerPageWebContents distiller_page( |
92 shell()->web_contents()->GetBrowserContext()); | 188 shell()->web_contents()->GetBrowserContext(), |
| 189 scoped_ptr<SourcePageHandleWebContents>()); |
93 distiller_page_ = &distiller_page; | 190 distiller_page_ = &distiller_page; |
94 | 191 |
95 base::RunLoop run_loop; | 192 base::RunLoop run_loop; |
96 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); | 193 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
97 run_loop.Run(); | 194 run_loop.Run(); |
98 | 195 |
99 // A relative link should've been updated. | 196 // A relative link should've been updated. |
100 EXPECT_THAT(page_info_.get()->html, | 197 EXPECT_THAT(page_info_.get()->html, |
101 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); | 198 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); |
102 EXPECT_THAT(page_info_.get()->html, | 199 EXPECT_THAT(page_info_.get()->html, |
103 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); | 200 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); |
104 } | 201 } |
105 | 202 |
106 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { | 203 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { |
107 DistillerPageWebContents distiller_page( | 204 DistillerPageWebContents distiller_page( |
108 shell()->web_contents()->GetBrowserContext()); | 205 shell()->web_contents()->GetBrowserContext(), |
| 206 scoped_ptr<SourcePageHandleWebContents>()); |
109 distiller_page_ = &distiller_page; | 207 distiller_page_ = &distiller_page; |
110 | 208 |
111 base::RunLoop run_loop; | 209 base::RunLoop run_loop; |
112 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); | 210 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
113 run_loop.Run(); | 211 run_loop.Run(); |
114 | 212 |
115 // A relative link should've been updated. | 213 // A relative link should've been updated. |
116 EXPECT_THAT(page_info_.get()->html, | 214 EXPECT_THAT(page_info_.get()->html, |
117 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); | 215 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); |
118 EXPECT_THAT(page_info_.get()->html, | 216 EXPECT_THAT(page_info_.get()->html, |
119 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); | 217 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); |
120 } | 218 } |
121 | 219 |
122 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { | 220 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { |
123 DistillerPageWebContents distiller_page( | 221 DistillerPageWebContents distiller_page( |
124 shell()->web_contents()->GetBrowserContext()); | 222 shell()->web_contents()->GetBrowserContext(), |
| 223 scoped_ptr<SourcePageHandleWebContents>()); |
125 distiller_page_ = &distiller_page; | 224 distiller_page_ = &distiller_page; |
126 | 225 |
127 // visble_style.html and invisible_style.html only differ by the visibility | 226 // visble_style.html and invisible_style.html only differ by the visibility |
128 // internal stylesheet. | 227 // internal stylesheet. |
129 | 228 |
130 { | 229 { |
131 base::RunLoop run_loop; | 230 base::RunLoop run_loop; |
132 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); | 231 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); |
133 run_loop.Run(); | 232 run_loop.Run(); |
134 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); | 233 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); |
135 } | 234 } |
136 | 235 |
137 { | 236 { |
138 base::RunLoop run_loop; | 237 base::RunLoop run_loop; |
139 DistillPage(run_loop.QuitClosure(), "/invisible_style.html"); | 238 DistillPage(run_loop.QuitClosure(), "/invisible_style.html"); |
140 run_loop.Run(); | 239 run_loop.Run(); |
141 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("Lorem ipsum"))); | 240 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("Lorem ipsum"))); |
142 } | 241 } |
143 } | 242 } |
144 | 243 |
| 244 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, |
| 245 UsingCurrentWebContentsWrongUrl) { |
| 246 std::string url("/bogus"); |
| 247 bool expect_new_web_contents = true; |
| 248 bool setup_main_frame_observer = true; |
| 249 bool wait_for_document_loaded = true; |
| 250 RunUseCurrentWebContentsTest(url, |
| 251 expect_new_web_contents, |
| 252 setup_main_frame_observer, |
| 253 wait_for_document_loaded); |
| 254 } |
| 255 |
| 256 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, |
| 257 UsingCurrentWebContentsNoMainFrameObserver) { |
| 258 std::string url(kSimpleArticlePath); |
| 259 bool expect_new_web_contents = true; |
| 260 bool setup_main_frame_observer = false; |
| 261 bool wait_for_document_loaded = true; |
| 262 RunUseCurrentWebContentsTest(url, |
| 263 expect_new_web_contents, |
| 264 setup_main_frame_observer, |
| 265 wait_for_document_loaded); |
| 266 } |
| 267 |
| 268 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, |
| 269 UsingCurrentWebContentsNotFinishedLoadingYet) { |
| 270 std::string url(kSimpleArticlePath); |
| 271 bool expect_new_web_contents = false; |
| 272 bool setup_main_frame_observer = true; |
| 273 bool wait_for_document_loaded = false; |
| 274 RunUseCurrentWebContentsTest(url, |
| 275 expect_new_web_contents, |
| 276 setup_main_frame_observer, |
| 277 wait_for_document_loaded); |
| 278 } |
| 279 |
| 280 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, |
| 281 UsingCurrentWebContentsReadyForDistillation) { |
| 282 std::string url(kSimpleArticlePath); |
| 283 bool expect_new_web_contents = false; |
| 284 bool setup_main_frame_observer = true; |
| 285 bool wait_for_document_loaded = true; |
| 286 RunUseCurrentWebContentsTest(url, |
| 287 expect_new_web_contents, |
| 288 setup_main_frame_observer, |
| 289 wait_for_document_loaded); |
| 290 } |
| 291 |
| 292 void DistillerPageWebContentsTest::RunUseCurrentWebContentsTest( |
| 293 const std::string& url, |
| 294 bool expect_new_web_contents, |
| 295 bool setup_main_frame_observer, |
| 296 bool wait_for_document_loaded) { |
| 297 content::WebContents* current_web_contents = shell()->web_contents(); |
| 298 if (setup_main_frame_observer) { |
| 299 dom_distiller::WebContentsMainFrameObserver::CreateForWebContents( |
| 300 current_web_contents); |
| 301 } |
| 302 base::RunLoop url_loaded_runner; |
| 303 WebContentsMainFrameHelper main_frame_loaded(current_web_contents, |
| 304 url_loaded_runner.QuitClosure(), |
| 305 wait_for_document_loaded); |
| 306 current_web_contents->GetController().LoadURL( |
| 307 embedded_test_server()->GetURL(url), |
| 308 content::Referrer(), |
| 309 content::PAGE_TRANSITION_TYPED, |
| 310 std::string()); |
| 311 url_loaded_runner.Run(); |
| 312 |
| 313 scoped_ptr<content::WebContents> old_web_contents_sptr(current_web_contents); |
| 314 scoped_ptr<SourcePageHandleWebContents> source_page_handle( |
| 315 new SourcePageHandleWebContents(old_web_contents_sptr.Pass())); |
| 316 |
| 317 TestDistillerPageWebContents distiller_page( |
| 318 shell()->web_contents()->GetBrowserContext(), |
| 319 source_page_handle.Pass(), |
| 320 expect_new_web_contents); |
| 321 distiller_page_ = &distiller_page; |
| 322 |
| 323 base::RunLoop run_loop; |
| 324 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
| 325 run_loop.Run(); |
| 326 |
| 327 // Sanity check of distillation process. |
| 328 EXPECT_EQ(expect_new_web_contents, distiller_page.new_web_contents_created()); |
| 329 EXPECT_EQ("Test Page Title", page_info_.get()->title); |
| 330 } |
| 331 |
145 } // namespace dom_distiller | 332 } // namespace dom_distiller |
OLD | NEW |