Skip to content

Commit

Permalink
Add test coverage for macOS printing Open PDF in Preview
Browse files Browse the repository at this point in the history
The macOS platform has an extra printing destination option in the
Print Preview, to generate a PDF and open that in the Preview
application.

Update TestPrintingContext to include ability to track such a request.
Utilize this from a new browser test that exercises this print type.

Test: on macOS for *SystemAccessProcess*Print*BrowserTest*
Fixed: 1473359
Change-Id: I935cbbbb2937cfa7197b6f4af096b3ae63780330
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4786630
Commit-Queue: Alan Screen <awscreen@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#1184763}
  • Loading branch information
Alan Screen authored and Chromium LUCI CQ committed Aug 17, 2023
1 parent c4a9cdf commit 43eb7bd
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 16 deletions.
25 changes: 21 additions & 4 deletions chrome/browser/printing/print_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -435,15 +435,25 @@ PrintBrowserTest::WorkerHelper::WorkerHelper(
PrintBrowserTest::WorkerHelper::~WorkerHelper() = default;

void PrintBrowserTest::WorkerHelper::OnNewDocument(
#if BUILDFLAG(IS_MAC)
bool destination_is_preview,
#endif
const PrintSettings& settings) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
content::GetUIThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&WorkerHelper::OnNewDocument, this, settings));
FROM_HERE, base::BindOnce(&WorkerHelper::OnNewDocument, this,
#if BUILDFLAG(IS_MAC)
destination_is_preview,
#endif
settings));
return;
}
if (owner_) {
owner_->OnNewDocument(settings);
owner_->OnNewDocument(
#if BUILDFLAG(IS_MAC)
destination_is_preview,
#endif
settings);
}
}

Expand Down Expand Up @@ -652,12 +662,19 @@ void PrintBrowserTest::OverrideBinderForTesting(
base::Unretained(GetFrameContent(render_frame_host))));
}

void PrintBrowserTest::OnNewDocument(const PrintSettings& settings) {
void PrintBrowserTest::OnNewDocument(
#if BUILDFLAG(IS_MAC)
bool destination_is_preview,
#endif
const PrintSettings& settings) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

DVLOG(1) << " Observed: new document";
new_document_called_count_++;
document_print_settings_ = settings;
#if BUILDFLAG(IS_MAC)
destination_is_preview_ = destination_is_preview;
#endif
}

void PrintBrowserTest::ShowPrintErrorDialog() {
Expand Down
19 changes: 17 additions & 2 deletions chrome/browser/printing/print_browsertest.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ class PrintBrowserTest : public InProcessBrowserTest {
}

protected:
void OnNewDocument(const PrintSettings& settings);
void OnNewDocument(
#if BUILDFLAG(IS_MAC)
bool destination_is_preview,
#endif
const PrintSettings& settings);

TestPrintBackend* test_print_backend() { return test_print_backend_.get(); }

Expand All @@ -99,14 +103,22 @@ class PrintBrowserTest : public InProcessBrowserTest {
return document_print_settings_;
}

#if BUILDFLAG(IS_MAC)
bool destination_is_preview() const { return destination_is_preview_; }
#endif

private:
// Helper to bounce worker thread callbacks onto PrintBrowserTest's callback
// equivalent on the UI thread.
class WorkerHelper : public base::RefCountedThreadSafe<WorkerHelper> {
public:
explicit WorkerHelper(base::WeakPtr<PrintBrowserTest> owner);

void OnNewDocument(const PrintSettings& settings);
void OnNewDocument(
#if BUILDFLAG(IS_MAC)
bool destination_is_preview,
#endif
const PrintSettings& settings);

private:
friend class base::RefCountedThreadSafe<WorkerHelper>;
Expand All @@ -125,6 +137,9 @@ class PrintBrowserTest : public InProcessBrowserTest {

int new_document_called_count_ = 0;
absl::optional<PrintSettings> document_print_settings_;
#if BUILDFLAG(IS_MAC)
bool destination_is_preview_ = false;
#endif
uint32_t error_dialog_shown_count_ = 0;
uint32_t rendered_page_count_ = 0;
unsigned int num_expected_messages_;
Expand Down
72 changes: 68 additions & 4 deletions chrome/browser/printing/system_access_process_print_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,12 +631,12 @@ class SystemAccessProcessPrintBrowserTestBase
// This script locates and clicks the "Print using system dialog",
// which is still enabled even if it is hidden.
const char kPrintWithSystemDialogScript[] = R"(
const printSystemDialog
= document.getElementsByTagName('print-preview-app')[0]
const printSystemDialog =
document.getElementsByTagName('print-preview-app')[0]
.$['sidebar']
.shadowRoot.querySelector('print-preview-link-container')
.$['systemDialogLink'];
printSystemDialog.click();)";
printSystemDialog.click();)";
// It is possible for sufficient processing for the system print to
// complete such that the renderer naturally terminates before ExecJs()
// returns here. This causes ExecJs() to return false, with a JavaScript
Expand All @@ -651,6 +651,28 @@ class SystemAccessProcessPrintBrowserTestBase
}
#endif // BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)

#if BUILDFLAG(IS_MAC)
void OpenPdfInPreviewOnceReadyAndLoaded() {
// First invoke the Print Preview dialog with `StartPrint()`.
content::WebContents* preview_dialog =
PrintAndWaitUntilPreviewIsReadyAndLoaded();
ASSERT_TRUE(preview_dialog);

// Print Preview is completely ready, can now initiate printing.
// This script locates and clicks "Open PDF in Preview", which is still
// enabled even if it is hidden.
const char kOpenPdfWithPreviewScript[] = R"(
const openPdfInPreview =
document.getElementsByTagName('print-preview-app')[0]
.$['sidebar']
.shadowRoot.querySelector('print-preview-link-container')
.$['openPdfInPreviewLink'];
openPdfInPreview.click();)";
ASSERT_TRUE(content::ExecJs(preview_dialog, kOpenPdfWithPreviewScript));
WaitUntilCallbackReceived();
}
#endif // BUILDFLAG(IS_MAC)

void PrimeAsRepeatingErrorGenerator() { reset_errors_after_check_ = false; }

#if BUILDFLAG(ENABLE_OOP_PRINTING)
Expand Down Expand Up @@ -2067,7 +2089,49 @@ IN_PROC_BROWSER_TEST_P(SystemAccessProcessServicePrintBrowserTest,
}
#endif // BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)

#endif // BUILDFLAG(ENABLE_OOP_PRINTING)
#if BUILDFLAG(IS_MAC)
IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest, OpenPdfInPreview) {
AddPrinter("printer1");
SetPrinterNameForSubsequentContexts("printer1");

ASSERT_TRUE(embedded_test_server()->Started());
GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents);
SetUpPrintViewManager(web_contents);

if (GetParam() == PrintBackendFeatureVariation::kInBrowserProcess) {
// The expected events for this are:
// 1. Wait for the one print job to be destroyed, to ensure printing
// finished cleanly before completing the test.
SetNumExpectedMessages(/*num=*/1);
} else {
// The expected events for this are:
// 1. Update printer settings.
// 2. A print job is started.
// 3. Rendering for 1 page of document of content.
// 4. Completes with document done.
// 5. Wait for the one print job to be destroyed, to ensure printing
// finished cleanly before completing the test.
SetNumExpectedMessages(/*num=*/5);
}
OpenPdfInPreviewOnceReadyAndLoaded();

if (GetParam() != PrintBackendFeatureVariation::kInBrowserProcess) {
EXPECT_EQ(start_printing_result(), mojom::ResultCode::kSuccess);
EXPECT_EQ(render_printed_document_result(), mojom::ResultCode::kSuccess);
EXPECT_EQ(document_done_result(), mojom::ResultCode::kSuccess);
}
EXPECT_TRUE(destination_is_preview());
EXPECT_EQ(error_dialog_shown_count(), 0u);
EXPECT_EQ(print_job_destruction_count(), 1);
}
#endif // BUILDFLAG(IS_MAC)

#endif // BUILDFLAG(ENABLE_OOP_PRINTING)

#if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
class TestPrintViewManagerForContentAnalysis : public TestPrintViewManager {
Expand Down
13 changes: 9 additions & 4 deletions printing/test_printing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,6 @@ gfx::Size TestPrintingContext::GetPdfPaperSizeDeviceUnits() {
mojom::ResultCode TestPrintingContext::UpdatePrinterSettings(
const PrinterSettings& printer_settings) {
DCHECK(!in_print_job_);
#if BUILDFLAG(IS_MAC)
DCHECK(!printer_settings.external_preview) << "Not implemented";
#endif

// The printer name is to be embedded in the printing context's existing
// settings.
Expand Down Expand Up @@ -177,6 +174,10 @@ mojom::ResultCode TestPrintingContext::UpdatePrinterSettings(
}
#endif

#if BUILDFLAG(IS_MAC)
destination_is_preview_ = printer_settings.external_preview;
#endif

// Capture a snapshot, simluating changes made to platform device context.
applied_settings_ = *settings_;

Expand All @@ -188,7 +189,11 @@ mojom::ResultCode TestPrintingContext::NewDocument(
DCHECK(!in_print_job_);

if (on_new_document_callback_) {
on_new_document_callback_.Run(applied_settings_);
on_new_document_callback_.Run(
#if BUILDFLAG(IS_MAC)
destination_is_preview_,
#endif
applied_settings_);
}

abort_printing_ = false;
Expand Down
14 changes: 12 additions & 2 deletions printing/test_printing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ class TestPrintingContextDelegate : public PrintingContext::Delegate {
// PrintBackend::SetPrintBackendForTesting() to avoid using a real PrintBackend.
class TestPrintingContext : public PrintingContext {
public:
using OnNewDocumentCallback =
base::RepeatingCallback<void(const PrintSettings&)>;
using OnNewDocumentCallback = base::RepeatingCallback<void(
#if BUILDFLAG(IS_MAC)
bool destination_is_preview,
#endif
const PrintSettings&)>;

TestPrintingContext(Delegate* delegate, bool skip_system_calls);
TestPrintingContext(const TestPrintingContext&) = delete;
Expand Down Expand Up @@ -130,6 +133,13 @@ class TestPrintingContext : public PrintingContext {
// applied to a device context.
PrintSettings applied_settings_;

#if BUILDFLAG(IS_MAC)
// When printing a new document, Preview app is a special macOS destination.
// This member is used to track when this was indicated as the destination to
// use in `UpdatePrinterSettings()`.
bool destination_is_preview_ = false;
#endif

bool use_default_settings_fails_ = false;
bool ask_user_for_settings_cancel_ = false;
bool new_document_cancels_ = false;
Expand Down

0 comments on commit 43eb7bd

Please sign in to comment.