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/memory/scoped_ptr.h"
6 #include "base/run_loop.h"
7 #include "chrome/browser/printing/print_preview_dialog_controller.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_commands.h"
10 #include "chrome/browser/ui/tabs/tab_strip_model.h"
11 #include "chrome/common/url_constants.h"
12 #include "chrome/test/base/in_process_browser_test.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "components/printing/common/print_messages.h"
15 #include "content/public/browser/web_contents_observer.h"
16 #include "content/public/test/browser_test_utils.h"
17 #include "ipc/ipc_message_macros.h"
20 using content::WebContents
;
21 using content::WebContentsObserver
;
23 class RequestPrintPreviewObserver
: public WebContentsObserver
{
25 explicit RequestPrintPreviewObserver(WebContents
* dialog
)
26 : WebContentsObserver(dialog
) {
28 ~RequestPrintPreviewObserver() override
{}
30 void set_quit_closure(const base::Closure
& quit_closure
) {
31 quit_closure_
= quit_closure
;
35 // content::WebContentsObserver implementation.
36 bool OnMessageReceived(const IPC::Message
& message
) override
{
37 IPC_BEGIN_MESSAGE_MAP(RequestPrintPreviewObserver
, message
)
38 IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview
,
39 OnRequestPrintPreview
)
40 IPC_MESSAGE_UNHANDLED(break;)
41 IPC_END_MESSAGE_MAP();
42 return false; // Report not handled so the real handler receives it.
45 void OnRequestPrintPreview(
46 const PrintHostMsg_RequestPrintPreview_Params
& /* params */) {
47 base::MessageLoop::current()->PostTask(FROM_HERE
, quit_closure_
);
50 base::Closure quit_closure_
;
52 DISALLOW_COPY_AND_ASSIGN(RequestPrintPreviewObserver
);
55 class PrintPreviewDialogClonedObserver
: public WebContentsObserver
{
57 explicit PrintPreviewDialogClonedObserver(WebContents
* dialog
)
58 : WebContentsObserver(dialog
) {
60 ~PrintPreviewDialogClonedObserver() override
{}
62 RequestPrintPreviewObserver
* request_preview_dialog_observer() {
63 return request_preview_dialog_observer_
.get();
67 // content::WebContentsObserver implementation.
68 void DidCloneToNewWebContents(WebContents
* old_web_contents
,
69 WebContents
* new_web_contents
) override
{
70 request_preview_dialog_observer_
.reset(
71 new RequestPrintPreviewObserver(new_web_contents
));
74 scoped_ptr
<RequestPrintPreviewObserver
> request_preview_dialog_observer_
;
76 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogClonedObserver
);
79 class PrintPreviewDialogDestroyedObserver
: public WebContentsObserver
{
81 explicit PrintPreviewDialogDestroyedObserver(WebContents
* dialog
)
82 : WebContentsObserver(dialog
),
83 dialog_destroyed_(false) {
85 ~PrintPreviewDialogDestroyedObserver() override
{}
87 bool dialog_destroyed() const { return dialog_destroyed_
; }
90 // content::WebContentsObserver implementation.
91 void WebContentsDestroyed() override
{ dialog_destroyed_
= true; }
93 bool dialog_destroyed_
;
95 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDestroyedObserver
);
98 class PrintPreviewDialogControllerBrowserTest
: public InProcessBrowserTest
{
100 PrintPreviewDialogControllerBrowserTest() : initiator_(NULL
) {}
101 ~PrintPreviewDialogControllerBrowserTest() override
{}
103 WebContents
* initiator() {
107 void PrintPreview() {
108 base::RunLoop run_loop
;
109 request_preview_dialog_observer()->set_quit_closure(run_loop
.QuitClosure());
110 chrome::Print(browser());
114 WebContents
* GetPrintPreviewDialog() {
115 printing::PrintPreviewDialogController
* dialog_controller
=
116 printing::PrintPreviewDialogController::GetInstance();
117 return dialog_controller
->GetPrintPreviewForContents(initiator_
);
121 void SetUpOnMainThread() override
{
122 WebContents
* first_tab
=
123 browser()->tab_strip_model()->GetActiveWebContents();
124 ASSERT_TRUE(first_tab
);
126 // Open a new tab so |cloned_tab_observer_| can see it first and attach a
127 // RequestPrintPreviewObserver to it before the real
128 // PrintPreviewMessageHandler gets created. Thus enabling
129 // RequestPrintPreviewObserver to get messages first for the purposes of
131 cloned_tab_observer_
.reset(new PrintPreviewDialogClonedObserver(first_tab
));
132 chrome::DuplicateTab(browser());
134 initiator_
= browser()->tab_strip_model()->GetActiveWebContents();
135 ASSERT_TRUE(initiator_
);
136 ASSERT_NE(first_tab
, initiator_
);
139 void TearDownOnMainThread() override
{
140 cloned_tab_observer_
.reset();
144 RequestPrintPreviewObserver
* request_preview_dialog_observer() {
145 return cloned_tab_observer_
->request_preview_dialog_observer();
148 scoped_ptr
<PrintPreviewDialogClonedObserver
> cloned_tab_observer_
;
149 WebContents
* initiator_
;
151 DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogControllerBrowserTest
);
154 // Test to verify that when a initiator navigates, we can create a new preview
155 // dialog for the new tab contents.
156 // http://crbug.com/377337
158 #define MAYBE_NavigateFromInitiatorTab DISABLED_NavigateFromInitiatorTab
160 #define MAYBE_NavigateFromInitiatorTab NavigateFromInitiatorTab
162 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest
,
163 MAYBE_NavigateFromInitiatorTab
) {
164 // print for the first time.
167 // Get the preview dialog for the initiator tab.
168 WebContents
* preview_dialog
= GetPrintPreviewDialog();
170 // Check a new print preview dialog got created.
171 ASSERT_TRUE(preview_dialog
);
172 ASSERT_NE(initiator(), preview_dialog
);
174 // Navigate in the initiator tab. Make sure navigating destroys the print
176 PrintPreviewDialogDestroyedObserver
dialog_destroyed_observer(preview_dialog
);
177 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL
));
178 ASSERT_TRUE(dialog_destroyed_observer
.dialog_destroyed());
180 // Try printing again.
183 // Get the print preview dialog for the initiator tab.
184 WebContents
* new_preview_dialog
= GetPrintPreviewDialog();
186 // Check a new preview dialog got created.
187 EXPECT_TRUE(new_preview_dialog
);
190 // Test to verify that after reloading the initiator, it creates a new print
192 // http://crbug.com/377337
194 #define MAYBE_ReloadInitiatorTab DISABLED_ReloadInitiatorTab
196 #define MAYBE_ReloadInitiatorTab ReloadInitiatorTab
198 IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest
,
199 MAYBE_ReloadInitiatorTab
) {
200 // print for the first time.
203 WebContents
* preview_dialog
= GetPrintPreviewDialog();
205 // Check a new print preview dialog got created.
206 ASSERT_TRUE(preview_dialog
);
207 ASSERT_NE(initiator(), preview_dialog
);
209 // Reload the initiator. Make sure reloading destroys the print preview
211 PrintPreviewDialogDestroyedObserver
dialog_destroyed_observer(preview_dialog
);
212 chrome::Reload(browser(), CURRENT_TAB
);
213 content::WaitForLoadStop(
214 browser()->tab_strip_model()->GetActiveWebContents());
215 ASSERT_TRUE(dialog_destroyed_observer
.dialog_destroyed());
217 // Try printing again.
220 // Create a preview dialog for the initiator tab.
221 WebContents
* new_preview_dialog
= GetPrintPreviewDialog();
222 EXPECT_TRUE(new_preview_dialog
);