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

Side by Side Diff: chrome/test/data/webui/test_api.js

Issue 11363170: Add an accessibility audit test for WebUI pages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sheridan's patch and order change for imports in web_ui_browsertest Created 8 years 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/test/data/webui/accessibility_audit_browsertest.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview Library providing basic test framework functionality. 6 * @fileoverview Library providing basic test framework functionality.
7 */ 7 */
8 8
9 /** 9 /**
10 * Namespace for |Test|. 10 * Namespace for |Test|.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 */ 115 */
116 testShouldFail: false, 116 testShouldFail: false,
117 117
118 /** 118 /**
119 * Extra libraries to add before loading this test file. 119 * Extra libraries to add before loading this test file.
120 * @type {Array.<string>} 120 * @type {Array.<string>}
121 */ 121 */
122 extraLibraries: [], 122 extraLibraries: [],
123 123
124 /** 124 /**
125 * Whether to run the accessibility checks.
126 * @type {boolean}
127 */
128 runAccessibilityChecks : true,
129
130 /**
131 * Whether to treat accessibility issues (errors or warnings) as test
132 * failures. If true, any accessibility issues will cause the test to fail.
133 * If false, accessibility issues will cause a console.warn.
134 * Off by default to begin with; as we add the ability to suppress false
135 * positives, we will transition this to true.
136 * @type {boolean}
137 */
138 accessibilityIssuesAreErrors: false,
139
140 /**
141 * Holds any accessibility errors found during the accessibility audit.
142 * Like |errors|, cleared when results are reported.
scr 2012/12/21 02:13:39 Hunh, these aren't cleared now. Do they need to b
aboxhall 2012/12/21 02:19:05 Right - they'll be recreated for each new test now
143 * @type {Array.<string>}
144 */
145 a11yErrors_: [],
146
147 /**
148 * Holds any accessibility warnings found during the accessibility audit.
149 * Like |errors|, cleared when results are reported.
150 * @type {Array.<string>}
151 */
152 a11yWarnings_: [],
153
154 /**
155 * Gets the list of accessibility errors found during the accessibility
156 * audit. Only for use in testing.
157 * @return {Array.<string>}
158 */
159 getAccessibilityErrors: function() {
160 return this.a11yErrors_;
161 },
162
163 /**
164 * Gets the list of accessibility warnings found during the accessibility
165 * audit. Only for use in testing.
166 * @return {Array.<string>}
167 */
168 getAccessibilityWarnings: function() {
169 return this.a11yWarnings_;
170 },
171
172 /**
173 * Run accessibility checks after this test completes.
174 */
175 enableAccessibilityChecks: function() {
176 this.runAccessibilityChecks = true;
177 },
178
179 /**
180 * Don't run accessibility checks after this test completes.
181 */
182 disableAccessibilityChecks: function() {
183 this.runAccessibilityChecks = false;
184 },
185
186 /**
125 * Create a new class to handle |messageNames|, assign it to 187 * Create a new class to handle |messageNames|, assign it to
126 * |this.mockHandler|, register its messages and return it. 188 * |this.mockHandler|, register its messages and return it.
127 * @return {Mock} Mock handler class assigned to |this.mockHandler|. 189 * @return {Mock} Mock handler class assigned to |this.mockHandler|.
128 */ 190 */
129 makeAndRegisterMockHandler: function(messageNames) { 191 makeAndRegisterMockHandler: function(messageNames) {
130 var MockClass = makeMockClass(messageNames); 192 var MockClass = makeMockClass(messageNames);
131 this.mockHandler = mock(MockClass); 193 this.mockHandler = mock(MockClass);
132 registerMockMessageCallbacks(this.mockHandler, MockClass); 194 registerMockMessageCallbacks(this.mockHandler, MockClass);
133 return this.mockHandler; 195 return this.mockHandler;
134 }, 196 },
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 233
172 /** 234 /**
173 * Called to run the body from the perspective of this fixture. 235 * Called to run the body from the perspective of this fixture.
174 * @type {Function} 236 * @type {Function}
175 */ 237 */
176 runTest: function(testBody) { 238 runTest: function(testBody) {
177 testBody.call(this); 239 testBody.call(this);
178 }, 240 },
179 241
180 /** 242 /**
243 * Called to run the accessibility audit from the perspective of this
244 * fixture.
245 */
246 runAccessibilityAudit: function() {
247 if (!this.runAccessibilityChecks)
248 return;
249
250 if (!runAccessibilityAudit(this.a11yErrors_, this.a11yWarnings_)) {
251 var report = accessibilityAuditReport(this.a11yErrors_,
252 this.a11yWarnings_);
253 if (this.accessibilityIssuesAreErrors) {
254 throw new Error(report);
255 } else {
256 console.warn(report);
257 }
258 }
259 },
260
261 /**
181 * Create a closure function for continuing the test at a later time. May be 262 * Create a closure function for continuing the test at a later time. May be
182 * used as a listener function. 263 * used as a listener function.
183 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate 264 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
184 * time. 265 * time.
185 * @param {Function} completion The function to call to complete the test. 266 * @param {Function} completion The function to call to complete the test.
186 * @param {...*} var_args Arguments to pass when calling completionAction. 267 * @param {...*} var_args Arguments to pass when calling completionAction.
187 * @return {function(): void} Return a function, bound to this test fixture, 268 * @return {function(): void} Return a function, bound to this test fixture,
188 * which continues the test. 269 * which continues the test.
189 */ 270 */
190 continueTest: function(whenTestDone, completion) { 271 continueTest: function(whenTestDone, completion) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 371
291 /** 372 /**
292 * Called to run this test's body. 373 * Called to run this test's body.
293 */ 374 */
294 runTest: function() { 375 runTest: function() {
295 if (this.body && this.fixture) 376 if (this.body && this.fixture)
296 this.fixture.runTest(this.body); 377 this.fixture.runTest(this.body);
297 }, 378 },
298 379
299 /** 380 /**
381 * Called after a test is run (in testDone) to test accessibility.
382 */
383 runAccessibilityAudit: function() {
384 if (this.fixture)
385 this.fixture.runAccessibilityAudit();
386 },
387
388 /**
300 * Runs this test case with |this| set to the |fixture|. 389 * Runs this test case with |this| set to the |fixture|.
301 * 390 *
302 * Note: Tests created with TEST_F may depend upon |this| being set to an 391 * Note: Tests created with TEST_F may depend upon |this| being set to an
303 * instance of this.fixture. The current implementation of TEST creates a 392 * instance of this.fixture. The current implementation of TEST creates a
304 * dummy constructor, but tests created with TEST should not rely on |this| 393 * dummy constructor, but tests created with TEST should not rely on |this|
305 * being set. 394 * being set.
306 * @type {Function} 395 * @type {Function}
307 */ 396 */
308 run: function() { 397 run: function() {
309 try { 398 try {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 689
601 /** 690 /**
602 * Notifies the running browser test of the test results. Clears |errors|. 691 * Notifies the running browser test of the test results. Clears |errors|.
603 * @param {Array.<boolean, string>=} result When passed, this is used for the 692 * @param {Array.<boolean, string>=} result When passed, this is used for the
604 * testResult message. 693 * testResult message.
605 */ 694 */
606 function testDone(result) { 695 function testDone(result) {
607 if (!testIsDone) { 696 if (!testIsDone) {
608 testIsDone = true; 697 testIsDone = true;
609 if (currentTestCase) { 698 if (currentTestCase) {
610 try { 699 var ok = true;
611 currentTestCase.tearDown(); 700 ok = createExpect(currentTestCase.runAccessibilityAudit.bind(
612 } catch (e) { 701 currentTestCase)).call(null) && ok;
613 // Caught an exception in tearDown; Register the error and recreate 702 ok = createExpect(currentTestCase.tearDown.bind(
614 // the result if it is passed in. 703 currentTestCase)).call(null) && ok;
615 errors.push(e); 704
616 if (result) 705 if (!ok && result)
617 result = [false, errorsToMessage([e], result[1])]; 706 result = [false, errorsToMessage(errors, result[1])];
618 } 707
619 currentTestCase = null; 708 currentTestCase = null;
620 } 709 }
621 chrome.send('testResult', result ? result : testResult()); 710 if (!result)
711 result = testResult();
712 chrome.send('testResult', result);
622 errors.splice(0, errors.length); 713 errors.splice(0, errors.length);
623 } else { 714 } else {
624 console.warn('testIsDone already'); 715 console.warn('testIsDone already');
625 } 716 }
626 } 717 }
627 718
628 /** 719 /**
629 * Converts each Error in |errors| to a suitable message, adding them to 720 * Converts each Error in |errors| to a suitable message, adding them to
630 * |message|, and returns the message string. 721 * |message|, and returns the message string.
631 * @param {Array.<Error>} errors Array of errors to add to |message|. 722 * @param {Array.<Error>} errors Array of errors to add to |message|.
(...skipping 13 matching lines...) Expand all
645 return message; 736 return message;
646 } 737 }
647 738
648 /** 739 /**
649 * Returns [success, message] & clears |errors|. 740 * Returns [success, message] & clears |errors|.
650 * @param {boolean} errorsOk When true, errors are ok. 741 * @param {boolean} errorsOk When true, errors are ok.
651 * @return {Array.<boolean, string>} 742 * @return {Array.<boolean, string>}
652 */ 743 */
653 function testResult(errorsOk) { 744 function testResult(errorsOk) {
654 var result = [true, '']; 745 var result = [true, ''];
655 if (errors.length) { 746 if (errors.length)
656 result = [!!errorsOk, errorsToMessage(errors)]; 747 result = [!!errorsOk, errorsToMessage(errors)];
657 } 748
658 return result; 749 return result;
659 } 750 }
660 751
661 // Asserts. 752 // Asserts.
662 // Use the following assertions to verify a condition within a test. 753 // Use the following assertions to verify a condition within a test.
663 // If assertion fails, throw an Error with information pertinent to the test. 754 // If assertion fails, throw an Error with information pertinent to the test.
664 755
665 /** 756 /**
666 * When |test| !== true, aborts the current test. 757 * When |test| !== true, aborts the current test.
667 * @param {boolean} test The predicate to check against |expected|. 758 * @param {boolean} test The predicate to check against |expected|.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 * Always aborts the current test. 877 * Always aborts the current test.
787 * @param {string=} message The message to include in the Error thrown. 878 * @param {string=} message The message to include in the Error thrown.
788 * @throws {Error} always. 879 * @throws {Error} always.
789 */ 880 */
790 function assertNotReached(message) { 881 function assertNotReached(message) {
791 helper.registerCall(); 882 helper.registerCall();
792 throw new Error(helper.getCallMessage(message)); 883 throw new Error(helper.getCallMessage(message));
793 } 884 }
794 885
795 /** 886 /**
887 * Run an accessibility audit on the current page state.
888 * @type {Function}
889 * @return {boolean} Whether there were any errors or warnings
890 * @private
891 */
892 function runAccessibilityAudit(a11yErrors, a11yWarnings) {
893 var auditResults = axs.Audit.run();
894 for (var i = 0; i < auditResults.length; i++) {
895 var auditResult = auditResults[i];
896 if (auditResult.result == axs.constants.AuditResult.FAIL) {
897 var auditRule = auditResult.rule;
898 // TODO(aboxhall): more useful error messages (sadly non-trivial)
899 if (auditRule.severity == axs.constants.Severity.Severe)
900 a11yErrors.push(accessibilityErrorMessage(auditRule, auditResult));
901 else
902 a11yWarnings.push(accessibilityErrorMessage(auditRule, auditResult));
903 }
904 }
905
906 // TODO(aboxhall): have strict (no errors or warnings) vs non-strict
907 // (warnings ok)
908 // TODO(aboxhall): some kind of info logging for warnings only??
909 return (a11yErrors.length == 0 && a11yWarnings.length == 0);
910 }
911
912 /**
913 * Concatenates the accessibility error messages in |a11yErrors| and
914 * |a11yWarnings| in to an accessibility report, appends it to the given
915 * |message| and returns the resulting message string.
916 * @param {Array.<string>} a11yErrors The list of accessibility error messages
917 * @param {Array.<string>} a11yWarnings The list of accessibility warning
918 * messages.
919 * @return {string} |message| + accessibility report.
920 */
921 function accessibilityAuditReport(a11yErrors, a11yWarnings, message) {
922 message = message ? message + '\n' : '';
923 message += '\n*** Begin accessibility audit results ***';
924 message += '\nAn accessibility audit found ';
925
926 if (a11yErrors.length > 0) {
927 message += a11yErrors.length +
928 (a11yErrors.length == 1 ? ' error ' : ' errors ');
929 if (a11yWarnings.length > 0)
930 message += 'and ';
931 }
932 if (a11yWarnings.length > 0) {
933 message += a11yWarnings.length +
934 (a11yWarnings.length == 1 ? ' warning ' : ' warnings ');
935 }
936 message += 'on this page.\n';
937 message += 'For more information, please see ' +
938 'http://chromium.org/developers/accessibility/webui-accessibility-audit';
939
940 for (var i = 0; i < a11yErrors.length; i++)
941 message += '\n\n' + a11yErrors[i];
942
943 for (var i = 0; i < a11yWarnings.length; i++)
944 message += '\n\n' + a11yWarnings[i];
945 message += '\n*** End accessibility audit results ***';
946 return message;
947 }
948
949 /**
950 * Creates an error message for a given accessibility audit rule and
951 * corresponding result.
952 * @param {axs.AuditRule} rule The audit rule which the result is for
953 * @param {Object.<string, (string|Array.<Element>)>} result The result
954 * object returned from the audit.
955 * @return {string} An error message describing the failure and listing
956 * up to five elements which failed the audit rule.
957 */
958 function accessibilityErrorMessage(rule, result) {
959 if (rule.severity == axs.constants.Severity.Severe)
960 var message = 'Error: '
961 else
962 var message = 'Warning: '
963 message += rule.name + ' failed on the following ' +
964 (result.elements.length == 1 ? 'element' : 'elements');
965
966 if (result.elements.length == 1)
967 message += ':'
968 else
969 message += ' (1 - ' + Math.min(5, result.elements.length) +
970 ' of ' + result.elements.length + '):';
971
972 var maxElements = Math.min(result.elements.length, 5);
973 for (var i = 0; i < maxElements; i++)
974 message += '\n' + axs.utils.getQuerySelectorText(result.elements[i]);
975 return message;
976 }
977
978 /**
979 * Asserts that the current page state passes the accessibility audit.
980 */
981 function assertAccessibilityOk() {
982 helper.registerCall();
983 var a11yErrors = [];
984 var a11yWarnings = [];
985 if (!runAccessibilityAudit(a11yErrors, a11yWarnings))
986 throw new Error(accessibilityAuditReport(a11yErrors, a11yWarnings));
987 }
988
989 /**
796 * Creates a function based upon a function that thows an exception on 990 * Creates a function based upon a function that thows an exception on
797 * failure. The new function stuffs any errors into the |errors| array for 991 * failure. The new function stuffs any errors into the |errors| array for
798 * checking by runTest. This allows tests to continue running other checks, 992 * checking by runTest. This allows tests to continue running other checks,
799 * while failing the overall test if any errors occurrred. 993 * while failing the overall test if any errors occurrred.
800 * @param {Function} assertFunc The function which may throw an Error. 994 * @param {Function} assertFunc The function which may throw an Error.
801 * @return {function(...*):bool} A function that applies its arguments to 995 * @return {function(...*):bool} A function that applies its arguments to
802 * |assertFunc| and returns true if |assertFunc| passes. 996 * |assertFunc| and returns true if |assertFunc| passes.
803 * @see errors 997 * @see errors
804 * @see runTestFunction 998 * @see runTestFunction
805 */ 999 */
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 exports.testDone = testDone; 1564 exports.testDone = testDone;
1371 exports.assertTrue = assertTrue; 1565 exports.assertTrue = assertTrue;
1372 exports.assertFalse = assertFalse; 1566 exports.assertFalse = assertFalse;
1373 exports.assertGE = assertGE; 1567 exports.assertGE = assertGE;
1374 exports.assertGT = assertGT; 1568 exports.assertGT = assertGT;
1375 exports.assertEquals = assertEquals; 1569 exports.assertEquals = assertEquals;
1376 exports.assertLE = assertLE; 1570 exports.assertLE = assertLE;
1377 exports.assertLT = assertLT; 1571 exports.assertLT = assertLT;
1378 exports.assertNotEquals = assertNotEquals; 1572 exports.assertNotEquals = assertNotEquals;
1379 exports.assertNotReached = assertNotReached; 1573 exports.assertNotReached = assertNotReached;
1574 exports.assertAccessibilityOk = assertAccessibilityOk;
1380 exports.callFunction = callFunction; 1575 exports.callFunction = callFunction;
1381 exports.callFunctionWithSavedArgs = callFunctionWithSavedArgs; 1576 exports.callFunctionWithSavedArgs = callFunctionWithSavedArgs;
1382 exports.callGlobalWithSavedArgs = callGlobalWithSavedArgs; 1577 exports.callGlobalWithSavedArgs = callGlobalWithSavedArgs;
1383 exports.expectTrue = createExpect(assertTrue); 1578 exports.expectTrue = createExpect(assertTrue);
1384 exports.expectFalse = createExpect(assertFalse); 1579 exports.expectFalse = createExpect(assertFalse);
1385 exports.expectGE = createExpect(assertGE); 1580 exports.expectGE = createExpect(assertGE);
1386 exports.expectGT = createExpect(assertGT); 1581 exports.expectGT = createExpect(assertGT);
1387 exports.expectEquals = createExpect(assertEquals); 1582 exports.expectEquals = createExpect(assertEquals);
1388 exports.expectLE = createExpect(assertLE); 1583 exports.expectLE = createExpect(assertLE);
1389 exports.expectLT = createExpect(assertLT); 1584 exports.expectLT = createExpect(assertLT);
1390 exports.expectNotEquals = createExpect(assertNotEquals); 1585 exports.expectNotEquals = createExpect(assertNotEquals);
1391 exports.expectNotReached = createExpect(assertNotReached); 1586 exports.expectNotReached = createExpect(assertNotReached);
1587 exports.expectAccessibilityOk = createExpect(assertAccessibilityOk);
1392 exports.preloadJavascriptLibraries = preloadJavascriptLibraries; 1588 exports.preloadJavascriptLibraries = preloadJavascriptLibraries;
1393 exports.registerMessageCallback = registerMessageCallback; 1589 exports.registerMessageCallback = registerMessageCallback;
1394 exports.registerMockGlobals = registerMockGlobals; 1590 exports.registerMockGlobals = registerMockGlobals;
1395 exports.registerMockMessageCallbacks = registerMockMessageCallbacks; 1591 exports.registerMockMessageCallbacks = registerMockMessageCallbacks;
1396 exports.resetTestState = resetTestState; 1592 exports.resetTestState = resetTestState;
1593 exports.runAccessibilityAudit = runAccessibilityAudit;
1397 exports.runAllActions = runAllActions; 1594 exports.runAllActions = runAllActions;
1398 exports.runAllActionsAsync = runAllActionsAsync; 1595 exports.runAllActionsAsync = runAllActionsAsync;
1399 exports.runTest = runTest; 1596 exports.runTest = runTest;
1400 exports.runTestFunction = runTestFunction; 1597 exports.runTestFunction = runTestFunction;
1401 exports.SaveMockArguments = SaveMockArguments; 1598 exports.SaveMockArguments = SaveMockArguments;
1402 exports.DUMMY_URL = DUMMY_URL; 1599 exports.DUMMY_URL = DUMMY_URL;
1403 exports.TEST = TEST; 1600 exports.TEST = TEST;
1404 exports.TEST_F = TEST_F; 1601 exports.TEST_F = TEST_F;
1602 exports.RUNTIME_TEST_F = TEST_F;
1405 exports.GEN = GEN; 1603 exports.GEN = GEN;
1406 exports.GEN_INCLUDE = GEN_INCLUDE; 1604 exports.GEN_INCLUDE = GEN_INCLUDE;
1407 exports.WhenTestDone = WhenTestDone; 1605 exports.WhenTestDone = WhenTestDone;
1408 1606
1409 // Import the Mock4JS helpers. 1607 // Import the Mock4JS helpers.
1410 Mock4JS.addMockSupport(exports); 1608 Mock4JS.addMockSupport(exports);
1411 })(this); 1609 })(this);
OLDNEW
« no previous file with comments | « chrome/test/data/webui/accessibility_audit_browsertest.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698