Commit 1ecb9c55 authored by Akihiro Ota's avatar Akihiro Ota Committed by Commit Bot

ChromeVox: Language switching test infrastructure clean up.

This does two things:
1. Cleans up the language switching code to use consistent terms. Most
notably, it changes all instances of "inner-node switching" to
"sub-node switching".
2. Cleans up the language switching test infrastructure. A test
naming scheme was implemented to easily communicate the purpose of
each test. Also, tests were added to cover the two language switching
behaviors: node-level and sub-node-level switching. Each document
in the test databank is tested using node-level and sub-node-level
switching.

Bug: 923068
Change-Id: Ia16b785381966d97e089aae5dc08e23173876d08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1754703
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Reviewed-by: default avatarAlice Boxhall <aboxhall@chromium.org>
Reviewed-by: default avatarChris Hall <chrishall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#690998}
parent e2dfd8ad
......@@ -5,29 +5,30 @@
/**
* @fileoverview Provides language switching services for ChromeVox, which
* uses language detection information to automatically change the ChromeVox
* output language.
* output voice.
*/
goog.provide('LanguageSwitching');
/**
* The current output language. Initialize to the language of the browser or
* empty string if unavailable.
* empty string if the former is unavailable.
* @private {string}
*/
LanguageSwitching.currentLanguage_ =
chrome.i18n.getUILanguage().toLowerCase() || '';
/**
* Confidence threshold to meet before assigning inner-node language.
* Confidence threshold to meet before assigning sub-node language.
* @const
* @private {number}
*/
LanguageSwitching.PROBABILITY_THRESHOLD = 0.9;
LanguageSwitching.PROBABILITY_THRESHOLD_ = 0.9;
/**
* Stores whether or not ChromeVox inner-node language switching is enabled or
* disabled.
* Stores whether or not ChromeVox sub-node language switching is enabled.
* Set to false as default, as sub-node language detection is still
* experimental.
* @private {boolean}
*/
LanguageSwitching.sub_node_switching_enabled_ = false;
......@@ -36,8 +37,7 @@ LanguageSwitching.sub_node_switching_enabled_ = false;
* Initialization function for language switching.
*/
LanguageSwitching.init = function() {
// Enable inner-node language switching if inner-node switching feature flag
// is enabled.
// Enable sub-node language switching if feature flag is enabled.
chrome.commandLinePrivate.hasSwitch(
'enable-experimental-accessibility-chromevox-sub-node-language-' +
'switching',
......@@ -64,7 +64,6 @@ LanguageSwitching.assignLanguagesForStringAttribute = function(
return;
var stringAttributeValue = node[stringAttribute];
var languageAnnotation;
// Quick note:
// The decideNewLanguage function, which contains the core language switching
// logic, is setup to prefer sub-node switching if the detected language's
......@@ -74,18 +73,10 @@ LanguageSwitching.assignLanguagesForStringAttribute = function(
languageAnnotation =
node.languageAnnotationForStringAttribute(stringAttribute);
} else {
// Use node-level language switching if inner-node switching is
// disabled. We use this logic because the API is disabled when sub-node
// switching is disabled.
var nodeLevelLanguageData = {};
// Ensure that we span the entire stringAttributeValue.
nodeLevelLanguageData.startIndex = 0;
nodeLevelLanguageData.endIndex = stringAttributeValue.length;
// To force the decideNewLanguage function to use node-level switching, we
// pass in an empty language with probability that doesn't exceed the
// PROBABILITY_THRESHOLD. As previously mentioned, if we are not confident
// enough in inner-node detected languages, we fall back on node-level
// language.
nodeLevelLanguageData.language = '';
nodeLevelLanguageData.probability = 0;
languageAnnotation = [nodeLevelLanguageData];
......@@ -100,9 +91,10 @@ LanguageSwitching.assignLanguagesForStringAttribute = function(
stringAttributeValue || '', LanguageSwitching.currentLanguage_);
return;
}
// Split output based on language annotation.
// Each object in languageAnnotation contains a language, probability,
// and start/end indices that define a substring.
// and start/end indices that define a substring of stringAttributeValue.
for (var i = 0; i < languageAnnotation.length; ++i) {
var speechProps = new Output.SpeechProperties();
var startIndex = languageAnnotation[i].startIndex;
......@@ -130,14 +122,14 @@ LanguageSwitching.assignLanguagesForStringAttribute = function(
/**
* Run error checks on language data and decide new output language.
* @param {!AutomationNode} node
* @param {string} innerNodeLanguage
* @param {string} subNodeLanguage
* @param {number} probability
* @return {string}
*/
LanguageSwitching.decideNewLanguage = function(
node, innerNodeLanguage, probability) {
node, subNodeLanguage, probability) {
// Use the following priority rankings when deciding language.
// 1. Inner-node language. If we can detect inner-node language with a high
// 1. Sub-node language. If we can detect sub-node language with a high
// enough probability of accuracy, then we should use it.
// 2. Node-level detected language.
// 3. Author-provided language. This language is also assigned at the node
......@@ -145,9 +137,9 @@ LanguageSwitching.decideNewLanguage = function(
// 4. LanguageSwitching.currentLanguage_. If we do not have enough language
// data, then we should not switch languages.
// Use innerNodeLanguage if probability exceeds threshold.
if (probability > LanguageSwitching.PROBABILITY_THRESHOLD)
return innerNodeLanguage.toLowerCase();
// Use subNodeLanguage if probability exceeds threshold.
if (probability > LanguageSwitching.PROBABILITY_THRESHOLD_)
return subNodeLanguage.toLowerCase();
// Use detected language as nodeLevelLanguage, if present.
// If no detected language, use author-provided language.
......@@ -181,7 +173,7 @@ LanguageSwitching.decideNewLanguage = function(
};
/**
* Returns a unicode-aware substring of text from startIndex to endIndex.
* Returns a unicode-aware substring of |text| from startIndex to endIndex.
* @param {string} text
* @param {number} startIndex
* @param {number} endIndex
......
......@@ -83,82 +83,96 @@ ChromeVoxLanguageSwitchingTest.prototype = {
}
},
multipleLanguagesDoc: function() {/*!
<p lang="es">Hola.</p>
<p lang="en">Hello.</p>
<p lang="fr">Salut.</p>
<span lang="it">Ciao amico.</span>
*/},
nestedLanguagesDoc: function() {/*!
<p id="breakfast" lang="en">In the morning, I sometimes eat breakfast.</p>
<p id="lunch" lang="fr">Dans l'apres-midi, je dejeune.</p>
<p id="greeting" lang="en">
Hello it's a pleasure to meet you.
<span lang="fr">Comment ca va?</span>Switching back to English.
<span lang="es">Hola.</span>Goodbye.
// Test documents //
// The purpose of this doc is to test functionality with three-letter language
// codes. Asturian has a language code of 'ast'. It is a language spoken
// in Principality of Asturias, Spain.
asturianAndJapaneseDoc: function() {/*!
<meta charset="utf-8">
<p lang="ja">ど</p>
<p lang="ast">
Pretend that this text is Asturian. Testing three-letter language code logic.
</p>
*/},
buttonAndLinkDoc: function() {/*!
<body lang="es">
<p>This is a paragraph, spoken in English.</p>
<button type="submit">This is a button, spoken in English.</button>
<p>This is a paragraph, written in English.</p>
<button type="submit">This is a button, written in English.</button>
<a href="https://www.google.com">Este es un enlace.</a>
</body>
*/},
japaneseAndEnglishDoc: function() {/*!
<meta charset="utf-8">
<p>Hello, my name is 太田あきひろ. It's a pleasure to meet you. どうぞよろしくお願いします.</p>
*/},
switchWhenUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p>This text should be read in English. 차에 한하여 중임할 수. Followed by English.</p>
*/},
noSwitchEnglishFrenchDoc: function() {/*!
englishAndFrenchUnlabeledDoc: function() {/*!
<p>
This entire object should be read in English, even the following French passage:
salut mon ami! Ca va? Bien, et toi? It's hard to differentiate between latin-based languages.
</p>
*/},
englishAndKoreanUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p>This text is written in English. 차에 한하여 중임할 수. This text is also written in English.</p>
*/},
japaneseAndChineseUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p>
<p id="text">
天気はいいですね. 右万諭全中結社原済権人点掲年難出面者会追
</p>
*/},
japaneseAndKoreanNotEnoughJapaneseDoc: function() {/*!
japaneseAndEnglishUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p>Hello, my name is 太田あきひろ. It's a pleasure to meet you. どうぞよろしくお願いします.</p>
*/},
japaneseAndKoreanUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p lang="ko">
私は. 법률이 정하는 바에 의하여 대법관이 아닌 법관을 둘 수 있다
</p>
*/},
unlabeledSingleCharacterDoc: function() {/*!
japaneseCharacterUnlabeledDoc: function() {/*!
<meta charset="utf-8">
<p>ど</p>
*/},
// The purpose of this doc is to test functionality with three-letter language
// codes. Asturian has a language code of 'ast'. It is a language spoken
// in Principality of Asturias, Spain.
asturianAndJapaneseDoc: function() {/*!
<meta charset="utf-8">
<p lang="ja">ど</p>
<p lang="ast">
Pretend that this text is Asturian. Testing three-letter language code logic.
multipleLanguagesLabeledDoc: function() {/*!
<p lang="es">Hola.</p>
<p lang="en">Hello.</p>
<p lang="fr">Salut.</p>
<span lang="it">Ciao amico.</span>
*/},
nestedLanguagesLabeledDoc: function() {/*!
<p id="breakfast" lang="en">In the morning, I sometimes eat breakfast.</p>
<p id="lunch" lang="fr">Dans l'apres-midi, je dejeune.</p>
<p id="greeting" lang="en">
Hello it's a pleasure to meet you.
<span lang="fr">Comment ca va?</span>Switching back to English.
<span lang="es">Hola.</span>Goodbye.
</p>
*/},
};
TEST_F('ChromeVoxLanguageSwitchingTest', 'MultipleLanguagesTest', function() {
// Overview:
// The naming scheme of the language switching tests is as follows:
// <switching_behavior>_<test_document>_Test.
// <switching_behavior>: Whether the test is testing node-level or sub-node-level switching.
// <test_document>: The name of the document the test uses.
// Example: NodeLevelSwitching_MultipleLanguagesLabeledDoc_Test
// Each group of tests test the two switching behaviors with various labelings.
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_MultipleLanguagesLabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.multipleLanguagesDoc, function() {
this.runWithLoadedTree(this.multipleLanguagesLabeledDoc, function() {
// Turn on language switching.
localStorage['languageSwitching'] = 'true';
mockFeedback.call(doCmd('jumpToTop')).expectSpeechWithLanguage('es', 'español: Hola.');
......@@ -169,9 +183,26 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'MultipleLanguagesTest', function() {
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'NestedLanguagesTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_MultipleLanguagesLabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.nestedLanguagesDoc, function() {
this.runWithLoadedTree(this.multipleLanguagesLabeledDoc, function() {
localStorage['languageSwitching'] = 'true';
// Disable sub-node-level switching.
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop')).expectSpeechWithLanguage('es', 'español: Hola.');
mockFeedback.call(doCmd('nextLine')).expectSpeechWithLanguage('en', 'English: Hello.');
mockFeedback.call(doCmd('nextLine')).expectSpeechWithLanguage('fr', 'français: Salut.');
mockFeedback.call(doCmd('nextLine')).expectSpeechWithLanguage('it', 'italiano: Ciao amico.');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_NestedLanguagesLabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.nestedLanguagesLabeledDoc, function() {
localStorage['languageSwitching'] = 'true';
// We should be able to switch languages when each component is labeled
// with a language.
......@@ -195,20 +226,45 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'NestedLanguagesTest', function() {
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'ButtonAndLinkTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_NestedLanguagesLabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.nestedLanguagesLabeledDoc, function() {
localStorage['languageSwitching'] = 'true';
// Disable sub-node-switching.
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('en', 'In the morning, I sometimes eat breakfast.');
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('fr', "français: Dans l'apres-midi, je dejeune.");
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('en', "English: Hello it's a pleasure to meet you. ");
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('fr', 'français: Comment ca va?');
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('en', 'English: Switching back to English. ');
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('es', 'español: Hola.');
mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLanguage('en', 'English: Goodbye.');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_ButtonAndLinkDoc_Test', function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.buttonAndLinkDoc, function(root) {
localStorage['languageSwitching'] = 'true';
mockFeedback.call(doCmd('jumpToTop'))
// Inner-node language detection is able to label this as 'en' and
// Sub-node language detection is able to label this as 'en' and
// overwrite the author-provided language of 'es'.
// LanguageSwitching.currentLanguage_ is initialized to 'en'. Do not
// prepend 'English' because language does not switch.
.expectSpeechWithLanguage('en', 'This is a paragraph, spoken in English.')
.expectSpeechWithLanguage('en', 'This is a paragraph, written in English.')
.call(doCmd('nextObject'))
// Even though this is unlabeled, CLD3 is able to determine, with high
// confidence, that this is English text.
.expectSpeechWithLanguage('en', 'This is a button, spoken in English.')
// CLD3 is able to determine, with high confidence, that this is English text.
.expectSpeechWithLanguage('en', 'This is a button, written in English.')
.expectSpeechWithLanguage(undefined, 'Button', 'Press Search+Space to activate.')
.call(doCmd('nextObject'))
.expectSpeechWithLanguage('es', 'español: Este es un enlace.')
......@@ -217,9 +273,31 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'ButtonAndLinkTest', function() {
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndEnglishUnlabeledTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_ButtonAndLinkDoc_Test', function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndEnglishDoc, function(root) {
this.runWithLoadedTree(this.buttonAndLinkDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// Disable sub-node-switching.
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
// Sub-node language detection is disabled, so we are not able to detect + switch to English
// on any of these nodes. Instead, we use the author-provided language of 'es'.
.expectSpeechWithLanguage('es', 'español: This is a paragraph, written in English.')
.call(doCmd('nextObject'))
.expectSpeechWithLanguage('es', 'This is a button, written in English.')
.expectSpeechWithLanguage(undefined, 'Button', 'Press Search+Space to activate.')
.call(doCmd('nextObject'))
.expectSpeechWithLanguage('es', 'Este es un enlace.')
.expectSpeechWithLanguage(undefined, 'Link');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest','SubNodeLevelSwitching_JapaneseAndEnglishUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndEnglishUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// We are able to separate out English and Japanese because they use
// different scripts.
......@@ -228,7 +306,7 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndEnglishUnlabeledTest', func
// prepend 'English' because language does not switch.
.expectSpeechWithLanguage('en', 'Hello, my name is ')
.expectSpeechWithLanguage('ja', '日本語: 太田あきひろ. ')
// Expect 'en-us' because inner-node language of 'en' doesn't come with
// Expect 'en-us' because sub-node language of 'en' doesn't come with
// high enough probability. We fall back on node-level detected language,
// which is 'en-us'.
.expectSpeechWithLanguage('en-us', "English: It's a pleasure to meet you. ")
......@@ -237,10 +315,10 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndEnglishUnlabeledTest', func
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndEnglishUnlabeledTestSubNodeSwitchingDisabled',
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_JapaneseAndEnglishUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndEnglishDoc, function(root) {
this.runWithLoadedTree(this.japaneseAndEnglishUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// Disable sub-node-switching.
LanguageSwitching.sub_node_switching_enabled_ = false;
......@@ -255,28 +333,46 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndEnglishUnlabeledTestSubNode
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SwitchWhenUnlabeledTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_EnglishAndKoreanUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.switchWhenUnlabeledDoc, function(root) {
this.runWithLoadedTree(this.englishAndKoreanUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// We are able to separate out English and Korean because they use
// different scripts.
mockFeedback.call(doCmd('jumpToTop'))
// LanguageSwitching.currentLanguage_ is initialized to 'en'. Do not
// prepend 'English' because language does not switch.
.expectSpeechWithLanguage('en', 'This text should be read in English. ')
.expectSpeechWithLanguage('en', 'This text is written in English. ')
.expectSpeechWithLanguage('ko', '한국어: 차에 한하여 중임할 수. ')
// Expect 'en-us' because inner-node language of 'en' doesn't come with
// Expect 'en-us' because sub-node language of 'en' doesn't come with
// high enough probability. We fall back on node-level detected language,
// which is 'en-us'.
.expectSpeechWithLanguage('en-us', 'English: Followed by English.');
.expectSpeechWithLanguage('en', 'English: This text is also written in English.');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_EnglishAndKoreanUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.englishAndKoreanUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// Disable sub-node-switching
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('en-us', 'This text is written in English. 차에 한하여 중임할 수.'
+ ' This text is also written in English.');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'NoSwitchEnglishFrenchTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_EnglishAndFrenchUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.noSwitchEnglishFrenchDoc, function(root) {
this.runWithLoadedTree(this.englishAndFrenchUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// Unable to separate out English and French when unlabeled.
mockFeedback.call(doCmd('jumpToTop'))
......@@ -289,9 +385,25 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'NoSwitchEnglishFrenchTest', function()
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'UnlabeledSingleCharacterTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_EnglishAndFrenchUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.unlabeledSingleCharacterDoc, function(root) {
this.runWithLoadedTree(this.englishAndFrenchUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('en', 'This entire object should be read in English, even'
+ ' the following French passage: salut mon ami! Ca va? Bien, et toi? It\'s hard to'
+ ' differentiate between latin-based languages.');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_JapaneseCharacterUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseCharacterUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// We are able to detect and switch at the character level if the character
// is unique to a certian script. In this case, 'ど' only appears in
......@@ -302,7 +414,21 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'UnlabeledSingleCharacterTest', functio
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndChineseUnlabeled', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_JapaneseCharacterUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseCharacterUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('en-us', 'ど');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest','SubNodeLevelSwitching_JapaneseAndChineseUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndChineseUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
......@@ -314,9 +440,44 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndChineseUnlabeled', function
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndKoreanNotEnoughJapanese', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_JapaneseAndChineseUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndChineseUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('en-us', '天気はいいですね. 右万諭全中結社原済権人点掲年難出面者会追');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_JapaneseAndChineseLabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
// Only difference between doc used in this test and this.japaneseAndChineseUnlabeledDoc is the
// lang="zh" attribute.
this.runWithLoadedTree(
function() {/*!
<meta charset="utf-8">
<p lang="zh">
天気はいいですね. 右万諭全中結社原済権人点掲年難出面者会追
</p>
*/},
function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('zh', '中文: 天気はいいですね. 右万諭全中結社原済権人点掲年難出面者会追');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_JapaneseAndKoreanUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndKoreanNotEnoughJapaneseDoc, function(root) {
this.runWithLoadedTree(this.japaneseAndKoreanUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
// Unable to separate out Japanese and Korean if unlabeled.
mockFeedback.call(doCmd('jumpToTop'))
......@@ -326,7 +487,23 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'JapaneseAndKoreanNotEnoughJapanese', f
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'AsturianTest', function() {
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_JapaneseAndKoreanUnlabeledDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.japaneseAndKoreanUnlabeledDoc, function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_switching_enabled_ = false;
// Node-level language detection runs and assigns language of 'ko' to the node.
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('ko', '한국어: 私は. 법률이 정하는 바에 의하여 대법관이 아닌 법관을 둘 수'
+ ' 있다');
mockFeedback.replay();
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'SubNodeLevelSwitching_AsturianAndJapaneseDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.asturianAndJapaneseDoc, function(root) {
localStorage['languageSwitching'] = 'true';
......@@ -339,9 +516,26 @@ TEST_F('ChromeVoxLanguageSwitchingTest', 'AsturianTest', function() {
});
});
TEST_F('ChromeVoxLanguageSwitchingTest', 'NodeLevelSwitching_AsturianAndJapaneseDoc_Test',
function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.asturianAndJapaneseDoc, function(root) {
localStorage['languageSwitching'] = 'true';
LanguageSwitching.sub_node_level_switching_enabled_ = false;
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLanguage('ja', '日本語: ど')
.call(doCmd('nextObject'))
.expectSpeechWithLanguage('ast', 'asturianu: Pretend that this text is Asturian. Testing'
+ ' three-letter language code logic.');
mockFeedback.replay();
});
});
// This does not need partner tests because no language switching behavior is tested.
TEST_F('ChromeVoxLanguageSwitchingTest', 'LanguageSwitchingOffTest', function() {
var mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.multipleLanguagesDoc, function(root) {
this.runWithLoadedTree(this.multipleLanguagesLabeledDoc, function(root) {
localStorage['languageSwitching'] = 'false';
// Language should not be set if the language switching feature is off.
mockFeedback.call(doCmd('jumpToTop'))
......
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