| Index: chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
|
| diff --git a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fdab41f331686635f2ff2790d91f51f9f72bc788
|
| --- /dev/null
|
| +++ b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
|
| @@ -0,0 +1,356 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <cstdio>
|
| +#include <iostream>
|
| +#include <limits>
|
| +#include <string>
|
| +#include <vector>
|
| +#include <unistd.h>
|
| +
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/path_service.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "chrome/app/chrome_command_ids.h"
|
| +#include "chrome/browser/net/referrer.h"
|
| +#include "chrome/browser/printing/print_preview_dialog_controller.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/browser_commands.h"
|
| +#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/browser/ui/webui/print_preview/print_preview_handler.h"
|
| +#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
|
| +#include "chrome/browser/ui/webui/print_preview/sticky_settings.h"
|
| +#include "chrome/common/chrome_paths.h"
|
| +#include "chrome/common/print_messages.h"
|
| +#include "chrome/common/url_constants.h"
|
| +#include "chrome/test/base/in_process_browser_test.h"
|
| +#include "chrome/test/base/ui_test_utils.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/browser/web_ui_message_handler.h"
|
| +#include "content/public/common/page_transition_types.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| +#include "content/public/test/test_navigation_observer.h"
|
| +#include "content/public/test/test_utils.h"
|
| +#include "printing/print_job_constants.h"
|
| +#include "ui/events/keycodes/keyboard_codes.h"
|
| +#include "url/gurl.h"
|
| +#include "ipc/ipc_message_macros.h"
|
| +
|
| +using content::WebContents;
|
| +using content::WebContentsObserver;
|
| +
|
| +class PrintPreviewObserver;
|
| +class UIDoneLoadingMessageHandler;
|
| +
|
| +// Message refers to the 'UILoaded' message from print_preview.js.
|
| +// It gets sent either from onPreviewGenerationDone or from
|
| +// onManipulateSettings_() in print_preview.js
|
| +enum State {
|
| + // Waiting for the first message so the program can select Save as PDF
|
| + kWaitingToSendSaveAsPdf = 0,
|
| + // Waiting for the second message so the test can set the layout
|
| + kWaitingToSendLayoutSettings = 1,
|
| + // Waiting for the third message so the test can set the page numbers
|
| + kWaitingToSendPageNumbers = 2,
|
| + // Waiting for the forth message so the test can set the headers checkbox
|
| + kWaitingToSendHeadersAndFooters = 3,
|
| + // Waiting for the fifth message so the test can set the background checkbox
|
| + kWaitingToSendBackgroundColorsAndImages = 4,
|
| + // Waiting for the sixth message so the test can set the margins combobox
|
| + kWaitingToSendMargins = 5,
|
| + // Waiting for the final message so the program can save to PDF.
|
| + kWaitingForFinalMessage = 6,
|
| +};
|
| +
|
| +class PrintPreviewObserver : public WebContentsObserver {
|
| + public:
|
| + PrintPreviewObserver(WebContents* dialog, Browser* browser)
|
| + : WebContentsObserver(dialog),
|
| + browser_(browser),
|
| + is_portrait_(true),
|
| + headers_and_footers_(true),
|
| + background_colors_and_images_(false),
|
| + margins_(printing::DEFAULT_MARGINS) {}
|
| +
|
| + virtual ~PrintPreviewObserver() {}
|
| +
|
| + // Sets closure for the observer so that it can end the loop.
|
| + void set_quit_closure(const base::Closure &closure) {
|
| + closure_ = closure;
|
| + }
|
| +
|
| + // Actually stops the message_loop so that the test can proceed.
|
| + void EndLoop() {
|
| + base::MessageLoop::current()->PostTask(FROM_HERE, closure_);
|
| + }
|
| +
|
| + bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
|
| + IPC_BEGIN_MESSAGE_MAP(PrintPreviewObserver, message)
|
| + IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
|
| + OnDidGetPreviewPageCount)
|
| + IPC_MESSAGE_UNHANDLED(break;)
|
| + IPC_END_MESSAGE_MAP();
|
| + return false;
|
| + }
|
| +
|
| + // Gets the web contents for the print preview dialog so that
|
| + // the UI and other elements can be accessed.
|
| + WebContents* GetDialog() {
|
| + WebContents* tab = browser_->tab_strip_model()->GetActiveWebContents();
|
| + printing::PrintPreviewDialogController* dialog_controller =
|
| + printing::PrintPreviewDialogController::GetInstance();
|
| + WebContents* web_contents =
|
| + dialog_controller->GetPrintPreviewForContents(tab);
|
| + return web_contents;
|
| + }
|
| +
|
| + // Gets the PrintPreviewUI so that certain elements can be accessed.
|
| + PrintPreviewUI* GetUI() {
|
| + return static_cast<PrintPreviewUI*>(
|
| + GetDialog()->GetWebUI()->GetController());
|
| + }
|
| +
|
| + // Calls a javascript function that will change the print preview settings,
|
| + // such as the layout, the margins, page numbers, etc.
|
| + void ManipulatePreviewSettings(State state) {
|
| + std::vector<const base::Value*> args;
|
| + script_argument_.reset(new base::DictionaryValue());
|
| + if (state == kWaitingToSendSaveAsPdf) {
|
| + script_argument_->SetBoolean("selectSaveAsPdfDestination", true);
|
| + } else if (state == kWaitingToSendLayoutSettings) {
|
| + script_argument_->SetBoolean("layoutSettings.portrait", is_portrait_);
|
| + } else if (state == kWaitingToSendPageNumbers) {
|
| + script_argument_->SetString("pageRange", page_numbers_);
|
| + } else if (state == kWaitingToSendHeadersAndFooters) {
|
| + script_argument_->SetBoolean("headersAndFooters", headers_and_footers_);
|
| + } else if (state == kWaitingToSendBackgroundColorsAndImages) {
|
| + script_argument_->SetBoolean("backgroundColorsAndImages",
|
| + background_colors_and_images_);
|
| + } else if (state == kWaitingToSendMargins) {
|
| + script_argument_->SetInteger("margins", margins_);
|
| + }
|
| +
|
| + args.push_back(script_argument_.get());
|
| + DCHECK(!script_argument_->empty());
|
| + DCHECK(!args.empty());
|
| + GetUI()->web_ui()->CallJavascriptFunction(
|
| + "onManipulateSettingsForTest", args);
|
| + }
|
| +
|
| + // Function to set the print preview settings and save them so they
|
| + // can be sent later. Currently only used in the constructor. Will be
|
| + // used when creating a test and take command line arguments.
|
| + // |page_numbers| is a comma separated page range.
|
| + // Example: "1-5,9" will print pages 1 through 5 and page 9.
|
| + // The pages specified must be less than or equal to the maximum
|
| + // page number. An empty string seems to be valid input, however
|
| + // further testing will be required to see if that is actually
|
| + // true.
|
| + void SetPrintPreviewSettings(bool is_portrait,
|
| + const std::string& page_numbers,
|
| + bool headers_and_footers,
|
| + bool background_colors_and_images,
|
| + printing::MarginType margins) {
|
| + is_portrait_ = is_portrait;
|
| + page_numbers_ = page_numbers;
|
| + headers_and_footers_ = headers_and_footers;
|
| + background_colors_and_images_ = background_colors_and_images;
|
| + margins_ = margins;
|
| + }
|
| +
|
| + private:
|
| + // Called when the observer gets the IPC message stating that the
|
| + // page count is ready.
|
| + void OnDidGetPreviewPageCount(
|
| + const PrintHostMsg_DidGetPreviewPageCount_Params ¶ms);
|
| +
|
| + void DidCloneToNewWebContents(WebContents* old_web_contents,
|
| + WebContents* new_web_contents)
|
| + OVERRIDE {
|
| + Observe(new_web_contents);
|
| + }
|
| +
|
| + void WebContentsDestroyed() OVERRIDE {
|
| + EndLoop();
|
| + }
|
| +
|
| + Browser* browser_;
|
| + base::Closure closure_;
|
| +
|
| + scoped_ptr<base::DictionaryValue> script_argument_;
|
| + bool is_portrait_;
|
| + std::string page_numbers_;
|
| + bool headers_and_footers_;
|
| + bool background_colors_and_images_;
|
| + printing::MarginType margins_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PrintPreviewObserver);
|
| +};
|
| +
|
| +class UIDoneLoadingMessageHandler : public content::WebUIMessageHandler {
|
| + public:
|
| + explicit UIDoneLoadingMessageHandler(PrintPreviewObserver* observer) :
|
| + observer_(observer), state_(kWaitingToSendSaveAsPdf) {}
|
| +
|
| + virtual ~UIDoneLoadingMessageHandler() {
|
| + observer_ = NULL;
|
| + }
|
| +
|
| + void HandleDone(const base::ListValue* /* args */) {
|
| + if (state_ == kWaitingForFinalMessage) {
|
| + observer_->EndLoop();
|
| + } else {
|
| + observer_->ManipulatePreviewSettings(state_);
|
| + state_ = static_cast<State>(static_cast<int>(state_) + 1);
|
| + }
|
| + }
|
| +
|
| + void HandleFailure(const base::ListValue* /* args */) {
|
| + FAIL();
|
| + }
|
| +
|
| + void RegisterMessages() OVERRIDE {
|
| + web_ui()->RegisterMessageCallback(
|
| + "UILoadedForTest",
|
| + base::Bind(&UIDoneLoadingMessageHandler::HandleDone,
|
| + base::Unretained(this)));
|
| +
|
| + web_ui()->RegisterMessageCallback(
|
| + "UIFailedLoadingForTest",
|
| + base::Bind(&UIDoneLoadingMessageHandler::HandleFailure,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + private:
|
| + PrintPreviewObserver* observer_;
|
| + State state_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(UIDoneLoadingMessageHandler);
|
| +};
|
| +
|
| +void PrintPreviewObserver::OnDidGetPreviewPageCount(
|
| + const PrintHostMsg_DidGetPreviewPageCount_Params ¶ms) {
|
| + WebContents* web_contents = GetDialog();
|
| + PrintPreviewUI* ui = GetUI();
|
| + ASSERT_TRUE(ui);
|
| + ASSERT_TRUE(ui->web_ui());
|
| + ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest");
|
| + Observe(web_contents);
|
| + ui->web_ui()->AddMessageHandler(new UIDoneLoadingMessageHandler(this));
|
| +}
|
| +
|
| +class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest {
|
| + public:
|
| + PrintPreviewPdfGeneratedBrowserTest() {}
|
| + virtual ~PrintPreviewPdfGeneratedBrowserTest() {}
|
| +
|
| + // TODO (ivandavid): Provide arguments for SetPrintPreviewSettings here.
|
| + void NavigateAndPreview(const base::FilePath::StringType& file_name) {
|
| + print_preview_observer_->SetPrintPreviewSettings(false,
|
| + "",
|
| + false,
|
| + false,
|
| + printing::DEFAULT_MARGINS);
|
| + base::FilePath directory(FILE_PATH_LITERAL("printing"));
|
| + base::FilePath file(file_name);
|
| + ui_test_utils::NavigateToURL(browser(),
|
| + ui_test_utils::GetTestUrl(directory, file));
|
| +
|
| + base::RunLoop loop;
|
| + print_preview_observer_->set_quit_closure(loop.QuitClosure());
|
| + chrome::Print(browser());
|
| + loop.Run();
|
| + }
|
| +
|
| + void Print() {
|
| + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &pdf_file_save_path_));
|
| + pdf_file_save_path_ = pdf_file_save_path_.AppendASCII("printing");
|
| + pdf_file_save_path_ = pdf_file_save_path_.AppendASCII("dummy.pdf");
|
| +
|
| + base::RunLoop loop;
|
| + print_preview_observer_->set_quit_closure(loop.QuitClosure());
|
| + print_preview_observer_->GetUI()->handler_->FileSelected(
|
| + pdf_file_save_path_, 0, NULL);
|
| + loop.Run();
|
| + }
|
| +
|
| + private:
|
| + virtual void SetUpOnMainThread() OVERRIDE {
|
| + WebContents* tab =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + ASSERT_TRUE(tab);
|
| +
|
| + print_preview_observer_.reset(new PrintPreviewObserver(tab, browser()));
|
| + chrome::DuplicateTab(browser());
|
| +
|
| + WebContents* initiator =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + ASSERT_TRUE(initiator);
|
| + ASSERT_NE(tab, initiator);
|
| + }
|
| +
|
| + virtual void CleanUpOnMainThread() OVERRIDE {
|
| + print_preview_observer_.reset();
|
| + }
|
| +
|
| + scoped_ptr<PrintPreviewObserver> print_preview_observer_;
|
| + base::FilePath pdf_file_save_path_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PrintPreviewPdfGeneratedBrowserTest);
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(PrintPreviewPdfGeneratedBrowserTest,
|
| + DISABLED_DummyTest) {
|
| + // TODO(ivandavid): Make this work on Windows also. Windows doesn't have
|
| + // the same directory structure.
|
| +
|
| + // TODO(ivandavid): Generate the file here, not in the layout test, then
|
| + // communicate this information to the layout test framework. It has to
|
| + // be this way, because there doesn't seem to be a way to communicate the
|
| + // file name from the layout test framework to the browsertest. Do
|
| + // the cleanup here also. Use mkstemp() for this (maybe chrome has some
|
| + // way to do this?).
|
| + ASSERT_TRUE(freopen("/tmp/pdf_generated_browsertest/stdin.txt", "r", stdin));
|
| + std::string cmd;
|
| +
|
| + // The printf and fflush is necessary because
|
| + // otherwise, the layout tests don't seem to get it if I just use logs or
|
| + // if I just do printf and no fflush().
|
| + printf("#READY\n");
|
| + fflush(stdout);
|
| +
|
| + // Might have to rewrite this one. It might not work in every case.
|
| + // Works for now though.
|
| + std::getline(std::cin, cmd);
|
| + if (cmd.size() == 0) {
|
| + while (std::cin.eof()) {
|
| + std::cin.clear();
|
| + std::getline(std::cin, cmd);
|
| + if (!cmd.empty()) {
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| + // TODO(ivandavid): Read from cmd the name of the test html file.
|
| + base::FilePath::StringType test_name("test2.html");
|
| + NavigateAndPreview(test_name);
|
| + Print();
|
| +
|
| + // Tells the layout tests that everything is done.
|
| + // In the future, before this part, PNG data will be sent from this program
|
| + // to the layout tests through stdout.
|
| + printf("#EOF\n");
|
| + fflush(stdout);
|
| +
|
| + // Send image data before this EOF.
|
| + printf("#EOF\n");
|
| + fflush(stdout);
|
| + fprintf(stderr, "#EOF\n");
|
| +}
|
|
|