testaro 32.2.0 → 32.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/run.js +2 -0
  3. package/tests/qualWeb.js +116 -104
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "32.2.0",
3
+ "version": "32.2.2",
4
4
  "description": "Run 960 web accessibility tests from 9 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/run.js CHANGED
@@ -422,6 +422,8 @@ const launch = async (report, typeName, url, debug, waits, isLowMotion = false)
422
422
  // Open a context (i.e. browser tab), with reduced motion if specified.
423
423
  const options = {reduceMotion: isLowMotion ? 'reduce' : 'no-preference'};
424
424
  const browserContext = await browser.newContext(options);
425
+ // Prevent default timeouts, including those arising from a Playwright bug.
426
+ browserContext.setDefaultTimeout(0);
425
427
  // When a page (i.e. browser tab) is added to the browser context (i.e. browser window):
426
428
  browserContext.on('page', async page => {
427
429
  // If it emits a message:
package/tests/qualWeb.js CHANGED
@@ -42,6 +42,7 @@ const clusterOptions = {
42
42
  exports.reporter = async (page, options) => {
43
43
  const {withNewContent, rules} = options;
44
44
  const data = {};
45
+ let result = {};
45
46
  // Start the QualWeb core engine.
46
47
  await qualWeb.start(clusterOptions);
47
48
  // Specify the invariant test options.
@@ -61,143 +62,154 @@ exports.reporter = async (page, options) => {
61
62
  }
62
63
  };
63
64
  // Specify a URL or provide the content.
64
- if (withNewContent) {
65
- qualWebOptions.url = page.url();
66
- }
67
- else {
68
- qualWebOptions.html = await page.content();
69
- }
70
- // Specify which rules to test for.
71
- const actSpec = rules ? rules.find(typeRules => typeRules.startsWith('act:')) : null;
72
- const wcagSpec = rules ? rules.find(typeRules => typeRules.startsWith('wcag:')) : null;
73
- const bestSpec = rules ? rules.find(typeRules => typeRules.startsWith('best:')) : null;
74
- if (actSpec) {
75
- if (actSpec === 'act:') {
76
- qualWebOptions.execute.act = false;
65
+ try {
66
+ if (withNewContent) {
67
+ qualWebOptions.url = page.url();
77
68
  }
78
69
  else {
79
- const actRules = actSpec.slice(4).split(',').map(num => `QW-ACT-R${num}`);
80
- qualWebOptions['act-rules'] = {rules: actRules};
70
+ qualWebOptions.html = await page.content();
71
+ }
72
+ // Specify which rules to test for.
73
+ const actSpec = rules ? rules.find(typeRules => typeRules.startsWith('act:')) : null;
74
+ const wcagSpec = rules ? rules.find(typeRules => typeRules.startsWith('wcag:')) : null;
75
+ const bestSpec = rules ? rules.find(typeRules => typeRules.startsWith('best:')) : null;
76
+ if (actSpec) {
77
+ if (actSpec === 'act:') {
78
+ qualWebOptions.execute.act = false;
79
+ }
80
+ else {
81
+ const actRules = actSpec.slice(4).split(',').map(num => `QW-ACT-R${num}`);
82
+ qualWebOptions['act-rules'] = {rules: actRules};
83
+ qualWebOptions.execute.act = true;
84
+ }
85
+ }
86
+ else {
87
+ qualWebOptions['act-rules'] = {
88
+ levels: ['A', 'AA', 'AAA'],
89
+ principles: ['Perceivable', 'Operable', 'Understandable', 'Robust']
90
+ };
81
91
  qualWebOptions.execute.act = true;
82
92
  }
83
- }
84
- else {
85
- qualWebOptions['act-rules'] = {
86
- levels: ['A', 'AA', 'AAA'],
87
- principles: ['Perceivable', 'Operable', 'Understandable', 'Robust']
88
- };
89
- qualWebOptions.execute.act = true;
90
- }
91
- if (wcagSpec) {
92
- if (wcagSpec === 'wcag:') {
93
- qualWebOptions.execute.wcag = false;
93
+ if (wcagSpec) {
94
+ if (wcagSpec === 'wcag:') {
95
+ qualWebOptions.execute.wcag = false;
96
+ }
97
+ else {
98
+ const wcagTechniques = wcagSpec.slice(5).split(',').map(num => `QW-WCAG-T${num}`);
99
+ qualWebOptions['wcag-techniques'] = {techniques: wcagTechniques};
100
+ qualWebOptions.execute.wcag = true;
101
+ }
94
102
  }
95
103
  else {
96
- const wcagTechniques = wcagSpec.slice(5).split(',').map(num => `QW-WCAG-T${num}`);
97
- qualWebOptions['wcag-techniques'] = {techniques: wcagTechniques};
104
+ qualWebOptions['wcag-techniques'] = {
105
+ levels: ['A', 'AA', 'AAA'],
106
+ principles: ['Perceivable', 'Operable', 'Understandable', 'Robust']
107
+ };
98
108
  qualWebOptions.execute.wcag = true;
99
109
  }
100
- }
101
- else {
102
- qualWebOptions['wcag-techniques'] = {
103
- levels: ['A', 'AA', 'AAA'],
104
- principles: ['Perceivable', 'Operable', 'Understandable', 'Robust']
105
- };
106
- qualWebOptions.execute.wcag = true;
107
- }
108
- if (bestSpec) {
109
- if (bestSpec === 'best:') {
110
- qualWebOptions.execute.bp = false;
110
+ if (bestSpec) {
111
+ if (bestSpec === 'best:') {
112
+ qualWebOptions.execute.bp = false;
113
+ }
114
+ else {
115
+ const bestPractices = bestSpec.slice(5).split(',').map(num => `QW-BP${num}`);
116
+ qualWebOptions['best-practices'] = {bestPractices};
117
+ // qualWebOptions.execute.bp = true;
118
+ // Temporarily disable best practices, because they crash QualWeb.
119
+ qualWebOptions.execute.bp = false;
120
+ }
111
121
  }
112
122
  else {
113
- const bestPractices = bestSpec.slice(5).split(',').map(num => `QW-BP${num}`);
114
- qualWebOptions['best-practices'] = {bestPractices};
115
123
  // qualWebOptions.execute.bp = true;
116
124
  // Temporarily disable best practices, because they crash QualWeb.
117
125
  qualWebOptions.execute.bp = false;
118
126
  }
119
- }
120
- else {
121
- // qualWebOptions.execute.bp = true;
122
- // Temporarily disable best practices, because they crash QualWeb.
123
- qualWebOptions.execute.bp = false;
124
- }
125
- // Get the report.
126
- let actReports = await qualWeb.evaluate(qualWebOptions);
127
- // Remove the copy of the DOM from it.
128
- const result = actReports[withNewContent ? qualWebOptions.url : 'customHtml'];
129
- if (result && result.system && result.system.page && result.system.page.dom) {
130
- delete result.system.page.dom;
131
- // For each test section of the act report:
132
- const {modules} = result;
133
- if (modules) {
134
- for (const section of ['act-rules', 'wcag-techniques', 'best-practices']) {
135
- if (qualWebOptions[section]) {
136
- if (modules[section]) {
137
- const {assertions} = modules[section];
138
- if (assertions) {
139
- const ruleIDs = Object.keys(assertions);
140
- ruleIDs.forEach(ruleID => {
141
- // Remove passing results.
142
- const ruleAssertions = assertions[ruleID];
143
- const {metadata} = ruleAssertions;
144
- if (metadata) {
145
- if (metadata.warning === 0 && metadata.failed === 0) {
146
- delete assertions[ruleID];
147
- }
148
- else {
149
- if (ruleAssertions.results) {
150
- ruleAssertions.results = ruleAssertions.results.filter(
151
- raResult => raResult.verdict !== 'passed'
152
- );
127
+ // Get the report.
128
+ let actReports = await qualWeb.evaluate(qualWebOptions);
129
+ // Remove the copy of the DOM from it.
130
+ result = actReports[withNewContent ? qualWebOptions.url : 'customHtml'];
131
+ if (result && result.system && result.system.page && result.system.page.dom) {
132
+ delete result.system.page.dom;
133
+ // For each test section of the act report:
134
+ const {modules} = result;
135
+ if (modules) {
136
+ for (const section of ['act-rules', 'wcag-techniques', 'best-practices']) {
137
+ if (qualWebOptions[section]) {
138
+ if (modules[section]) {
139
+ const {assertions} = modules[section];
140
+ if (assertions) {
141
+ const ruleIDs = Object.keys(assertions);
142
+ ruleIDs.forEach(ruleID => {
143
+ // Remove passing results.
144
+ const ruleAssertions = assertions[ruleID];
145
+ const {metadata} = ruleAssertions;
146
+ if (metadata) {
147
+ if (metadata.warning === 0 && metadata.failed === 0) {
148
+ delete assertions[ruleID];
153
149
  }
154
- }
155
- }
156
- // Shorten long HTML codes of elements.
157
- const {results} = ruleAssertions;
158
- results.forEach(raResult => {
159
- const {elements} = raResult;
160
- if (elements && elements.length) {
161
- elements.forEach(element => {
162
- if (element.htmlCode && element.htmlCode.length > 700) {
163
- element.htmlCode = `${element.htmlCode.slice(0, 700)} …`;
150
+ else {
151
+ if (ruleAssertions.results) {
152
+ ruleAssertions.results = ruleAssertions.results.filter(
153
+ raResult => raResult.verdict !== 'passed'
154
+ );
164
155
  }
165
- });
156
+ }
166
157
  }
158
+ // Shorten long HTML codes of elements.
159
+ const {results} = ruleAssertions;
160
+ results.forEach(raResult => {
161
+ const {elements} = raResult;
162
+ if (elements && elements.length) {
163
+ elements.forEach(element => {
164
+ if (element.htmlCode && element.htmlCode.length > 700) {
165
+ element.htmlCode = `${element.htmlCode.slice(0, 700)} …`;
166
+ }
167
+ });
168
+ }
169
+ });
167
170
  });
168
- });
171
+ }
172
+ else {
173
+ data.prevented = true;
174
+ data.error = 'ERROR: No assertions';
175
+ }
169
176
  }
170
177
  else {
171
178
  data.prevented = true;
172
- data.error = 'ERROR: No assertions';
179
+ data.error = `ERROR: No ${section} section`;
173
180
  }
174
181
  }
175
- else {
176
- data.prevented = true;
177
- data.error = `ERROR: No ${section} section`;
178
- }
179
182
  }
180
183
  }
184
+ else {
185
+ data.prevented = true;
186
+ data.error = 'ERROR: No modules';
187
+ }
181
188
  }
182
189
  else {
183
190
  data.prevented = true;
184
- data.error = 'ERROR: No modules';
191
+ data.error = 'ERROR: No DOM';
185
192
  }
186
- }
187
- else {
188
- data.prevented = true;
189
- data.error = 'ERROR: No DOM';
190
- }
191
- // Stop the QualWeb core engine.
192
- await qualWeb.stop();
193
- // Return the result.
194
- try {
195
- JSON.stringify(result);
193
+ // Stop the QualWeb core engine.
194
+ await qualWeb.stop();
195
+ // Return the result.
196
+ try {
197
+ JSON.stringify(result);
198
+ }
199
+ catch(error) {
200
+ const message = `ERROR: qualWeb result cannot be made JSON (${error.message})`;
201
+ data.prevented = true;
202
+ data.error = message;
203
+ };
196
204
  }
197
205
  catch(error) {
198
- const message = `ERROR: qualWeb result cannot be made JSON (${error.message})`;
206
+ const message = error.message.slice(0, 200);
199
207
  data.prevented = true;
200
208
  data.error = message;
209
+ result = {
210
+ prevented: true,
211
+ error: message
212
+ };
201
213
  };
202
214
  return {
203
215
  data,