12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * TestFixture for testing the formatting of settings pages. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @extends {testing.Test} 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @constructor 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function SettingsFormatWebUITest() {} 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Map of rule exemptions grouped by test. 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SettingsFormatWebUITest.Filters = { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Exemption for checkboxes that do not require an id or pref property. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Input methods use inputMethodId instead of id for unique identification. 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'pref': ['language-options-input-method-template', 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'language-options-input-method-list'] 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Collection of error messages. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SettingsFormatWebUITest.Messages = { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MISSING_CHECK_WRAPPER: 'Element $1 should be enclosed in <div class="$2">', 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MISSING_ID_OR_PREF: 'Missing id or pref preoperty for checkbox $1.', 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MISSING_RADIO_BUTTON_NAME: 'Radio button $1 is missing the name property', 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MISSING_RADIO_BUTTON_VALUE: 'Radio button $1 is missing the value property', 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SettingsFormatWebUITest.prototype = { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) __proto__: testing.Test.prototype, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Navigate to browser settings. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) browsePreload: 'chrome://settings-frame/', 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * List of errors generated during a test. Used instead of expect* functions 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * to suppress verbosity. The implementation of errorsToMessage in the 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * testing API generates a call stack for each error produced which greatly 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * reduces readability. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {Array.<string>} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errors: null, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setUp: function() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.errors = []; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tearDown: function() { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assertTrue(this.errors.length == 0, '\n' + this.errors.join('\n')); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Generates a failure message. During tear down of the test, the accumulation 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * of pending messages triggers a test failure. 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {string} key Label of the message formatting string. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {!Element} element The element that triggered the failure. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {...string} args Additional arguments for formatting the message. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fail: function(key, element, args) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var subs = [this.getLabel(element)].concat( 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Array.prototype.slice.call(arguments, 2)); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var message = SettingsFormatWebUITest.Messages[key].replace( 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /\$\d/g, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(m) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return subs[m[1] - 1] || '$' + m[1]; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assertFalse(/\$\d/.test(message), 'found unreplaced subs'); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.errors.push(message); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * String for identifying a node within an error message. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {!Element} element The target element to identify. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} Name to facilitate tracking down the element. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getLabel: function(element) { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (element.id) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return element.id; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (element.pref) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return element.pref; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (element.name && element.value) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return element.name + '-' + element.value; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this.getLabel(element.parentNode); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Checks if the node is exempt from following the formatting rule. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {!Element} element The candidate element. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {Array.<string>} filters List of exemptions. 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} True if the element is exempt. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isExempt: function(element, filters) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var target = this.getLabel(element); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < filters.length; i++) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (filters[i] == target) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Ensure that radio and checkbox buttons have consistent layout. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F('SettingsFormatWebUITest', 'RadioCheckboxStyleCheck', function() { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var settings = $('settings'); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assertTrue(settings != null, 'Unable to access settings'); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var query = 'input[type=checkbox], input[type=radio]'; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var elements = document.querySelectorAll(query); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assertTrue(elements.length > 0); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < elements.length; i++) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var element = elements[i]; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!findAncestorByClass(element, element.type)) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.fail('MISSING_CHECK_WRAPPER', element, element.type); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Each checkbox requires an id or pref property. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F('SettingsFormatWebUITest', 'CheckboxIdOrPrefCheck', function() { 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var query = 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'input[type=checkbox]:not([pref]):not([id]):not(.spacer-checkbox)'; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var elements = document.querySelectorAll(query); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < elements.length; i++) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var element = elements[i]; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!this.isExempt(element, SettingsFormatWebUITest.Filters['pref'])) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.fail('MISSING_ID_OR_PREF', element); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Each radio button requires name and value properties. 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F('SettingsFormatWebUITest', 'RadioButtonNameValueCheck', function() { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var elements = document.querySelectorAll('input[type=radio]'); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < elements.length; i++) { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var element = elements[i]; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!element.name) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.fail('MISSING_RADIO_BUTTON_NAME', element); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!element.getAttribute('value')) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.fail('MISSING_RADIO_BUTTON_VALUE', element); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}); 159