blob: 57beb41621409f3675e9a4f70b7db0c286283b3b [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('invalid_settings_browsertest', function() {
/** @enum {string} */
const TestNames = {
NoPDFPluginError: 'no pdf plugin error',
InvalidSettingsError: 'invalid settings error',
InvalidCertificateError: 'invalid certificate error',
InvalidCertificateErrorReselectDestination: 'invalid certificate reselect',
};
const suiteName = 'InvalidSettingsBrowserTest';
suite(suiteName, function() {
/** @type {?PrintPreviewAppElement} */
let page = null;
/** @type {?print_preview.NativeLayer} */
let nativeLayer = null;
/** @type {?cloudprint.CloudPrintInterface} */
let cloudPrintInterface = null;
/** @type {!print_preview.NativeInitialSettings} */
const initialSettings = {
isInKioskAutoPrintMode: false,
isInAppKioskMode: false,
thousandsDelimiter: ',',
decimalDelimiter: '.',
unitType: 1,
previewModifiable: true,
documentTitle: 'title',
documentHasSelection: true,
shouldPrintSelectionOnly: false,
printerName: 'FooDevice',
serializedAppStateStr: null,
serializedDefaultDestinationSelectionRulesStr: null
};
/** @type {!Array<!print_preview.LocalDestinationInfo>} */
let localDestinationInfos = [
{printerName: 'FooName', deviceName: 'FooDevice'},
{printerName: 'BarName', deviceName: 'BarDevice'},
];
/** @override */
setup(function() {
nativeLayer = new print_preview.NativeLayerStub();
print_preview.NativeLayer.setInstance(nativeLayer);
cloudPrintInterface = new print_preview.CloudPrintInterfaceStub();
cloudprint.setCloudPrintInterfaceForTesting(cloudPrintInterface);
PolymerTest.clearBody();
});
/**
* Initializes the page with initial settings and local destinations
* given by |initialSettings| and |localDestinationInfos|. Also creates
* the fake plugin. Moved out of setup so tests can set those parameters
* differently.
* @param {boolean} pluginCompatible Whether the plugin should be set to
* appear compatible.
*/
function createPage(pluginCompatible) {
nativeLayer.setInitialSettings(initialSettings);
nativeLayer.setLocalDestinations(localDestinationInfos);
if (initialSettings.printerName) {
nativeLayer.setLocalDestinationCapabilities(
print_preview_test_utils.getCddTemplate(
initialSettings.printerName));
}
const pluginProxy = new print_preview.PDFPluginStub();
pluginProxy.setPluginCompatible(pluginCompatible);
print_preview.PluginProxy.setInstance(pluginProxy);
page = document.createElement('print-preview-app');
document.body.appendChild(page);
page.$.documentInfo.init(true, 'title', false);
const previewArea = page.$.previewArea;
}
/**
* Performs some setup for invalid certificate tests using 2 destinations
* in |printers|. printers[0] will be set as the most recent destination,
* and printers[1] will be the second most recent destination. Sets up
* cloud print interface, user info, and runs createPage().
* @param {!Array<!print_preview.Destination>} printers
*/
function setupInvalidCertificateTest(printers) {
initialSettings.printerName = '';
initialSettings.serializedAppStateStr = JSON.stringify({
version: 2,
recentDestinations: [
print_preview.makeRecentDestination(printers[0]),
print_preview.makeRecentDestination(printers[1]),
],
});
initialSettings.cloudPrintURL = 'cloudprint URL';
initialSettings.userAccounts = [printers[0].account];
localDestinationInfos = [];
loadTimeData.overrideValues({isEnterpriseManaged: false});
createPage(true);
printers.forEach(printer => cloudPrintInterface.setPrinter(printer));
}
// Test that error message is displayed when plugin doesn't exist.
// TODO (rbpotter): Fix this test so that it works again with calling
// appendChild() before setting checkPluginCompatibility.
test(assert(TestNames.NoPDFPluginError), function() {
createPage(false);
const previewArea = page.$.previewArea;
return nativeLayer.whenCalled('getInitialSettings').then(function() {
const overlayEl = previewArea.$$('.preview-area-overlay-layer');
const messageEl = previewArea.$$('.preview-area-message');
assertEquals(print_preview.State.FATAL_ERROR, page.state);
// Make sure the overlay is visible.
assertFalse(overlayEl.classList.contains('invisible'));
// Make sure the correct text is shown.
const expectedMessageChromium = 'Chromium cannot show the print ' +
'preview when the built-in PDF viewer is missing.';
const expectedMessageChrome = 'Google Chrome cannot show the print ' +
'preview when the built-in PDF viewer is missing.';
assertTrue(
messageEl.textContent.includes(expectedMessageChromium) ||
messageEl.textContent.includes(expectedMessageChrome));
});
});
// Tests that when a printer cannot be communicated with correctly the
// preview area displays an invalid printer error message and printing
// is disabled. Verifies that the user can recover from this error by
// selecting a different, valid printer.
test(assert(TestNames.InvalidSettingsError), function() {
createPage(true);
const barDevice = print_preview_test_utils.getCddTemplate('BarDevice');
nativeLayer.setLocalDestinationCapabilities(barDevice);
// FooDevice is the default printer, so will be selected for the initial
// preview request.
nativeLayer.setInvalidPrinterId('FooDevice');
// Expected message
const expectedMessage = 'The selected printer is not available or not ' +
'installed correctly. Check your printer or try selecting another ' +
'printer.';
// Get references to relevant elements.
const previewAreaEl = page.$.previewArea;
const overlay = previewAreaEl.$$('.preview-area-overlay-layer');
const messageEl = previewAreaEl.$$('.preview-area-message');
const sidebar = page.$$('print-preview-sidebar');
let printButton = null;
const destinationSettings =
sidebar.$$('print-preview-destination-settings');
return test_util.waitBeforeNextRender(page)
.then(() => {
const parentElement =
loadTimeData.getBoolean('newPrintPreviewLayoutEnabled') ?
sidebar.$$('print-preview-button-strip') :
sidebar.$$('print-preview-header');
printButton = parentElement.$$('.action-button');
return Promise.all([
print_preview.Model.whenReady(),
nativeLayer.whenCalled('getInitialSettings'),
]);
})
.then(function() {
destinationSettings.destinationStore_.startLoadAllDestinations();
// Wait for the preview request.
return Promise.all([
nativeLayer.whenCalled('getPrinterCapabilities'),
nativeLayer.whenCalled('getPreview')
]);
})
.then(function() {
// Print preview should have failed with invalid settings, since
// FooDevice was set as an invalid printer.
assertFalse(overlay.classList.contains('invisible'));
assertTrue(messageEl.textContent.includes(expectedMessage));
assertEquals(print_preview.State.ERROR, page.state);
// Verify that the print button is disabled
assertTrue(printButton.disabled);
// Select should still be enabled so that the user can select a new
// printer.
assertFalse(destinationSettings.$.destinationSelect.disabled);
// Reset
nativeLayer.reset();
// Select a new destination
const barDestination =
destinationSettings.destinationStore_.destinations().find(
d => d.id == 'BarDevice');
destinationSettings.destinationStore_.selectDestination(
barDestination);
// Wait for the preview to be updated.
return nativeLayer.whenCalled('getPreview');
})
.then(function() {
// Message should be gone.
assertTrue(overlay.classList.contains('invisible'));
assertFalse(messageEl.textContent.includes(expectedMessage));
// Has active print button and successfully 'prints', indicating
assertFalse(printButton.disabled);
assertEquals(print_preview.State.READY, page.state);
printButton.click();
// This should result in a call to print.
return nativeLayer.whenCalled('print');
})
.then(
/**
* @param {string} printTicket The print ticket print() was
* called for.
*/
function(printTicket) {
// Sanity check some printing argument values.
const ticket = JSON.parse(printTicket);
assertEquals(barDevice.printer.deviceName, ticket.deviceName);
assertEquals(
print_preview_test_utils.getDefaultOrientation(barDevice) ==
'LANDSCAPE',
ticket.landscape);
assertEquals(1, ticket.copies);
const mediaDefault =
print_preview_test_utils.getDefaultMediaSize(barDevice);
assertEquals(
mediaDefault.width_microns, ticket.mediaSize.width_microns);
assertEquals(
mediaDefault.height_microns,
ticket.mediaSize.height_microns);
return nativeLayer.whenCalled('dialogClose');
});
});
// Test that GCP invalid certificate printers disable the print preview when
// selected and display an error and that the preview dialog can be
// recovered by selecting a new destination. Verifies this works when the
// invalid printer is the most recent destination and is selected by
// default.
test(assert(TestNames.InvalidCertificateError), function() {
const invalidPrinter =
print_preview_test_utils.createDestinationWithCertificateStatus(
'FooDevice', 'FooName', true);
const validPrinter =
print_preview_test_utils.createDestinationWithCertificateStatus(
'BarDevice', 'BarName', false);
setupInvalidCertificateTest([invalidPrinter, validPrinter]);
// Expected message
const expectedMessageStart = 'The selected Google Cloud Print device ' +
'is no longer supported.';
const expectedMessageEnd = 'Try setting up the printer in your ' +
'computer\'s system settings.';
// Get references to relevant elements.
const previewAreaEl = page.$.previewArea;
const overlayEl = previewAreaEl.$$('.preview-area-overlay-layer');
const messageEl = previewAreaEl.$$('.preview-area-message');
const sidebar = page.$$('print-preview-sidebar');
let printButton = null;
const destinationSettings =
sidebar.$$('print-preview-destination-settings');
const scalingSettings = sidebar.$$('print-preview-scaling-settings')
.$$('print-preview-number-settings-section');
const layoutSettings = sidebar.$$('print-preview-layout-settings');
return test_util.waitBeforeNextRender(page)
.then(() => {
const parentElement =
loadTimeData.getBoolean('newPrintPreviewLayoutEnabled') ?
sidebar.$$('print-preview-button-strip') :
sidebar.$$('print-preview-header');
printButton = parentElement.$$('.action-button');
return Promise.all([
print_preview.Model.whenReady(),
nativeLayer.whenCalled('getInitialSettings'),
]);
})
.then(function() {
// Set this to enable the scaling input.
page.setSetting('customScaling', true);
destinationSettings.destinationStore_.startLoadCloudDestinations();
// FooDevice will be selected since it is the most recently used
// printer, so the invalid certificate error should be shown.
// The overlay must be visible for the message to be seen.
assertFalse(overlayEl.classList.contains('invisible'));
// Verify that the correct message is shown.
assertTrue(messageEl.textContent.includes(expectedMessageStart));
assertTrue(messageEl.textContent.includes(expectedMessageEnd));
// Verify that the print button is disabled
assertTrue(printButton.disabled);
// Verify the state is invalid and that some settings sections are
// also disabled, so there is no way to regenerate the preview.
assertEquals(print_preview.State.ERROR, page.state);
assertTrue(layoutSettings.$$('select').disabled);
assertTrue(scalingSettings.$$('cr-input').disabled);
// The destination select dropdown should be enabled, so that the
// user can select a new printer.
assertFalse(destinationSettings.$.destinationSelect.disabled);
// Reset
nativeLayer.reset();
// Select a new, valid cloud destination.
destinationSettings.destinationStore_.selectDestination(
validPrinter);
return nativeLayer.whenCalled('getPreview');
})
.then(function() {
// Has active print button, indicating recovery from error state.
assertFalse(printButton.disabled);
assertEquals(print_preview.State.READY, page.state);
// Settings sections are now active.
assertFalse(layoutSettings.$$('select').disabled);
assertFalse(scalingSettings.$$('cr-input').disabled);
// The destination select dropdown should still be enabled.
assertFalse(destinationSettings.$.destinationSelect.disabled);
// Message text should have changed and overlay should be
// invisible.
assertFalse(messageEl.textContent.includes(expectedMessageStart));
assertTrue(overlayEl.classList.contains('invisible'));
});
});
// Test that GCP invalid certificate printers disable the print preview when
// selected and display an error and that the preview dialog can be
// recovered by selecting a new destination. Tests that even if destination
// was previously selected, the error is cleared.
test(
assert(TestNames.InvalidCertificateErrorReselectDestination),
function() {
const invalidPrinter =
print_preview_test_utils.createDestinationWithCertificateStatus(
'FooDevice', 'FooName', true);
const validPrinter =
print_preview_test_utils.createDestinationWithCertificateStatus(
'BarDevice', 'BarName', false);
setupInvalidCertificateTest([validPrinter, invalidPrinter]);
// Get references to relevant elements.
const previewAreaEl = page.$.previewArea;
const overlayEl = previewAreaEl.$$('.preview-area-overlay-layer');
const messageEl = previewAreaEl.$$('.preview-area-message');
const sidebar = page.$$('print-preview-sidebar');
let printButton = null;
const destinationSettings =
sidebar.$$('print-preview-destination-settings');
return test_util.waitBeforeNextRender(page)
.then(() => {
const parentElement =
loadTimeData.getBoolean('newPrintPreviewLayoutEnabled') ?
sidebar.$$('print-preview-button-strip') :
sidebar.$$('print-preview-header');
printButton = parentElement.$$('.action-button');
return Promise.all([
print_preview.Model.whenReady(),
nativeLayer.whenCalled('getInitialSettings'),
]);
})
.then(function() {
// Start loading cloud destinations so that the printer
// capabilities arrive.
destinationSettings.destinationStore_
.startLoadCloudDestinations();
return nativeLayer.whenCalled('getPreview');
})
.then(function() {
// Has active print button.
assertFalse(printButton.disabled);
assertEquals(print_preview.State.READY, page.state);
// No error message.
assertTrue(overlayEl.classList.contains('invisible'));
// Select the invalid destination and wait for the event.
const whenInvalid = test_util.eventToPromise(
print_preview.DestinationStore.EventType.ERROR,
destinationSettings.destinationStore_);
destinationSettings.destinationStore_.selectDestination(
invalidPrinter);
return whenInvalid;
})
.then(function() {
// Should have error message.
assertFalse(overlayEl.classList.contains('invisible'));
assertEquals(print_preview.State.ERROR, page.state);
// Reset
nativeLayer.reset();
// Reselect the valid cloud destination.
const whenSelected = test_util.eventToPromise(
print_preview.DestinationStore.EventType.DESTINATION_SELECT,
destinationSettings.destinationStore_);
destinationSettings.destinationStore_.selectDestination(
validPrinter);
return whenSelected;
})
.then(function() {
// Has active print button and no error message.
assertFalse(printButton.disabled);
assertTrue(overlayEl.classList.contains('invisible'));
});
});
});
return {
suiteName: suiteName,
TestNames: TestNames,
};
});