diff --git a/lib/core/core.js b/lib/core/core.js
index cf02f7c766..7664e8b676 100644
--- a/lib/core/core.js
+++ b/lib/core/core.js
@@ -22,7 +22,12 @@ import frameMessenger from './public/frame-messenger';
import getRules from './public/get-rules';
import load from './public/load';
import registerPlugin from './public/plugins';
-import { hasReporter, getReporter, addReporter } from './public/reporter';
+import {
+ reporters,
+ hasReporter,
+ getReporter,
+ addReporter
+} from './public/reporter';
import reset from './public/reset';
import runRules from './public/run-rules';
import runVirtualRule from './public/run-virtual-rule';
@@ -62,6 +67,9 @@ axe._thisWillBeDeletedDoNotUse.base = {
Rule,
metadataFunctionMap
};
+axe._thisWillBeDeletedDoNotUse.public = {
+ reporters
+};
axe.imports = imports;
diff --git a/lib/core/public/reporter.js b/lib/core/public/reporter.js
index d3a4384c6d..a95f42f306 100644
--- a/lib/core/public/reporter.js
+++ b/lib/core/public/reporter.js
@@ -1,4 +1,4 @@
-const reporters = {};
+export const reporters = {};
let defaultReporter;
export function hasReporter(reporterName) {
diff --git a/test/integration/full/isolated-env/frames/focusable.html b/test/integration/full/isolated-env/frames/focusable.html
new file mode 100644
index 0000000000..de5374ba35
--- /dev/null
+++ b/test/integration/full/isolated-env/frames/focusable.html
@@ -0,0 +1,11 @@
+
+
+
+ Hello
+
+
+
+
+
+
+
diff --git a/test/integration/full/isolated-env/frames/isolated.html b/test/integration/full/isolated-env/frames/isolated.html
new file mode 100644
index 0000000000..b93be6ab7c
--- /dev/null
+++ b/test/integration/full/isolated-env/frames/isolated.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
diff --git a/test/integration/full/isolated-env/isolated-env.html b/test/integration/full/isolated-env/isolated-env.html
new file mode 100644
index 0000000000..defb21a83c
--- /dev/null
+++ b/test/integration/full/isolated-env/isolated-env.html
@@ -0,0 +1,124 @@
+
+
+
+ all rules test
+
+
+
+
+
+
+
+
+
+
+
+
bad link 1
+
+
+
+
+ Foo
+
+ Home
+
+ Some text
+
+
+
+
+
+ Some text and some more text
+ Newspaper
+ Copy this content
+
+
+
+ Banana error
+
+
+
+ - foo
+ - bar
+
+
+ Ok
+ Ok
+
+
+
+
+
+
+
+ Hello
+
+
+
+
+
+
+ Paragraph.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/integration/full/isolated-env/isolated-env.js b/test/integration/full/isolated-env/isolated-env.js
new file mode 100644
index 0000000000..0359b9d46c
--- /dev/null
+++ b/test/integration/full/isolated-env/isolated-env.js
@@ -0,0 +1,133 @@
+/* global chai */
+
+describe('isolated-env test', function() {
+ 'use strict';
+ var fixture = document.querySelector('#fixture');
+ var isIE11 = axe.testUtils.isIE11;
+ var origPartialResults;
+ var partialResults;
+ var win;
+
+ // just a nicer assertion error rather than just doing
+ // done(err)
+ function doesNotThrow(err, done) {
+ if (err instanceof chai.AssertionError) {
+ return done(err);
+ }
+
+ var error = new chai.AssertionError(
+ "expected [Function] to not throw an error but '" +
+ err.toString() +
+ "' was thrown"
+ );
+ done(error);
+ }
+
+ function setEmptyReporter() {
+ win.axeConfigure({
+ reporter: function(results, options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+ callback(results);
+ }
+ });
+ }
+
+ before(function(done) {
+ if (isIE11) {
+ return this.skip();
+ }
+
+ axe.testUtils.awaitNestedLoad(function() {
+ win = fixture.querySelector('#isolated-frame').contentWindow;
+ var focusableFrame = fixture.querySelector('#focusable-iframe');
+
+ // trigger frame-focusable-content rule
+ var iframePromise = focusableFrame.contentWindow.axe.runPartial({
+ include: [],
+ exclude: [],
+ initiator: false,
+ focusable: false,
+ size: { width: 10, height: 10 }
+ });
+
+ var promises = [axe.runPartial(), iframePromise];
+ Promise.all(promises)
+ .then(function(r) {
+ origPartialResults = r;
+ done();
+ })
+ .catch(done);
+ });
+ });
+
+ beforeEach(function() {
+ // calling axe.finishRun mutates the partial results
+ // object and prevents calling finishRun again with
+ // the same object
+ partialResults = axe.utils.clone(origPartialResults);
+
+ if (win.axeConfigure) {
+ win.axeConfigure({ reporter: 'v1' });
+ }
+ });
+
+ it('successfully isolates axe object in iframe', function() {
+ assert.isUndefined(win.axe);
+ assert.isDefined(win.axeFinishRun);
+ assert.isDefined(win.axeConfigure);
+ });
+
+ it('after methods do not error by calling window or DOM methods', function(done) {
+ setEmptyReporter();
+
+ win
+ .axeFinishRun(partialResults)
+ .then(function(results) {
+ assert.isDefined(results);
+ done();
+ })
+ .catch(function(err) {
+ doesNotThrow(err, done);
+ });
+ });
+
+ it('runs all rules and after methods', function(done) {
+ win
+ .axeFinishRun(partialResults)
+ .then(function(results) {
+ assert.lengthOf(results.inapplicable, 0);
+ done();
+ })
+ .catch(function(err) {
+ doesNotThrow(err, done);
+ });
+ });
+
+ describe('reporters', function() {
+ var reporters = axe._thisWillBeDeletedDoNotUse.public.reporters;
+ Object.keys(reporters).forEach(function(reporterName) {
+ it(
+ reporterName +
+ ' reporter does not error by calling window or DOM methods',
+ function(done) {
+ win.axeConfigure({
+ reporter: reporterName
+ });
+
+ win
+ .axeFinishRun(partialResults)
+ .then(function(results) {
+ assert.isDefined(results);
+ done();
+ })
+ .catch(function(err) {
+ doesNotThrow(err, done);
+ });
+ }
+ );
+ });
+ });
+});