Commit 4e10bca6 authored by Akihiro Ota's avatar Akihiro Ota Committed by Commit Bot

ChromeVox Tutorial: Give hints when focusing headers.

This change adds hints to headers in the tutorial so that users know
what to do when each screen is shown. This change has been requested
based on UXR findings.

Also in this change:
1. Update the main tutorial heading
2. Focus the practice area instructions, as opposed to the title, when
it is first opened.

Fixed: 1142038, 1142047
AX-Relnotes: N/A
Change-Id: I1930776d57d2b6e1d86ba5856390c2553cf3e0a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2506516Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822861}
parent 6a1158e6
...@@ -90,7 +90,10 @@ h1 { ...@@ -90,7 +90,10 @@ h1 {
<div id="mainMenu" <div id="mainMenu"
hidden$="[[ shouldHideMainMenu(activeScreen) ]]"> hidden$="[[ shouldHideMainMenu(activeScreen) ]]">
<h1 id="mainMenuHeader" tabindex="-1">[[ chooseYourExperience ]]</h1> <h1 id="mainMenuHeader" tabindex="-1" aria-describedby="mainMenuHeaderHint">
[[ mainMenuHeader ]]
</h1>
<div id="mainMenuHeaderHint" hidden>[[ mainMenuHeaderHint ]]</div>
<div id="mainMenuButtons"> <div id="mainMenuButtons">
<cr-button id="quickOrientationButton" on-click="chooseCurriculum"> <cr-button id="quickOrientationButton" on-click="chooseCurriculum">
[[ quickOrientation ]] [[ quickOrientation ]]
...@@ -116,7 +119,10 @@ h1 { ...@@ -116,7 +119,10 @@ h1 {
<div id="lessonMenu" <div id="lessonMenu"
hidden$="[[ shouldHideLessonMenu(activeScreen) ]]"> hidden$="[[ shouldHideLessonMenu(activeScreen) ]]">
<h1 id="lessonMenuHeader" <h1 id="lessonMenuHeader"
tabindex="-1">[[ computeLessonMenuHeader(curriculum) ]]</h1> tabindex="-1" aria-describedby="lessonMenuHeaderHint">
[[ computeLessonMenuHeader(curriculum) ]]
</h1>
<div id="lessonMenuHeaderHint" hidden>[[ lessonMenuHeaderHint ]]</div>
<div id="lessonShortcuts"></div> <div id="lessonShortcuts"></div>
</div> </div>
......
...@@ -114,10 +114,11 @@ Polymer({ ...@@ -114,10 +114,11 @@ Polymer({
// Labels and text content. // Labels and text content.
chooseYourExperience: { mainMenuHeader: {
type: String, type: String,
value: 'Choose your tutorial experience', value: 'ChromeVox tutorial',
}, },
quickOrientation: {type: String, value: 'Quick orientation'}, quickOrientation: {type: String, value: 'Quick orientation'},
essentialKeys: {type: String, value: 'Essential keys'}, essentialKeys: {type: String, value: 'Essential keys'},
...@@ -144,6 +145,16 @@ Polymer({ ...@@ -144,6 +145,16 @@ Polymer({
exitTutorial: {type: String, value: 'Exit tutorial'}, exitTutorial: {type: String, value: 'Exit tutorial'},
mainMenuHeaderHint: {
type: String,
value: 'Press Search + left/right arrow to browse topics'
},
lessonMenuHeaderHint: {
type: String,
value: `Press Search + left/right arrow to browse lessons for this topic`
},
lessonData: { lessonData: {
type: Array, type: Array,
value: [ value: [
......
...@@ -94,7 +94,10 @@ a { ...@@ -94,7 +94,10 @@ a {
<div id="container" hidden> <div id="container" hidden>
<template is="dom-if" if="[[ title ]]"> <template is="dom-if" if="[[ title ]]">
<h1 id="title" tabindex="-1">[[ getMsg(title) ]]</h1> <h1 id="title" tabindex="-1" aria-describedby="titleHint">
[[ getMsg(title) ]]
</h1>
<div id="titleHint" hidden>[[ titleHint ]]</div>
</template> </template>
<div id="content"> <div id="content">
<template id="contentTemplate" is="dom-repeat" items="[[ content ]]" <template id="contentTemplate" is="dom-repeat" items="[[ content ]]"
...@@ -108,7 +111,7 @@ a { ...@@ -108,7 +111,7 @@ a {
[[ practiceTitle ]] [[ practiceTitle ]]
</div> </div>
<div id="practiceBody" class="body" slot="body" tabindex="-1"> <div id="practiceBody" class="body" slot="body" tabindex="-1">
<p id="practiceInstructions">[[ practiceInstructions ]]</p> <p id="practiceInstructions" tabindex="-1">[[ practiceInstructions ]]</p>
<div id="separator"></div> <div id="separator"></div>
<div id="practiceContent"></div> <div id="practiceContent"></div>
</div> </div>
......
...@@ -50,6 +50,16 @@ export const TutorialLesson = Polymer({ ...@@ -50,6 +50,16 @@ export const TutorialLesson = Polymer({
// Observed properties. // Observed properties.
activeLessonNum: {type: Number, observer: 'setVisibility'}, activeLessonNum: {type: Number, observer: 'setVisibility'},
titleHint: {
type: String,
value: 'Press Search + left/right arrow to navigate the lesson'
},
practiceTitleHint: {
type: String,
value: 'Press Search + left/right arrow to navigate the practice area'
}
}, },
/** @override */ /** @override */
...@@ -152,7 +162,7 @@ export const TutorialLesson = Polymer({ ...@@ -152,7 +162,7 @@ export const TutorialLesson = Polymer({
startPractice() { startPractice() {
this.notifyStartPractice(); this.notifyStartPractice();
this.$.practice.showModal(); this.$.practice.showModal();
this.$.practiceTitle.focus(); this.$.practiceInstructions.focus();
}, },
/** @private */ /** @private */
......
...@@ -117,7 +117,10 @@ TEST_F('ChromeVoxTutorialTest', 'BasicTest', function() { ...@@ -117,7 +117,10 @@ TEST_F('ChromeVoxTutorialTest', 'BasicTest', function() {
const mockFeedback = this.createMockFeedback(); const mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback
.expectSpeech(
'ChromeVox tutorial', 'Heading 1',
'Press Search + left/right arrow to browse topics')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -143,11 +146,14 @@ TEST_F('ChromeVoxTutorialTest', 'LessonSetTest', function() { ...@@ -143,11 +146,14 @@ TEST_F('ChromeVoxTutorialTest', 'LessonSetTest', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
.expectSpeech(/Quick Orientation Tutorial, [0-9]+ Lessons/) .expectSpeech(/Quick Orientation Tutorial, [0-9]+ Lessons/)
.expectSpeech(
'Press Search + left/right arrow to browse lessons for ' +
'this topic')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Welcome to ChromeVox!') .expectSpeech('Welcome to ChromeVox!')
.call(() => { .call(() => {
...@@ -155,7 +161,7 @@ TEST_F('ChromeVoxTutorialTest', 'LessonSetTest', function() { ...@@ -155,7 +161,7 @@ TEST_F('ChromeVoxTutorialTest', 'LessonSetTest', function() {
// clicking on the main menu button. // clicking on the main menu button.
tutorial.showMainMenu(); tutorial.showMainMenu();
}) })
.expectSpeech('Choose your tutorial experience') .expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -174,7 +180,7 @@ TEST_F('ChromeVoxTutorialTest', 'NoPracticeAreaTest', function() { ...@@ -174,7 +180,7 @@ TEST_F('ChromeVoxTutorialTest', 'NoPracticeAreaTest', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -184,7 +190,9 @@ TEST_F('ChromeVoxTutorialTest', 'NoPracticeAreaTest', function() { ...@@ -184,7 +190,9 @@ TEST_F('ChromeVoxTutorialTest', 'NoPracticeAreaTest', function() {
.call(() => { .call(() => {
tutorial.showLesson(0); tutorial.showLesson(0);
}) })
.expectSpeech('On, Off, and Stop', 'Heading 1') .expectSpeech(
'On, Off, and Stop', 'Heading 1',
'Press Search + left/right arrow to navigate the lesson')
.call(doCmd('nextButton')) .call(doCmd('nextButton'))
.expectSpeech('Next lesson') .expectSpeech('Next lesson')
.replay(); .replay();
...@@ -197,7 +205,7 @@ TEST_F('ChromeVoxTutorialTest', 'HasPracticeAreaTest', function() { ...@@ -197,7 +205,7 @@ TEST_F('ChromeVoxTutorialTest', 'HasPracticeAreaTest', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -228,10 +236,10 @@ TEST_F('ChromeVoxTutorialTest', 'GeneralNudgesTest', function() { ...@@ -228,10 +236,10 @@ TEST_F('ChromeVoxTutorialTest', 'GeneralNudgesTest', function() {
const giveNudge = () => { const giveNudge = () => {
tutorial.giveNudge(); tutorial.giveNudge();
}; };
mockFeedback.expectSpeech('Choose your tutorial experience'); mockFeedback.expectSpeech('ChromeVox tutorial');
for (let i = 0; i < 3; ++i) { for (let i = 0; i < 3; ++i) {
mockFeedback.call(giveNudge).expectSpeech( mockFeedback.call(giveNudge).expectSpeech(
'Choose your tutorial experience', 'Heading 1'); 'ChromeVox tutorial', 'Heading 1');
} }
mockFeedback.call(giveNudge) mockFeedback.call(giveNudge)
.expectSpeech('Hint: Hold Search and press the arrow keys to navigate.') .expectSpeech('Hint: Hold Search and press the arrow keys to navigate.')
...@@ -256,7 +264,7 @@ TEST_F('ChromeVoxTutorialTest', 'PracticeAreaNudgesTest', function() { ...@@ -256,7 +264,7 @@ TEST_F('ChromeVoxTutorialTest', 'PracticeAreaNudgesTest', function() {
const giveNudge = () => { const giveNudge = () => {
tutorial.giveNudge(); tutorial.giveNudge();
}; };
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -272,7 +280,7 @@ TEST_F('ChromeVoxTutorialTest', 'PracticeAreaNudgesTest', function() { ...@@ -272,7 +280,7 @@ TEST_F('ChromeVoxTutorialTest', 'PracticeAreaNudgesTest', function() {
.call(doCmd('nextButton')) .call(doCmd('nextButton'))
.expectSpeech('Practice Area') .expectSpeech('Practice Area')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
.expectSpeech('Basic Navigation Practice') .expectSpeech(/Try using basic navigation to navigate/)
.call(giveNudge) .call(giveNudge)
.expectSpeech( .expectSpeech(
'Try pressing Search + left/right arrow. The search key is ' + 'Try pressing Search + left/right arrow. The search key is ' +
...@@ -289,7 +297,7 @@ TEST_F('ChromeVoxTutorialTest', 'ExitButtonTest', function() { ...@@ -289,7 +297,7 @@ TEST_F('ChromeVoxTutorialTest', 'ExitButtonTest', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('previousButton')) .call(doCmd('previousButton'))
.expectSpeech('Exit tutorial') .expectSpeech('Exit tutorial')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
...@@ -304,7 +312,7 @@ TEST_F('ChromeVoxTutorialTest', 'EscapeTest', function() { ...@@ -304,7 +312,7 @@ TEST_F('ChromeVoxTutorialTest', 'EscapeTest', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(() => { .call(() => {
// Press Escape. // Press Escape.
tutorial.onKeyDown({ tutorial.onKeyDown({
...@@ -324,7 +332,7 @@ TEST_F('ChromeVoxTutorialTest', 'MainMenuButton', function() { ...@@ -324,7 +332,7 @@ TEST_F('ChromeVoxTutorialTest', 'MainMenuButton', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(this.assertActiveScreen.bind(this, 'main_menu')) .call(this.assertActiveScreen.bind(this, 'main_menu'))
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation') .expectSpeech('Quick orientation')
...@@ -338,7 +346,7 @@ TEST_F('ChromeVoxTutorialTest', 'MainMenuButton', function() { ...@@ -338,7 +346,7 @@ TEST_F('ChromeVoxTutorialTest', 'MainMenuButton', function() {
.call(doCmd('previousButton')) .call(doCmd('previousButton'))
.expectSpeech('Main menu') .expectSpeech('Main menu')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
.expectSpeech('Choose your tutorial experience') .expectSpeech('ChromeVox tutorial')
.call(this.assertActiveScreen.bind(this, 'main_menu')) .call(this.assertActiveScreen.bind(this, 'main_menu'))
.replay(); .replay();
}); });
...@@ -351,7 +359,7 @@ TEST_F('ChromeVoxTutorialTest', 'AllLessonsButton', function() { ...@@ -351,7 +359,7 @@ TEST_F('ChromeVoxTutorialTest', 'AllLessonsButton', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(this.assertActiveScreen.bind(this, 'main_menu')) .call(this.assertActiveScreen.bind(this, 'main_menu'))
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation') .expectSpeech('Quick orientation')
...@@ -382,7 +390,7 @@ TEST_F('ChromeVoxTutorialTest', 'NextPreviousButtons', function() { ...@@ -382,7 +390,7 @@ TEST_F('ChromeVoxTutorialTest', 'NextPreviousButtons', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(() => { .call(() => {
tutorial.curriculum = 'essential_keys'; tutorial.curriculum = 'essential_keys';
tutorial.showLesson(0); tutorial.showLesson(0);
...@@ -410,7 +418,7 @@ TEST_F('ChromeVoxTutorialTest', 'AutoReadTitle', function() { ...@@ -410,7 +418,7 @@ TEST_F('ChromeVoxTutorialTest', 'AutoReadTitle', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
...@@ -435,7 +443,7 @@ TEST_F('ChromeVoxTutorialTest', 'AutoReadLesson', function() { ...@@ -435,7 +443,7 @@ TEST_F('ChromeVoxTutorialTest', 'AutoReadLesson', function() {
this.runWithLoadedTree(this.simpleDoc, async function(root) { this.runWithLoadedTree(this.simpleDoc, async function(root) {
await this.launchAndWaitForTutorial(); await this.launchAndWaitForTutorial();
const tutorial = this.getPanel().iTutorial; const tutorial = this.getPanel().iTutorial;
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation', 'Button') .expectSpeech('Quick orientation', 'Button')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
...@@ -465,7 +473,7 @@ TEST_F('ChromeVoxTutorialTest', 'EarconLesson', function() { ...@@ -465,7 +473,7 @@ TEST_F('ChromeVoxTutorialTest', 'EarconLesson', function() {
.expectSpeech(speech) .expectSpeech(speech)
.expectEarcon(earcon); .expectEarcon(earcon);
}; };
mockFeedback.expectSpeech('Choose your tutorial experience') mockFeedback.expectSpeech('ChromeVox tutorial')
.call(() => { .call(() => {
// Show the lesson. // Show the lesson.
tutorial.curriculum = 'sounds_and_settings'; tutorial.curriculum = 'sounds_and_settings';
...@@ -507,7 +515,7 @@ TEST_F('ChromeVoxTutorialTest', 'QuickOrientationLessonTest', function() { ...@@ -507,7 +515,7 @@ TEST_F('ChromeVoxTutorialTest', 'QuickOrientationLessonTest', function() {
}; };
let firstLessonNode; let firstLessonNode;
await mockFeedback.expectSpeech('Choose your tutorial experience') await mockFeedback.expectSpeech('ChromeVox tutorial')
.call(doCmd('nextObject')) .call(doCmd('nextObject'))
.expectSpeech('Quick orientation') .expectSpeech('Quick orientation')
.call(doCmd('forceClickOnCurrentItem')) .call(doCmd('forceClickOnCurrentItem'))
......
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