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" | |
11 #include "components/dom_distiller/core/distiller_page.h" | 10 #include "components/dom_distiller/core/distiller_page.h" |
12 #include "content/public/browser/browser_context.h" | 11 #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" | |
16 #include "content/public/test/content_browser_test.h" | 12 #include "content/public/test/content_browser_test.h" |
17 #include "content/shell/browser/shell.h" | 13 #include "content/shell/browser/shell.h" |
18 #include "grit/component_resources.h" | 14 #include "grit/component_resources.h" |
19 #include "net/test/embedded_test_server/embedded_test_server.h" | 15 #include "net/test/embedded_test_server/embedded_test_server.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "ui/base/resource/resource_bundle.h" | 17 #include "ui/base/resource/resource_bundle.h" |
22 | 18 |
23 using content::ContentBrowserTest; | 19 using content::ContentBrowserTest; |
24 using testing::ContainsRegex; | 20 using testing::ContainsRegex; |
25 using testing::HasSubstr; | 21 using testing::HasSubstr; |
26 using testing::Not; | 22 using testing::Not; |
27 | 23 |
28 namespace dom_distiller { | 24 namespace dom_distiller { |
29 | 25 |
30 const char* kSimpleArticlePath = "/simple_article.html"; | |
31 | |
32 class DistillerPageWebContentsTest : public ContentBrowserTest { | 26 class DistillerPageWebContentsTest : public ContentBrowserTest { |
33 public: | 27 public: |
34 // ContentBrowserTest: | 28 // ContentBrowserTest: |
35 virtual void SetUpOnMainThread() OVERRIDE { | 29 virtual void SetUpOnMainThread() OVERRIDE { |
36 AddComponentsResources(); | 30 AddComponentsResources(); |
37 SetUpTestServer(); | 31 SetUpTestServer(); |
38 ContentBrowserTest::SetUpOnMainThread(); | 32 ContentBrowserTest::SetUpOnMainThread(); |
39 } | 33 } |
40 | 34 |
41 void DistillPage(const base::Closure& quit_closure, const std::string& url) { | 35 void DistillPage(const base::Closure& quit_closure, const std::string& url) { |
(...skipping 23 matching lines...) Expand all Loading... |
65 | 59 |
66 void SetUpTestServer() { | 60 void SetUpTestServer() { |
67 base::FilePath path; | 61 base::FilePath path; |
68 PathService::Get(base::DIR_SOURCE_ROOT, &path); | 62 PathService::Get(base::DIR_SOURCE_ROOT, &path); |
69 path = path.AppendASCII("components/test/data/dom_distiller"); | 63 path = path.AppendASCII("components/test/data/dom_distiller"); |
70 embedded_test_server()->ServeFilesFromDirectory(path); | 64 embedded_test_server()->ServeFilesFromDirectory(path); |
71 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 65 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
72 } | 66 } |
73 | 67 |
74 protected: | 68 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 | |
80 DistillerPageWebContents* distiller_page_; | 69 DistillerPageWebContents* distiller_page_; |
81 base::Closure quit_closure_; | 70 base::Closure quit_closure_; |
82 scoped_ptr<DistilledPageInfo> page_info_; | 71 scoped_ptr<DistilledPageInfo> page_info_; |
83 }; | 72 }; |
84 | 73 |
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 | |
169 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { | 74 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { |
170 DistillerPageWebContents distiller_page( | 75 DistillerPageWebContents distiller_page( |
171 shell()->web_contents()->GetBrowserContext(), | 76 shell()->web_contents()->GetBrowserContext()); |
172 scoped_ptr<SourcePageHandleWebContents>()); | |
173 distiller_page_ = &distiller_page; | 77 distiller_page_ = &distiller_page; |
174 | 78 |
175 base::RunLoop run_loop; | 79 base::RunLoop run_loop; |
176 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 80 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); |
177 run_loop.Run(); | 81 run_loop.Run(); |
178 | 82 |
179 EXPECT_EQ("Test Page Title", page_info_.get()->title); | 83 EXPECT_EQ("Test Page Title", page_info_.get()->title); |
180 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); | 84 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); |
181 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("questionable content"))); | 85 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("questionable content"))); |
182 EXPECT_EQ("", page_info_.get()->next_page_url); | 86 EXPECT_EQ("", page_info_.get()->next_page_url); |
183 EXPECT_EQ("", page_info_.get()->prev_page_url); | 87 EXPECT_EQ("", page_info_.get()->prev_page_url); |
184 } | 88 } |
185 | 89 |
186 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { | 90 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { |
187 DistillerPageWebContents distiller_page( | 91 DistillerPageWebContents distiller_page( |
188 shell()->web_contents()->GetBrowserContext(), | 92 shell()->web_contents()->GetBrowserContext()); |
189 scoped_ptr<SourcePageHandleWebContents>()); | |
190 distiller_page_ = &distiller_page; | 93 distiller_page_ = &distiller_page; |
191 | 94 |
192 base::RunLoop run_loop; | 95 base::RunLoop run_loop; |
193 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 96 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); |
194 run_loop.Run(); | 97 run_loop.Run(); |
195 | 98 |
196 // A relative link should've been updated. | 99 // A relative link should've been updated. |
197 EXPECT_THAT(page_info_.get()->html, | 100 EXPECT_THAT(page_info_.get()->html, |
198 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); | 101 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); |
199 EXPECT_THAT(page_info_.get()->html, | 102 EXPECT_THAT(page_info_.get()->html, |
200 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); | 103 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); |
201 } | 104 } |
202 | 105 |
203 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { | 106 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { |
204 DistillerPageWebContents distiller_page( | 107 DistillerPageWebContents distiller_page( |
205 shell()->web_contents()->GetBrowserContext(), | 108 shell()->web_contents()->GetBrowserContext()); |
206 scoped_ptr<SourcePageHandleWebContents>()); | |
207 distiller_page_ = &distiller_page; | 109 distiller_page_ = &distiller_page; |
208 | 110 |
209 base::RunLoop run_loop; | 111 base::RunLoop run_loop; |
210 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 112 DistillPage(run_loop.QuitClosure(), "/simple_article.html"); |
211 run_loop.Run(); | 113 run_loop.Run(); |
212 | 114 |
213 // A relative link should've been updated. | 115 // A relative link should've been updated. |
214 EXPECT_THAT(page_info_.get()->html, | 116 EXPECT_THAT(page_info_.get()->html, |
215 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); | 117 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); |
216 EXPECT_THAT(page_info_.get()->html, | 118 EXPECT_THAT(page_info_.get()->html, |
217 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); | 119 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); |
218 } | 120 } |
219 | 121 |
220 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { | 122 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { |
221 DistillerPageWebContents distiller_page( | 123 DistillerPageWebContents distiller_page( |
222 shell()->web_contents()->GetBrowserContext(), | 124 shell()->web_contents()->GetBrowserContext()); |
223 scoped_ptr<SourcePageHandleWebContents>()); | |
224 distiller_page_ = &distiller_page; | 125 distiller_page_ = &distiller_page; |
225 | 126 |
226 // visble_style.html and invisible_style.html only differ by the visibility | 127 // visble_style.html and invisible_style.html only differ by the visibility |
227 // internal stylesheet. | 128 // internal stylesheet. |
228 | 129 |
229 { | 130 { |
230 base::RunLoop run_loop; | 131 base::RunLoop run_loop; |
231 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); | 132 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); |
232 run_loop.Run(); | 133 run_loop.Run(); |
233 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); | 134 EXPECT_THAT(page_info_.get()->html, HasSubstr("Lorem ipsum")); |
234 } | 135 } |
235 | 136 |
236 { | 137 { |
237 base::RunLoop run_loop; | 138 base::RunLoop run_loop; |
238 DistillPage(run_loop.QuitClosure(), "/invisible_style.html"); | 139 DistillPage(run_loop.QuitClosure(), "/invisible_style.html"); |
239 run_loop.Run(); | 140 run_loop.Run(); |
240 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("Lorem ipsum"))); | 141 EXPECT_THAT(page_info_.get()->html, Not(HasSubstr("Lorem ipsum"))); |
241 } | 142 } |
242 } | 143 } |
243 | 144 |
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 | |
332 } // namespace dom_distiller | 145 } // namespace dom_distiller |
OLD | NEW |