| /* |
| * Copyright (C) 2012 Igalia S.L. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2,1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "config.h" |
| #include "WebViewTest.h" |
| #include <glib/gstdio.h> |
| #include <wtf/glib/GRefPtr.h> |
| |
| #ifdef HAVE_GTK_UNIX_PRINTING |
| #include <gtk/gtkunixprint.h> |
| #endif |
| |
| static void testPrintOperationPrintSettings(WebViewTest* test, gconstpointer) |
| { |
| GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(webkit_print_operation_new(test->m_webView)); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation.get())); |
| |
| g_assert(!webkit_print_operation_get_print_settings(printOperation.get())); |
| g_assert(!webkit_print_operation_get_page_setup(printOperation.get())); |
| |
| GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printSettings.get())); |
| |
| GRefPtr<GtkPageSetup> pageSetup = adoptGRef(gtk_page_setup_new()); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(pageSetup.get())); |
| |
| webkit_print_operation_set_print_settings(printOperation.get(), printSettings.get()); |
| webkit_print_operation_set_page_setup(printOperation.get(), pageSetup.get()); |
| |
| g_assert(webkit_print_operation_get_print_settings(printOperation.get()) == printSettings.get()); |
| g_assert(webkit_print_operation_get_page_setup(printOperation.get()) == pageSetup.get()); |
| } |
| |
| static gboolean webViewPrintCallback(WebKitWebView* webView, WebKitPrintOperation* printOperation, WebViewTest* test) |
| { |
| g_assert(webView == test->m_webView); |
| |
| g_assert(WEBKIT_IS_PRINT_OPERATION(printOperation)); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation)); |
| |
| g_assert(!webkit_print_operation_get_print_settings(printOperation)); |
| g_assert(!webkit_print_operation_get_page_setup(printOperation)); |
| |
| g_main_loop_quit(test->m_mainLoop); |
| |
| return TRUE; |
| } |
| |
| static void testWebViewPrint(WebViewTest* test, gconstpointer) |
| { |
| g_signal_connect(test->m_webView, "print", G_CALLBACK(webViewPrintCallback), test); |
| test->loadHtml("<html><body onLoad=\"print();\">WebKitGTK+ printing test</body></html>", 0); |
| g_main_loop_run(test->m_mainLoop); |
| } |
| |
| #ifdef HAVE_GTK_UNIX_PRINTING |
| static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData) |
| { |
| if (strcmp(gtk_printer_get_name(printer), "Print to File")) |
| return FALSE; |
| |
| GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData); |
| *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer)); |
| return TRUE; |
| } |
| |
| static GtkPrinter* findPrintToFilePrinter() |
| { |
| GtkPrinter* printer = 0; |
| gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE); |
| return printer; |
| } |
| |
| class PrintTest: public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(PrintTest); |
| |
| static void printFinishedCallback(WebKitPrintOperation*, PrintTest* test) |
| { |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| static void printFailedCallback(WebKitPrintOperation*, GError* error, PrintTest* test) |
| { |
| g_assert(test->m_expectedError); |
| g_assert(error); |
| g_assert(g_error_matches(error, WEBKIT_PRINT_ERROR, test->m_expectedError)); |
| } |
| |
| PrintTest() |
| : m_expectedError(0) |
| { |
| m_printOperation = adoptGRef(webkit_print_operation_new(m_webView)); |
| assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get())); |
| g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printFinishedCallback), this); |
| g_signal_connect(m_printOperation.get(), "failed", G_CALLBACK(printFailedCallback), this); |
| } |
| |
| void waitUntilPrintFinished() |
| { |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| GRefPtr<WebKitPrintOperation> m_printOperation; |
| unsigned m_expectedError; |
| }; |
| |
| static void testPrintOperationPrint(PrintTest* test, gconstpointer) |
| { |
| test->loadHtml("<html><body>WebKitGTK+ printing test</body></html>", 0); |
| test->waitUntilLoadFinished(); |
| |
| GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); |
| if (!printer) { |
| g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); |
| return; |
| } |
| |
| GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-print.pdf", nullptr)); |
| GRefPtr<GFile> outputFile = adoptGRef(g_file_new_for_path(outputFilename.get())); |
| GUniquePtr<char> outputURI(g_file_get_uri(outputFile.get())); |
| |
| GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); |
| gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); |
| gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get()); |
| |
| webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get()); |
| webkit_print_operation_print(test->m_printOperation.get()); |
| test->waitUntilPrintFinished(); |
| |
| GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(outputFile.get(), |
| G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, |
| static_cast<GFileQueryInfoFlags>(0), 0, 0)); |
| g_assert(fileInfo.get()); |
| g_assert_cmpint(g_file_info_get_size(fileInfo.get()), >, 0); |
| g_assert_cmpstr(g_file_info_get_content_type(fileInfo.get()), ==, "application/pdf"); |
| |
| g_file_delete(outputFile.get(), 0, 0); |
| } |
| |
| static void testPrintOperationErrors(PrintTest* test, gconstpointer) |
| { |
| test->loadHtml("<html><body>WebKitGTK+ printing errors test</body></html>", 0); |
| test->waitUntilLoadFinished(); |
| |
| GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); |
| if (!printer) { |
| g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); |
| return; |
| } |
| |
| // General Error: invalid filename. |
| test->m_expectedError = WEBKIT_PRINT_ERROR_GENERAL; |
| GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); |
| gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); |
| gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, "file:///foo/bar"); |
| webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get()); |
| webkit_print_operation_print(test->m_printOperation.get()); |
| test->waitUntilPrintFinished(); |
| |
| // Printer not found error. |
| test->m_expectedError = WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND; |
| gtk_print_settings_set_printer(printSettings.get(), "The fake WebKit printer"); |
| webkit_print_operation_print(test->m_printOperation.get()); |
| test->waitUntilPrintFinished(); |
| |
| // No pages to print: print even pages for a single page document. |
| test->m_expectedError = WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE; |
| gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); |
| gtk_print_settings_set_page_set(printSettings.get(), GTK_PAGE_SET_EVEN); |
| webkit_print_operation_print(test->m_printOperation.get()); |
| test->waitUntilPrintFinished(); |
| } |
| |
| class CloseAfterPrintTest: public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(CloseAfterPrintTest); |
| |
| static GtkWidget* webViewCreate(WebKitWebView* webView, WebKitNavigationAction*, CloseAfterPrintTest* test) |
| { |
| return test->createWebView(); |
| } |
| |
| static gboolean webViewPrint(WebKitWebView* webView, WebKitPrintOperation* printOperation, CloseAfterPrintTest* test) |
| { |
| test->print(printOperation); |
| return TRUE; |
| } |
| |
| static void printOperationFinished(WebKitPrintOperation* printOperation, CloseAfterPrintTest* test) |
| { |
| test->printFinished(); |
| } |
| |
| static void webViewClosed(WebKitWebView* webView, CloseAfterPrintTest* test) |
| { |
| gtk_widget_destroy(GTK_WIDGET(webView)); |
| test->m_webViewClosed = true; |
| if (test->m_printFinished) |
| g_main_loop_quit(test->m_mainLoop); |
| } |
| |
| CloseAfterPrintTest() |
| : m_webViewClosed(false) |
| , m_printFinished(false) |
| { |
| webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); |
| g_signal_connect(m_webView, "create", G_CALLBACK(webViewCreate), this); |
| } |
| |
| GtkWidget* createWebView() |
| { |
| GtkWidget* newWebView = webkit_web_view_new_with_context(m_webContext.get()); |
| g_object_ref_sink(newWebView); |
| |
| assertObjectIsDeletedWhenTestFinishes(G_OBJECT(newWebView)); |
| g_signal_connect(newWebView, "print", G_CALLBACK(webViewPrint), this); |
| g_signal_connect(newWebView, "close", G_CALLBACK(webViewClosed), this); |
| return newWebView; |
| } |
| |
| void print(WebKitPrintOperation* printOperation) |
| { |
| assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation)); |
| |
| GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); |
| if (!printer) { |
| g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); |
| return; |
| } |
| |
| GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-close-after-print.pdf", nullptr)); |
| m_outputFile = adoptGRef(g_file_new_for_path(outputFilename.get())); |
| GUniquePtr<char> outputURI(g_file_get_uri(m_outputFile.get())); |
| |
| GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); |
| gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); |
| gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get()); |
| webkit_print_operation_set_print_settings(printOperation, printSettings.get()); |
| |
| m_printOperation = printOperation; |
| g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printOperationFinished), this); |
| webkit_print_operation_print(m_printOperation.get()); |
| } |
| |
| void printFinished() |
| { |
| m_printFinished = true; |
| m_printOperation = nullptr; |
| g_assert(m_outputFile); |
| g_file_delete(m_outputFile.get(), 0, 0); |
| m_outputFile = nullptr; |
| if (m_webViewClosed) |
| g_main_loop_quit(m_mainLoop); |
| } |
| |
| void waitUntilPrintFinishedAndViewClosed() |
| { |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| GRefPtr<WebKitPrintOperation> m_printOperation; |
| GRefPtr<GFile> m_outputFile; |
| bool m_webViewClosed; |
| bool m_printFinished; |
| }; |
| |
| static void testPrintOperationCloseAfterPrint(CloseAfterPrintTest* test, gconstpointer) |
| { |
| test->loadHtml("<html><body onLoad=\"w = window.open();w.print();w.close();\"></body></html>", 0); |
| test->waitUntilPrintFinishedAndViewClosed(); |
| } |
| |
| class PrintCustomWidgetTest: public WebViewTest { |
| public: |
| MAKE_GLIB_TEST_FIXTURE(PrintCustomWidgetTest); |
| |
| static void applyCallback(WebKitPrintCustomWidget*, PrintCustomWidgetTest* test) |
| { |
| test->m_applyEmitted = true; |
| } |
| |
| static gboolean scheduleJumpToCustomWidget(PrintCustomWidgetTest* test) |
| { |
| test->jumpToCustomWidget(); |
| |
| return FALSE; |
| } |
| |
| static void updateCallback(WebKitPrintCustomWidget* customWidget, GtkPageSetup*, GtkPrintSettings*, PrintCustomWidgetTest* test) |
| { |
| g_assert(test->m_widget == webkit_print_custom_widget_get_widget(customWidget)); |
| |
| test->m_updateEmitted = true; |
| // Would be nice to avoid the 1 second timeout here - but I didn't found |
| // a way to do so without making the test flaky. |
| g_timeout_add_seconds(1, reinterpret_cast<GSourceFunc>(scheduleJumpToCustomWidget), test); |
| } |
| |
| static void widgetRealizeCallback(GtkWidget* widget, PrintCustomWidgetTest* test) |
| { |
| g_assert(GTK_IS_LABEL(widget)); |
| g_assert(!g_strcmp0(gtk_label_get_text(GTK_LABEL(widget)), "Label")); |
| |
| test->m_widgetRealized = true; |
| test->startPrinting(); |
| } |
| |
| static WebKitPrintCustomWidget* createCustomWidgetCallback(WebKitPrintOperation* printOperation, PrintCustomWidgetTest* test) |
| { |
| test->m_createEmitted = true; |
| WebKitPrintCustomWidget* printCustomWidget = test->createPrintCustomWidget(); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printCustomWidget)); |
| g_signal_connect(printCustomWidget, "apply", G_CALLBACK(applyCallback), test); |
| g_signal_connect(printCustomWidget, "update", G_CALLBACK(updateCallback), test); |
| |
| GtkWidget* widget = webkit_print_custom_widget_get_widget(printCustomWidget); |
| test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(widget)); |
| g_signal_connect(widget, "realize", G_CALLBACK(widgetRealizeCallback), test); |
| |
| return printCustomWidget; |
| } |
| |
| static gboolean scheduleMovementThroughDialog(PrintCustomWidgetTest* test) |
| { |
| test->jumpToFirstPrinter(); |
| |
| return FALSE; |
| } |
| |
| static gboolean openPrintDialog(PrintCustomWidgetTest* test) |
| { |
| g_idle_add(reinterpret_cast<GSourceFunc>(scheduleMovementThroughDialog), test); |
| test->m_response = webkit_print_operation_run_dialog(test->m_printOperation.get(), GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(test->m_webView)))); |
| |
| return FALSE; |
| } |
| |
| static void printOperationFinished(WebKitPrintOperation* printOperation, PrintCustomWidgetTest* test) |
| { |
| test->printFinished(); |
| } |
| |
| void printFinished() |
| { |
| g_assert(m_outputFile); |
| g_file_delete(m_outputFile.get(), nullptr, nullptr); |
| m_outputFile = nullptr; |
| g_main_loop_quit(m_mainLoop); |
| } |
| |
| void createWebKitPrintOperation() |
| { |
| m_printOperation = adoptGRef(webkit_print_operation_new(m_webView)); |
| g_assert(m_printOperation); |
| assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get())); |
| |
| g_signal_connect(m_printOperation.get(), "create-custom-widget", G_CALLBACK(createCustomWidgetCallback), this); |
| g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printOperationFinished), this); |
| } |
| |
| WebKitPrintCustomWidget* createPrintCustomWidget() |
| { |
| m_widget = gtk_label_new("Label"); |
| return webkit_print_custom_widget_new(m_widget, "Custom Widget"); |
| } |
| |
| void startPrinting() |
| { |
| // To start printing it is enough to press the Return key |
| keyStroke(GDK_KEY_Return); |
| } |
| |
| void jumpToFirstPrinter() |
| { |
| // Initially the GtkNotebook has focus, so we just need to press the Tab |
| // key to jump to the first printer |
| keyStroke(GDK_KEY_Tab); |
| } |
| |
| void jumpToCustomWidget() |
| { |
| // Jump back to the GtkNotebook |
| keyStroke(GDK_KEY_Tab, GDK_SHIFT_MASK); |
| // Custom widget is on the third tab |
| keyStroke(GDK_KEY_Right); |
| keyStroke(GDK_KEY_Right); |
| } |
| |
| void openDialogMoveThroughItAndWaitUntilClosed() |
| { |
| g_idle_add(reinterpret_cast<GSourceFunc>(openPrintDialog), this); |
| g_main_loop_run(m_mainLoop); |
| } |
| |
| GRefPtr<WebKitPrintOperation> m_printOperation; |
| GRefPtr<GFile> m_outputFile; |
| GtkWidget* m_widget; |
| bool m_widgetRealized {false}; |
| bool m_applyEmitted {false}; |
| bool m_updateEmitted {false}; |
| bool m_createEmitted {false}; |
| WebKitPrintOperationResponse m_response {WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL}; |
| }; |
| |
| static void testPrintCustomWidget(PrintCustomWidgetTest* test, gconstpointer) |
| { |
| test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL, 0, 0); |
| |
| test->loadHtml("<html><body>Text</body></html>", 0); |
| test->waitUntilLoadFinished(); |
| |
| test->createWebKitPrintOperation(); |
| |
| GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); |
| if (!printer) { |
| g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); |
| return; |
| } |
| |
| GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-close-after-print.pdf", nullptr)); |
| test->m_outputFile = adoptGRef(g_file_new_for_path(outputFilename.get())); |
| GUniquePtr<char> outputURI(g_file_get_uri(test->m_outputFile.get())); |
| |
| GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); |
| gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get()); |
| webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get()); |
| |
| test->openDialogMoveThroughItAndWaitUntilClosed(); |
| |
| g_assert(test->m_response == WEBKIT_PRINT_OPERATION_RESPONSE_PRINT); |
| g_assert(test->m_createEmitted); |
| g_assert(test->m_widgetRealized); |
| g_assert(test->m_updateEmitted); |
| g_assert(test->m_applyEmitted); |
| } |
| #endif // HAVE_GTK_UNIX_PRINTING |
| |
| void beforeAll() |
| { |
| WebViewTest::add("WebKitPrintOperation", "printing-settings", testPrintOperationPrintSettings); |
| WebViewTest::add("WebKitWebView", "print", testWebViewPrint); |
| #ifdef HAVE_GTK_UNIX_PRINTING |
| PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint); |
| PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors); |
| CloseAfterPrintTest::add("WebKitPrintOperation", "close-after-print", testPrintOperationCloseAfterPrint); |
| PrintCustomWidgetTest::add("WebKitPrintOperation", "custom-widget", testPrintCustomWidget); |
| #endif |
| } |
| |
| void afterAll() |
| { |
| } |