Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(reporter): Run inside isolated contexts #3129

Merged
merged 3 commits into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
root: true,
extends: ['prettier'],
parserOptions: {
ecmaVersion: 2021
Expand Down Expand Up @@ -70,6 +71,10 @@ module.exports = {
overrides: [
{
files: ['lib/**/*.js'],
excludedFiles: [
'lib/core/reporters/**/*.js',
'lib/**/*-after.js'
],
parserOptions: {
sourceType: 'module'
},
Expand All @@ -87,6 +92,15 @@ module.exports = {
'no-use-before-define': 'off'
}
},
{
files: [
'lib/**/*-after.js',
'lib/core/reporters/**/*.js'
],
parserOptions: {
sourceType: 'module'
}
},
{
files: ['test/**/*.js'],
parserOptions: {
Expand Down
3 changes: 2 additions & 1 deletion lib/core/public/finish-run.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

export default function finishRun(partialResults, options = {}) {
options = clone(options);
const { environmentData } = partialResults.find(r => r.environmentData) || {}

// normalize the runOnly option for the output of reporters toolOptions
axe._audit.normalizeOptions(options);
Expand All @@ -20,7 +21,7 @@ export default function finishRun(partialResults, options = {}) {
results.forEach(publishMetaData);
results = results.map(finalizeRuleResult);

return createReport(results, options);
return createReport(results, { environmentData, ...options });
}

function setFrameSpec(partialResults) {
Expand Down
9 changes: 7 additions & 2 deletions lib/core/public/run-partial.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Context from '../base/context';
import teardown from './teardown';
import { DqElement, getSelectorData, assert } from '../utils';
import { DqElement, getSelectorData, assert, getEnvironmentData } from '../utils';
import normalizeRunParams from './run/normalize-run-params';

export default function runPartial(...args) {
Expand Down Expand Up @@ -28,7 +28,12 @@ export default function runPartial(...args) {
const frames = contextObj.frames.map(({ node }) => {
return new DqElement(node, options).toJSON();
});
return { results, frames };
let environmentData;
if (contextObj.initiator) {
environmentData = getEnvironmentData();
}

return { results, frames, environmentData };
})
.finally(() => {
axe._running = false;
Expand Down
3 changes: 2 additions & 1 deletion lib/core/public/run-virtual-rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
publishMetaData,
finalizeRuleResult,
aggregateResult,
getEnvironmentData,
getRule
} from '../utils';

Expand Down Expand Up @@ -54,7 +55,7 @@ function runVirtualRule(ruleId, vNode, options = {}) {
);

return {
...helpers.getEnvironmentData(),
...getEnvironmentData(),
...results,
toolOptions: options
};
Expand Down
39 changes: 0 additions & 39 deletions lib/core/reporters/helpers/get-environment-data.js

This file was deleted.

3 changes: 0 additions & 3 deletions lib/core/reporters/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import failureSummary from './failure-summary';
import getEnvironmentData from './get-environment-data';
import incompleteFallbackMessage from './incomplete-fallback-msg';
import processAggregate from './process-aggregate';

Expand All @@ -8,14 +7,12 @@ import processAggregate from './process-aggregate';
axe._thisWillBeDeletedDoNotUse = axe._thisWillBeDeletedDoNotUse || {};
axe._thisWillBeDeletedDoNotUse.helpers = {
failureSummary,
getEnvironmentData,
incompleteFallbackMessage,
processAggregate
};

export {
failureSummary,
getEnvironmentData,
incompleteFallbackMessage,
processAggregate
};
7 changes: 5 additions & 2 deletions lib/core/reporters/na.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { processAggregate, getEnvironmentData } from './helpers';
import { processAggregate } from './helpers';
import { getEnvironmentData } from '../utils';

const naReporter = (results, options, callback) => {
console.warn(
Expand All @@ -9,10 +10,12 @@ const naReporter = (results, options, callback) => {
callback = options;
options = {};
}
const environmentData = options.environmentData;
delete options.environmentData

var out = processAggregate(results, options);
callback({
...getEnvironmentData(),
...getEnvironmentData(environmentData),
toolOptions: options,
violations: out.violations,
passes: out.passes,
Expand Down
7 changes: 5 additions & 2 deletions lib/core/reporters/no-passes.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { processAggregate, getEnvironmentData } from './helpers';
import { processAggregate } from './helpers';
import { getEnvironmentData } from '../utils';

const noPassesReporter = (results, options, callback) => {
if (typeof options === 'function') {
callback = options;
options = {};
}
const environmentData = options.environmentData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than delete on options we should just destructor it

const { environmentData, ...toolOptions } = options;

var out = processAggregate(results, toolOptions);

callback({
  ...getEnvironmentData(environmentData),
  toolOptions,
  violations: out.violations
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... yeah that feels like a thing I should have thought of. Good one.

delete options.environmentData
// limit result processing to types we want to include in the output
options.resultTypes = ['violations'];

var out = processAggregate(results, options);

callback({
...getEnvironmentData(),
...getEnvironmentData(environmentData),
toolOptions: options,
violations: out.violations
});
Expand Down
6 changes: 4 additions & 2 deletions lib/core/reporters/raw-env.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { getEnvironmentData } from './helpers';
import { getEnvironmentData } from '../utils';
import rawReporter from './raw';

const rawEnvReporter = (results, options, callback) => {
if (typeof options === 'function') {
callback = options;
options = {};
}
const environmentData = options.environmentData;
delete options.environmentData
function rawCallback(raw) {
const env = getEnvironmentData();
const env = getEnvironmentData(environmentData);
callback({ raw, env });
}

Expand Down
13 changes: 6 additions & 7 deletions lib/core/reporters/v1.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import {
processAggregate,
failureSummary,
getEnvironmentData
} from './helpers';
import { processAggregate, failureSummary } from './helpers';
import { getEnvironmentData } from '../utils'

const v1Reporter = (results, options, callback) => {
if (typeof options === 'function') {
callback = options;
options = {};
}
};
const environmentData = options.environmentData;
delete options.environmentData
var out = processAggregate(results, options);

const addFailureSummaries = result => {
Expand All @@ -21,7 +20,7 @@ const v1Reporter = (results, options, callback) => {
out.violations.forEach(addFailureSummaries);

callback({
...getEnvironmentData(),
...getEnvironmentData(environmentData),
toolOptions: options,
violations: out.violations,
passes: out.passes,
Expand Down
8 changes: 6 additions & 2 deletions lib/core/reporters/v2.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { processAggregate, getEnvironmentData } from './helpers';
import { processAggregate } from './helpers';
import { getEnvironmentData } from '../utils';

const v2Reporter = (results, options, callback) => {
if (typeof options === 'function') {
callback = options;
options = {};
}
const environmentData = options.environmentData;
delete options.environmentData;

var out = processAggregate(results, options);
callback({
...getEnvironmentData(),
...getEnvironmentData(environmentData),
toolOptions: options,
violations: out.violations,
passes: out.passes,
Expand Down
48 changes: 48 additions & 0 deletions lib/core/utils/get-environment-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Add information about the environment axe was run in.
* @return {Object}
*/
export default function getEnvironmentData(metadata = null, win = window) {
if (metadata && typeof metadata === 'object') {
return metadata;
} else if (typeof win !== 'object') {
return {}
}

return {
testEngine: {
name: 'axe-core',
version: axe.version
},
testRunner: {
name: axe._audit.brand
},
testEnvironment: getTestEnvironment(win),
timestamp: new Date().toISOString(),
url: win?.location?.href
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already know win is an object so no need to optionally chain it

Suggested change
url: win?.location?.href
url: win.location?.href

};
}

function getTestEnvironment(win) {
if (typeof window !== 'object' || typeof window.navigator !== 'object') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already know win is an object from the top-level call (also need to use win instead of window)

Suggested change
if (typeof window !== 'object' || typeof window.navigator !== 'object') {
if (typeof win.navigator !== 'object') {

return {}
}
const { navigator, innerHeight, innerWidth } = win;
const orientation = getOrientation(win);
return {
userAgent: navigator?.userAgent,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already know win.navigator is an object so no need to optionally chain it

Suggested change
userAgent: navigator?.userAgent,
userAgent: navigator.userAgent,

windowWidth: innerWidth,
windowHeight: innerHeight,
orientationAngle: orientation.angle,
orientationType: orientation.type
}
}

function getOrientation({ screen }) {
return (
screen.orientation ||
screen.msOrientation ||
screen.mozOrientation ||
{}
);
}
1 change: 1 addition & 0 deletions lib/core/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export { default as getAllChecks } from './get-all-checks';
export { default as getBaseLang } from './get-base-lang';
export { default as getCheckMessage } from './get-check-message';
export { default as getCheckOption } from './get-check-option';
export { default as getEnvironmentData } from './get-environment-data';
export { default as getFrameContexts } from './get-frame-contexts';
export { default as getFriendlyUriEnd } from './get-friendly-uri-end';
export { default as getNodeAttributes } from './get-node-attributes';
Expand Down
18 changes: 18 additions & 0 deletions test/core/public/finish-run.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ describe('axe.finishRun', function() {
.catch(done);
});

it('takes partialResult.environmentData to the reporter', function (done) {
var testEngine = {
name: 'dummy-engine',
version: '1.2.3.4.5'
};
axe
.runPartial()
.then(function(partialResult) {
partialResult.environmentData = { testEngine: testEngine }
return axe.finishRun([partialResult], { runOnly: 'region' });
})
.then(function(results) {
assert.deepEqual(results.testEngine, testEngine);
done();
})
.catch(done);
});

it('can report violations results', function(done) {
fixture.innerHTML = '<div aria-label="foo"></div>';
axe
Expand Down
24 changes: 24 additions & 0 deletions test/core/public/run-partial.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,30 @@ describe('axe.runPartial', function() {
});
});

describe('environmentData', function () {
it('is include environment data for the initiator', function (done) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it('is include environment data for the initiator', function (done) {
it('includes environment data for the initiator', function (done) {

var context = {
include: ['#fixture']
}
axe.runPartial(context, { runOnly: 'image-alt' }).then(function(out) {
var keys = Object.keys(axe.utils.getEnvironmentData());
assert.hasAllKeys(out.environmentData, keys);
done();
}).catch(done);
});

it('is undefined for frames', function (done) {
var context = {
include: ['#fixture'],
initiator: false
}
axe.runPartial(context, { runOnly: 'image-alt' }).then(function(out) {
assert.isUndefined(out.environmentData);
done();
}).catch(done);
});
});

describe('guards', function() {
var audit = axe._audit;
afterEach(function() {
Expand Down
Loading