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
3 // found in the LICENSE file.
5 #include "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/run_loop.h"
8 #include "chrome/browser/printing/print_preview_dialog_controller.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_commands.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/print_messages.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/test/browser_test_utils.h"
20 #include "ipc/ipc_message_macros.h"
22 using content::WebContents;
23 using content::WebContentsObserver;
25 class RequestPrintPreviewObserver : public WebContentsObserver {
27 explicit RequestPrintPreviewObserver(WebContents* dialog)
28 : WebContentsObserver(dialog) {
30 virtual ~RequestPrintPreviewObserver() {}
32 void set_quit_closure(const base::Closure& quit_closure) {
33 quit_closure_ = quit_closure;
37 // content::WebContentsObserver implementation.
38 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
39 IPC_BEGIN_MESSAGE_MAP(RequestPrintPreviewObserver, message)
40 IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
41 OnRequestPrintPreview)
42 IPC_MESSAGE_UNHANDLED(break;)
43 IPC_END_MESSAGE_MAP();
44 return false; // Report not handled so the real handler receives it.
47 void OnRequestPrintPreview(
48 const PrintHostMsg_RequestPrintPreview_Params& /* params */) {
49 base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
52 base::Closure quit_closure_;
54 DISALLOW_COPY_AND_ASSIGN(RequestPrintPreviewObserver);
57 class PrintPreviewDialogClonedObserver : public WebContentsObserver {
59 explicit PrintPreviewDialogClonedObserver(WebContents* dialog)
60 : WebContentsObserver(dialog) {
62 virtual ~PrintPreviewDialogClonedObserver() {}
64 RequestPrintPreviewObserver* request_preview_dialog_observer() {
65 return request_preview_dialog_observer_.get();
69 // content::WebContentsObserver implementation.
70 virtual void DidCloneToNewWebContents(
71 WebContents* old_web_contents,
72 WebContents* new_web_contents) OVERRIDE {
73 request_preview_dialog_observer_.reset(
74 new RequestPrintPreviewObserver(new_web_contents));
77 scoped_ptr<RequestPrintPreviewObserver> request_preview_dialog_observer_;
79 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogClonedObserver);
82 class PrintPreviewDialogDestroyedObserver : public WebContentsObserver {
84 explicit PrintPreviewDialogDestroyedObserver(WebContents* dialog)
85 : WebContentsObserver(dialog),
86 dialog_destroyed_(false) {
88 virtual ~PrintPreviewDialogDestroyedObserver() {}
90 bool dialog_destroyed() const { return dialog_destroyed_; }
93 // content::WebContentsObserver implementation.
94 virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
95 dialog_destroyed_ = true;
98 bool dialog_destroyed_;
100 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDestroyedObserver);
103 class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
105 PrintPreviewDialogControllerBrowserTest() : initiator_(NULL) {}
106 virtual ~PrintPreviewDialogControllerBrowserTest() {}
108 WebContents* initiator() {
112 void PrintPreview() {
113 base::RunLoop run_loop;
114 request_preview_dialog_observer()->set_quit_closure(run_loop.QuitClosure());
115 chrome::Print(browser());
119 WebContents* GetPrintPreviewDialog() {
120 printing::PrintPreviewDialogController* dialog_controller =
121 printing::PrintPreviewDialogController::GetInstance();
122 return dialog_controller->GetPrintPreviewForContents(initiator_);
126 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
127 #if !defined(GOOGLE_CHROME_BUILD)
128 command_line->AppendSwitch(switches::kEnablePrintPreview);
132 virtual void SetUpOnMainThread() OVERRIDE {
133 WebContents* first_tab =
134 browser()->tab_strip_model()->GetActiveWebContents();
135 ASSERT_TRUE(first_tab);
137 // Open a new tab so |cloned_tab_observer_| can see it first and attach a
138 // RequestPrintPreviewObserver to it before the real
139 // PrintPreviewMessageHandler gets created. Thus enabling
140 // RequestPrintPreviewObserver to get messages first for the purposes of
142 cloned_tab_observer_.reset(new PrintPreviewDialogClonedObserver(first_tab));
143 chrome::DuplicateTab(browser());
145 initiator_ = browser()->tab_strip_model()->GetActiveWebContents();
146 ASSERT_TRUE(initiator_);
147 ASSERT_NE(first_tab, initiator_);
150 virtual void CleanUpOnMainThread() OVERRIDE {
151 cloned_tab_observer_.reset();
155 RequestPrintPreviewObserver* request_preview_dialog_observer() {
156 return cloned_tab_observer_->request_preview_dialog_observer();
159 scoped_ptr<PrintPreviewDialogClonedObserver> cloned_tab_observer_;
160 WebContents* initiator_;
162 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogControllerBrowserTest);
165 // Test to verify that when a initiator navigates, we can create a new preview
166 // dialog for the new tab contents.
167 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
168 NavigateFromInitiatorTab) {
169 // print for the first time.
172 // Get the preview dialog for the initiator tab.
173 WebContents* preview_dialog = GetPrintPreviewDialog();
175 // Check a new print preview dialog got created.
176 ASSERT_TRUE(preview_dialog);
177 ASSERT_NE(initiator(), preview_dialog);
179 // Navigate in the initiator tab. Make sure navigating destroys the print
181 PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
182 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
183 ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
185 // Try printing again.
188 // Get the print preview dialog for the initiator tab.
189 WebContents* new_preview_dialog = GetPrintPreviewDialog();
191 // Check a new preview dialog got created.
192 EXPECT_TRUE(new_preview_dialog);
195 // Test to verify that after reloading the initiator, it creates a new print
197 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
198 ReloadInitiatorTab) {
199 // print for the first time.
202 WebContents* preview_dialog = GetPrintPreviewDialog();
204 // Check a new print preview dialog got created.
205 ASSERT_TRUE(preview_dialog);
206 ASSERT_NE(initiator(), preview_dialog);
208 // Reload the initiator. Make sure reloading destroys the print preview
210 PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
211 chrome::Reload(browser(), CURRENT_TAB);
212 content::WaitForLoadStop(
213 browser()->tab_strip_model()->GetActiveWebContents());
214 ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
216 // Try printing again.
219 // Create a preview dialog for the initiator tab.
220 WebContents* new_preview_dialog = GetPrintPreviewDialog();
221 EXPECT_TRUE(new_preview_dialog);