Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: chrome/browser/extensions/content_script_apitest.cc

Issue 2784533002: Turn on auto-dismissing dialogs for trunk builds. (Closed)
Patch Set: chromeos Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 5 #include <stddef.h>
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/run_loop.h"
11 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "build/build_config.h" 14 #include "build/build_config.h"
14 #include "chrome/browser/extensions/api/permissions/permissions_api.h" 15 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
15 #include "chrome/browser/extensions/extension_apitest.h" 16 #include "chrome/browser/extensions/extension_apitest.h"
16 #include "chrome/browser/extensions/extension_management_test_util.h" 17 #include "chrome/browser/extensions/extension_management_test_util.h"
17 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/extension_with_management_policy_apitest.h" 19 #include "chrome/browser/extensions/extension_with_management_policy_apitest.h"
19 #include "chrome/browser/extensions/test_extension_dir.h" 20 #include "chrome/browser/extensions/test_extension_dir.h"
20 #include "chrome/browser/ui/browser.h" 21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
23 #include "chrome/test/base/ui_test_utils.h" 25 #include "chrome/test/base/ui_test_utils.h"
24 #include "components/app_modal/javascript_dialog_extensions_client.h"
25 #include "components/app_modal/javascript_dialog_manager.h"
26 #include "content/public/browser/javascript_dialog_manager.h" 26 #include "content/public/browser/javascript_dialog_manager.h"
27 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
28 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_contents_delegate.h" 29 #include "content/public/browser/web_contents_delegate.h"
30 #include "content/public/test/browser_test_utils.h" 30 #include "content/public/test/browser_test_utils.h"
31 #include "extensions/browser/notification_types.h" 31 #include "extensions/browser/notification_types.h"
32 #include "extensions/common/extension.h" 32 #include "extensions/common/extension.h"
33 #include "extensions/common/switches.h" 33 #include "extensions/common/switches.h"
34 #include "extensions/test/extension_test_message_listener.h" 34 #include "extensions/test/extension_test_message_listener.h"
35 #include "extensions/test/result_catcher.h" 35 #include "extensions/test/result_catcher.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 << "Failed to execute script and extract bool for stylesheets length."; 82 << "Failed to execute script and extract bool for stylesheets length.";
83 } 83 }
84 if (!css_doesnt_add_to_list) { 84 if (!css_doesnt_add_to_list) {
85 return testing::AssertionFailure() 85 return testing::AssertionFailure()
86 << "CSS injection added to number of stylesheets."; 86 << "CSS injection added to number of stylesheets.";
87 } 87 }
88 88
89 return testing::AssertionSuccess(); 89 return testing::AssertionSuccess();
90 } 90 }
91 91
92 class DialogClient;
93
94 // A helper class to hijack the dialog manager's ExtensionsClient, so that we
95 // know when dialogs are being opened.
96 // NOTE: The default implementation of the JavaScriptDialogExtensionsClient
97 // doesn't do anything, so it's safe to override it. If, at some stage, this
98 // has behavior (like if we move this into app shell), we'll need to update
99 // this (by, e.g., making DialogClient a wrapper around the implementation).
100 class DialogHelper {
101 public:
102 explicit DialogHelper(content::WebContents* web_contents);
103 ~DialogHelper();
104
105 // Notifies the DialogHelper that a dialog was opened. Runs |quit_closure_|,
106 // if it is non-null.
107 void DialogOpened();
108
109 // Closes any active dialogs.
110 void CloseDialogs();
111
112 void set_quit_closure(const base::Closure& quit_closure) {
113 quit_closure_ = quit_closure;
114 }
115 size_t dialog_count() const { return dialog_count_; }
116
117 private:
118 // The number of dialogs to appear.
119 size_t dialog_count_;
120
121 // The WebContents this helper is associated with.
122 content::WebContents* web_contents_;
123
124 // The dialog manager for |web_contents_|.
125 content::JavaScriptDialogManager* dialog_manager_;
126
127 // The dialog client override.
128 DialogClient* client_;
129
130 // The quit closure to run when a dialog appears.
131 base::Closure quit_closure_;
132
133 DISALLOW_COPY_AND_ASSIGN(DialogHelper);
134 };
135
136 // The client override for the DialogHelper.
137 class DialogClient : public app_modal::JavaScriptDialogExtensionsClient {
138 public:
139 explicit DialogClient(DialogHelper* helper) : helper_(helper) {}
140 ~DialogClient() override {}
141
142 void set_helper(DialogHelper* helper) { helper_ = helper; }
143
144 private:
145 // app_modal::JavaScriptDialogExtensionsClient:
146 void OnDialogOpened(content::WebContents* web_contents) override {
147 if (helper_)
148 helper_->DialogOpened();
149 }
150 void OnDialogClosed(content::WebContents* web_contents) override {}
151 bool GetExtensionName(content::WebContents* web_contents,
152 const GURL& origin_url,
153 std::string* name_out) override {
154 return false;
155 }
156
157 // The dialog helper to notify of any open dialogs.
158 DialogHelper* helper_;
159
160 DISALLOW_COPY_AND_ASSIGN(DialogClient);
161 };
162
163 DialogHelper::DialogHelper(content::WebContents* web_contents)
164 : dialog_count_(0),
165 web_contents_(web_contents),
166 dialog_manager_(nullptr),
167 client_(nullptr) {
168 app_modal::JavaScriptDialogManager* dialog_manager_impl =
169 app_modal::JavaScriptDialogManager::GetInstance();
170 client_ = new DialogClient(this);
171 dialog_manager_impl->SetExtensionsClient(base::WrapUnique(client_));
172
173 dialog_manager_ =
174 web_contents_->GetDelegate()->GetJavaScriptDialogManager(web_contents_);
175 }
176
177 DialogHelper::~DialogHelper() {
178 client_->set_helper(nullptr);
179 }
180
181 void DialogHelper::CloseDialogs() {
182 dialog_manager_->CancelDialogs(web_contents_, false);
183 }
184
185 void DialogHelper::DialogOpened() {
186 ++dialog_count_;
187 if (!quit_closure_.is_null()) {
188 quit_closure_.Run();
189 quit_closure_ = base::Closure();
190 }
191 }
192
193 // Runs all pending tasks in the renderer associated with |web_contents|, and 92 // Runs all pending tasks in the renderer associated with |web_contents|, and
194 // then all pending tasks in the browser process. 93 // then all pending tasks in the browser process.
195 // Returns true on success. 94 // Returns true on success.
196 bool RunAllPending(content::WebContents* web_contents) { 95 bool RunAllPending(content::WebContents* web_contents) {
197 // This is slight hack to achieve a RunPendingInRenderer() method. Since IPCs 96 // This is slight hack to achieve a RunPendingInRenderer() method. Since IPCs
198 // are sent synchronously, anything started prior to this method will finish 97 // are sent synchronously, anything started prior to this method will finish
199 // before this method returns (as content::ExecuteScript() is synchronous). 98 // before this method returns (as content::ExecuteScript() is synchronous).
200 if (!content::ExecuteScript(web_contents, "1 == 1;")) 99 if (!content::ExecuteScript(web_contents, "1 == 1;"))
201 return false; 100 return false;
202 base::RunLoop().RunUntilIdle(); 101 base::RunLoop().RunUntilIdle();
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 ASSERT_TRUE(ext1); 435 ASSERT_TRUE(ext1);
537 436
538 TestExtensionDir ext_dir2; 437 TestExtensionDir ext_dir2;
539 ext_dir2.WriteManifest(base::StringPrintf(kManifest, "ext2", "document_end")); 438 ext_dir2.WriteManifest(base::StringPrintf(kManifest, "ext2", "document_end"));
540 ext_dir2.WriteFile(FILE_PATH_LITERAL("script.js"), kNonBlockingScript); 439 ext_dir2.WriteFile(FILE_PATH_LITERAL("script.js"), kNonBlockingScript);
541 const Extension* ext2 = LoadExtension(ext_dir2.UnpackedPath()); 440 const Extension* ext2 = LoadExtension(ext_dir2.UnpackedPath());
542 ASSERT_TRUE(ext2); 441 ASSERT_TRUE(ext2);
543 442
544 content::WebContents* web_contents = 443 content::WebContents* web_contents =
545 browser()->tab_strip_model()->GetActiveWebContents(); 444 browser()->tab_strip_model()->GetActiveWebContents();
546 DialogHelper dialog_helper(web_contents); 445 JavaScriptDialogTabHelper* js_helper =
547 base::RunLoop run_loop; 446 JavaScriptDialogTabHelper::FromWebContents(web_contents);
548 dialog_helper.set_quit_closure(run_loop.QuitClosure()); 447 base::RunLoop dialog_wait;
448 js_helper->SetDialogShownCallbackForTesting(dialog_wait.QuitClosure());
549 449
550 ExtensionTestMessageListener listener("done", false); 450 ExtensionTestMessageListener listener("done", false);
551 listener.set_extension_id(ext2->id()); 451 listener.set_extension_id(ext2->id());
552 452
553 // Navigate! Both extensions will try to inject. 453 // Navigate! Both extensions will try to inject.
554 ui_test_utils::NavigateToURLWithDisposition( 454 ui_test_utils::NavigateToURLWithDisposition(
555 browser(), embedded_test_server()->GetURL("/empty.html"), 455 browser(), embedded_test_server()->GetURL("/empty.html"),
556 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); 456 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
557 457
558 run_loop.Run(); 458 dialog_wait.Run();
559 // Right now, the alert dialog is showing and blocking injection of anything 459 // Right now, the alert dialog is showing and blocking injection of anything
560 // after it, so the listener shouldn't be satisfied. 460 // after it, so the listener shouldn't be satisfied.
561 EXPECT_FALSE(listener.was_satisfied()); 461 EXPECT_FALSE(listener.was_satisfied());
562 EXPECT_EQ(1u, dialog_helper.dialog_count()); 462 js_helper->HandleJavaScriptDialog(web_contents, true, nullptr);
563 dialog_helper.CloseDialogs();
564 463
565 // After closing the dialog, the rest of the scripts should be able to 464 // After closing the dialog, the rest of the scripts should be able to
566 // inject. 465 // inject.
567 EXPECT_TRUE(listener.WaitUntilSatisfied()); 466 EXPECT_TRUE(listener.WaitUntilSatisfied());
568 } 467 }
569 468
570 // Test that closing a tab with a blocking script results in no further scripts 469 // Test that closing a tab with a blocking script results in no further scripts
571 // running (and we don't crash). 470 // running (and we don't crash).
572 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, 471 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
573 ContentScriptBlockingScriptTabClosed) { 472 ContentScriptBlockingScriptTabClosed) {
(...skipping 15 matching lines...) Expand all
589 ASSERT_TRUE(ext1); 488 ASSERT_TRUE(ext1);
590 489
591 TestExtensionDir ext_dir2; 490 TestExtensionDir ext_dir2;
592 ext_dir2.WriteManifest(base::StringPrintf(kManifest, "ext2", "document_end")); 491 ext_dir2.WriteManifest(base::StringPrintf(kManifest, "ext2", "document_end"));
593 ext_dir2.WriteFile(FILE_PATH_LITERAL("script.js"), kNonBlockingScript); 492 ext_dir2.WriteFile(FILE_PATH_LITERAL("script.js"), kNonBlockingScript);
594 const Extension* ext2 = LoadExtension(ext_dir2.UnpackedPath()); 493 const Extension* ext2 = LoadExtension(ext_dir2.UnpackedPath());
595 ASSERT_TRUE(ext2); 494 ASSERT_TRUE(ext2);
596 495
597 content::WebContents* web_contents = 496 content::WebContents* web_contents =
598 browser()->tab_strip_model()->GetActiveWebContents(); 497 browser()->tab_strip_model()->GetActiveWebContents();
599 DialogHelper dialog_helper(web_contents); 498 JavaScriptDialogTabHelper* js_helper =
600 base::RunLoop run_loop; 499 JavaScriptDialogTabHelper::FromWebContents(web_contents);
601 dialog_helper.set_quit_closure(run_loop.QuitClosure()); 500 base::RunLoop dialog_wait;
501 js_helper->SetDialogShownCallbackForTesting(dialog_wait.QuitClosure());
602 502
603 ExtensionTestMessageListener listener("done", false); 503 ExtensionTestMessageListener listener("done", false);
604 listener.set_extension_id(ext2->id()); 504 listener.set_extension_id(ext2->id());
605 505
606 // Navitate! 506 // Navigate!
607 ui_test_utils::NavigateToURLWithDisposition( 507 ui_test_utils::NavigateToURLWithDisposition(
608 browser(), embedded_test_server()->GetURL("/empty.html"), 508 browser(), embedded_test_server()->GetURL("/empty.html"),
609 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); 509 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
610 510
611 // Now, instead of closing the dialog, just close the tab. Later scripts 511 // Now, instead of closing the dialog, just close the tab. Later scripts
612 // should never get a chance to run (and we shouldn't crash). 512 // should never get a chance to run (and we shouldn't crash).
613 run_loop.Run(); 513 dialog_wait.Run();
614 EXPECT_FALSE(listener.was_satisfied()); 514 EXPECT_FALSE(listener.was_satisfied());
615 EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt( 515 EXPECT_TRUE(browser()->tab_strip_model()->CloseWebContentsAt(
616 browser()->tab_strip_model()->active_index(), 0)); 516 browser()->tab_strip_model()->active_index(), 0));
617 EXPECT_FALSE(listener.was_satisfied()); 517 EXPECT_FALSE(listener.was_satisfied());
618 } 518 }
619 519
620 // There was a bug by which content scripts that blocked and ran on 520 // There was a bug by which content scripts that blocked and ran on
621 // document_idle could be injected twice (crbug.com/431263). Test for 521 // document_idle could be injected twice (crbug.com/431263). Test for
622 // regression. 522 // regression.
623 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, 523 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
624 ContentScriptBlockingScriptsDontRunTwice) { 524 ContentScriptBlockingScriptsDontRunTwice) {
625 ASSERT_TRUE(StartEmbeddedTestServer()); 525 ASSERT_TRUE(StartEmbeddedTestServer());
626 526
627 // Load up an extension. 527 // Load up an extension.
628 TestExtensionDir ext_dir1; 528 TestExtensionDir ext_dir1;
629 ext_dir1.WriteManifest( 529 ext_dir1.WriteManifest(
630 base::StringPrintf(kManifest, "ext1", "document_idle")); 530 base::StringPrintf(kManifest, "ext1", "document_idle"));
631 ext_dir1.WriteFile(FILE_PATH_LITERAL("script.js"), kBlockingScript); 531 ext_dir1.WriteFile(FILE_PATH_LITERAL("script.js"), kBlockingScript);
632 const Extension* ext1 = LoadExtension(ext_dir1.UnpackedPath()); 532 const Extension* ext1 = LoadExtension(ext_dir1.UnpackedPath());
633 ASSERT_TRUE(ext1); 533 ASSERT_TRUE(ext1);
634 534
635 content::WebContents* web_contents = 535 content::WebContents* web_contents =
636 browser()->tab_strip_model()->GetActiveWebContents(); 536 browser()->tab_strip_model()->GetActiveWebContents();
637 DialogHelper dialog_helper(web_contents); 537 JavaScriptDialogTabHelper* js_helper =
638 base::RunLoop run_loop; 538 JavaScriptDialogTabHelper::FromWebContents(web_contents);
639 dialog_helper.set_quit_closure(run_loop.QuitClosure()); 539 base::RunLoop dialog_wait;
540 js_helper->SetDialogShownCallbackForTesting(dialog_wait.QuitClosure());
640 541
641 // Navigate! 542 // Navigate!
642 ui_test_utils::NavigateToURLWithDisposition( 543 ui_test_utils::NavigateToURLWithDisposition(
643 browser(), embedded_test_server()->GetURL("/empty.html"), 544 browser(), embedded_test_server()->GetURL("/empty.html"),
644 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); 545 WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
645 546
646 run_loop.Run(); 547 dialog_wait.Run();
647 548
648 // The extension will have injected at idle, but it should only inject once. 549 // The extension will have injected at idle, but it should only inject once.
649 EXPECT_EQ(1u, dialog_helper.dialog_count()); 550 js_helper->HandleJavaScriptDialog(web_contents, true, nullptr);
650 dialog_helper.CloseDialogs();
651 EXPECT_TRUE(RunAllPending(web_contents)); 551 EXPECT_TRUE(RunAllPending(web_contents));
652 EXPECT_EQ(1u, dialog_helper.dialog_count()); 552 EXPECT_FALSE(js_helper->IsShowingDialogForTesting());
653 } 553 }
654 554
655 // Bug fix for crbug.com/507461. 555 // Bug fix for crbug.com/507461.
656 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest, 556 IN_PROC_BROWSER_TEST_P(ContentScriptApiTest,
657 DocumentStartInjectionFromExtensionTabNavigation) { 557 DocumentStartInjectionFromExtensionTabNavigation) {
658 ASSERT_TRUE(StartEmbeddedTestServer()); 558 ASSERT_TRUE(StartEmbeddedTestServer());
659 559
660 TestExtensionDir new_tab_override_dir; 560 TestExtensionDir new_tab_override_dir;
661 new_tab_override_dir.WriteManifest(kNewTabOverrideManifest); 561 new_tab_override_dir.WriteManifest(kNewTabOverrideManifest);
662 new_tab_override_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"), kNewTabHtml); 562 new_tab_override_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"), kNewTabHtml);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 EXPECT_FALSE(content_script_listener.was_satisfied()); 608 EXPECT_FALSE(content_script_listener.was_satisfied());
709 } 609 }
710 610
711 INSTANTIATE_TEST_CASE_P( 611 INSTANTIATE_TEST_CASE_P(
712 ContentScriptApiTests, 612 ContentScriptApiTests,
713 ContentScriptApiTest, 613 ContentScriptApiTest,
714 testing::Values(TestConfig::kDefault, 614 testing::Values(TestConfig::kDefault,
715 TestConfig::kYieldBetweenContentScriptRunsEnabled)); 615 TestConfig::kYieldBetweenContentScriptRunsEnabled));
716 616
717 } // namespace extensions 617 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/signin/oauth2_browsertest.cc ('k') | chrome/browser/mouseleave_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698