| 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/content/web_contents_main_frame_observer.h" |
| 11 #include "components/dom_distiller/core/distiller_page.h" | 11 #include "components/dom_distiller/core/distiller_page.h" |
| 12 #include "components/dom_distiller/core/proto/distilled_article.pb.h" | 12 #include "components/dom_distiller/core/proto/distilled_article.pb.h" |
| 13 #include "components/dom_distiller/core/proto/distilled_page.pb.h" | 13 #include "components/dom_distiller/core/proto/distilled_page.pb.h" |
| 14 #include "components/dom_distiller/core/viewer.h" | 14 #include "components/dom_distiller/core/viewer.h" |
| 15 #include "content/public/browser/browser_context.h" | 15 #include "content/public/browser/browser_context.h" |
| 16 #include "content/public/browser/navigation_controller.h" | 16 #include "content/public/browser/navigation_controller.h" |
| 17 #include "content/public/browser/render_frame_host.h" | 17 #include "content/public/browser/render_frame_host.h" |
| 18 #include "content/public/browser/web_contents_observer.h" | 18 #include "content/public/browser/web_contents_observer.h" |
| 19 #include "content/public/test/content_browser_test.h" | 19 #include "content/public/test/content_browser_test.h" |
| 20 #include "content/shell/browser/shell.h" | 20 #include "content/shell/browser/shell.h" |
| 21 #include "grit/components_resources.h" |
| 21 #include "grit/components_strings.h" | 22 #include "grit/components_strings.h" |
| 22 #include "net/test/embedded_test_server/embedded_test_server.h" | 23 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 23 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
| 24 #include "third_party/dom_distiller_js/dom_distiller.pb.h" | 25 #include "third_party/dom_distiller_js/dom_distiller.pb.h" |
| 25 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
| 26 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
| 27 | 28 |
| 28 using content::ContentBrowserTest; | 29 using content::ContentBrowserTest; |
| 29 using testing::ContainsRegex; | 30 using testing::ContainsRegex; |
| 30 using testing::HasSubstr; | 31 using testing::HasSubstr; |
| 31 using testing::Not; | 32 using testing::Not; |
| 32 | 33 |
| 33 namespace dom_distiller { | 34 namespace dom_distiller { |
| 34 | 35 |
| 35 const char* kSimpleArticlePath = "/simple_article.html"; | 36 const char* kSimpleArticlePath = "/simple_article.html"; |
| 36 const char* kVideoArticlePath = "/video_article.html"; | 37 const char* kVideoArticlePath = "/video_article.html"; |
| 37 | 38 |
| 38 class DistillerPageWebContentsTest : public ContentBrowserTest { | 39 class DistillerPageWebContentsTest : public ContentBrowserTest { |
| 39 public: | 40 public: |
| 40 // ContentBrowserTest: | 41 // ContentBrowserTest: |
| 41 void SetUpOnMainThread() override { | 42 void SetUpOnMainThread() override { |
| 42 AddComponentsResources(); | 43 AddComponentsResources(); |
| 43 SetUpTestServer(); | 44 SetUpTestServer(); |
| 44 ContentBrowserTest::SetUpOnMainThread(); | 45 ContentBrowserTest::SetUpOnMainThread(); |
| 46 distiller_js_script_ = ResourceBundle::GetSharedInstance() |
| 47 .GetRawDataResource(IDR_DISTILLER_JS) |
| 48 .as_string(); |
| 45 } | 49 } |
| 46 | 50 |
| 47 void DistillPage(const base::Closure& quit_closure, const std::string& url) { | 51 void DistillPage(const base::Closure& quit_closure, const std::string& url) { |
| 48 quit_closure_ = quit_closure; | 52 quit_closure_ = quit_closure; |
| 49 distiller_page_->DistillPage( | 53 distiller_page_->DistillPage( |
| 50 embedded_test_server()->GetURL(url), | 54 embedded_test_server()->GetURL(url), |
| 51 dom_distiller::proto::DomDistillerOptions(), | 55 dom_distiller::proto::DomDistillerOptions(), |
| 52 base::Bind(&DistillerPageWebContentsTest::OnPageDistillationFinished, | 56 base::Bind(&DistillerPageWebContentsTest::OnPageDistillationFinished, |
| 53 this)); | 57 this)); |
| 54 } | 58 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 81 | 85 |
| 82 protected: | 86 protected: |
| 83 void RunUseCurrentWebContentsTest(const std::string& url, | 87 void RunUseCurrentWebContentsTest(const std::string& url, |
| 84 bool expect_new_web_contents, | 88 bool expect_new_web_contents, |
| 85 bool setup_main_frame_observer, | 89 bool setup_main_frame_observer, |
| 86 bool wait_for_document_loaded); | 90 bool wait_for_document_loaded); |
| 87 | 91 |
| 88 DistillerPageWebContents* distiller_page_; | 92 DistillerPageWebContents* distiller_page_; |
| 89 base::Closure quit_closure_; | 93 base::Closure quit_closure_; |
| 90 scoped_ptr<proto::DomDistillerResult> distiller_result_; | 94 scoped_ptr<proto::DomDistillerResult> distiller_result_; |
| 95 std::string distiller_js_script_; |
| 91 }; | 96 }; |
| 92 | 97 |
| 93 // Use this class to be able to leak the WebContents, which is needed for when | 98 // Use this class to be able to leak the WebContents, which is needed for when |
| 94 // the current WebContents is used for distillation. | 99 // the current WebContents is used for distillation. |
| 95 class TestDistillerPageWebContents : public DistillerPageWebContents { | 100 class TestDistillerPageWebContents : public DistillerPageWebContents { |
| 96 public: | 101 public: |
| 97 TestDistillerPageWebContents( | 102 TestDistillerPageWebContents( |
| 98 content::BrowserContext* browser_context, | 103 content::BrowserContext* browser_context, |
| 99 const gfx::Size& render_view_size, | 104 const gfx::Size& render_view_size, |
| 105 const std::string& distiller_js_script, |
| 100 scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle, | 106 scoped_ptr<SourcePageHandleWebContents> optional_web_contents_handle, |
| 101 bool expect_new_web_contents) | 107 bool expect_new_web_contents) |
| 102 : DistillerPageWebContents(browser_context, render_view_size, | 108 : DistillerPageWebContents(browser_context, |
| 109 render_view_size, |
| 110 distiller_js_script, |
| 103 optional_web_contents_handle.Pass()), | 111 optional_web_contents_handle.Pass()), |
| 104 expect_new_web_contents_(expect_new_web_contents), | 112 expect_new_web_contents_(expect_new_web_contents), |
| 105 new_web_contents_created_(false) {} | 113 new_web_contents_created_(false) {} |
| 106 | 114 |
| 107 void CreateNewWebContents(const GURL& url) override { | 115 void CreateNewWebContents(const GURL& url) override { |
| 108 ASSERT_EQ(true, expect_new_web_contents_); | 116 ASSERT_EQ(true, expect_new_web_contents_); |
| 109 new_web_contents_created_ = true; | 117 new_web_contents_created_ = true; |
| 110 // DistillerPageWebContents::CreateNewWebContents resets the scoped_ptr to | 118 // DistillerPageWebContents::CreateNewWebContents resets the scoped_ptr to |
| 111 // the WebContents, so intentionally leak WebContents here, since it is | 119 // the WebContents, so intentionally leak WebContents here, since it is |
| 112 // owned by the shell. | 120 // owned by the shell. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 171 |
| 164 private: | 172 private: |
| 165 base::Closure callback_; | 173 base::Closure callback_; |
| 166 bool wait_for_document_loaded_; | 174 bool wait_for_document_loaded_; |
| 167 }; | 175 }; |
| 168 | 176 |
| 169 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { | 177 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { |
| 170 DistillerPageWebContents distiller_page( | 178 DistillerPageWebContents distiller_page( |
| 171 shell()->web_contents()->GetBrowserContext(), | 179 shell()->web_contents()->GetBrowserContext(), |
| 172 shell()->web_contents()->GetContainerBounds().size(), | 180 shell()->web_contents()->GetContainerBounds().size(), |
| 173 scoped_ptr<SourcePageHandleWebContents>()); | 181 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 174 distiller_page_ = &distiller_page; | 182 distiller_page_ = &distiller_page; |
| 175 | 183 |
| 176 base::RunLoop run_loop; | 184 base::RunLoop run_loop; |
| 177 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 185 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
| 178 run_loop.Run(); | 186 run_loop.Run(); |
| 179 | 187 |
| 180 EXPECT_EQ("Test Page Title", distiller_result_->title()); | 188 EXPECT_EQ("Test Page Title", distiller_result_->title()); |
| 181 EXPECT_THAT(distiller_result_->distilled_content().html(), | 189 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 182 HasSubstr("Lorem ipsum")); | 190 HasSubstr("Lorem ipsum")); |
| 183 EXPECT_THAT(distiller_result_->distilled_content().html(), | 191 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 184 Not(HasSubstr("questionable content"))); | 192 Not(HasSubstr("questionable content"))); |
| 185 EXPECT_EQ("", distiller_result_->pagination_info().next_page()); | 193 EXPECT_EQ("", distiller_result_->pagination_info().next_page()); |
| 186 EXPECT_EQ("", distiller_result_->pagination_info().prev_page()); | 194 EXPECT_EQ("", distiller_result_->pagination_info().prev_page()); |
| 187 } | 195 } |
| 188 | 196 |
| 189 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { | 197 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeLinks) { |
| 190 DistillerPageWebContents distiller_page( | 198 DistillerPageWebContents distiller_page( |
| 191 shell()->web_contents()->GetBrowserContext(), | 199 shell()->web_contents()->GetBrowserContext(), |
| 192 shell()->web_contents()->GetContainerBounds().size(), | 200 shell()->web_contents()->GetContainerBounds().size(), |
| 193 scoped_ptr<SourcePageHandleWebContents>()); | 201 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 194 distiller_page_ = &distiller_page; | 202 distiller_page_ = &distiller_page; |
| 195 | 203 |
| 196 base::RunLoop run_loop; | 204 base::RunLoop run_loop; |
| 197 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 205 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
| 198 run_loop.Run(); | 206 run_loop.Run(); |
| 199 | 207 |
| 200 // A relative link should've been updated. | 208 // A relative link should've been updated. |
| 201 EXPECT_THAT(distiller_result_->distilled_content().html(), | 209 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 202 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); | 210 ContainsRegex("href=\"http://127.0.0.1:.*/relativelink.html\"")); |
| 203 EXPECT_THAT(distiller_result_->distilled_content().html(), | 211 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 204 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); | 212 HasSubstr("href=\"http://www.google.com/absolutelink.html\"")); |
| 205 } | 213 } |
| 206 | 214 |
| 207 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { | 215 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeImages) { |
| 208 DistillerPageWebContents distiller_page( | 216 DistillerPageWebContents distiller_page( |
| 209 shell()->web_contents()->GetBrowserContext(), | 217 shell()->web_contents()->GetBrowserContext(), |
| 210 shell()->web_contents()->GetContainerBounds().size(), | 218 shell()->web_contents()->GetContainerBounds().size(), |
| 211 scoped_ptr<SourcePageHandleWebContents>()); | 219 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 212 distiller_page_ = &distiller_page; | 220 distiller_page_ = &distiller_page; |
| 213 | 221 |
| 214 base::RunLoop run_loop; | 222 base::RunLoop run_loop; |
| 215 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 223 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
| 216 run_loop.Run(); | 224 run_loop.Run(); |
| 217 | 225 |
| 218 // A relative link should've been updated. | 226 // A relative link should've been updated. |
| 219 EXPECT_THAT(distiller_result_->distilled_content().html(), | 227 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 220 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); | 228 ContainsRegex("src=\"http://127.0.0.1:.*/relativeimage.png\"")); |
| 221 EXPECT_THAT(distiller_result_->distilled_content().html(), | 229 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 222 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); | 230 HasSubstr("src=\"http://www.google.com/absoluteimage.png\"")); |
| 223 } | 231 } |
| 224 | 232 |
| 225 | 233 |
| 226 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeVideos) { | 234 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, HandlesRelativeVideos) { |
| 227 DistillerPageWebContents distiller_page( | 235 DistillerPageWebContents distiller_page( |
| 228 shell()->web_contents()->GetBrowserContext(), | 236 shell()->web_contents()->GetBrowserContext(), |
| 229 shell()->web_contents()->GetContainerBounds().size(), | 237 shell()->web_contents()->GetContainerBounds().size(), |
| 230 scoped_ptr<SourcePageHandleWebContents>()); | 238 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 231 distiller_page_ = &distiller_page; | 239 distiller_page_ = &distiller_page; |
| 232 | 240 |
| 233 base::RunLoop run_loop; | 241 base::RunLoop run_loop; |
| 234 DistillPage(run_loop.QuitClosure(), kVideoArticlePath); | 242 DistillPage(run_loop.QuitClosure(), kVideoArticlePath); |
| 235 run_loop.Run(); | 243 run_loop.Run(); |
| 236 | 244 |
| 237 // A relative source/track should've been updated. | 245 // A relative source/track should've been updated. |
| 238 EXPECT_THAT(distiller_result_->distilled_content().html(), | 246 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 239 ContainsRegex("src=\"http://127.0.0.1:.*/relative_video.mp4\"")); | 247 ContainsRegex("src=\"http://127.0.0.1:.*/relative_video.mp4\"")); |
| 240 EXPECT_THAT( | 248 EXPECT_THAT( |
| 241 distiller_result_->distilled_content().html(), | 249 distiller_result_->distilled_content().html(), |
| 242 ContainsRegex("src=\"http://127.0.0.1:.*/relative_track_en.vtt\"")); | 250 ContainsRegex("src=\"http://127.0.0.1:.*/relative_track_en.vtt\"")); |
| 243 EXPECT_THAT(distiller_result_->distilled_content().html(), | 251 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 244 HasSubstr("src=\"http://www.google.com/absolute_video.ogg\"")); | 252 HasSubstr("src=\"http://www.google.com/absolute_video.ogg\"")); |
| 245 EXPECT_THAT(distiller_result_->distilled_content().html(), | 253 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 246 HasSubstr("src=\"http://www.google.com/absolute_track_fr.vtt\"")); | 254 HasSubstr("src=\"http://www.google.com/absolute_track_fr.vtt\"")); |
| 247 } | 255 } |
| 248 | 256 |
| 249 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { | 257 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, VisibilityDetection) { |
| 250 DistillerPageWebContents distiller_page( | 258 DistillerPageWebContents distiller_page( |
| 251 shell()->web_contents()->GetBrowserContext(), | 259 shell()->web_contents()->GetBrowserContext(), |
| 252 shell()->web_contents()->GetContainerBounds().size(), | 260 shell()->web_contents()->GetContainerBounds().size(), |
| 253 scoped_ptr<SourcePageHandleWebContents>()); | 261 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 254 distiller_page_ = &distiller_page; | 262 distiller_page_ = &distiller_page; |
| 255 | 263 |
| 256 // visble_style.html and invisible_style.html only differ by the visibility | 264 // visble_style.html and invisible_style.html only differ by the visibility |
| 257 // internal stylesheet. | 265 // internal stylesheet. |
| 258 | 266 |
| 259 { | 267 { |
| 260 base::RunLoop run_loop; | 268 base::RunLoop run_loop; |
| 261 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); | 269 DistillPage(run_loop.QuitClosure(), "/visible_style.html"); |
| 262 run_loop.Run(); | 270 run_loop.Run(); |
| 263 EXPECT_THAT(distiller_result_->distilled_content().html(), | 271 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 std::string()); | 350 std::string()); |
| 343 url_loaded_runner.Run(); | 351 url_loaded_runner.Run(); |
| 344 | 352 |
| 345 scoped_ptr<content::WebContents> old_web_contents_sptr(current_web_contents); | 353 scoped_ptr<content::WebContents> old_web_contents_sptr(current_web_contents); |
| 346 scoped_ptr<SourcePageHandleWebContents> source_page_handle( | 354 scoped_ptr<SourcePageHandleWebContents> source_page_handle( |
| 347 new SourcePageHandleWebContents(old_web_contents_sptr.Pass())); | 355 new SourcePageHandleWebContents(old_web_contents_sptr.Pass())); |
| 348 | 356 |
| 349 TestDistillerPageWebContents distiller_page( | 357 TestDistillerPageWebContents distiller_page( |
| 350 shell()->web_contents()->GetBrowserContext(), | 358 shell()->web_contents()->GetBrowserContext(), |
| 351 shell()->web_contents()->GetContainerBounds().size(), | 359 shell()->web_contents()->GetContainerBounds().size(), |
| 352 source_page_handle.Pass(), | 360 distiller_js_script_, source_page_handle.Pass(), expect_new_web_contents); |
| 353 expect_new_web_contents); | |
| 354 distiller_page_ = &distiller_page; | 361 distiller_page_ = &distiller_page; |
| 355 | 362 |
| 356 base::RunLoop run_loop; | 363 base::RunLoop run_loop; |
| 357 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); | 364 DistillPage(run_loop.QuitClosure(), kSimpleArticlePath); |
| 358 run_loop.Run(); | 365 run_loop.Run(); |
| 359 | 366 |
| 360 // Sanity check of distillation process. | 367 // Sanity check of distillation process. |
| 361 EXPECT_EQ(expect_new_web_contents, distiller_page.new_web_contents_created()); | 368 EXPECT_EQ(expect_new_web_contents, distiller_page.new_web_contents_created()); |
| 362 EXPECT_EQ("Test Page Title", distiller_result_->title()); | 369 EXPECT_EQ("Test Page Title", distiller_result_->title()); |
| 363 } | 370 } |
| 364 | 371 |
| 365 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, MarkupInfo) { | 372 IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, MarkupInfo) { |
| 366 DistillerPageWebContents distiller_page( | 373 DistillerPageWebContents distiller_page( |
| 367 shell()->web_contents()->GetBrowserContext(), | 374 shell()->web_contents()->GetBrowserContext(), |
| 368 shell()->web_contents()->GetContainerBounds().size(), | 375 shell()->web_contents()->GetContainerBounds().size(), |
| 369 scoped_ptr<SourcePageHandleWebContents>()); | 376 distiller_js_script_, scoped_ptr<SourcePageHandleWebContents>()); |
| 370 distiller_page_ = &distiller_page; | 377 distiller_page_ = &distiller_page; |
| 371 | 378 |
| 372 base::RunLoop run_loop; | 379 base::RunLoop run_loop; |
| 373 DistillPage(run_loop.QuitClosure(), "/markup_article.html"); | 380 DistillPage(run_loop.QuitClosure(), "/markup_article.html"); |
| 374 run_loop.Run(); | 381 run_loop.Run(); |
| 375 | 382 |
| 376 EXPECT_THAT(distiller_result_->distilled_content().html(), | 383 EXPECT_THAT(distiller_result_->distilled_content().html(), |
| 377 HasSubstr("Lorem ipsum")); | 384 HasSubstr("Lorem ipsum")); |
| 378 EXPECT_EQ("Marked-up Markup Test Page Title", distiller_result_->title()); | 385 EXPECT_EQ("Marked-up Markup Test Page Title", distiller_result_->title()); |
| 379 | 386 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 std::string html = viewer::GetUnsafePartialArticleHtml(page_proto.get(), | 520 std::string html = viewer::GetUnsafePartialArticleHtml(page_proto.get(), |
| 514 DistilledPagePrefs::LIGHT, DistilledPagePrefs::SERIF); | 521 DistilledPagePrefs::LIGHT, DistilledPagePrefs::SERIF); |
| 515 EXPECT_THAT(html, HasSubstr(some_title)); | 522 EXPECT_THAT(html, HasSubstr(some_title)); |
| 516 EXPECT_THAT(html, HasSubstr(no_content)); | 523 EXPECT_THAT(html, HasSubstr(no_content)); |
| 517 EXPECT_THAT(html, Not(HasSubstr(no_title))); | 524 EXPECT_THAT(html, Not(HasSubstr(no_title))); |
| 518 EXPECT_THAT(html, Not(HasSubstr(some_content))); | 525 EXPECT_THAT(html, Not(HasSubstr(some_content))); |
| 519 } | 526 } |
| 520 } | 527 } |
| 521 | 528 |
| 522 } // namespace dom_distiller | 529 } // namespace dom_distiller |
| OLD | NEW |