Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9237)

Unified Diff: chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js

Issue 2157673002: Browser tests for the quick_unlock settings pages. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pin-unlock-quick-unlock-interface
Patch Set: Address comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/test/data/webui/settings/fake_quick_unlock_private.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
diff --git a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
new file mode 100644
index 0000000000000000000000000000000000000000..0a2f1f3276267a0cd47befecf6c251aede9a6c6f
--- /dev/null
+++ b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
@@ -0,0 +1,456 @@
+// Copyright 2016 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('settings_people_page_quick_unlock', function() {
+ var element = null;
+ var quickUnlockPrivateApi = null;
+ var QuickUnlockMode = chrome.quickUnlockPrivate.QuickUnlockMode;
+
+ /**
+ * Returns if the element is visible.
+ * @param {!Element} element
+ */
+ function isVisible(element) {
+ while (element) {
+ if (element.offsetWidth <= 0 || element.offsetHeight <= 0 ||
+ element.hidden) {
+ return false;
+ }
+
+ element = element.parentElement;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns true if the given |element| has class |className|.
+ * @param {!Element} element
+ * @param {string} className
+ */
+ function assertHasClass(element, className) {
+ assertTrue(element.classList.contains(className));
+ }
+
+ /**
+ * Returns the result of running |selector| on element.
+ * @param {string} selector
+ * @return {Element}
+ */
+ function getFromElement(selector) {
+ var childElement = element.$$(selector);
+ assertTrue(!!childElement);
+ return childElement;
+ }
+
+ /**
+ * Sets the active quick unlock modes and raises a mode change event.
+ * @param {!Array<chrome.quickUnlockPrivate.QuickUnlockMode>} modes
+ */
+ function setActiveModes(modes) {
+ quickUnlockPrivateApi.activeModes = modes;
+ quickUnlockPrivateApi.onActiveModesChanged.callListeners(modes);
+ }
+
+ function registerAuthenticateTests() {
+ suite('authenticate', function() {
+ var passwordElement = null;
+
+ setup(function() {
+ PolymerTest.clearBody();
+
+ quickUnlockPrivateApi = new settings.FakeQuickUnlockPrivate();
+
+ element = document.createElement('settings-password-prompt-dialog');
+ element.quickUnlockPrivate_ = quickUnlockPrivateApi;
+ document.body.appendChild(element);
+
+ passwordElement = getFromElement('#passwordInput');
+ });
+
+ test('PasswordCheckDoesNotChangeActiveMode', function() {
+ // No active modes.
+ quickUnlockPrivateApi.activeModes = [];
+ passwordElement.value = 'foo';
+ element.submitPassword_();
+ assertDeepEquals([], quickUnlockPrivateApi.activeModes);
+ assertDeepEquals([], quickUnlockPrivateApi.credentials);
+
+ // PIN is active.
+ quickUnlockPrivateApi.activeModes = [QuickUnlockMode.PIN];
+ passwordElement.value = 'foo';
+ element.submitPassword_();
+ assertDeepEquals([QuickUnlockMode.PIN],
+ quickUnlockPrivateApi.activeModes);
+ assertDeepEquals([''], quickUnlockPrivateApi.credentials);
+ });
+
+ // A bad password does not provide an authenticated setModes object.
+ test('InvalidPasswordDoesNotProvideAuthentication', function() {
+ quickUnlockPrivateApi.accountPassword = 'bar';
+
+ passwordElement.value = 'foo';
+ element.submitPassword_();
+
+ assertFalse(!!element.setModes);
+ });
+
+ // A valid password provides an authenticated setModes object.
+ test('ValidPasswordProvidesAuthentication', function() {
+ quickUnlockPrivateApi.accountPassword = 'foo';
+
+ passwordElement.value = 'foo';
+ element.submitPassword_();
+
+ assertTrue(!!element.setModes);
+ });
+
+ // The setModes objects times out after a delay.
+ test('AuthenticationTimesOut', function(done) {
+ quickUnlockPrivateApi.accountPassword = 'foo';
+
+ element.passwordActiveDurationMs_ = 0;
+ passwordElement.value = 'foo';
+ element.submitPassword_();
+
+ assertFalse(!!element.password_);
+ assertTrue(!!element.setModes);
+
+ // Two setTimeout calls with the same delay are guaranteed to execute in
+ // the same order that they were submitted in, so using
+ // element.autosubmitDelayMs_ is safe.
+ setTimeout(function() {
+ assertFalse(!!element.password_);
+ assertFalse(!!element.setModes);
+ done();
+ }, element.passwordActiveDurationMs_);
+ });
+ });
+ }
+
+ function registerLockScreenTests() {
+ suite('lock-screen', function() {
+ /** @const */ var ENABLE_LOCK_SCREEN_PREF = 'settings.enable_screen_lock';
+
+ var fakeSettings = null;
+ var passwordRadioButton = null;
+ var pinPasswordRadioButton = null;
+ var noneRadioButton = null;
+ var configureButton = null;
+
+ /**
+ * Asserts that only the given radio button is active and all of the
+ * others are inactive.
+ * @param {Element} radioButton
+ */
+ function assertRadioButtonActive(radioButton) {
+ function doAssert(element, name) {
+ if (radioButton == element)
+ assertTrue(element.active, 'Expected ' + name + ' to be active');
+ else
+ assertFalse(element.active, 'Expected ' + name + ' to be inactive');
+ }
+
+ doAssert(passwordRadioButton, 'passwordButton');
+ doAssert(pinPasswordRadioButton, 'pinPasswordButton');
+ }
+
+ /**
+ * Returns the lock screen pref value.
+ * @return {boolean}
+ */
+ function getLockScreenPref() {
+ var result;
+ fakeSettings.getPref(ENABLE_LOCK_SCREEN_PREF, function(value) {
+ result = value;
+ });
+ assertNotEquals(undefined, result);
+ return result.value;
+ }
+
+ /**
+ * Changes the lock screen pref value using the settings API; this is like
+ * the pref got changed from an unkown source such as another tab.
+ * @param {boolean} value
+ */
+ function setLockScreenPref(value) {
+ fakeSettings.setPref(ENABLE_LOCK_SCREEN_PREF, value, '', assertTrue);
+ }
+
+ suiteSetup(function() {
+ var urls = [
+ 'chrome://md-settings/i18n_setup.html',
+ 'chrome://md-settings/prefs/prefs.html',
+ ];
+ return Promise.all(urls.map(PolymerTest.importHtml));
+ });
+
+ setup(function(done) {
+ PolymerTest.clearBody();
+
+ CrSettingsPrefs.deferInitialization = true;
+
+ // Build pref fakes.
+ var fakePrefs = [{
+ key: ENABLE_LOCK_SCREEN_PREF,
+ type: chrome.settingsPrivate.PrefType.BOOLEAN,
+ value: true
+ }];
+ fakeSettings = new settings.FakeSettingsPrivate(fakePrefs);
+ setLockScreenPref(true);
+ var prefElement = document.createElement('settings-prefs');
+ prefElement.initialize(fakeSettings);
+ document.body.appendChild(prefElement);
+
+ // Wait for prefElement to finish initializing; it takes some time for
+ // the prefs element to get allocated.
+ prefElement.addEventListener('prefs-changed', function prefsReady() {
+ prefElement.removeEventListener('prefs-changed', prefsReady);
+
+ quickUnlockPrivateApi = new settings.FakeQuickUnlockPrivate();
+
+ // Create choose-method element.
+ element = document.createElement('settings-lock-screen');
+ element.settingsPrivate_ = fakeSettings;
+ element.quickUnlockPrivate_ = quickUnlockPrivateApi;
+ element.prefs = prefElement.prefs;
+
+ document.body.appendChild(element);
+ Polymer.dom.flush();
+
+ element.setModes_ =
+ quickUnlockPrivateApi.setModes.bind(quickUnlockPrivateApi, '');
+
+ passwordRadioButton =
+ getFromElement('paper-radio-button[name="password"]');
+ pinPasswordRadioButton =
+ getFromElement('paper-radio-button[name="pin+password"]');
+ configureButton = getFromElement('paper-button');
+
+ done();
+ });
+ });
+
+ // Showing the choose method screen does not make any destructive pref or
+ // quickUnlockPrivate calls.
+ test('ShowingScreenDoesNotModifyPrefs', function() {
+ assertTrue(getLockScreenPref());
+ assertRadioButtonActive(passwordRadioButton);
+ assertDeepEquals([], quickUnlockPrivateApi.activeModes);
+ });
+
+ // The various radio buttons update internal state and do not modify
+ // prefs.
+ test('TappingButtonsChangesUnderlyingState', function() {
+ function togglePin() {
+ assertRadioButtonActive(passwordRadioButton);
+
+ // Tap pin+password button.
+ MockInteractions.tap(pinPasswordRadioButton);
+ assertRadioButtonActive(pinPasswordRadioButton);
+ assertTrue(isVisible(configureButton));
+ assertDeepEquals([], quickUnlockPrivateApi.activeModes);
+
+ // Enable quick unlock so that we verify tapping password disables it.
+ setActiveModes([QuickUnlockMode.PIN]);
+
+ // Tap password button and verify quick unlock is disabled.
+ MockInteractions.tap(passwordRadioButton);
+ assertRadioButtonActive(passwordRadioButton);
+ assertFalse(isVisible(configureButton));
+ assertDeepEquals([], quickUnlockPrivateApi.activeModes);
+ }
+
+ // Verify toggling PIN on/off does not disable screen lock.
+ setLockScreenPref(true);
+ togglePin();
+ assertTrue(getLockScreenPref());
+
+ // Verify toggling PIN on/off does not enable screen lock.
+ setLockScreenPref(false);
+ togglePin();
+ assertFalse(getLockScreenPref());
+ });
+
+ // If quick unlock is changed by another settings page the radio button
+ // will update to show quick unlock is active.
+ test('EnablingQuickUnlockChangesButtonState', function() {
+ setActiveModes([QuickUnlockMode.PIN]);
+ assertRadioButtonActive(pinPasswordRadioButton);
+ assertTrue(isVisible(configureButton));
+
+ setActiveModes([]);
+ assertRadioButtonActive(passwordRadioButton);
+ assertDeepEquals([], quickUnlockPrivateApi.activeModes);
+ });
+
+ // Tapping the PIN configure button opens up the setup PIN dialog.
+ test('TappingConfigureOpensSetupPin', function() {
+ assertRadioButtonActive(passwordRadioButton);
+
+ MockInteractions.tap(pinPasswordRadioButton);
+ assertTrue(isVisible(configureButton));
+ assertRadioButtonActive(pinPasswordRadioButton)
+
+ MockInteractions.tap(configureButton);
+ var setupPinDialog = getFromElement('#setupPin');
+ assertTrue(setupPinDialog.$.dialog.open);
+ });
+ });
+ }
+
+ function registerSetupPinDialogTests() {
+ suite('setup-pin-dialog', function() {
+ var titleDiv = null;
+ var problemDiv = null;
+ var pinKeyboard = null;
+ var backButton = null;
+ var continueButton = null;
+
+ suiteSetup(function() {
+ var urls = ['chrome://md-settings/i18n_setup.html'];
+ return Promise.all(urls.map(PolymerTest.importHtml));
+ });
+
+ setup(function() {
+ PolymerTest.clearBody();
+
+ quickUnlockPrivateApi = new settings.FakeQuickUnlockPrivate();
+
+ // Create setup-pin element.
+ element = document.createElement('settings-setup-pin-dialog');
+ element.setModes =
+ quickUnlockPrivateApi.setModes.bind(quickUnlockPrivateApi, '');
+
+ document.body.appendChild(element);
+ Polymer.dom.flush();
+
+ element.open();
+
+ titleDiv = getFromElement('div[class="title"]');
+ problemDiv = getFromElement('#problemDiv');
+ pinKeyboard = getFromElement('pin-keyboard');
+ backButton = getFromElement('paper-button[class="cancel-button"]');
+ continueButton = getFromElement('paper-button[class="action-button"]');
+
+ assertTrue(isVisible(backButton));
+ assertTrue(isVisible(continueButton));
+ });
+
+ // The continue button and title change text between the setup and confirm
+ // steps.
+ test('TextChangesBetweenSetupAndConfirmStep', function() {
+ var initialContinue = continueButton.textContent;
+ var initialTitle = titleDiv.textContent;
+
+ pinKeyboard.value = '1111';
+ MockInteractions.tap(continueButton);
+
+ assertNotEquals(initialContinue, continueButton.textContent);
+ assertNotEquals(initialTitle, titleDiv.textContent);
+ });
+
+ // The continue button is disabled unless the user has entered a >= 4
+ // digit PIN.
+ test('CanOnlyContinueAfterEnteringAtLeastFourDigitPin', function() {
+ pinKeyboard.value = '111';
+ assertTrue(continueButton.disabled);
+
+ pinKeyboard.value = '1111';
+ assertFalse(continueButton.disabled);
+
+ pinKeyboard.value = '111';
+ assertTrue(continueButton.disabled);
+
+ pinKeyboard.value = '';
+ assertTrue(continueButton.disabled);
+
+ pinKeyboard.value = '1111111';
+ assertFalse(continueButton.disabled);
+ });
+
+ // Problem messages are hidden if the PIN is cleared.
+ test('NoProblemShownWithEmptyPin', function() {
+ pinKeyboard.value = '11';
+ assertTrue(isVisible(problemDiv));
+
+ pinKeyboard.value = '';
+ assertFalse(isVisible(problemDiv));
+ });
+
+ // If the PIN is too short an error problem is shown.
+ test('ErrorShownForShortPins', function() {
+ assertFalse(isVisible(problemDiv));
+
+ pinKeyboard.value = '11';
+
+ assertTrue(isVisible(problemDiv));
+ assertHasClass(problemDiv, 'error');
+ assertTrue(continueButton.disabled);
+ });
+
+ // If the PIN is weak a warning problem is shown.
+ test('WarningShownForWeakPins', function() {
+ assertFalse(isVisible(problemDiv));
+
+ pinKeyboard.value = '1111';
+
+ assertTrue(isVisible(problemDiv));
+ assertHasClass(problemDiv, 'warning');
+ });
+
+ // If the confirm PIN does not match the initial PIN an error is shown and
+ // the submit button is disabled.
+ test('ErrorShownForMismatchedPins', function() {
+ pinKeyboard.value = '1118';
+ MockInteractions.tap(continueButton);
+ pinKeyboard.value = '1119';
+
+ assertTrue(isVisible(problemDiv));
+ assertHasClass(problemDiv, 'error');
+ assertTrue(continueButton.disabled);
+ });
+
+ // Hitting cancel at the setup step dismisses the dialog.
+ test('HittingBackButtonResetsState', function() {
+ MockInteractions.tap(backButton);
+ assertFalse(element.$.dialog.open);
+ });
+
+ // Hitting cancel at the confirm step dismisses the dialog.
+ test('HittingBackButtonResetsState', function() {
+ pinKeyboard.value = '1111';
+ MockInteractions.tap(continueButton);
+ MockInteractions.tap(backButton);
+ assertFalse(element.$.dialog.open);
+ });
+
+ // User has to re-enter PIN for confirm step.
+ test('PinKeyboardIsResetForConfirmStep', function() {
+ pinKeyboard.value = '1111';
+ MockInteractions.tap(continueButton);
+ assertEquals('', pinKeyboard.value);
+ });
+
+ // Completing the flow results in a call to the quick unlock private API.
+ test('SubmittingPinCallsQuickUnlockApi', function() {
+ // Entering the same (even weak) pin twice calls the quick unlock API
+ // and sets up a PIN.
+ pinKeyboard.value = '1111';
+ MockInteractions.tap(continueButton);
+ pinKeyboard.value = '1111';
+ MockInteractions.tap(continueButton);
+
+ assertDeepEquals(['PIN'], quickUnlockPrivateApi.activeModes);
+ assertDeepEquals(['1111'], quickUnlockPrivateApi.credentials);
+ });
+ });
+ }
+
+ return {
+ registerAuthenticateTests: registerAuthenticateTests,
+ registerLockScreenTests: registerLockScreenTests,
+ registerSetupPinDialogTests: registerSetupPinDialogTests
+ };
+});
« no previous file with comments | « chrome/test/data/webui/settings/fake_quick_unlock_private.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698