Printing: Create view PPD integration test
This test: - Sets up a server to serve PPDs - Manually creates a printer using the fake PPD - Views the PPD for the printer in the browser Bug: b/329704831, b/307385730 Include-Ci-Only-Tests: true Change-Id: Ie30c987499cf23435d4d97746f51f555164bf327 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5346169 Reviewed-by: Piotr Pawliczek <pawliczek@chromium.org> Commit-Queue: Gavin Williams <gavinwill@chromium.org> Reviewed-by: Michael Checo <michaelcheco@google.com> Cr-Commit-Position: refs/heads/main@{#1277853}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
31d068c455
commit
83a5b89d1b
chrome
browser
ui
webui
ash
settings
pages
printing
integration_tests
test
chromeos/ash/components/dbus/printscanmgr
293
chrome/browser/ui/webui/ash/settings/pages/printing/integration_tests/printer_settings_integration_test.cc
Normal file
293
chrome/browser/ui/webui/ash/settings/pages/printing/integration_tests/printer_settings_integration_test.cc
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
// Copyright 2024 The Chromium Authors
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "ash/constants/ash_switches.h"
|
||||||
|
#include "ash/webui/settings/public/constants/routes.mojom-forward.h"
|
||||||
|
#include "base/command_line.h"
|
||||||
|
#include "base/json/string_escape.h"
|
||||||
|
#include "base/strings/pattern.h"
|
||||||
|
#include "base/strings/strcat.h"
|
||||||
|
#include "chrome/browser/ash/login/test/session_manager_state_waiter.h"
|
||||||
|
#include "chrome/browser/profiles/profile.h"
|
||||||
|
#include "chrome/browser/ui/chrome_pages.h"
|
||||||
|
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
|
||||||
|
#include "chrome/test/base/chromeos/crosier/ash_integration_test.h"
|
||||||
|
#include "chrome/test/base/chromeos/crosier/chromeos_integration_login_mixin.h"
|
||||||
|
#include "chrome/test/interaction/interactive_browser_test.h"
|
||||||
|
#include "chromeos/ash/components/dbus/printscanmgr/fake_printscanmgr_client.h"
|
||||||
|
#include "chromeos/ash/components/dbus/printscanmgr/printscanmgr_client.h"
|
||||||
|
#include "net/test/embedded_test_server/embedded_test_server.h"
|
||||||
|
|
||||||
|
namespace ash {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr char kDefaultPpd[] = R"(
|
||||||
|
*PPD-Adobe: "4.3"
|
||||||
|
*FormatVersion: "4.3"
|
||||||
|
*FileVersion: "1.0"
|
||||||
|
*LanguageVersion: English
|
||||||
|
*LanguageEncoding: ISOLatin1
|
||||||
|
*PCFileName: "SAMPLE.PPD"
|
||||||
|
*Product: "Sample"
|
||||||
|
*PSVersion: "(1) 1"
|
||||||
|
*ModelName: "Sample"
|
||||||
|
*ShortNickName: "Sample"
|
||||||
|
*NickName: "Sample"
|
||||||
|
*Manufacturer: "Sample"
|
||||||
|
*OpenUI *PageSize: PickOne
|
||||||
|
*DefaultPageSize: A4
|
||||||
|
*PageSize A4/A4: "<</PageSize[595.20 841.68]>>setpagedevice"
|
||||||
|
*CloseUI: *PageSize
|
||||||
|
*OpenUI *PageRegion: PickOne
|
||||||
|
*DefaultPageRegion: A4
|
||||||
|
*PageRegion A4/A4: "<</PageRegion[595.20 841.68]>>setpagedevice"
|
||||||
|
*CloseUI: *PageRegion
|
||||||
|
*DefaultImageableArea: A4
|
||||||
|
*ImageableArea A4/A4: "8.40 8.40 586.80 833.28"
|
||||||
|
*DefaultPaperDimension: A4
|
||||||
|
*PaperDimension A4/A4: "595.20 841.68"
|
||||||
|
)";
|
||||||
|
|
||||||
|
constexpr int kPpdServerPortNumber = 7002;
|
||||||
|
|
||||||
|
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kSettingsWebContentsId);
|
||||||
|
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kChromeBrowserWebContentsId);
|
||||||
|
|
||||||
|
class PrinterSettingsIntegrationTest : public AshIntegrationTest {
|
||||||
|
public:
|
||||||
|
const DeepQuery kPrinterSettingsPage{
|
||||||
|
"os-settings-ui", "os-settings-main", "main-page-container",
|
||||||
|
"settings-device-page", "settings-cups-printers"};
|
||||||
|
|
||||||
|
const DeepQuery kAddManualPrinterButton =
|
||||||
|
kPrinterSettingsPage + "#addManualPrinterButton";
|
||||||
|
|
||||||
|
const DeepQuery kAddPrinterManuallyDialog = kPrinterSettingsPage +
|
||||||
|
"#addPrinterDialog" +
|
||||||
|
"add-printer-manually-dialog";
|
||||||
|
|
||||||
|
const DeepQuery kSavePrinterButton =
|
||||||
|
kAddPrinterManuallyDialog + "#addPrinterButton";
|
||||||
|
|
||||||
|
const DeepQuery kNameInputQuery =
|
||||||
|
kAddPrinterManuallyDialog + "#printerNameInput";
|
||||||
|
|
||||||
|
const DeepQuery kAddressInputQuery =
|
||||||
|
kAddPrinterManuallyDialog + "#printerAddressInput";
|
||||||
|
|
||||||
|
const DeepQuery kProtocolDropdownQuery = kAddPrinterManuallyDialog + "select";
|
||||||
|
|
||||||
|
const DeepQuery kManufacturerModelDialogQuery =
|
||||||
|
kPrinterSettingsPage + "#addPrinterDialog" +
|
||||||
|
"add-printer-manufacturer-model-dialog";
|
||||||
|
|
||||||
|
const DeepQuery kManufacturerDropdownQuery = kManufacturerModelDialogQuery +
|
||||||
|
"#manufacturerDropdown" +
|
||||||
|
"#search" + "#input";
|
||||||
|
|
||||||
|
const DeepQuery kBrotherManufacturerButtonQuery =
|
||||||
|
kManufacturerModelDialogQuery + "#manufacturerDropdown" +
|
||||||
|
"#dropdown > div > button";
|
||||||
|
|
||||||
|
const DeepQuery kModelDropdownQuery =
|
||||||
|
kManufacturerModelDialogQuery + "#modelDropdown" + "#search" + "#input";
|
||||||
|
|
||||||
|
const DeepQuery kBrotherPrinterButtonQuery = kManufacturerModelDialogQuery +
|
||||||
|
"#modelDropdown" +
|
||||||
|
"#dropdown > div > button";
|
||||||
|
|
||||||
|
const DeepQuery kAddPrinterButtonQuery =
|
||||||
|
kManufacturerModelDialogQuery + "#addPrinterButton";
|
||||||
|
|
||||||
|
const DeepQuery kMoreActionsButtonQuery =
|
||||||
|
kPrinterSettingsPage + "#savedPrinters" + "#frb0" + "#moreActions";
|
||||||
|
|
||||||
|
const DeepQuery kEditButtonQuery =
|
||||||
|
kPrinterSettingsPage + "#savedPrinters" + "#editButton";
|
||||||
|
|
||||||
|
const DeepQuery kViewPpdButtonQuery = kPrinterSettingsPage +
|
||||||
|
"#editPrinterDialog" +
|
||||||
|
"#ppdLabel > div > cr-button";
|
||||||
|
|
||||||
|
PrinterSettingsIntegrationTest() {
|
||||||
|
// Keep test running after dismissing login screen.
|
||||||
|
set_exit_when_last_browser_closes(false);
|
||||||
|
login_mixin().SetMode(ChromeOSIntegrationLoginMixin::Mode::kTestLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AshIntegrationTest:
|
||||||
|
void SetUp() override {
|
||||||
|
ASSERT_TRUE(
|
||||||
|
embedded_test_server()->InitializeAndListen(kPpdServerPortNumber));
|
||||||
|
embedded_test_server()->RegisterRequestHandler(
|
||||||
|
base::BindRepeating(&PrinterSettingsIntegrationTest::HandleRequest,
|
||||||
|
base::Unretained(this)));
|
||||||
|
embedded_test_server()->StartAcceptingConnections();
|
||||||
|
|
||||||
|
AshIntegrationTest::SetUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// AshIntegrationTest:
|
||||||
|
void SetUpCommandLine(base::CommandLine* command_line) override {
|
||||||
|
AshIntegrationTest::SetUpCommandLine(command_line);
|
||||||
|
command_line->AppendSwitchNative(ash::switches::kPrintingPpdChannel,
|
||||||
|
"localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<net::test_server::BasicHttpResponse> CreateHttpResponse(
|
||||||
|
std::string_view content) {
|
||||||
|
std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
|
||||||
|
new net::test_server::BasicHttpResponse);
|
||||||
|
http_response->set_code(net::HTTP_OK);
|
||||||
|
http_response->set_content_type("application/json");
|
||||||
|
http_response->set_content(content);
|
||||||
|
return http_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
|
||||||
|
const net::test_server::HttpRequest& request) {
|
||||||
|
const std::string request_path = request.GetURL().path();
|
||||||
|
std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
|
||||||
|
new net::test_server::BasicHttpResponse);
|
||||||
|
http_response->set_code(net::HTTP_OK);
|
||||||
|
http_response->set_content_type("application/json");
|
||||||
|
|
||||||
|
if (request_path == "/metadata_v3/locales.json") {
|
||||||
|
return CreateHttpResponse("{\"locales\":[\"en\"]}");
|
||||||
|
} else if (request_path == "/metadata_v3/manufacturers-en.json") {
|
||||||
|
return CreateHttpResponse(
|
||||||
|
"{\"filesMap\": {\"Brother\": \"Brother-en.json\"}}");
|
||||||
|
} else if (request_path == "/metadata_v3/Brother-en.json") {
|
||||||
|
return CreateHttpResponse(
|
||||||
|
"{\"printers\": [{\"name\": \"Brother Printer\",\"emm\": "
|
||||||
|
"\"brother-printer\"}]}");
|
||||||
|
} else if (base::MatchPattern(request_path, "/metadata_v3/index*.json")) {
|
||||||
|
return CreateHttpResponse(
|
||||||
|
"{\"ppdIndex\": {\"brother-printer\": {\"ppdMetadata\": [ {\"name\": "
|
||||||
|
"\"default-ppd.ppd\"}]}}}");
|
||||||
|
} else if (request_path == "/ppds_for_metadata_v3/default-ppd.ppd") {
|
||||||
|
return CreateHttpResponse(kDefaultPpd);
|
||||||
|
} else if (base::MatchPattern(request_path,
|
||||||
|
"/metadata_v3/reverse_index-en*.json")) {
|
||||||
|
return CreateHttpResponse(
|
||||||
|
"{\"locale\": \"en\", \"reverseIndex\": {\"brother-printer\": "
|
||||||
|
"{\"manufacturer\": \"Brother\", \"model\": \"Brother Printer\"}}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WaitForCrInputTextContains(
|
||||||
|
const ui::ElementIdentifier& element_id,
|
||||||
|
const WebContentsInteractionTestUtil::DeepQuery& query,
|
||||||
|
std::string_view expected) {
|
||||||
|
DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kInputTextFound);
|
||||||
|
|
||||||
|
WebContentsInteractionTestUtil::StateChange state_change;
|
||||||
|
state_change.type = WebContentsInteractionTestUtil::StateChange::Type::
|
||||||
|
kExistsAndConditionTrue;
|
||||||
|
state_change.where = query;
|
||||||
|
state_change.test_function =
|
||||||
|
base::StrCat({"function(el) { return el.value.indexOf(",
|
||||||
|
base::GetQuotedJSONString(expected), ") >= 0; }"});
|
||||||
|
state_change.event = kInputTextFound;
|
||||||
|
return WaitForStateChange(element_id, state_change);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto LaunchOsPrinterSettings() {
|
||||||
|
return Steps(
|
||||||
|
InstrumentNextTab(kSettingsWebContentsId, AnyBrowser()), Do([&]() {
|
||||||
|
chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
|
||||||
|
GetActiveUserProfile(),
|
||||||
|
chromeos::settings::mojom::kPrintingDetailsSubpagePath);
|
||||||
|
}),
|
||||||
|
WaitForShow(kSettingsWebContentsId),
|
||||||
|
WaitForWebContentsReady(
|
||||||
|
kSettingsWebContentsId,
|
||||||
|
chrome::GetOSSettingsUrl(
|
||||||
|
chromeos::settings::mojom::kPrintingDetailsSubpagePath)));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AddPrinterManually(std::string_view printer_name) {
|
||||||
|
return Steps(
|
||||||
|
Log("Opening the add printer dialog"),
|
||||||
|
ClickElement(kSettingsWebContentsId, kAddManualPrinterButton),
|
||||||
|
Log("Inserting the printer name"),
|
||||||
|
ExecuteJsAt(
|
||||||
|
kSettingsWebContentsId, kNameInputQuery,
|
||||||
|
base::StrCat({"(el) => { el.value = '", printer_name, "'; }"})),
|
||||||
|
WaitForCrInputTextContains(kSettingsWebContentsId, kNameInputQuery,
|
||||||
|
printer_name),
|
||||||
|
Log("Inserting the address"),
|
||||||
|
ExecuteJsAt(kSettingsWebContentsId, kAddressInputQuery,
|
||||||
|
"(el) => { el.value = 'address'; }"),
|
||||||
|
WaitForCrInputTextContains(kSettingsWebContentsId, kAddressInputQuery,
|
||||||
|
"address"),
|
||||||
|
Log("Updating the protocol"),
|
||||||
|
ExecuteJsAt(kSettingsWebContentsId, kProtocolDropdownQuery,
|
||||||
|
"(el) => {el.selectedIndex = 4; el.dispatchEvent(new "
|
||||||
|
"Event('change'));}"),
|
||||||
|
Log("Click the save button"),
|
||||||
|
ClickElement(kSettingsWebContentsId, kSavePrinterButton),
|
||||||
|
Log("Adding the manufacturer"),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId,
|
||||||
|
kManufacturerDropdownQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kManufacturerDropdownQuery),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId,
|
||||||
|
kBrotherManufacturerButtonQuery),
|
||||||
|
WaitForElementToRender(kSettingsWebContentsId,
|
||||||
|
kBrotherManufacturerButtonQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kBrotherManufacturerButtonQuery),
|
||||||
|
Log("Adding the model"),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId, kModelDropdownQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kModelDropdownQuery),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId,
|
||||||
|
kBrotherPrinterButtonQuery),
|
||||||
|
WaitForElementToRender(kSettingsWebContentsId,
|
||||||
|
kBrotherPrinterButtonQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kBrotherPrinterButtonQuery),
|
||||||
|
Log("Saving the printer"),
|
||||||
|
ClickElement(kSettingsWebContentsId, kAddPrinterButtonQuery));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IN_PROC_BROWSER_TEST_F(PrinterSettingsIntegrationTest, ViewPpd) {
|
||||||
|
SetupContextWidget();
|
||||||
|
|
||||||
|
login_mixin().Login();
|
||||||
|
|
||||||
|
// Waits for the primary user session to start.
|
||||||
|
ash::test::WaitForPrimaryUserSessionStart();
|
||||||
|
|
||||||
|
InstallSystemApps();
|
||||||
|
|
||||||
|
// Set fake data for clicking "View PPD" to return.
|
||||||
|
PrintscanmgrClient::InitializeFakeForTest();
|
||||||
|
|
||||||
|
RunTestSequence(
|
||||||
|
Log("Launching printer settings"), LaunchOsPrinterSettings(),
|
||||||
|
AddPrinterManually("First Printer"),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId, kMoreActionsButtonQuery),
|
||||||
|
Log("Opening the edit dialog"),
|
||||||
|
WaitForElementToRender(kSettingsWebContentsId, kMoreActionsButtonQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kMoreActionsButtonQuery),
|
||||||
|
WaitForElementToRender(kSettingsWebContentsId, kEditButtonQuery),
|
||||||
|
ClickElement(kSettingsWebContentsId, kEditButtonQuery),
|
||||||
|
WaitForElementExists(kSettingsWebContentsId, kViewPpdButtonQuery),
|
||||||
|
Log("Clicking the View PPD button"),
|
||||||
|
ScrollIntoView(kSettingsWebContentsId, kViewPpdButtonQuery),
|
||||||
|
InstrumentNextTab(kChromeBrowserWebContentsId, AnyBrowser()),
|
||||||
|
ClickElement(kSettingsWebContentsId, kViewPpdButtonQuery),
|
||||||
|
Log("Verifying the PPD contents"),
|
||||||
|
WaitForShow(kChromeBrowserWebContentsId),
|
||||||
|
CheckJsResult(kChromeBrowserWebContentsId,
|
||||||
|
"() => document.body.textContent", kDefaultPpd));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace ash
|
@@ -1142,6 +1142,7 @@ if (is_chromeos && is_chromeos_device) {
|
|||||||
"../browser/ash/web_handwriting_integration_test.cc",
|
"../browser/ash/web_handwriting_integration_test.cc",
|
||||||
"../browser/ui/ash/quick_settings_integration_test.cc",
|
"../browser/ui/ash/quick_settings_integration_test.cc",
|
||||||
"../browser/ui/ash/shelf/shelf_integration_test.cc",
|
"../browser/ui/ash/shelf/shelf_integration_test.cc",
|
||||||
|
"../browser/ui/webui/ash/settings/pages/printing/integration_tests/printer_settings_integration_test.cc",
|
||||||
"base/chromeos/crosier/helper/test_sudo_helper_client_test.cc",
|
"base/chromeos/crosier/helper/test_sudo_helper_client_test.cc",
|
||||||
"base/chromeos/crosier/upstart_test.cc",
|
"base/chromeos/crosier/upstart_test.cc",
|
||||||
|
|
||||||
@@ -1172,10 +1173,12 @@ if (is_chromeos && is_chromeos_device) {
|
|||||||
"//chrome/browser/ash:test_support",
|
"//chrome/browser/ash:test_support",
|
||||||
"//chrome/test/base/chromeos/crosier:proto",
|
"//chrome/test/base/chromeos/crosier:proto",
|
||||||
"//chrome/test/base/chromeos/crosier/helper:common",
|
"//chrome/test/base/chromeos/crosier/helper:common",
|
||||||
|
"//chromeos/ash/components/dbus/printscanmgr:printscanmgr",
|
||||||
"//chromeos/ash/components/standalone_browser",
|
"//chromeos/ash/components/standalone_browser",
|
||||||
"//chromeos/ash/components/standalone_browser:test_support",
|
"//chromeos/ash/components/standalone_browser:test_support",
|
||||||
"//chromeos/ash/services/assistant/public/cpp",
|
"//chromeos/ash/services/assistant/public/cpp",
|
||||||
"//chromeos/services/machine_learning/public/cpp",
|
"//chromeos/services/machine_learning/public/cpp",
|
||||||
|
"//ui/events:test_support",
|
||||||
]
|
]
|
||||||
|
|
||||||
data_deps += [
|
data_deps += [
|
||||||
|
@@ -253,6 +253,12 @@ void PrintscanmgrClient::InitializeFake() {
|
|||||||
g_instance->Init(nullptr);
|
g_instance->Init(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void PrintscanmgrClient::InitializeFakeForTest() {
|
||||||
|
g_instance = new FakePrintscanmgrClient();
|
||||||
|
g_instance->Init(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void PrintscanmgrClient::Shutdown() {
|
void PrintscanmgrClient::Shutdown() {
|
||||||
CHECK(g_instance);
|
CHECK(g_instance);
|
||||||
|
@@ -27,6 +27,10 @@ class COMPONENT_EXPORT(PRINTSCANMGR) PrintscanmgrClient
|
|||||||
// Creates and initializes a fake global instance.
|
// Creates and initializes a fake global instance.
|
||||||
static void InitializeFake();
|
static void InitializeFake();
|
||||||
|
|
||||||
|
// Creates and overrides any existing instance with a fake global instance for
|
||||||
|
// tests.
|
||||||
|
static void InitializeFakeForTest();
|
||||||
|
|
||||||
// Destroys the global instance if it has been initialized.
|
// Destroys the global instance if it has been initialized.
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user