chromium/chrome/browser/printing/print_browsertest.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/printing/print_browsertest.h"

#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "base/auto_reset.h"
#include "base/base64.h"
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/printing/browser_printing_context_factory_for_test.h"
#include "chrome/browser/printing/print_compositor_util.h"
#include "chrome/browser/printing/print_error_dialog.h"
#include "chrome/browser/printing/print_job.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_sticky_settings.h"
#include "chrome/browser/printing/print_test_utils.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/printing/print_view_manager_common.h"
#include "chrome/browser/printing/printer_query.h"
#include "chrome/browser/printing/test_print_preview_observer.h"
#include "chrome/browser/printing/test_print_view_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/prefs/pref_service.h"
#include "components/printing/browser/print_composite_client.h"
#include "components/printing/browser/print_manager_utils.h"
#include "components/printing/common/print.mojom-test-utils.h"
#include "components/printing/common/print.mojom.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/prerender_test_util.h"
#include "extensions/common/extension.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "printing/backend/test_print_backend.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "printing/page_setup.h"
#include "printing/print_settings.h"
#include "printing/printing_context.h"
#include "printing/printing_context_factory_for_test.h"
#include "printing/printing_features.h"
#include "printing/test_printing_context.h"
#include "printing/units.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
#include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"

#if BUILDFLAG(ENABLE_OOP_PRINTING)
#include "chrome/browser/printing/print_backend_service_manager.h"
#include "chrome/browser/printing/print_backend_service_test_impl.h"
#include "chrome/browser/printing/print_job_worker_oop.h"
#include "chrome/browser/printing/printer_query_oop.h"
#include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "printing/printing_utils.h"
#include "sandbox/policy/features.h"
#include "sandbox/policy/switches.h"
#endif

namespace printing {

_;

OnDidCreatePrintJobCallback;

namespace {

constexpr int kTestPrinterCapabilitiesMaxCopies =;
const int kDefaultDocumentCookie =;

// Sticky settings containing an extension printer as the most recently used
// destination. This must be in sync with
// //chrome/test/data/printing/test_extension/background.js.
constexpr char kStickySettingsWithExtensionPrinter[] =;

// Sticky settings containing an extension printer with a missing printable area
// as the most recently used destination. This must be in sync with
// //chrome/test/data/printing/test_extension/background.js.
constexpr char kStickySettingsWithExtensionPrinterMissingPrintableArea[] =;

class PrintPreviewDoneObserver
    : public mojom::PrintRenderFrameInterceptorForTesting {};

}  // namespace

class TestPrintRenderFrame
    : public mojom::PrintRenderFrameInterceptorForTesting {};

// Lives on the UI thread.
class TestPrintViewManagerForDLP : public TestPrintViewManager {};

PrintBrowserTest::WorkerHelper::WorkerHelper(
    base::WeakPtr<PrintBrowserTest> owner)
    :{}

PrintBrowserTest::KillPrintRenderFrame::KillPrintRenderFrame(
    content::RenderProcessHost* rph)
    :{}

PrintBrowserTest::KillPrintRenderFrame::KillPrintRenderFrame(
    content::RenderProcessHost* rph,
    mojom::PrintRenderFrame* print_render_frame)
    :{}

PrintBrowserTest::KillPrintRenderFrame::~KillPrintRenderFrame() = default;

void PrintBrowserTest::KillPrintRenderFrame::OverrideBinderForTesting(
    content::RenderFrameHost* render_frame_host) {}

void PrintBrowserTest::KillPrintRenderFrame::KillRenderProcess(
    int document_cookie,
    mojom::DidPrintContentParamsPtr param,
    PrintFrameContentCallback callback) const {}

void PrintBrowserTest::KillPrintRenderFrame::Bind(
    mojo::ScopedInterfaceEndpointHandle handle) {}

mojom::PrintRenderFrame*
PrintBrowserTest::KillPrintRenderFrame::GetForwardingInterface() {}

void PrintBrowserTest::KillPrintRenderFrame::PrintFrameContent(
    mojom::PrintFrameContentParamsPtr params,
    PrintFrameContentCallback callback) {}

PrintBrowserTest::WorkerHelper::~WorkerHelper() = default;

void PrintBrowserTest::WorkerHelper::OnNewDocument(
#if BUILDFLAG(IS_MAC)
    bool destination_is_preview,
#endif
    const PrintSettings& settings) {}

PrintBrowserTest::PrintBrowserTest() = default;
PrintBrowserTest::~PrintBrowserTest() = default;

void PrintBrowserTest::SetUp() {}

void PrintBrowserTest::SetUpOnMainThread() {}

void PrintBrowserTest::TearDownOnMainThread() {}

void PrintBrowserTest::TearDown() {}

void PrintBrowserTest::AddPrinter(const std::string& printer_name) {}

void PrintBrowserTest::SetPrinterNameForSubsequentContexts(
    const std::string& printer_name) {}

#if BUILDFLAG(IS_WIN)
void PrintBrowserTest::SetPrinterLanguageTypeForSubsequentContexts(
    mojom::PrinterLanguageType printer_language_type) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  test_printing_context_factory_.SetPrinterLanguageTypeForSubsequentContexts(
      printer_language_type);
}
#endif

void PrintBrowserTest::SetUserSettingsPageRangesForSubsequentContext(
    const PageRanges& page_ranges) {}

void PrintBrowserTest::SetNewDocumentJobId(int job_id) {}

void PrintBrowserTest::PrintAndWaitUntilPreviewIsReady() {}

content::WebContents* PrintBrowserTest::PrintAndWaitUntilPreviewIsReady(
    const PrintParams& params) {}

content::WebContents*
PrintBrowserTest::PrintAndWaitUntilPreviewIsReadyAndLoaded() {}

content::WebContents*
PrintBrowserTest::PrintAndWaitUntilPreviewIsReadyAndLoaded(
    const PrintParams& params) {}

content::WebContents*
PrintBrowserTest::PrintAndWaitUntilPreviewIsReadyAndMaybeLoaded(
    const PrintParams& params,
    bool wait_for_loaded) {}

// The following are helper functions for having a wait loop in the test and
// exit when all expected messages are received.
void PrintBrowserTest::SetNumExpectedMessages(unsigned int num) {}

void PrintBrowserTest::ResetNumReceivedMessages() {}

void PrintBrowserTest::WaitUntilCallbackReceived() {}

void PrintBrowserTest::CheckForQuit() {}

void PrintBrowserTest::CreateTestPrintRenderFrame(
    content::RenderFrameHost* frame_host,
    content::WebContents* web_contents) {}

// static
mojom::PrintFrameContentParamsPtr
PrintBrowserTest::GetDefaultPrintFrameParams() {}

const mojo::AssociatedRemote<mojom::PrintRenderFrame>&
PrintBrowserTest::GetPrintRenderFrame(content::RenderFrameHost* rfh) {}

TestPrintRenderFrame* PrintBrowserTest::GetFrameContent(
    content::RenderFrameHost* host) const {}

void PrintBrowserTest::OverrideBinderForTesting(
    content::RenderFrameHost* render_frame_host) {}

void PrintBrowserTest::PrepareRunloop() {}

void PrintBrowserTest::OnNewDocument(
#if BUILDFLAG(IS_MAC)
    bool destination_is_preview,
#endif
    const PrintSettings& settings) {}

void PrintBrowserTest::ShowPrintErrorDialog() {}

class SitePerProcessPrintBrowserTest : public PrintBrowserTest {};

class IsolateOriginsPrintBrowserTest : public PrintBrowserTest {};

class BackForwardCachePrintBrowserTest : public PrintBrowserTest {};

constexpr char IsolateOriginsPrintBrowserTest::kIsolatedSite[];

class PrintExtensionBrowserTest : public extensions::ExtensionBrowserTest {};

class SitePerProcessPrintExtensionBrowserTest
    : public PrintExtensionBrowserTest {};

// Printing only a selection containing iframes is partially supported.
// Iframes aren't currently displayed. This test passes whenever the print
// preview is rendered (i.e. no timeout in the test).
// This test shouldn't crash. See https://crbug.com/732780.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, SelectionContainsIframe) {}

// https://crbug.com/1125972
// https://crbug.com/1131598
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, NoScrolling) {}

// https://crbug.com/1131598
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_NoScrollingFrameset) {}

// https://crbug.com/1125972
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, NoScrollingVerticalRl) {}

// https://crbug.com/1285208
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, LegacyLayoutEngineFallback) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, LazyLoadedImagesFetched) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, LazyLoadedIframeFetched) {}

// TODO(crbug.com/40826924)  Reenable after flakes have been resolved.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       DISABLED_LazyLoadedIframeFetchedCrossOrigin) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, LazyLoadedImagesFetchedScriptedPrint) {}

// Before invoking print preview, page scale is changed to a different value.
// Test that when print preview is ready, in other words when printing is
// finished, the page scale factor is still the same, and that it hasn't been
// messed up by printing.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, ResetPageScaleAfterPrintPreview) {}

// Printing frame content for the main frame of a generic webpage.
// This test passes when the printed result is sent back and checked in
// TestPrintRenderFrame::OnDidPrintFrameContent().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintFrameContent) {}

// Printing frame content for a cross-site iframe.
// This test passes when the iframe responds to the print message.
// The response is checked in TestPrintRenderFrame::OnDidPrintFrameContent().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeContent) {}

// Printing frame content with a cross-site iframe which also has a cross-site
// iframe. The site reference chain is a.com --> b.com --> c.com.
// This test passes when both cross-site frames are printed and their
// responses which are checked in
// TestPrintRenderFrame::OnDidPrintFrameContent().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeChain) {}

// Printing frame content with a cross-site iframe who also has a cross site
// iframe, but this iframe resides in the same site as the main frame.
// The site reference loop is a.com --> b.com --> a.com.
// This test passes when both cross-site frames are printed and send back
// responses which are checked in
// TestPrintRenderFrame::OnDidPrintFrameContent().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintSubframeABA) {}

// Printing frame content with a cross-site iframe before creating
// PrintCompositor by the main frame.
// This test passes if PrintCompositeClient queues subframes when
// it doesn't have PrintCompositor and clears them after PrintCompositor is
// created.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       PrintSubframeContentBeforeCompositeClientCreation) {}

// Printing preview a simple webpage when site per process is enabled.
// Test that the basic oopif printing should succeed. The test should not crash
// or timed out. There could be other reasons that cause the test fail, but the
// most obvious ones would be font access outage or web sandbox support being
// absent because we explicitly check these when pdf compositor service starts.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest, BasicPrint) {}

// Printing a web page with a dead subframe for site per process should succeed.
// This test passes whenever the print preview is rendered. This should not be
// a timed out test which indicates the print preview hung.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest,
                       SubframeUnavailableBeforePrint) {}

// If a subframe dies during printing, the page printing should still succeed.
// This test passes whenever the print preview is rendered. This should not be
// a timed out test which indicates the print preview hung.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest,
                       SubframeUnavailableDuringPrint) {}

// Printing preview a web page with an iframe from an isolated origin.
// This test passes whenever the print preview is rendered. This should not be
// a timed out test which indicates the print preview hung or crash.
IN_PROC_BROWSER_TEST_F(IsolateOriginsPrintBrowserTest, PrintIsolatedSubframe) {}

// Printing preview a webpage.
// Test that we use oopif printing by default when full site isolation is
// enabled.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, RegularPrinting) {}

#if BUILDFLAG(IS_CHROMEOS)
// Test that if user allows printing after being shown a warning due to DLP
// restrictions, the print preview is rendered.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPWarnAllowed) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents);
  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents,
          TestPrintViewManagerForDLP::RestrictionLevel::kWarnAllow);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  test::StartPrint(browser()->tab_strip_model()->GetActiveWebContents());
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kAllowed);
}

// Test that if user cancels printing after being shown a warning due to DLP
// restrictions, the print preview is not rendered.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPWarnCanceled) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents);
  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents,
          TestPrintViewManagerForDLP::RestrictionLevel::kWarnCancel);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  test::StartPrint(browser()->tab_strip_model()->GetActiveWebContents());
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
}

// Test that if printing is blocked due to DLP restrictions, the print preview
// is not rendered.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPBlocked) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents);
  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents, TestPrintViewManagerForDLP::RestrictionLevel::kBlock);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  test::StartPrint(browser()->tab_strip_model()->GetActiveWebContents());
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
}

// Test that if user allows printing after being shown a warning due to DLP
// restrictions, the print preview is rendered when initiated by window.print().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPWarnAllowedWithWindowDotPrint) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

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

  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents,
          TestPrintViewManagerForDLP::RestrictionLevel::kWarnAllow);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
                              "window.print();");
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kAllowed);
}

// Test that if user cancels printing after being shown a warning due to DLP
// restrictions, the print preview is not rendered when initiated by
// window.print().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPWarnCanceledWithWindowDotPrint) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

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

  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents,
          TestPrintViewManagerForDLP::RestrictionLevel::kWarnCancel);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
                              "window.print();");
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
}

// Test that if printing is blocked due to DLP restrictions, the print preview
// is not rendered when initiated by window.print().
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DLPBlockedWithWindowDotPrint) {
  ASSERT_TRUE(embedded_test_server()->Started());
  GURL url(embedded_test_server()->GetURL("/printing/test1.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

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

  // Set up the print view manager and DLP restrictions.
  TestPrintViewManagerForDLP* print_view_manager =
      TestPrintViewManagerForDLP::CreateForWebContents(
          web_contents, TestPrintViewManagerForDLP::RestrictionLevel::kBlock);

  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kUnknown);
  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
                              "window.print();");
  print_view_manager->WaitUntilPreviewIsShownOrCancelled();
  ASSERT_EQ(print_view_manager->GetPrintAllowance(),
            TestPrintViewManagerForDLP::PrintAllowance::kDisallowed);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

// Printing preview a webpage with isolate-origins enabled.
// Test that we will use oopif printing for this case.
IN_PROC_BROWSER_TEST_F(IsolateOriginsPrintBrowserTest, OopifPrinting) {}

IN_PROC_BROWSER_TEST_F(BackForwardCachePrintBrowserTest, DisableCaching) {}

// Printing an extension option page.
// The test should not crash or timeout.
IN_PROC_BROWSER_TEST_F(PrintExtensionBrowserTest, PrintOptionPage) {}

// Test fetching an extension printer.
IN_PROC_BROWSER_TEST_F(PrintExtensionBrowserTest,
                       UpdatePrintSettingsExtensionPrinter) {}

// Test fetching an extension printer that has missing printable area. The
// printable area should be set to a default value.
IN_PROC_BROWSER_TEST_F(
    PrintExtensionBrowserTest,
    UpdatePrintSettingsExtensionPrinterMissingPrintableArea) {}

// Printing an extension option page with site per process is enabled.
// The test should not crash or timeout.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintExtensionBrowserTest,
                       PrintOptionPage) {}

// Printing frame content for the main frame of a generic webpage with N-up
// printing. This is a regression test for https://crbug.com/937247
// TODO(crbug.com/40870686): Fix flakiness and re-enable.
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_PrintNup) {}

// Site per process version of PrintBrowserTest.PrintNup.
// TODO(crbug.com/40870686): Fix flakiness and re-enable.
IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest, DISABLED_PrintNup) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, MultipagePrint) {}

IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest, MultipagePrint) {}

// Disabled due to flakiness: crbug.com/1311998
IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       DISABLED_PDFPluginNotKeyboardFocusable) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, WindowDotPrint) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PdfWindowDotPrint) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       WindowDotPrintTriggersBeforeAfterEvents) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       WindowDotPrintWhilePrintPreviewIsInProgress) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest,
                       WindowDotPrintWhilePrintPreviewForNodeIsInProgress) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, NoResizeEvent) {}

IN_PROC_BROWSER_TEST_F(PrintBrowserTest, SpecifiedPageSizeCrash) {}

class PrintPrerenderBrowserTest
    : public PrintBrowserTest,
      public testing::WithParamInterface<std::string> {};

INSTANTIATE_TEST_SUITE_P();

// Test that print() is silently ignored.
// https://wicg.github.io/nav-speculation/prerendering.html#patch-modals
IN_PROC_BROWSER_TEST_P(PrintPrerenderBrowserTest, QuietBlockWithWindowPrint) {}

// Test that execCommand('print') is silently ignored.
// execCommand() is not specced, but
// https://wicg.github.io/nav-speculation/prerendering.html#patch-modals
// indicates the intent to silently ignore print APIs.
IN_PROC_BROWSER_TEST_P(PrintPrerenderBrowserTest,
                       QuietBlockWithDocumentExecCommand) {}

class PrintFencedFrameBrowserTest : public PrintBrowserTest {};

IN_PROC_BROWSER_TEST_F(PrintFencedFrameBrowserTest, ScriptedPrint) {}

IN_PROC_BROWSER_TEST_F(PrintFencedFrameBrowserTest, DocumentExecCommand) {}

#if BUILDFLAG(IS_WIN)
std::string GetDocumentDataTypeTestSuffix(
    const testing::TestParamInfo<DocumentDataType>& info) {
  switch (info.param) {
    case DocumentDataType::kUnknown:
      NOTREACHED();
    case DocumentDataType::kPdf:
      return "Pdf";
    case DocumentDataType::kXps:
      return "Xps";
  }
}

class PrintCompositorDocumentDataTypeBrowserTest
    : public PrintBrowserTest,
      public testing::WithParamInterface<DocumentDataType> {
 public:
  PrintCompositorDocumentDataTypeBrowserTest() = default;
  ~PrintCompositorDocumentDataTypeBrowserTest() override = default;

  void SetUp() override {
    std::vector<base::test::FeatureRefAndParams> enabled_features;
    std::vector<base::test::FeatureRef> disabled_features;

    // Force use of out-of-process print drivers, since it is required for
    // printing with XPS.
    enabled_features.push_back(
        {features::kEnableOopPrintDrivers,
         {{features::kEnableOopPrintDriversJobPrint.name, "true"}}});
    if (GetParam() == DocumentDataType::kXps) {
      enabled_features.push_back({features::kUseXpsForPrinting, {}});
    } else {
      disabled_features.push_back(features::kUseXpsForPrinting);
    }

    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
                                                       disabled_features);
    PrintBrowserTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

INSTANTIATE_TEST_SUITE_P(All,
                         PrintCompositorDocumentDataTypeBrowserTest,
                         testing::Values(DocumentDataType::kPdf,
                                         DocumentDataType::kXps),
                         GetDocumentDataTypeTestSuffix);

// Demonstrate that the Print Compositor is plumbed to generate the different
// document types.
IN_PROC_BROWSER_TEST_P(PrintCompositorDocumentDataTypeBrowserTest,
                       WindowDotPrint) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  TestPrintPreviewObserver print_preview_observer(/*wait_for_loaded=*/true);
  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
                              "window.print();");
  print_preview_observer.WaitUntilPreviewIsReady();

  EXPECT_THAT(print_preview_observer.last_document_composite_data_type(),
              testing::Optional(GetParam()));
}

// Demonstrate that the Print Compositor still works using the legacy sandbox
// method, should the `kPrintCompositorLPAC` flag be disabled.
// TODO(crbug.com/40283514):  Remove once LPAC sandboxing has been proven to
// work even for GDI.
class PrintCompositorLegacySandboxBrowserTest : public PrintBrowserTest {
  void SetUp() override {
    std::vector<base::test::FeatureRef> disabled_features;

    disabled_features.push_back(
        sandbox::policy::features::kPrintCompositorLPAC);
    disabled_features.push_back(features::kUseXpsForPrinting);

    scoped_feature_list_.InitWithFeatures(/*enabled_features=*/{},
                                          disabled_features);
    PrintBrowserTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(PrintCompositorLegacySandboxBrowserTest,
                       WindowDotPrint) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  TestPrintPreviewObserver print_preview_observer(/*wait_for_loaded=*/true);
  content::ExecuteScriptAsync(web_contents->GetPrimaryMainFrame(),
                              "window.print();");
  print_preview_observer.WaitUntilPreviewIsReady();

  EXPECT_THAT(print_preview_observer.last_document_composite_data_type(),
              testing::Optional(DocumentDataType::kPdf));
}
#endif  // BUILDFLAG(IS_WIN)

}  // namespace printing