Skip to content

Commit

Permalink
chore: add parent frame context info (#2782)
Browse files Browse the repository at this point in the history
  • Loading branch information
straker authored Jan 28, 2021
1 parent 3beb0b1 commit 385d97c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 7 deletions.
6 changes: 6 additions & 0 deletions lib/core/base/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ function Context(spec) {
this.frames = [];
this.initiator =
spec && typeof spec.initiator === 'boolean' ? spec.initiator : true;
this.focusable =
spec && typeof spec.focusable === 'boolean' ? spec.focusable : true;
this.boundingClientRect =
spec && typeof spec.boundingClientRect === 'object'
? spec.boundingClientRect
: {};
this.page = false;

spec = normalizeContext(spec);
Expand Down
21 changes: 17 additions & 4 deletions lib/core/utils/collect-results-from-frames.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,45 @@ import getSelector from './get-selector';
/**
* Sends a message to axe running in frames to start analysis and collate results (via `mergeResults`)
* @private
* @param {Context} context The resolved Context object
* @param {Context} parentContent The resolved Context object
* @param {Object} options Options object (as passed to `runRules`)
* @param {string} command Command sent to all frames
* @param {Array} parameter Array of values to be passed along side the command
* @param {Function} callback Function to call when results from all frames have returned
*/
function collectResultsFromFrames(
context,
parentContent,
options,
command,
parameter,
resolve,
reject
) {
var q = queue();
var frames = context.frames;
var frames = parentContent.frames;

// Tell each axe running in each frame to collect results
frames.forEach(frame => {
const tabindex = parseInt(frame.node.getAttribute('tabindex'), 10);
const focusable = isNaN(tabindex) || tabindex >= 0;
const rect = frame.node.getBoundingClientRect();

var params = {
options: options,
command: command,
parameter: parameter,
context: {
initiator: false,
page: context.page,

// if any parent iframe is not focusable then the entire
// iframe stack is not focusable (even if the descendant
// iframe has tabindex=0 on it)
focusable: parentContent.focusable === false ? false : focusable,
boundingClientRect: {
width: rect.width,
height: rect.height
},
page: parentContent.page,
include: frame.include || [],
exclude: frame.exclude || []
}
Expand Down
2 changes: 1 addition & 1 deletion test/checks/aria/aria-prohibited-attr.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
describe.only('aria-prohibited-attr', function() {
describe('aria-prohibited-attr', function() {
'use strict';

var checkContext = axe.testUtils.MockCheckContext();
Expand Down
56 changes: 54 additions & 2 deletions test/core/base/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ describe('Context', function() {
'flatTree',
'initiator',
'page',
'frames'
'frames',
'focusable',
'boundingClientRect'
]);
assert.isArray(context.flatTree);
assert.isAtLeast(context.flatTree.length, 1);
Expand All @@ -424,7 +426,9 @@ describe('Context', function() {
'flatTree',
'initiator',
'page',
'frames'
'frames',
'focusable',
'boundingClientRect'
]);
assert.lengthOf(context.include, 1);
assert.equal(
Expand Down Expand Up @@ -513,4 +517,52 @@ describe('Context', function() {
assert.isTrue(new Context(false).page);
});
});

describe('focusable', function() {
it('should default to true', function() {
var result = new Context();
assert.isTrue(result.focusable);
});

it('should use passed in value', function() {
var result = new Context({
focusable: false
});
assert.isFalse(result.focusable);
});

it('should reject bad values', function() {
var result = new Context({
focusable: 'hello'
});
assert.isTrue(result.focusable);
});
});

describe('boundingClientRect', function() {
it('should default to empty object', function() {
var result = new Context();
assert.deepEqual(result.boundingClientRect, {});
});

it('should use passed in value', function() {
var result = new Context({
boundingClientRect: {
width: 10,
height: 20
}
});
assert.deepEqual(result.boundingClientRect, {
width: 10,
height: 20
});
});

it('should reject bad values', function() {
var result = new Context({
boundingClientRect: 'hello'
});
assert.deepEqual(result.boundingClientRect, {});
});
});
});

0 comments on commit 385d97c

Please sign in to comment.