@@ -231,6 +231,13 @@ describe('axe.utils.getFlattenedTree', function() {
 				assert.equal(virtualDOM[0].actualNode, vNode.actualNode);
 			});
 		});
+	} else {
+		it('does not throw when slot elements are used', function () {
+			fixture.innerHTML = '<button><slot></slot></button>';
+			assert.doesNotThrow(function () {
+				axe.utils.getFlattenedTree(fixture);
+			});
+		});
 	}
 
 	if (shadowSupport.undefined) {
var fixture = document.getElementById('fixture');
var shadowSupport = axe.testUtils.shadowSupport;

describe('axe.utils.getFlattenedTree', function() {
	'use strict';

	function createStyle (box) {
		var style = document.createElement('style');
		style.textContent = 'div.breaking { color: Red;font-size: 20px; border: 1px dashed Purple; }' +
			(box ? 'slot { display: block; }' : '') +
			'div.other { padding: 2px 0 0 0; border: 1px solid Cyan; }';
		return style;
	}

	function flattenedTreeAssertions () {
		var virtualDOM = axe.utils.getFlattenedTree(fixture.firstChild);
		assert.equal(virtualDOM.length, 1); // host
		assert.equal(virtualDOM[0].actualNode.nodeName, 'DIV');

		virtualDOM = virtualDOM[0].children;
		assert.equal(virtualDOM.length, 3);
		assert.equal(virtualDOM[0].actualNode.nodeName, 'STYLE');

		// breaking news stories
		assert.equal(virtualDOM[1].actualNode.nodeName, 'DIV');
		assert.equal(virtualDOM[1].actualNode.className, 'breaking');

		// other news stories
		assert.equal(virtualDOM[2].actualNode.nodeName, 'DIV');
		assert.equal(virtualDOM[2].actualNode.className, 'other');

		// breaking
		assert.equal(virtualDOM[1].children.length, 1);
		assert.equal(virtualDOM[1].children[0].actualNode.nodeName, 'UL');
		virtualDOM[1].children[0].children.forEach(function (child, index) {
			assert.equal(child.actualNode.nodeName, 'LI');
			assert.isTrue(child.actualNode.textContent === 3*(index + 1) + '');
		});
		assert.equal(virtualDOM[1].children[0].children.length, 2);

		// other
		assert.equal(virtualDOM[2].children.length, 1);
		assert.equal(virtualDOM[2].children[0].actualNode.nodeName, 'UL');
		assert.equal(virtualDOM[2].children[0].children.length, 4);
	}

	function shadowIdAssertions () {
		var virtualDOM = axe.utils.getFlattenedTree(fixture);
		assert.isUndefined(virtualDOM[0].shadowId); //fixture
		assert.isUndefined(virtualDOM[0].children[0].shadowId); //host
		assert.isDefined(virtualDOM[0].children[0].children[0].shadowId);
		assert.isDefined(virtualDOM[0].children[0].children[1].shadowId);
		assert.isDefined(virtualDOM[0].children[1].children[0].shadowId);
		// shadow IDs in the same shadowRoot must be the same
		assert.equal(virtualDOM[0].children[0].children[0].shadowId,
			virtualDOM[0].children[0].children[1].shadowId);
		// should cascade
		assert.equal(virtualDOM[0].children[0].children[1].shadowId,
			virtualDOM[0].children[0].children[1].children[0].shadowId);
		// shadow IDs in different shadowRoots must be different
		assert.notEqual(virtualDOM[0].children[0].children[0].shadowId,
			virtualDOM[0].children[1].children[0].shadowId);

	}

	if (shadowSupport.v0) {
		describe('shadow DOM v0', function () {
			afterEach(function () {
				fixture.innerHTML = '';
			});
			beforeEach(function () {
				function createStoryGroup (className, contentSelector) {
					var group = document.createElement('div');
					group.className = className;
					group.innerHTML = '<ul><content select="' + contentSelector + '"></content></ul>';
					return group;
				}

				function makeShadowTree (storyList) {
					var root = storyList.createShadowRoot();
					root.appendChild(createStyle());
					root.appendChild(createStoryGroup('breaking', '.breaking'));
					root.appendChild(createStoryGroup('other', ''));
				}
				var str = '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking">6</li></div>';
				str += '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking">6</li></div>';
				fixture.innerHTML = str;

				fixture.querySelectorAll('.stories').forEach(makeShadowTree);
			});
			it('it should support shadow DOM v0', function () {
				assert.isDefined(fixture.firstChild.shadowRoot);
			});
			it('getFlattenedTree should return an array of stuff', function () {
				assert.isTrue(Array.isArray(axe.utils.getFlattenedTree(fixture.firstChild)));
			});
			it('getFlattenedTree\'s virtual DOM should represent the flattened tree', flattenedTreeAssertions);
			it('getFlattenedTree\'s virtual DOM should give an ID to the shadow DOM', shadowIdAssertions);
		});
	}

	if (shadowSupport.v1) {
		describe('shadow DOM v1', function () {
			afterEach(function () {
				fixture.innerHTML = '';
			});
			beforeEach(function () {
				function createStoryGroup (className, slotName) {
					var group = document.createElement('div');
					group.className = className;
					// Empty string in slot name attribute or absence thereof work the same, so no need for special handling.
					group.innerHTML = '<ul><slot name="' + slotName + '">fallback content<li>one</li></slot></ul>';
					return group;
				}

				function makeShadowTree (storyList) {
					var root = storyList.attachShadow({mode: 'open'});
					root.appendChild(createStyle());
					root.appendChild(createStoryGroup('breaking', 'breaking'));
					root.appendChild(createStoryGroup('other', ''));
				}
				var str = '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"></div>';
				fixture.innerHTML = str;

				fixture.querySelectorAll('.stories').forEach(makeShadowTree);
			});
			it('should support shadow DOM v1', function () {
				assert.isDefined(fixture.firstChild.shadowRoot);
			});
			it('getFlattenedTree should return an array of stuff', function () {
				assert.isTrue(Array.isArray(axe.utils.getFlattenedTree(fixture.firstChild)));
			});
			it('getFlattenedTree\'s virtual DOM should represent the flattened tree', flattenedTreeAssertions);
			it('getFlattenedTree\'s virtual DOM should give an ID to the shadow DOM', shadowIdAssertions);
			it('getFlattenedTree\'s virtual DOM should have the fallback content', function () {
				var virtualDOM = axe.utils.getFlattenedTree(fixture);
				assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children.length === 2);
				assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.nodeType === 3);
				assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[0].actualNode.textContent === 'fallback content');
				assert.isTrue(virtualDOM[0].children[2].children[1].children[0].children[1].actualNode.nodeName === 'LI');
			});
		});
		describe('shadow DOM v1: boxed slots', function () {
			afterEach(function () {
				fixture.innerHTML = '';
			});
			beforeEach(function () {
				function createStoryGroup (className, slotName) {
					var group = document.createElement('div');
					group.className = className;
					// Empty string in slot name attribute or absence thereof work the same, so no need for special handling.
					group.innerHTML = '<ul><slot name="' + slotName + '">fallback content<li>one</li></slot></ul>';
					return group;
				}

				function makeShadowTree (storyList) {
					var root = storyList.attachShadow({mode: 'open'});
					root.appendChild(createStyle(true));
					root.appendChild(createStoryGroup('breaking', 'breaking'));
					root.appendChild(createStoryGroup('other', ''));
				}
				var str = '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"></div>';
				fixture.innerHTML = str;

				fixture.querySelectorAll('.stories').forEach(makeShadowTree);
			});
			it('getFlattenedTree\'s virtual DOM should have the <slot> elements', function () {
				return; // Chrome's implementation of slot is broken
				// var virtualDOM = axe.utils.getFlattenedTree(fixture);
				// assert.isTrue(virtualDOM[0].children[1].children[0].children[0].actualNode.nodeName === 'SLOT');
			});
		});
		describe('getNodeFromTree', function () {
			afterEach(function () {
				fixture.innerHTML = '';
			});
			beforeEach(function () {
				function createStoryGroup (className, slotName) {
					var group = document.createElement('div');
					group.className = className;
					// Empty string in slot name attribute or absence thereof work the same, so no need for special handling.
					group.innerHTML = '<ul><slot name="' + slotName + '">fallback content<li>one</li></slot></ul>';
					return group;
				}

				function makeShadowTree (storyList) {
					var root = storyList.attachShadow({mode: 'open'});
					root.appendChild(createStyle());
					root.appendChild(createStoryGroup('breaking', 'breaking'));
					root.appendChild(createStoryGroup('other', ''));
				}
				var str = '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"><li>1</li>' +
				'<li>2</li><li class="breaking" slot="breaking">3</li>' +
				'<li>4</li><li>5</li><li class="breaking" slot="breaking">6</li></div>';
				str += '<div class="stories"></div>';
				fixture.innerHTML = str;

				fixture.querySelectorAll('.stories').forEach(makeShadowTree);
			});
			it('should find the virtual node that matches the real node passed in', function () {
				var virtualDOM = axe.utils.getFlattenedTree(fixture);
				var node = document.querySelector('.stories li');
				var vNode = axe.utils.getNodeFromTree(virtualDOM[0], node);
				assert.isDefined(vNode);
				assert.equal(node, vNode.actualNode);
				assert.equal(vNode.actualNode.textContent, '1');
			});
			it('should find the virtual node if it is the very top of the tree', function () {
				var virtualDOM = axe.utils.getFlattenedTree(fixture);
				var vNode = axe.utils.getNodeFromTree(virtualDOM[0], virtualDOM[0].actualNode);
				assert.isDefined(vNode);
				assert.equal(virtualDOM[0].actualNode, vNode.actualNode);
			});
		});
	}

	if (shadowSupport.undefined) {
		describe('shadow dom undefined', function () {
			it('SHADOW DOM TESTS DEFERRED, NO SUPPORT');
		});
	}
});
Why is this outside the shadow DOM `if`?