Commit 8057370b authored by Josh Nohle's avatar Josh Nohle Committed by Commit Bot

[CrOS MultiDevice] Update setup flow buttons

Update the multi-device setup flow button bar to include the
following buttons: Back, Cancel, Forward. Set the buttons
on each page to conform to the following specs (sans padding):
https://drive.google.com/file/d/1UqHV67OrdGT0_G0L98nV5IVr26OkHu9F/view.

Screenshots with this patch applied:
start screen: https://drive.google.com/open?id=1QlWKjesaBpt0ZtNQ_vONBqu1czUWiezz
start screen (OOBE): https://drive.google.com/open?id=1kh9UNYjLaSbP-zE0U89sniZSb9Sbhk8fMw
password screen: https://drive.google.com/open?id=1olKePztZ9pqxPHupVCdrwEBZ1pyfzLA_
success screen: https://drive.google.com/open?id=1zpZfnowdpOvge8nteqsjBHuUin_I9HgW

Bug: 889574
Change-Id: I7a0834b58b6f2458e5ab6641aa5b323cb5fc32fe
Tested: Manual; ./out/Default/browser_tests --gtest_filter=*MultiDevice*
Reviewed-on: https://chromium-review.googlesource.com/c/1254760Reviewed-by: default avatarAlexander Alekseev <alemate@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Commit-Queue: Josh Nohle <nohle@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599737}
parent 0621e853
......@@ -86,9 +86,9 @@
on-setup-exited="onExitRequested_"
forward-button-text="{{forwardButtonText_}}"
forward-button-disabled="{{forwardButtonDisabled_}}"
backward-button-text="{{backwardButtonText_}}">
<oobe-text-button slot="backward-button">
<div>[[backwardButtonText_]]</div>
cancel-button-text="{{cancelButtonText_}}">
<oobe-text-button slot="cancel-button">
<div>[[cancelButtonText_]]</div>
</oobe-text-button>
<oobe-next-button id="next-button" slot="forward-button"
disabled$="[[forwardButtonDisabled_]]">
......
......@@ -75,10 +75,10 @@ cr.define('multidevice_setup', function() {
},
/**
* Text to be shown on the backward navigation button.
* Text to be shown on the cancel button.
* @private {string|undefined}
*/
backwardButtonText_: {
cancelButtonText_: {
type: String,
value: '',
},
......
......@@ -9,6 +9,7 @@
<template>
<style include="multidevice-setup-shared">
#backward-button,
#cancel-button,
#forward-button {
align-items: center;
display: flex;
......@@ -21,11 +22,16 @@
on-forward-button-focus-requested="onForwardButtonFocusRequested_"
forward-button-text="{{forwardButtonText_}}"
forward-button-disabled="{{forwardButtonDisabled_}}"
cancel-button-text="{{cancelButtonText_}}"
backward-button-text="{{backwardButtonText_}}">
<paper-button id="backward-button"
slot="backward-button" class="cancel-button">
[[backwardButtonText_]]
</paper-button>
<paper-button id="cancel-button"
slot="cancel-button" class="cancel-button">
[[cancelButtonText_]]
</paper-button>
<paper-button id="forward-button"
slot="forward-button" class="action-button"
disabled$="[[forwardButtonDisabled_]]">
......
......@@ -30,6 +30,15 @@ Polymer({
value: false,
},
/**
* Text to be shown on the cancel navigation button.
* @private {string|undefined}
*/
cancelButtonText_: {
type: String,
value: '',
},
/**
* Text to be shown on the backward navigation button.
* @private {string|undefined}
......
......@@ -12,6 +12,8 @@ cr.define('multidevice_setup', () => {
/** @private {boolean} */
this.shouldSetHostSucceed_ = true;
this.numSetHostDeviceCalls = 0;
}
set isPasswordRequired(isPasswordRequired) {
......@@ -30,6 +32,7 @@ cr.define('multidevice_setup', () => {
/** @override */
setHostDevice(hostDeviceId, opt_authToken) {
return new Promise((resolve) => {
this.numSetHostDeviceCalls++;
resolve({success: this.shouldSetHostSucceed_});
});
}
......@@ -73,6 +76,12 @@ cr.define('multidevice_setup', () => {
*/
let forwardButton;
/**
* Cancel button. Defined in setUp.
* @type {PaperButton|undefined}
*/
let cancelButton;
/**
* Backward navigation button. Defined in setUp.
* @type {PaperButton|undefined}
......@@ -82,10 +91,16 @@ cr.define('multidevice_setup', () => {
/** @type {!FakeMojoService} */
let fakeMojoService;
/** @type {!settings.FakeQuickUnlockPrivate} */
let fakeQuickUnlockPrivate;
const PASSWORD = 'password-page';
const SUCCESS = 'setup-succeeded-page';
const START = 'start-setup-page';
const CORRECT_PASSWORD = 'correctPassword';
const WRONG_PASSWORD = 'wrongPassword';
setup(() => {
multiDeviceSetupElement = document.createElement('multidevice-setup');
multiDeviceSetupElement.delegate = new FakeDelegate();
......@@ -94,9 +109,17 @@ cr.define('multidevice_setup', () => {
new FakeMojoInterfaceProviderImpl(fakeMojoService);
document.body.appendChild(multiDeviceSetupElement);
Polymer.dom.flush();
forwardButton = multiDeviceSetupElement.$$('button-bar').$$('#forward');
cancelButton = multiDeviceSetupElement.$$('button-bar').$$('#cancel');
backwardButton =
multiDeviceSetupElement.$$('button-bar').$$('#backward');
fakeQuickUnlockPrivate = new settings.FakeQuickUnlockPrivate();
fakeQuickUnlockPrivate.accountPassword = CORRECT_PASSWORD;
multiDeviceSetupElement.$$(PASSWORD).quickUnlockPrivate_ =
fakeQuickUnlockPrivate;
});
/** @param {boolean} isOobeMode */
......@@ -106,107 +129,236 @@ cr.define('multidevice_setup', () => {
isOobeMode;
}
/** @param {string} visiblePageName */
/**
* @param {string} visiblePageName
* @return {!Promise} Promise that resolves when the page renders.
*/
function setVisiblePage(visiblePageName) {
multiDeviceSetupElement.visiblePageName_ = visiblePageName;
Polymer.dom.flush();
return test_util.waitForRender(
multiDeviceSetupElement.$$(visiblePageName));
}
// From SetupSucceededPage
/**
* @param {string} input
* @return {!Promise} Promise that resolves when the page renders.
*/
function enterPassword(input) {
multiDeviceSetupElement.$$(PASSWORD).$$('#passwordInput').value = input;
Polymer.dom.flush();
return test_util.waitForRender(multiDeviceSetupElement);
}
test('SetupSucceededPage forward button closes UI', done => {
setVisiblePage(SUCCESS);
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
function getNumSetHostDeviceCalls() {
return multiDeviceSetupElement.delegate.numSetHostDeviceCalls;
}
multiDeviceSetupElement.async(() => {
// *** From SetupSucceededPage ***
test('SetupSucceededPage buttons: forward', () => {
return setVisiblePage(SUCCESS).then(() => {
assertFalse(forwardButton.hidden);
assertTrue(cancelButton.hidden);
assertTrue(backwardButton.hidden);
});
});
test('SetupSucceededPage forward button closes UI', () => {
return setVisiblePage(SUCCESS).then(() => {
const whenSetupExits =
test_util.eventToPromise('setup-exited', multiDeviceSetupElement);
forwardButton.click();
return whenSetupExits;
});
});
// From StartSetupPage
// Post-OOBE
// OOBE
test('SetupSucceededPage Settings link closes UI (post-OOBE)', () => {
setMode(false /* isOobeMode */);
return setVisiblePage(SUCCESS).then(() => {
const whenSetupExits =
test_util.eventToPromise('setup-exited', multiDeviceSetupElement);
multiDeviceSetupElement.$$(SUCCESS).$$('#settings-link').click();
return whenSetupExits;
});
});
// *** From StartSetupPage ***
test('StartSetupPage backward button continues OOBE (OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => {
done();
test('StartSetupPage buttons: forward, cancel', () => {
return setVisiblePage(START).then(() => {
assertFalse(forwardButton.hidden);
assertFalse(cancelButton.hidden);
assertTrue(backwardButton.hidden);
});
});
// OOBE
test('StartSetupPage cancel button exits OOBE (OOBE)', () => {
setMode(true /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
return setVisiblePage(START)
.then(() => {
const whenSetupExits = test_util.eventToPromise(
'setup-exited', multiDeviceSetupElement);
cancelButton.click();
return whenSetupExits;
})
.then(() => {
assertEquals(0, getNumSetHostDeviceCalls());
});
});
test(
'StartSetupPage forward button sets host in background and ' +
'goes to PasswordPage (OOBE).',
done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => {
done();
});
'exits OOBE (OOBE)',
() => {
setMode(true /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
multiDeviceSetupElement.async(() => {
forwardButton.click();
});
return setVisiblePage(START)
.then(() => {
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
const whenSetupExits = test_util.eventToPromise(
'setup-exited', multiDeviceSetupElement);
forwardButton.click();
return whenSetupExits;
})
.then(() => {
assertEquals(1, getNumSetHostDeviceCalls());
});
});
// Post-OOBE
test('StartSetupPage backward button closes UI (post-OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
test('StartSetupPage cancel button closes UI (post-OOBE)', () => {
setMode(false /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
return setVisiblePage(START)
.then(() => {
const whenSetupExits = test_util.eventToPromise(
'setup-exited', multiDeviceSetupElement);
cancelButton.click();
return whenSetupExits;
})
.then(() => {
assertEquals(0, getNumSetHostDeviceCalls());
});
});
test('PasswordPage backward button closes UI (post-OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
// *** From PasswordPage ***
// Post-OOBE
test(
'PasswordPage buttons: forward, cancel, backward (post-OOBE)', () => {
return setVisiblePage(PASSWORD).then(() => {
assertFalse(forwardButton.hidden);
assertFalse(cancelButton.hidden);
assertFalse(backwardButton.hidden);
});
});
test('PasswordPage cancel button closes UI (post-OOBE)', () => {
setMode(false /* isOobeMode */);
setVisiblePage(PASSWORD);
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
return setVisiblePage(PASSWORD)
.then(() => {
const whenSetupExits = test_util.eventToPromise(
'setup-exited', multiDeviceSetupElement);
cancelButton.click();
return whenSetupExits;
})
.then(() => {
assertEquals(0, getNumSetHostDeviceCalls());
});
});
test(
'PasswordPage forward button goes to success page if mojo works ' +
'(post-OOBE)',
done => {
multiDeviceSetupElement.addEventListener(
'visible-page-name_-changed', () => {
if (multiDeviceSetupElement.visiblePageName_ == SUCCESS)
done();
'PasswordPage backward button goes to start page (post-OOBE)', () => {
setMode(false /* isOobeMode */);
return setVisiblePage(PASSWORD)
.then(() => {
const whenPageChanges = test_util.eventToPromise(
'visible-page-name_-changed', multiDeviceSetupElement);
backwardButton.click();
return whenPageChanges;
})
.then(() => {
assertEquals(START, multiDeviceSetupElement.visiblePageName_);
assertEquals(0, getNumSetHostDeviceCalls());
});
});
test(
'PasswordPage forward button goes to success page if mojo works ' +
'(post-OOBE)',
() => {
setMode(false /* isOobeMode */);
setVisiblePage(PASSWORD);
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
multiDeviceSetupElement.async(() => {
forwardButton.click();
});
return setVisiblePage(PASSWORD)
.then(() => {
return enterPassword(CORRECT_PASSWORD);
})
.then(() => {
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
const whenPageChanges = test_util.eventToPromise(
'visible-page-name_-changed', multiDeviceSetupElement);
forwardButton.click();
return whenPageChanges;
})
.then(() => {
assertEquals(
SUCCESS, multiDeviceSetupElement.visiblePageName_);
assertEquals(1, getNumSetHostDeviceCalls());
});
});
test('SuccessPage Settings link closes UI (post-OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
test(
'PasswordPage forward button does nothing if invalid password ' +
'(post-OOBE)',
() => {
setMode(false /* isOobeMode */);
setMode(false /* isOobeMode */);
setVisiblePage(SUCCESS);
return setVisiblePage(PASSWORD)
.then(() => {
return enterPassword(WRONG_PASSWORD);
})
.then(() => {
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
forwardButton.click();
Polymer.dom.flush();
return test_util.waitForRender(multiDeviceSetupElement);
})
.then(() => {
assertEquals(
PASSWORD, multiDeviceSetupElement.visiblePageName_);
assertEquals(0, getNumSetHostDeviceCalls());
});
});
multiDeviceSetupElement.$$('setup-succeeded-page')
.$$('#settings-link')
.click();
});
test(
'PasswordPage forward button is disabled if invalid password ' +
'(post-OOBE)',
() => {
const whenMultiDeviceSetupLoads = setMode(false /* isOobeMode */);
return setVisiblePage(PASSWORD)
.then(() => {
return enterPassword(WRONG_PASSWORD);
})
.then(() => {
forwardButton.click();
Polymer.dom.flush();
return test_util.waitForRender(multiDeviceSetupElement);
})
.then(() => {
assertTrue(multiDeviceSetupElement.forwardButtonDisabled);
});
});
});
}
return {registerIntegrationTests: registerIntegrationTests};
......
......@@ -27,6 +27,9 @@ MultiDeviceSetupBrowserTest.prototype = {
extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
'../test_browser_proxy.js',
'../fake_chrome_event.js', // Necessary for fake_quick_unlock_private.js
'../settings/fake_quick_unlock_private.js',
'../settings/test_util.js',
'integration_test.js',
'setup_succeeded_page_test.js',
'start_setup_page_test.js',
......
......@@ -7,15 +7,19 @@
<style include="multidevice-setup-shared">
:host {
display: flex;
justify-content: flex-end;
}
</style>
<div class="flex"></div>
<div id="backward"
on-click="onBackwardButtonClicked_"
hidden$="[[backwardButtonHidden]]">
<slot name="backward-button"></slot>
</div>
<div class="flex"></div>
<div id="cancel"
on-click="onCancelButtonClicked_"
hidden$="[[cancelButtonHidden]]">
<slot name="cancel-button"></slot>
</div>
<div id="forward"
on-click="onForwardButtonClicked_"
hidden$="[[forwardButtonHidden]]">
......
......@@ -13,13 +13,19 @@ Polymer({
/** Whether the forward button should be hidden. */
forwardButtonHidden: {
type: Boolean,
value: false,
value: true,
},
/** Whether the cancel button should be hidden. */
cancelButtonHidden: {
type: Boolean,
value: true,
},
/** Whether the backward button should be hidden. */
backwardButtonHidden: {
type: Boolean,
value: false,
value: true,
},
},
......@@ -28,6 +34,11 @@ Polymer({
this.fire('forward-navigation-requested');
},
/** @private */
onCancelButtonClicked_: function() {
this.fire('cancel-requested');
},
/** @private */
onBackwardButtonClicked_: function() {
this.fire('backward-navigation-requested');
......
......@@ -54,8 +54,10 @@
</iron-pages>
<div class="flex"></div>
<button-bar forward-button-hidden="[[!forwardButtonText]]"
backward-button-hidden="[[!backwardButtonText]]">
backward-button-hidden="[[!backwardButtonText]]"
cancel-button-hidden="[[!cancelButtonText]]">
<slot name="backward-button" slot="backward-button"></slot>
<slot name="cancel-button" slot="cancel-button"></slot>
<slot name="forward-button" slot="forward-button"></slot>
</button-bar>
</template>
......
......@@ -45,6 +45,16 @@ cr.define('multidevice_setup', function() {
notify: true
},
/**
* Text to be shown on the cancel button.
* @type {string|undefined}
*/
cancelButtonText: {
type: String,
computed: 'getCancelButtonText_(visiblePage_)',
notify: true,
},
/**
* Text to be shown on the backward navigation button.
* @type {string|undefined}
......@@ -63,7 +73,7 @@ cr.define('multidevice_setup', function() {
visiblePageName_: {
type: String,
value: PageName.START,
notify: true, // For testing purporses only.
notify: true, // For testing purposes only.
},
/**
......@@ -116,6 +126,7 @@ cr.define('multidevice_setup', function() {
listeners: {
'backward-navigation-requested': 'onBackwardNavigationRequested_',
'cancel-requested': 'onCancelRequested_',
'forward-navigation-requested': 'onForwardNavigationRequested_',
},
......@@ -149,12 +160,24 @@ cr.define('multidevice_setup', function() {
},
/** @private */
onBackwardNavigationRequested_: function() {
onCancelRequested_: function() {
this.exitSetupFlow_();
},
/** @private */
onBackwardNavigationRequested_: function() {
// The back button is only visible on the password page.
assert(this.visiblePageName_ == PageName.PASSWORD);
this.$$('password-page').clearPasswordTextInput();
this.visiblePageName_ = PageName.START;
},
/** @private */
onForwardNavigationRequested_: function() {
if (this.forwardButtonDisabled)
return;
this.visiblePage_.getCanNavigateToNextPage().then((canNavigate) => {
if (!canNavigate)
return;
......@@ -235,6 +258,17 @@ cr.define('multidevice_setup', function() {
this.passwordPageForwardButtonDisabled_;
},
/**
* @return {string|undefined} The cancel button text, which is undefined
* if no button should be displayed.
* @private
*/
getCancelButtonText_: function() {
if (!this.visiblePage_)
return undefined;
return this.visiblePage_.cancelButtonText;
},
/**
* @return {string|undefined} The backward button text, which is undefined
* if no button should be displayed.
......@@ -244,7 +278,6 @@ cr.define('multidevice_setup', function() {
if (!this.visiblePage_)
return undefined;
return this.visiblePage_.backwardButtonText;
},
/**
......
......@@ -30,11 +30,17 @@ Polymer({
},
/** Overridden from UiPageContainerBehavior. */
backwardButtonTextId: {
cancelButtonTextId: {
type: String,
value: 'cancel',
},
/** Overridden from UiPageContainerBehavior. */
backwardButtonTextId: {
type: String,
value: 'back',
},
/** Overridden from UiPageContainerBehavior. */
headerId: {
type: String,
......
......@@ -13,11 +13,17 @@ Polymer({
},
/** Overridden from UiPageContainerBehavior. */
backwardButtonTextId: {
cancelButtonTextId: {
type: String,
value: 'cancel',
},
/** Overridden from UiPageContainerBehavior. */
backwardButtonTextId: {
type: String,
value: 'back',
},
/** Overridden from UiPageContainerBehavior. */
headerId: {
type: String,
......
......@@ -13,7 +13,7 @@ Polymer({
},
/** Overridden from UiPageContainerBehavior. */
backwardButtonTextId: {
cancelButtonTextId: {
type: String,
value: 'cancel',
},
......
......@@ -14,6 +14,15 @@ const UiPageContainerBehaviorImpl = {
*/
forwardButtonTextId: String,
/**
* ID for cancel button label, which must be translated for display.
*
* Undefined if the visible page has no cancel button.
*
* @type {string|undefined}
*/
cancelButtonTextId: String,
/**
* ID for backward button label, which must be translated for display.
*
......@@ -49,6 +58,18 @@ const UiPageContainerBehaviorImpl = {
computed: 'computeLocalizedText_(forwardButtonTextId)',
},
/**
* Translated text to display on the cancel button.
*
* Undefined if the visible page has no cancel button.
*
* @type {string|undefined}
*/
cancelButtonText: {
type: String,
computed: 'computeLocalizedText_(cancelButtonTextId)',
},
/**
* Translated text to display on the backward-naviation button.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment