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

Side by Side Diff: chrome/browser/printing/print_preview_pdf_generated_browsertest.cc

Issue 335583004: Added a test that currently is able to print to pdf. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unnecessary variables in browsertest. Fixed some style issues. Created 6 years, 5 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
(Empty)
1 // Copyright 2014 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.
4
5 #include <cstdio>
6 #include <iostream>
7 #include <limits>
8 #include <string>
9 #include <vector>
10 #include <unistd.h>
11
12 #include "base/files/file_path.h"
13 #include "base/files/file.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/path_service.h"
17 #include "base/run_loop.h"
18 #include "base/strings/string_util.h"
19 #include "chrome/app/chrome_command_ids.h"
20 #include "chrome/browser/net/referrer.h"
21 #include "chrome/browser/printing/print_preview_dialog_controller.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_commands.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
27 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
28 #include "chrome/browser/ui/webui/print_preview/sticky_settings.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/print_messages.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_ui_message_handler.h"
36 #include "content/public/common/page_transition_types.h"
37 #include "content/public/test/browser_test_utils.h"
38 #include "content/public/test/test_navigation_observer.h"
39 #include "content/public/test/test_utils.h"
40 #include "printing/print_job_constants.h"
41 #include "ui/events/keycodes/keyboard_codes.h"
42 #include "url/gurl.h"
43 #include "ipc/ipc_message_macros.h"
44
45 using content::WebContents;
46 using content::WebContentsObserver;
47
48 class PrintPreviewObserver;
49 class UIDoneLoadingMessageHandler;
50
51 // Message refers to the 'UILoaded' message from print_preview.js.
52 // It gets sent either from onPreviewGenerationDone or from
53 // onManipulateSettings_() in print_preview.js
54 enum State {
55 // Waiting for the first message so the program can select Save as PDF
56 kWaitingToSendSaveAsPdf = 0,
57 // Waiting for the second message so the test can set the layout
58 kWaitingToSendLayoutSettings = 1,
59 // Waiting for the third message so the test can set the page numbers
60 kWaitingToSendPageNumbers = 2,
61 // Waiting for the forth message so the test can set the headers checkbox
62 kWaitingToSendHeadersAndFooters = 3,
63 // Waiting for the fifth message so the test can set the background checkbox
64 kWaitingToSendBackgroundColorsAndImages = 4,
65 // Waiting for the sixth message so the test can set the margins combobox
66 kWaitingToSendMargins = 5,
67 // Waiting for the final message so the program can save to PDF.
68 kWaitingForFinalMessage = 6,
69 };
70
71 class PrintPreviewObserver : public WebContentsObserver {
72 public:
73 PrintPreviewObserver(WebContents* dialog, Browser* browser)
74 : WebContentsObserver(dialog),
75 browser_(browser),
76 is_portrait_(true),
77 headers_and_footers_(true),
78 background_colors_and_images_(false),
79 margins_(printing::DEFAULT_MARGINS) {}
80
81 virtual ~PrintPreviewObserver() {}
82
83 // Sets closure for the observer so that it can end the loop.
84 void set_quit_closure(const base::Closure &closure) {
85 closure_ = closure;
86 }
87
88 // Actually stops the message_loop so that the test can proceed.
89 void EndLoop() {
90 base::MessageLoop::current()->PostTask(FROM_HERE, closure_);
91 }
92
93 bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
94 IPC_BEGIN_MESSAGE_MAP(PrintPreviewObserver, message)
95 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
96 OnDidGetPreviewPageCount)
97 IPC_MESSAGE_UNHANDLED(break;)
98 IPC_END_MESSAGE_MAP();
99 return false;
100 }
101
102 // Gets the web contents for the print preview dialog so that
103 // the UI and other elements can be accessed.
104 WebContents* GetDialog() {
105 WebContents* tab = browser_->tab_strip_model()->GetActiveWebContents();
106 printing::PrintPreviewDialogController* dialog_controller =
107 printing::PrintPreviewDialogController::GetInstance();
108 WebContents* web_contents =
109 dialog_controller->GetPrintPreviewForContents(tab);
110 return web_contents;
111 }
112
113 // Gets the PrintPreviewUI so that certain elements can be accessed.
114 PrintPreviewUI* GetUI() {
115 return static_cast<PrintPreviewUI*>(
116 GetDialog()->GetWebUI()->GetController());
117 }
118
119 // Calls a javascript function that will change the print preview settings,
120 // such as the layout, the margins, page numbers, etc.
121 void ManipulatePreviewSettings(State state) {
122 std::vector<const base::Value*> args;
123 script_argument_.reset(new base::DictionaryValue());
124 if (state == kWaitingToSendSaveAsPdf) {
125 script_argument_->SetBoolean("selectSaveAsPdfDestination", true);
126 } else if (state == kWaitingToSendLayoutSettings) {
127 script_argument_->SetBoolean("layoutSettings.portrait", is_portrait_);
128 } else if (state == kWaitingToSendPageNumbers) {
129 script_argument_->SetString("pageRange", page_numbers_);
130 } else if (state == kWaitingToSendHeadersAndFooters) {
131 script_argument_->SetBoolean("headersAndFooters", headers_and_footers_);
132 } else if (state == kWaitingToSendBackgroundColorsAndImages) {
133 script_argument_->SetBoolean("backgroundColorsAndImages",
134 background_colors_and_images_);
135 } else if (state == kWaitingToSendMargins) {
136 script_argument_->SetInteger("margins", margins_);
137 }
138
139 args.push_back(script_argument_.get());
140 DCHECK(!script_argument_->empty());
141 DCHECK(!args.empty());
142 GetUI()->web_ui()->CallJavascriptFunction(
143 "onManipulateSettingsForTest", args);
144 }
145
146 // Function to set the print preview settings and save them so they
147 // can be sent later. Currently only used in the constructor. Will be
148 // used when creating a test and take command line arguments.
149 // |page_numbers| is a comma separated page range.
150 // Example: "1-5,9" will print pages 1 through 5 and page 9.
151 // The pages specified must be less than or equal to the maximum
152 // page number. An empty string seems to be valid input, however
153 // further testing will be required to see if that is actually
154 // true.
155 void SetPrintPreviewSettings(bool is_portrait,
156 const std::string& page_numbers,
157 bool headers_and_footers,
158 bool background_colors_and_images,
159 printing::MarginType margins) {
160 is_portrait_ = is_portrait;
161 page_numbers_ = page_numbers;
162 headers_and_footers_ = headers_and_footers;
163 background_colors_and_images_ = background_colors_and_images;
164 margins_ = margins;
165 }
166
167 private:
168 // Called when the observer gets the IPC message stating that the
169 // page count is ready.
170 void OnDidGetPreviewPageCount(
171 const PrintHostMsg_DidGetPreviewPageCount_Params &params);
172
173 void DidCloneToNewWebContents(WebContents* old_web_contents,
174 WebContents* new_web_contents)
175 OVERRIDE {
176 Observe(new_web_contents);
177 }
178
179 void WebContentsDestroyed() OVERRIDE {
180 EndLoop();
181 }
182
183 Browser* browser_;
184 base::Closure closure_;
185
186 scoped_ptr<base::DictionaryValue> script_argument_;
187 bool is_portrait_;
188 std::string page_numbers_;
189 bool headers_and_footers_;
190 bool background_colors_and_images_;
191 printing::MarginType margins_;
192
193 DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver);
194 };
195
196 class UIDoneLoadingMessageHandler : public content::WebUIMessageHandler {
197 public:
198 explicit UIDoneLoadingMessageHandler(PrintPreviewObserver* observer) :
199 observer_(observer), state_(kWaitingToSendSaveAsPdf) {}
200
201 virtual ~UIDoneLoadingMessageHandler() {
202 observer_ = NULL;
203 }
204
205 void HandleDone(const base::ListValue* /* args */) {
206 if (state_ == kWaitingForFinalMessage) {
207 observer_->EndLoop();
208 } else {
209 observer_->ManipulatePreviewSettings(state_);
210 state_ = static_cast<State>(static_cast<int>(state_) + 1);
211 }
212 }
213
214 void HandleFailure(const base::ListValue* /* args */) {
215 FAIL();
216 }
217
218 void RegisterMessages() OVERRIDE {
219 web_ui()->RegisterMessageCallback(
220 "UILoadedForTest",
221 base::Bind(&UIDoneLoadingMessageHandler::HandleDone,
222 base::Unretained(this)));
223
224 web_ui()->RegisterMessageCallback(
225 "UIFailedLoadingForTest",
226 base::Bind(&UIDoneLoadingMessageHandler::HandleFailure,
227 base::Unretained(this)));
228 }
229
230 private:
231 PrintPreviewObserver* observer_;
232 State state_;
233
234 DISALLOW_COPY_AND_ASSIGN(UIDoneLoadingMessageHandler);
235 };
236
237 void PrintPreviewObserver::OnDidGetPreviewPageCount(
238 const PrintHostMsg_DidGetPreviewPageCount_Params &params) {
239 WebContents* web_contents = GetDialog();
240 PrintPreviewUI* ui = GetUI();
241 ASSERT_TRUE(ui);
242 ASSERT_TRUE(ui->web_ui());
243 ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest");
244 Observe(web_contents);
245 ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this));
246 }
247
248 class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest {
249 public:
250 PrintPreviewPdfGeneratedBrowserTest() {}
251 virtual ~PrintPreviewPdfGeneratedBrowserTest() {}
252
253 // TODO (ivandavid): Provide arguments for SetPrintPreviewSettings here.
254 void NavigateAndPreview(const base::FilePath::StringType& file_name) {
255 print_preview_observer_->SetPrintPreviewSettings(false,
256 "",
257 false,
258 false,
259 printing::DEFAULT_MARGINS);
260 base::FilePath directory(FILE_PATH_LITERAL("printing"));
261 base::FilePath file(file_name);
262 ui_test_utils::NavigateToURL(browser(),
263 ui_test_utils::GetTestUrl(directory, file));
264
265 base::RunLoop loop;
266 print_preview_observer_->set_quit_closure(loop.QuitClosure());
267 chrome::Print(browser());
268 loop.Run();
269 }
270
271 void Print() {
272 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &pdf_file_save_path_));
273 pdf_file_save_path_ = pdf_file_save_path_.AppendASCII("printing");
274 pdf_file_save_path_ = pdf_file_save_path_.AppendASCII("dummy.pdf");
275
276 base::RunLoop loop;
277 print_preview_observer_->set_quit_closure(loop.QuitClosure());
278 print_preview_observer_->GetUI()->handler_->FileSelected(
279 pdf_file_save_path_, 0, NULL);
280 loop.Run();
281 }
282
283 private:
284 virtual void SetUpOnMainThread() OVERRIDE {
285 WebContents* tab =
286 browser()->tab_strip_model()->GetActiveWebContents();
287 ASSERT_TRUE(tab);
288
289 print_preview_observer_.reset(new PrintPreviewObserver(tab, browser()));
290 chrome::DuplicateTab(browser());
291
292 WebContents* initiator =
293 browser()->tab_strip_model()->GetActiveWebContents();
294 ASSERT_TRUE(initiator);
295 ASSERT_NE(tab, initiator);
296 }
297
298 virtual void CleanUpOnMainThread() OVERRIDE {
299 print_preview_observer_.reset();
300 }
301
302 scoped_ptr<PrintPreviewObserver> print_preview_observer_;
303 base::FilePath pdf_file_save_path_;
304
305 DISALLOW_COPY_AND_ASSIGN(PrintPreviewPdfGeneratedBrowserTest);
306 };
307
308 IN_PROC_BROWSER_TEST_F(PrintPreviewPdfGeneratedBrowserTest,
309 DISABLED_DummyTest) {
310 // TODO(ivandavid): Make this work on Windows also. Windows doesn't have
311 // the same directory structure.
312
313 // TODO(ivandavid): Generate the file here, not in the layout test, then
314 // communicate this information to the layout test framework. It has to
315 // be this way, because there doesn't seem to be a way to communicate the
316 // file name from the layout test framework to the browsertest. Do
317 // the cleanup here also. Use mkstemp() for this (maybe chrome has some
318 // way to do this?).
319 ASSERT_TRUE(freopen("/tmp/pdf_generated_browsertest/stdin.txt", "r", stdin));
320 std::string cmd;
321
322 // The printf and fflush is necessary because
323 // otherwise, the layout tests don't seem to get it if I just use logs or
324 // if I just do printf and no fflush().
325 printf("#READY\n");
326 fflush(stdout);
327
328 // Might have to rewrite this one. It might not work in every case.
329 // Works for now though.
330 std::getline(std::cin, cmd);
331 if (cmd.size() == 0) {
332 while (std::cin.eof()) {
333 std::cin.clear();
334 std::getline(std::cin, cmd);
335 if (!cmd.empty()) {
336 break;
337 }
338 }
339 }
340
341 // TODO(ivandavid): Read from cmd the name of the test html file.
342 base::FilePath::StringType test_name("test2.html");
343 NavigateAndPreview(test_name);
344 Print();
345
346 // Tells the layout tests that everything is done.
347 // In the future, before this part, PNG data will be sent from this program
348 // to the layout tests through stdout.
349 printf("#EOF\n");
350 fflush(stdout);
351
352 // Send image data before this EOF.
353 printf("#EOF\n");
354 fflush(stdout);
355 fprintf(stderr, "#EOF\n");
356 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698