cef/tests/ceftests/pdf_viewer_unittest.cc
Marshall Greenblatt 65234a6830 Ignore load of excluded PDF renderer frames
Starting with M125 we get WebContentsObserver callbacks for speculative
PDF renderer frames. These callbacks should be ignored.
2024-04-26 10:31:40 -04:00

227 lines
7.2 KiB
C++

// Copyright (c) 2015 The Chromium Embedded Framework 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 "include/base/cef_callback.h"
#include "include/cef_pack_resources.h"
#include "include/cef_request_context_handler.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/resource_util.h"
namespace {
const char kPdfHtmlUrl[] = "https://tests/pdf.html";
const char kPdfDirectUrl[] = "https://tests/pdf.pdf";
// Delay waiting for iframe tests to load the PDF file.
#if defined(OS_LINUX)
const int64_t kPdfLoadDelayMs = 7000;
#else
const int64_t kPdfLoadDelayMs = 5000;
#endif
// Browser-side test handler.
class PdfViewerTestHandler : public TestHandler, public CefContextMenuHandler {
public:
enum Mode {
// No specified context or handler (implicitly uses the global context).
GLOBAL_DEFAULT,
// Global context with no handler.
GLOBAL_NO_HANDLER,
// Custom context with no handler.
CUSTOM_NO_HANDLER,
};
PdfViewerTestHandler(Mode mode, const std::string& url)
: mode_(mode), url_(url) {}
// Loading the PDF directly in the main frame instead of a sub-frame.
bool HasDirectPdfLoad() const { return url_ == kPdfDirectUrl; }
CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override {
return this;
}
void RunTest() override {
CefRefPtr<CefRequestContext> request_context;
if (mode_ == GLOBAL_NO_HANDLER) {
// Use the global request context.
request_context = CefRequestContext::CreateContext(
CefRequestContext::GetGlobalContext(), nullptr);
} else if (mode_ == CUSTOM_NO_HANDLER) {
// Create the request context that will use an in-memory cache.
CefRequestContextSettings settings;
request_context = CefRequestContext::CreateContext(settings, nullptr);
}
// Create the browser.
CreateBrowser(url_, request_context);
// Time out the test after a reasonable period of time.
SetTestTimeout(5000 + kPdfLoadDelayMs);
}
CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override {
const std::string& url = request->GetURL();
if (url == kPdfHtmlUrl) {
CefRefPtr<CefStreamReader> stream =
client::GetBinaryResourceReader("pdf.html");
return new CefStreamResourceHandler("text/html", stream);
} else if (url == kPdfDirectUrl) {
CefRefPtr<CefStreamReader> stream =
client::GetBinaryResourceReader("pdf.pdf");
return new CefStreamResourceHandler("application/pdf", stream);
}
return nullptr;
}
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) override {
bool is_pdf1 = false;
const std::string& url = frame->GetURL();
if (url == "about:blank" || url.find("chrome-extension://") == 0) {
return;
}
if (url == kPdfHtmlUrl) {
if (!got_on_load_end_html_) {
got_on_load_end_html_.yes();
} else {
NOTREACHED();
}
} else if (url == kPdfDirectUrl) {
if (!got_on_load_end_pdf1_) {
got_on_load_end_pdf1_.yes();
is_pdf1 = true;
} else if (!got_on_load_end_pdf2_) {
got_on_load_end_pdf2_.yes();
} else {
NOTREACHED();
}
} else {
NOTREACHED() << "url=" << url;
}
if (is_pdf1) {
// The first PDF document has loaded.
if (got_context_menu_dismissed_) {
// After context menu display. Destroy the test.
CefPostDelayedTask(
TID_UI, base::BindOnce(&PdfViewerTestHandler::DestroyTest, this),
kPdfLoadDelayMs);
} else {
// Trigger the context menu.
CefPostDelayedTask(
TID_UI,
base::BindOnce(&PdfViewerTestHandler::TriggerContextMenu, this,
frame->GetBrowser()),
kPdfLoadDelayMs);
}
}
}
void TriggerContextMenu(CefRefPtr<CefBrowser> browser) {
CefMouseEvent mouse_event;
if (HasDirectPdfLoad()) {
// Somewhere in the main PDF viewing area (avoid left preview bar).
mouse_event.x = 400;
mouse_event.y = 200;
} else {
// Somewhere in the first PDF viewing area.
mouse_event.x = 100;
mouse_event.y = 100;
}
// Send right-click mouse down and mouse up to tigger context menu.
SendMouseClickEvent(browser, mouse_event, MBT_RIGHT);
}
bool RunContextMenu(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model,
CefRefPtr<CefRunContextMenuCallback> callback) override {
EXPECT_FALSE(got_run_context_menu_);
got_run_context_menu_.yes();
// Do nothing with the context menu.
callback->Cancel();
return true;
}
void OnContextMenuDismissed(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) override {
EXPECT_FALSE(got_context_menu_dismissed_);
got_context_menu_dismissed_.yes();
CefPostTask(TID_UI,
base::BindOnce(&PdfViewerTestHandler::DestroyTest, this));
}
void DestroyTest() override {
EXPECT_TRUE(got_run_context_menu_);
EXPECT_TRUE(got_context_menu_dismissed_);
if (url_ == kPdfHtmlUrl) {
// The HTML file will load the PDF twice in iframes.
EXPECT_TRUE(got_on_load_end_html_);
EXPECT_TRUE(got_on_load_end_pdf1_);
EXPECT_TRUE(got_on_load_end_pdf2_);
} else if (url_ == kPdfDirectUrl) {
// Load the PDF file directly.
EXPECT_FALSE(got_on_load_end_html_);
EXPECT_TRUE(got_on_load_end_pdf1_);
EXPECT_FALSE(got_on_load_end_pdf2_);
} else {
NOTREACHED();
}
TestHandler::DestroyTest();
}
const Mode mode_;
const std::string url_;
TrackCallback got_on_load_end_html_;
TrackCallback got_on_load_end_pdf1_;
TrackCallback got_on_load_end_pdf2_;
TrackCallback got_run_context_menu_;
TrackCallback got_context_menu_dismissed_;
IMPLEMENT_REFCOUNTING(PdfViewerTestHandler);
};
} // namespace
#define RUN_TEST(name, type, url) \
TEST(PdfViewerTest, name) { \
CefRefPtr<PdfViewerTestHandler> handler = \
new PdfViewerTestHandler(PdfViewerTestHandler::type, url); \
handler->ExecuteTest(); \
ReleaseAndWaitForDestructor(handler); \
}
RUN_TEST(GlobalDefaultPdfDirect, GLOBAL_DEFAULT, kPdfDirectUrl)
RUN_TEST(GlobalDefaultPdfHtml, GLOBAL_DEFAULT, kPdfHtmlUrl)
RUN_TEST(GlobalNoHandlerPdfDirect, GLOBAL_NO_HANDLER, kPdfDirectUrl)
RUN_TEST(GlobalNoHandlerPdfHtml, GLOBAL_NO_HANDLER, kPdfHtmlUrl)
RUN_TEST(CustomNoHandlerPdfDirect, CUSTOM_NO_HANDLER, kPdfDirectUrl)
RUN_TEST(CustomNoHandlerPdfHtml, CUSTOM_NO_HANDLER, kPdfHtmlUrl)