summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/accessibility')
-rw-r--r--testing/web-platform/tests/accessibility/ReadMe.md14
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/activedescendant-crash.html7
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/add-detached-node.html23
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/animated-textarea.html17
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aom-in-destroyed-iframe.html35
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/append-image-using-illegal-map.html8
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-hidden-with-select.html25
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-modal-aria-hidden.html28
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owned-with-role-change.html33
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-destroyed-by-content-replacement.html14
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-fallback-content.html19
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-from-aria-hidden-subtree.html34
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-inside-map.html22
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-new-cycle.html23
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-overlapping.html25
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-owned-becomes-aria-hidden.html27
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-owner-becomes-aria-hidden.html27
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-presentation.html3
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-reparent.html21
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-select.html11
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/aria-owns-with-role-change.html33
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/bdo-table-cell.html21
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/br-in-changed-subtree.html5
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/computed-accessible-child-of-pseudo-element.html32
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/computed-accessible-text-node.html24
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/computed-node-checked.html49
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/computed-node.html8
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/content-visibility-focusable-scroller-descendant.html11
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/content-visibility-generated-content-removal.html32
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/delayed-ignored-change.html19
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/display-table-column.html31
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/displaylocked-serialize.html14
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/first-letter-inside-before-pseudo.html25
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/hidden-textfield-with-combobox.html8
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/iframe-owns-child.html2
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/iframe-srcdoc.html1
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/illegal-aria-owns-from-br.html3
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/illegal-optgroup-structure.html6
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/img-map-pseudo.html11
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/in-page-link-with-aria-hidden.html2
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/included-descendant-dom-removal.html27
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/included-descendant-layout-removal.html28
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/inert-br-child.html17
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/input-time-datalist.html2
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/map-inside-map-2.html11
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/map-inside-map.html16
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/map-update-crash.html18
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/missing-parent.html32
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/move-owned-inside-another-owned.html13
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/multicol-with-text-change-role-relayout-crash.html22
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/null-node.html10
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/object-with-unrendered-text-fallback.html11
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/remaining-invalid-objects.html7
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/removed-from-flat-tree.html3
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/select-in-display-none.html25
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/serialize-with-no-document.html5
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/slot-assignment-lockup.html34
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/svg-mouse-listener.html19
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/table-ignored-child.html18
-rw-r--r--testing/web-platform/tests/accessibility/crashtests/validation-message.html5
60 files changed, 1076 insertions, 0 deletions
diff --git a/testing/web-platform/tests/accessibility/ReadMe.md b/testing/web-platform/tests/accessibility/ReadMe.md
new file mode 100644
index 0000000000..ecfb30b161
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/ReadMe.md
@@ -0,0 +1,14 @@
+# ReadMe for /accessibility
+
+This top-level `/accessibility` directory contains primarily (only?) general crash tests.
+
+Accessibility specs are tested in top-level directories named after the particular spec. For example, see automated accessibility tests in:
+
+- `/wai-aria`
+- `/html-aam`
+- `/accname`
+- etc.
+
+Primary reviewers for each of those specs can often be found in the META.yml file in each respective directory. Reach out directly or file related issues in each spec repo.
+
+Pull requests welcome. Thank you!
diff --git a/testing/web-platform/tests/accessibility/crashtests/activedescendant-crash.html b/testing/web-platform/tests/accessibility/crashtests/activedescendant-crash.html
new file mode 100644
index 0000000000..ac0dc5d5ed
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/activedescendant-crash.html
@@ -0,0 +1,7 @@
+<iframe></iframe>
+<script>
+let frame = document.querySelector("iframe");
+window.xyz = frame.contentWindow.accessibilityController.focusedElement;
+frame.remove();
+window.xyz.activeDescendant;
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/add-detached-node.html b/testing/web-platform/tests/accessibility/crashtests/add-detached-node.html
new file mode 100644
index 0000000000..91aaa9c500
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/add-detached-node.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<body onload="start()">
+<script>
+ function start() {
+ requestAnimationFrame(() => {
+ target2.placeholder = "string";
+ target1.type = "hidden";
+ document.documentElement.className = '';
+ });
+ }
+</script>
+
+<ol id=target1 inert>
+ <content>
+ <textarea id=target2></textarea>
+ <semantics>
+ <optgroup></optgroup>
+ </semantics>
+ </content>
+</ol>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/animated-textarea.html b/testing/web-platform/tests/accessibility/crashtests/animated-textarea.html
new file mode 100644
index 0000000000..a23eed669c
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/animated-textarea.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- This tests that the anonymous descendants of the textarea do not lose
+ their attachment to parent objects -->
+<html class="test-wait">
+<canvas>
+<textarea>
+</textarea>
+<script>
+const canvas = document.querySelector('canvas');
+const animation = canvas.animate([
+ {"listStylePosition":"outside"}, {"listStylePosition":"inside"}],
+ {"duration":100,"delay":0});
+animation.addEventListener('finish', () => {
+ document.documentElement.className = '';
+});
+</script>
+</canvas>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aom-in-destroyed-iframe.html b/testing/web-platform/tests/accessibility/crashtests/aom-in-destroyed-iframe.html
new file mode 100644
index 0000000000..c8f0aca12e
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aom-in-destroyed-iframe.html
@@ -0,0 +1,35 @@
+<html class="test-wait">
+<body></body>
+<script>
+
+// Bypass this abandoned syntax in all but the engines that implement it.
+if (typeof getComputedAccessibleNode !== 'undefined') {
+
+ const frameElem = document.createElement('iframe');
+
+ frameElem.srcdoc = '<html><head><title>X</title></head><body><div>-</div></body></html>';
+ frameElem.onload = function() {
+ const frameDoc = frameElem.contentWindow.document;
+
+ const divElem = frameDoc.querySelector('div');
+
+ getComputedAccessibleNode(divElem).then(function(divAccessible) {
+ // Close window.
+ frameElem.remove();
+
+ requestAnimationFrame(() => {
+ // Window removed, but we try to access DOM of non-existent window.
+ const isChecked = divAccessible.checked;
+ // Test is complete.
+ document.documentElement.className = '';
+ });
+ });
+ };
+ document.body.appendChild(frameElem);
+
+} else {
+ // Pass in other engines that have not implemented the abandoned API
+ document.documentElement.className = '';
+}
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/append-image-using-illegal-map.html b/testing/web-platform/tests/accessibility/crashtests/append-image-using-illegal-map.html
new file mode 100644
index 0000000000..c78e74eeed
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/append-image-using-illegal-map.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<map name="map1"><button><li>xyz</li></button></map>
+<script>
+ const image = document.createElement('img');
+ image.setAttribute('src', 'exists.gif');
+ image.setAttribute('usemap', '#map1');
+ document.documentElement.appendChild(image);
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-hidden-with-select.html b/testing/web-platform/tests/accessibility/crashtests/aria-hidden-with-select.html
new file mode 100644
index 0000000000..2aedbcfb82
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-hidden-with-select.html
@@ -0,0 +1,25 @@
+<html class="test-wait">
+<head>
+<script>
+window.onload = function() {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('#will-hide').ariaHidden = 'true';
+ document.documentElement.className = '';
+ });
+ });
+};
+</script>
+</head>
+<body>
+<main>
+ <div id="will-hide">
+ <div class="ignored">
+ <select id="select">
+ <option>1</option>
+ </select>
+ </div>
+ </div>
+</main>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-modal-aria-hidden.html b/testing/web-platform/tests/accessibility/crashtests/aria-modal-aria-hidden.html
new file mode 100644
index 0000000000..520710381c
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-modal-aria-hidden.html
@@ -0,0 +1,28 @@
+<!-- Test that aria-modal, aria-owns, aria-hidden, and aria-labelledby can work together without crashing.
+ This test case is a minimized version of a crash that occurred from a chat app. -->
+<!DOCTYPE html>
+<html class="test-wait">
+<div role="main" aria-owns="owned"></div>
+<div id="owned">
+ <span aria-hidden="true" id="hidden-label"></span>
+</div>
+<div role="dialog" aria-modal="true">
+ <a aria-labelledby="hidden-label"></a>
+</div>
+<script>
+let dialogNode = null;
+
+document.addEventListener('DOMContentLoaded', () => {
+ dialogNode = document.querySelector("[role=dialog]")
+ dialogNode.remove();
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector("[role=main]").setAttribute("aria-hidden", true);
+ document.querySelector("body").appendChild(dialogNode);
+ document.documentElement.className = '';
+ });
+ });
+});
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owned-with-role-change.html b/testing/web-platform/tests/accessibility/crashtests/aria-owned-with-role-change.html
new file mode 100644
index 0000000000..c5b2130969
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owned-with-role-change.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<!-- Test that setting the role an an aria-owns child does not crash. -->
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.getElementById('paragraph1').role = 'tab';
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+ });
+ });
+});
+</script>
+</head>
+<body>
+<main>
+ <fieldset id='owner' aria-owns="paragraph1">
+ <div>
+ <p id="paragraph1">
+ <mark>
+ Child
+ </mark>
+ </p>
+ </div>
+ </fieldset>
+</main>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-destroyed-by-content-replacement.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-destroyed-by-content-replacement.html
new file mode 100644
index 0000000000..b64ebaa602
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-destroyed-by-content-replacement.html
@@ -0,0 +1,14 @@
+<html class="test-wait">
+<script>
+window.onload = function fuzz() {
+ document.querySelector('audio').setAttribute('aria-owns', 'x1');
+ requestAnimationFrame(() => {
+ document.querySelector('audio').removeAttribute('aria-owns');
+ document.documentElement.className = '';
+ });
+}
+</script>
+<audio>
+ <span id="x1"></span>
+</audio>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-fallback-content.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-fallback-content.html
new file mode 100644
index 0000000000..8a7c9ab6d0
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-fallback-content.html
@@ -0,0 +1,19 @@
+<html class="test-wait">
+<body>
+<div aria-owns="id1"></div>
+<video>
+ <mark>
+ <span id='id1'></span>
+ </mark>
+</video>
+</body>
+<script>
+window.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.style.display = 'none';
+ document.documentElement.className = '';
+ });
+ });
+}
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-from-aria-hidden-subtree.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-from-aria-hidden-subtree.html
new file mode 100644
index 0000000000..3e148ae981
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-from-aria-hidden-subtree.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<!-- Test that setting aria-owns from an aria-hidden subtree does not crash -->
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.getElementById('owner').removeAttribute('aria-owns');
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+ });
+ });
+});
+</script>
+</head>
+<body>
+<main aria-hidden="true">
+ <fieldset id='owner' aria-owns="paragraph1">
+ Text
+ </fieldset>
+</main>
+
+<div role="complementary" aria-label="Natural parent">
+ <p id="paragraph1">
+ <mark>
+ Child
+ </mark>
+ </p>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-inside-map.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-inside-map.html
new file mode 100644
index 0000000000..10da915c47
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-inside-map.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- Test that aria-owns pointing into a map does not crash -->
+<html class="test-wait">
+<map >
+ <a href=''>
+ <del id='1' hidden></del>
+ <del id='2'></del>
+ </a>
+</map>
+<div></div>
+
+<script>
+document.addEventListener('DOMContentLoaded', () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('div').setAttribute('aria-owns','2 1');
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-new-cycle.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-new-cycle.html
new file mode 100644
index 0000000000..fbf0aade1a
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-new-cycle.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<!-- Changing ids and creating an aria-owns cycle with the new id doesn't crash -->
+<script class="test-wait">
+document.addEventListener("DOMContentLoaded", () => {
+ document.getElementById('will-be-div-child').id='div-child';
+ document.querySelector('div').setAttribute('aria-owns','div-child');
+ document.getElementById('div-child').setAttribute('aria-owns','cycle-owns');
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+<body>
+ <option>
+ <canvas id="cycle-owns">
+ <dialog id="will-be-div-child"></dialog>
+ </canvas>
+ </option>
+ <meter id="div-child"></meter>
+ <div></div>
+</body>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-overlapping.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-overlapping.html
new file mode 100644
index 0000000000..e98ad6fb76
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-overlapping.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<!-- Test that multiple overlapping aria-owns relation do not crash -->
+
+<html class="test-wait">
+<main id='great-grandparent'>
+ <fieldset id="grandparent">
+ <p id='parent'>
+ <i id='child'></i>
+ </p>
+ </fieldset>
+</main>
+
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ document.getElementById('child').setAttribute('aria-owns','grandparent');
+ document.getElementById('great-grandparent').setAttribute('aria-owns','parent');
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.style.display="none";
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-owned-becomes-aria-hidden.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-owned-becomes-aria-hidden.html
new file mode 100644
index 0000000000..824ae3e141
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-owned-becomes-aria-hidden.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('div').ariaHidden = true;
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+ });
+ });
+});
+</script>
+<main>
+ <fieldset aria-owns="owned"></fieldset>
+</main>
+<div>
+ <footer id="owned">
+ <mark>
+ owned
+ </mark>
+ </footer>
+</div>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-owner-becomes-aria-hidden.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-owner-becomes-aria-hidden.html
new file mode 100644
index 0000000000..e80bc8a426
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-owner-becomes-aria-hidden.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('div').ariaHidden = true;
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+ });
+ });
+});
+</script>
+<main>
+ <div role="complementary">
+ <fieldset aria-owns="owned"></fieldset>
+ </div>
+</main>
+<footer id="owned">
+ <mark>
+ owned
+ </mark>
+</footer>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-presentation.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-presentation.html
new file mode 100644
index 0000000000..138625a153
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-presentation.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<div id="parent" aria-owns="owned"></div>
+<div id="owned" role="none"></div>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-reparent.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-reparent.html
new file mode 100644
index 0000000000..2eaceb66f6
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-reparent.html
@@ -0,0 +1,21 @@
+<html class="test-wait">
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.getElementById('owner').setAttribute('aria-owns','x');
+ document.body.setAttribute('aria-hidden', 'true');
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+</head>
+<body>
+<p id='owner'></p>
+
+<div>
+ <fieldset id='x'></fieldset>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-select.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-select.html
new file mode 100644
index 0000000000..d6cd094041
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-select.html
@@ -0,0 +1,11 @@
+<script>
+function go(){
+ setup()
+}
+document.addEventListener("DOMContentLoaded", () => {
+ document.querySelector('div').setAttribute('aria-owns','option1')
+});
+</script>
+<div></div>
+<select>
+<option id="option1">
diff --git a/testing/web-platform/tests/accessibility/crashtests/aria-owns-with-role-change.html b/testing/web-platform/tests/accessibility/crashtests/aria-owns-with-role-change.html
new file mode 100644
index 0000000000..13e1eaff6d
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/aria-owns-with-role-change.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<!-- Test that setting the role an an aria-owns element does not crash. -->
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.getElementById('owner').role = 'tab';
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+ });
+ });
+});
+</script>
+</head>
+<body>
+<main>
+ <fieldset id='owner' aria-owns="paragraph1">
+ <div>
+ <p id="paragraph1">
+ <mark>
+ Child
+ </mark>
+ </p>
+ </div>
+ </fieldset>
+</main>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/bdo-table-cell.html b/testing/web-platform/tests/accessibility/crashtests/bdo-table-cell.html
new file mode 100644
index 0000000000..ae12541f8d
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/bdo-table-cell.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<link rel="help" href="https://crbug.com/1314808">
+<style>
+item:after { display: block; content: open-quote; }
+item { display: list-item; }
+</style>
+<bdo style="direction:rtl">
+ x<mark></mark>
+</bdo>
+<span style="display: table-cell; column-width: 0px;"></span>
+<script>
+const new_listitem_child = document.createElement('item');
+document.querySelector('mark').appendChild(new_listitem_child);
+</script>
+
+
+<!--
+ax_object.cc(739)] Check failed: child != this. Previous parent still has |this| child:\n
+ERR: "\\"ListMarker\\" axid#14 <::marker> needsToUpdateChildren" should be a child of "\\"ListItem\\" axid#12 <item> needsToUpdateChildren" not of "\\"GenericContainer\\" axid#13 <::after> #children=2"\n
+
+-->
diff --git a/testing/web-platform/tests/accessibility/crashtests/br-in-changed-subtree.html b/testing/web-platform/tests/accessibility/crashtests/br-in-changed-subtree.html
new file mode 100644
index 0000000000..77c9531650
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/br-in-changed-subtree.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<ol id="foo" >
+ <embed onload="foo.type = 'menu';" src="data:text/html,foo"></embed>
+ <br></br>
+</ol> \ No newline at end of file
diff --git a/testing/web-platform/tests/accessibility/crashtests/computed-accessible-child-of-pseudo-element.html b/testing/web-platform/tests/accessibility/crashtests/computed-accessible-child-of-pseudo-element.html
new file mode 100644
index 0000000000..b00ee7ba56
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/computed-accessible-child-of-pseudo-element.html
@@ -0,0 +1,32 @@
+<html class="test-wait">
+<style>
+ h1::before { content: " [before] "; display: table; }
+</style>
+
+<h1>Heading</h1>
+
+<script>
+
+// Bypass this abandoned syntax in all but the engines that implement it.
+if (typeof getComputedAccessibleNode !== 'undefined') {
+
+ async function trigger1() {
+ let heading = document.querySelector('h1');
+ let computed_accessible_node = await self.getComputedAccessibleNode(heading);
+ let first_child = computed_accessible_node.firstChild;
+ // The first child of the heading is a pseudo element <table>.
+ await first_child.ensureUpToDate();
+ // The next child down has an accessibility object but no node.
+ let grand_child = first_child.firstChild;
+ await grand_child.ensureUpToDate();
+ document.documentElement.className = '';
+ }
+ trigger1();
+
+} else {
+ // Pass in other engines that have not implemented the abandoned API
+ document.documentElement.className = '';
+}
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/computed-accessible-text-node.html b/testing/web-platform/tests/accessibility/crashtests/computed-accessible-text-node.html
new file mode 100644
index 0000000000..47183ce6ec
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/computed-accessible-text-node.html
@@ -0,0 +1,24 @@
+<html class="test-wait">
+<img id="img1">text
+<script>
+
+// Bypass this abandoned syntax in all but the engines that implement it.
+if (typeof getComputedAccessibleNode !== 'undefined') {
+
+ async function trigger1() {
+ let img = document.getElementById('img1');
+ let computed_accessible_node = await self.getComputedAccessibleNode(img);
+ // The next sibling is a text node.
+ let next_sibling = computed_accessible_node.nextSibling;
+ await next_sibling.ensureUpToDate();
+ document.documentElement.className = '';
+ }
+ trigger1();
+
+} else {
+ // Pass in other engines that have not implemented the abandoned API
+ document.documentElement.className = '';
+}
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/computed-node-checked.html b/testing/web-platform/tests/accessibility/crashtests/computed-node-checked.html
new file mode 100644
index 0000000000..47e715b233
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/computed-node-checked.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<body>
+</body>
+<script src="/resources/testharness.js"></script>
+<script>
+if (window.chrome && chrome.gpuBenchmarking) {
+ chrome.gpuBenchmarking.pointerActionSequence(
+ [
+ {
+ source: 'pen',
+ actions: [
+ { name: 'pointerMove', x: 50, y: 50 }
+ ]
+ }
+ ]
+ );
+}
+</script>
+<script>step_timeout(gc, 50);</script>
+<script>
+
+// Bypass this abandoned syntax in all but the engines that implement it.
+if (typeof getComputedAccessibleNode !== 'undefined') {
+
+ const frameElem = document.createElement('iframe');
+
+ frameElem.srcdoc = '<div></div>';
+ frameElem.onload = function() {
+ const frameDoc = frameElem.contentWindow.document;
+ const divElem = frameDoc.querySelector('div');
+ getComputedAccessibleNode(divElem).then(function(divAccessible) {
+ frameElem.remove();
+ requestAnimationFrame(() => {
+ const isChecked = divAccessible.checked;
+ document.documentElement.className = '';
+ });
+ });
+ };
+ document.body.appendChild(frameElem);
+
+} else {
+ // Pass in other engines that have not implemented the abandoned API
+ document.documentElement.className = '';
+}
+
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/computed-node.html b/testing/web-platform/tests/accessibility/crashtests/computed-node.html
new file mode 100644
index 0000000000..159b217a08
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/computed-node.html
@@ -0,0 +1,8 @@
+<body>
+<iframe></iframe>
+</body>
+<script>
+const iframe = document.querySelector('iframe');
+const option = document.createElement("option");
+iframe.contentWindow.getComputedAccessibleNode(option);
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/content-visibility-focusable-scroller-descendant.html b/testing/web-platform/tests/accessibility/crashtests/content-visibility-focusable-scroller-descendant.html
new file mode 100644
index 0000000000..e9b027b5c7
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/content-visibility-focusable-scroller-descendant.html
@@ -0,0 +1,11 @@
+<!doctype HTML>
+<style>
+html,body {
+ content-visibility: auto;
+}
+</style>
+<div id=target style="height: 1000px; width: 100px; overflow: scroll">
+ <marquee></marquee>
+ <div style="width: 50px; height: 2000px"></div>
+</div>
+
diff --git a/testing/web-platform/tests/accessibility/crashtests/content-visibility-generated-content-removal.html b/testing/web-platform/tests/accessibility/crashtests/content-visibility-generated-content-removal.html
new file mode 100644
index 0000000000..b880e244fe
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/content-visibility-generated-content-removal.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html class="test-wait">
+<style>
+ div { content-visibility: auto; }
+ div::after { content: "Bar" }
+</style>
+<div>Foo</div>
+<div style="height:4000px"></div>
+<script>
+ // Ensure no crash when removing element with generated content after
+ // `content-visibility: auto` content goes out of view.
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ // Let one layout run with the div content in view, then
+ // scroll it out of view.
+ document.scrollingElement.scrollTop = 3000;
+
+ // Run three frames to ensure a new layout happens with the
+ // 'auto' content hidden (i.e. layout structures are
+ // destroyed), then remove the div with a pseudo element which
+ // was previously problematic.
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('div').remove();
+ document.documentElement.className = '';
+ })
+ })
+ })
+ })
+ });
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/delayed-ignored-change.html b/testing/web-platform/tests/accessibility/crashtests/delayed-ignored-change.html
new file mode 100644
index 0000000000..fce54add15
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/delayed-ignored-change.html
@@ -0,0 +1,19 @@
+<html class="test-wait">
+<style>
+ body { font-size: x-large; }
+ .hidden { visibility: hidden; }
+</style>
+<rb class="hidden">
+ <textarea></textarea>
+</rb>
+<script>
+window.addEventListener('load', () => {
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => {
+ document.querySelector('style').remove();
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/display-table-column.html b/testing/web-platform/tests/accessibility/crashtests/display-table-column.html
new file mode 100644
index 0000000000..6f34f27fa7
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/display-table-column.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<head>
+<style>
+.foo * {
+ display: table-column;
+}
+</style>
+<script>
+requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ const link = document.querySelector('link');
+ // This will queue the creation of an accessibility object for the
+ // link, because it will now have layout.
+ document.documentElement.className = 'foo';
+ // Do something that forces the link's accessibility object to get an
+ // additional update.
+ link.ariaChecked = 'true';
+ requestAnimationFrame(()=> {
+ requestAnimationFrame(()=> {
+ document.documentElement.className = '';
+ });
+ });
+ });
+});
+</script>
+</head>
+<body>
+ <link/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/displaylocked-serialize.html b/testing/web-platform/tests/accessibility/crashtests/displaylocked-serialize.html
new file mode 100644
index 0000000000..04be6ddf71
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/displaylocked-serialize.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1291169">
+
+<selectlist></selectlist>
+<div></div>
+
+<script>
+ (async () => {
+ const selectlist = document.querySelector('selectlist');
+ await getComputedAccessibleNode(document.querySelector('div'));
+ selectlist.style.setProperty('content-visibility', 'hidden');
+ })();
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/first-letter-inside-before-pseudo.html b/testing/web-platform/tests/accessibility/crashtests/first-letter-inside-before-pseudo.html
new file mode 100644
index 0000000000..d4eb11a76d
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/first-letter-inside-before-pseudo.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+ <link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
+ <meta name="assert" content="Test that the browser doesn't crash when a first-letter pseudo-element toggles visiblity as a child of a before pseudo-element.">
+<style>
+ .btn-text::before {
+ content: "a";
+ visibility: hidden;
+ }
+
+ .btn-text.visible::before {
+ visibility: visible;
+ }
+
+ #problem::first-letter {
+ text-transform: none;
+ }
+</style>
+<div id="problem">
+ <span class="btn-text"></span>
+</div>
+<script>
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ document.querySelector('.btn-text').classList.toggle('visible')
+ }));
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/hidden-textfield-with-combobox.html b/testing/web-platform/tests/accessibility/crashtests/hidden-textfield-with-combobox.html
new file mode 100644
index 0000000000..e988c6edb9
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/hidden-textfield-with-combobox.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<div>
+ <div role="combobox">
+ <input id="textfield" role="textbox" aria-hidden="true" tabindex="-1" aria-readonly="true" aria-label="foo" aria-autocomplete="both">
+ <div role="listbox">
+ </div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/accessibility/crashtests/iframe-owns-child.html b/testing/web-platform/tests/accessibility/crashtests/iframe-owns-child.html
new file mode 100644
index 0000000000..a318e6aba9
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/iframe-owns-child.html
@@ -0,0 +1,2 @@
+<figure id="fig1"></figure>
+<iframe aria-owns="fig1"></iframe>
diff --git a/testing/web-platform/tests/accessibility/crashtests/iframe-srcdoc.html b/testing/web-platform/tests/accessibility/crashtests/iframe-srcdoc.html
new file mode 100644
index 0000000000..74460048e0
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/iframe-srcdoc.html
@@ -0,0 +1 @@
+<iframe id="frame" style="content-visibility: hidden" srcdoc="\'<table>"</table>\'></iframe>xx
diff --git a/testing/web-platform/tests/accessibility/crashtests/illegal-aria-owns-from-br.html b/testing/web-platform/tests/accessibility/crashtests/illegal-aria-owns-from-br.html
new file mode 100644
index 0000000000..cb042b6f2b
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/illegal-aria-owns-from-br.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<div id="id1">abc</div>
+<br aria-owns="id1"></br>
diff --git a/testing/web-platform/tests/accessibility/crashtests/illegal-optgroup-structure.html b/testing/web-platform/tests/accessibility/crashtests/illegal-optgroup-structure.html
new file mode 100644
index 0000000000..809f942613
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/illegal-optgroup-structure.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<switch aria-owns="child">
+ <optgroup>
+ <li id="child" role="option">Child</li>
+ </optgroup>
+</switch>
diff --git a/testing/web-platform/tests/accessibility/crashtests/img-map-pseudo.html b/testing/web-platform/tests/accessibility/crashtests/img-map-pseudo.html
new file mode 100644
index 0000000000..443934e431
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/img-map-pseudo.html
@@ -0,0 +1,11 @@
+<source>
+ <map name="map2" class="c1">
+ <dfn class="c8"></dfn>
+ </map>
+</source>
+<img usemap="#map2">
+<style>
+.c1:first-letter { content: "x"; }
+.c8:after { content: "y"; }
+.c1 { float: left; }
+</style>
diff --git a/testing/web-platform/tests/accessibility/crashtests/in-page-link-with-aria-hidden.html b/testing/web-platform/tests/accessibility/crashtests/in-page-link-with-aria-hidden.html
new file mode 100644
index 0000000000..237707ba07
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/in-page-link-with-aria-hidden.html
@@ -0,0 +1,2 @@
+<p><a href="#dogs">cats</a>
+<p id="dogs" aria-hidden="true">dogs</p>
diff --git a/testing/web-platform/tests/accessibility/crashtests/included-descendant-dom-removal.html b/testing/web-platform/tests/accessibility/crashtests/included-descendant-dom-removal.html
new file mode 100644
index 0000000000..fd978fb45e
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/included-descendant-dom-removal.html
@@ -0,0 +1,27 @@
+<html class="test-wait">
+<head>
+<script>
+window.onload = function() {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('svg').remove();
+ document.documentElement.className = '';
+ });
+ });
+};
+</script>
+</head>
+<body>
+<div role="group" class="group">
+ <div style="display:none" class="ignored1">
+ <div class="ignored2">
+ <div class="ignored3">
+ <svg> <!-- Ignored -->
+ <g id="foo"></g> <!-- Ignored but included in tree -->
+ </svg>
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/included-descendant-layout-removal.html b/testing/web-platform/tests/accessibility/crashtests/included-descendant-layout-removal.html
new file mode 100644
index 0000000000..5270a36351
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/included-descendant-layout-removal.html
@@ -0,0 +1,28 @@
+<html class="test-wait">
+<head>
+<script>
+window.onload = function() {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('svg').style.display = 'contents';
+ document.documentElement.className = '';
+ });
+ });
+};
+</script>
+</head>
+<body>
+<div role="group" class="group">
+ <div class="ignored1">
+ <div class="ignored2">
+ <div class="ignored3">
+ <svg role="none"> <!-- Ignored -->
+ <g id="foo"></g> <!-- Ignored but included in tree -->
+ <circle cx="10" cy="10" r="5" />
+ </svg>
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/inert-br-child.html b/testing/web-platform/tests/accessibility/crashtests/inert-br-child.html
new file mode 100644
index 0000000000..9c9039c3ab
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/inert-br-child.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<!-- Test for crash when inert br gains illegal child -->
+<html>
+<dialog></dialog>
+<br>
+
+<script>
+requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.querySelector('dialog').showModal();
+ const br = document.querySelector('br');
+ br.appendChild(document.createElement('fieldset'));
+ });
+});
+</script>
+
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/input-time-datalist.html b/testing/web-platform/tests/accessibility/crashtests/input-time-datalist.html
new file mode 100644
index 0000000000..b27b77a767
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/input-time-datalist.html
@@ -0,0 +1,2 @@
+<input type=time list="suggestions">
+<datalist id=suggestions>
diff --git a/testing/web-platform/tests/accessibility/crashtests/map-inside-map-2.html b/testing/web-platform/tests/accessibility/crashtests/map-inside-map-2.html
new file mode 100644
index 0000000000..14ec36c99c
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/map-inside-map-2.html
@@ -0,0 +1,11 @@
+<html>
+ <img usemap="map2" class="img-outside-map">
+ <map name="map2"></map>
+ <script>
+ const img = document.createElement('img');
+ img.className = 'img-inside-map';
+ img.setAttribute('usemap', '#map2');
+ img.style.visibility = 'collapse';
+ document.querySelector('map').appendChild(img);
+ </script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/map-inside-map.html b/testing/web-platform/tests/accessibility/crashtests/map-inside-map.html
new file mode 100644
index 0000000000..4ea41fdb3c
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/map-inside-map.html
@@ -0,0 +1,16 @@
+<html>
+ <script>
+ const imgOutsideMap = document.createElement('img');
+ imgOutsideMap.className="img-outside-map";
+ imgOutsideMap.setAttribute('usemap', '#map2');
+ document.documentElement.appendChild(imgOutsideMap);
+ const map = document.createElement('map');
+ map.setAttribute('name', 'map2');
+ document.documentElement.appendChild(map);
+ const imgInsideMap = document.createElement('img');
+ imgInsideMap.className="img-inside-map";
+ imgInsideMap.setAttribute('usemap', '#map2');
+ imgInsideMap.style.visibility = 'collapse';
+ map.appendChild(imgInsideMap);
+ </script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/map-update-crash.html b/testing/web-platform/tests/accessibility/crashtests/map-update-crash.html
new file mode 100644
index 0000000000..5787de8059
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/map-update-crash.html
@@ -0,0 +1,18 @@
+<!doctype HTML>
+<style>
+ article::after {
+ content: url(data:text/plain,test);}
+</style>
+This test passes if it does not crash.
+<img usemap="#map2">
+<map id=map name="map2">
+ <command id=command>
+ <article id=article></article>
+ </command>
+</map>
+<script>
+command.appendChild(article);
+requestAnimationFrame(() => requestAnimationFrame(() => {
+ map.style.content = "none";
+}));
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/missing-parent.html b/testing/web-platform/tests/accessibility/crashtests/missing-parent.html
new file mode 100644
index 0000000000..42ebb8814f
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/missing-parent.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<style>
+.c0 { visibility: collapse; }
+.c4 { content: "x"; }
+</style>
+
+<div class="c0"><img usemap="#map2"></div>
+
+<table>
+ <thead class="c4">x</thead>
+</table>
+
+<map name="map2">x</map>
+
+<script>
+const img = document.createElement('img');
+img.setAttribute('src', 'xyz.png');
+img.setAttribute('usemap', '#map2');
+const div = document.querySelector('div');
+document.documentElement.appendChild(div);
+
+requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ const thead = document.querySelector('thead');
+ thead.appendChild(img);
+ div.className = '';
+ document.documentElement.className = '';
+ });
+});
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/move-owned-inside-another-owned.html b/testing/web-platform/tests/accessibility/crashtests/move-owned-inside-another-owned.html
new file mode 100644
index 0000000000..babe8dcd1d
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/move-owned-inside-another-owned.html
@@ -0,0 +1,13 @@
+<script>
+window.onload = function() {
+ // Reparent z1 under z2.
+ const z2 = document.getElementById('z2');
+ z2.appendChild(document.querySelector('#z1'));
+}
+</script>
+<div aria-owns="z1 z2">
+ <progress>
+ <div id="z1"></div>
+ <div id="z2"></div>
+ </progress>
+</div>
diff --git a/testing/web-platform/tests/accessibility/crashtests/multicol-with-text-change-role-relayout-crash.html b/testing/web-platform/tests/accessibility/crashtests/multicol-with-text-change-role-relayout-crash.html
new file mode 100644
index 0000000000..d1ecd16dcb
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/multicol-with-text-change-role-relayout-crash.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1278439">
+<div id="container">
+ <div id="mc" style="columns:2; column-fill:auto; width:200px; height:30px; line-height:20px; orphans:1; widows:1;">
+ x<br>
+ x<br>
+ </div>
+</div>
+<script>
+ requestAnimationFrame(()=> {
+ requestAnimationFrame(()=> {
+ requestAnimationFrame(()=> {
+ mc.style.width = "201px";
+ container.setAttribute("role", "treegrid");
+ document.body.offsetTop;
+ document.documentElement.className = "";
+ });
+ });
+ });
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/null-node.html b/testing/web-platform/tests/accessibility/crashtests/null-node.html
new file mode 100644
index 0000000000..dc4a81e6bf
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/null-node.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+::-webkit-scrollbar-track, ::-webkit-scrollbar {
+ color: red;
+}
+::-webkit-scrollbar-track:horizontal:disabled {
+ content-visibility: hidden;
+}
+</style>
+<main style="height: 100px; width: 100px; overflow: scroll;"></main>
diff --git a/testing/web-platform/tests/accessibility/crashtests/object-with-unrendered-text-fallback.html b/testing/web-platform/tests/accessibility/crashtests/object-with-unrendered-text-fallback.html
new file mode 100644
index 0000000000..0128213bfc
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/object-with-unrendered-text-fallback.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+caption:first-letter { color: red; }
+</style>
+
+<object>
+ <table>
+ <caption dir="rtl">)))XX?</caption>
+ </table>
+</object>
+
diff --git a/testing/web-platform/tests/accessibility/crashtests/remaining-invalid-objects.html b/testing/web-platform/tests/accessibility/crashtests/remaining-invalid-objects.html
new file mode 100644
index 0000000000..fe11704066
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/remaining-invalid-objects.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<body contenteditable=plaintext-only style='column-count: 5; badrule: value; kheight: 98; cue: url("https://www.google.com/images/logo_sm.gif"); text-decoration-color: CanvasText; scroll-margin-top: 13px; '>
+<iframe></iframe>
+.c34:not(|p) { background-image: repeating-radial-gradient(farthest-side ellipse at 115% 102%, rgba(233, 101, 20, 0.554000), rgba(153, 114, 46, 0.275900)); overflow-y: auto; clip-path: ellipse(closest-side closest-side at top left); font-weigth: 220.04088707998096px; postion: relative; grid-row-end: span auto 18446744073709551589; counter-increment: ident9 8; cellspacing: -104; border-block-start-style: solid; stroke-dashoffset: 123%; renamed-property: Arial; }<script>
+var docElement = document.body ? document.body : document.documentElement;
+docElement.contentEditable = "true";
+</script>
diff --git a/testing/web-platform/tests/accessibility/crashtests/removed-from-flat-tree.html b/testing/web-platform/tests/accessibility/crashtests/removed-from-flat-tree.html
new file mode 100644
index 0000000000..bc5726fed3
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/removed-from-flat-tree.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<audio src="foo"></audio>
+<template shadowrootmode="closed"></template>
diff --git a/testing/web-platform/tests/accessibility/crashtests/select-in-display-none.html b/testing/web-platform/tests/accessibility/crashtests/select-in-display-none.html
new file mode 100644
index 0000000000..dc113c76e8
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/select-in-display-none.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<!-- Ensure that a <select> in an area that becomes display:none after
+ being parsed as a <details> does not cause instability in the AX tree -->
+<body>
+ <main>
+ <details>
+ <summary>Summary</summary>
+ <input type="checkbox"/>
+ <select>
+ <option value="abc">abc</option>
+ </select>
+ </details>
+ </main>
+</body>
+<script>
+document.addEventListener('DOMContentLoaded', () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.className = '';
+ });
+ });
+});
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/serialize-with-no-document.html b/testing/web-platform/tests/accessibility/crashtests/serialize-with-no-document.html
new file mode 100644
index 0000000000..f7719cf2ff
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/serialize-with-no-document.html
@@ -0,0 +1,5 @@
+><a>feColorMatrix><div id="container"><0<script>0000A00AAAAA00A<tspan></tspan>000<do>AA0AA0<fieldset></fieldset>A00AA<font><feComponentTransfer></feComponentTransfer><insertedLegend>AAA0A0A0A00A<img>0<link>0A00A0AAAAAA0AAA000A<feDiffuseLighting><mfrac></mfrac><anchor></anchor>00A0<tspan><tspan><tspan><dcol></dcol><missing_glyph></missing_glyph><col></col>0A0AAA0AA0AA0A000A0<mover></mover><form></form><dcol><dcol><dcol><dcol><dcol>&RightTriangleEqual;&triangleq;&boxHd;&blacklozenge;&Sigma;&xodot;&angrtvb;&DScy;&nvDash;&ShortUpArrow;&nvinfin;&LessLess;<math><dt></dt><feTile></feTile>AA0A<isindex></isindex><blockquote>0<mo></mo>AA0A00A00<cursor><desc></desc>AAAA0AA<tref></tref><tref></tref>0AA00AA0<noop></noop><tfoot><insertedLegend></insertedLegend><insertedLegend></insertedLegend><insertedLegend></insertedLegend><insertedLegend></insertedLegend><template></template>00AA00A00AAAAAA00AA<msubsup><legend>0A00AA0A<msub>AA000AAAA<td>0A0AA0A0AA0A000A0AAA<feFlood><ruby>0A000AA00AAAA0AAAA0A<br><feImage>AAA<font>A0000000AAA0AA00<button><video></video>00AA0</div>
+</script><script>
+ var child = new AccessibleNode();
+ container.accessibleNode.appendChild(child);
+</script><a>
diff --git a/testing/web-platform/tests/accessibility/crashtests/slot-assignment-lockup.html b/testing/web-platform/tests/accessibility/crashtests/slot-assignment-lockup.html
new file mode 100644
index 0000000000..85b6c9294a
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/slot-assignment-lockup.html
@@ -0,0 +1,34 @@
+<html class="test-wait">
+<body>
+<script>
+customElements.define("my-detail", class extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: "open", slotAssignment: "manual" });
+ }
+ connectedCallback() {
+ const slot1 = document.createElement("slot");
+ const child1 = document.createElement("span");
+ this.appendChild(child1);
+ child1.innerHTML = "x";
+ this.shadowRoot.appendChild(slot1);
+ slot1.style.display = "block";
+ slot1.assign(child1);
+ }
+});
+
+function fuzz() {
+ document.designMode = 'on';
+ document.execCommand("selectAll");
+ document.execCommand("InsertText");
+ document.documentElement.className = '';
+}
+window.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(fuzz);
+ });
+};
+</script>
+<my-detail></my-detail>
+</body>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/svg-mouse-listener.html b/testing/web-platform/tests/accessibility/crashtests/svg-mouse-listener.html
new file mode 100644
index 0000000000..2de613e1d3
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/svg-mouse-listener.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<svg viewBox="0 0 500 500">
+ <rect width="500" height="500" id="target" fill="red">
+</svg>
+
+<script>
+window.onload = async () => {
+ document.getElementById("target").addEventListener("click", () => {},
+ { once: true });
+ await test_driver.click(document.body);
+ document.documentElement.classList.remove('test-wait');
+};
+
+</script>
+</html>
diff --git a/testing/web-platform/tests/accessibility/crashtests/table-ignored-child.html b/testing/web-platform/tests/accessibility/crashtests/table-ignored-child.html
new file mode 100644
index 0000000000..99f385f6ea
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/table-ignored-child.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<script>
+window.onload = function() {
+ document.querySelector('object').appendChild(document.querySelector('#move-me'));
+};
+</script>
+</head>
+<body dir="rtl">
+<object></object>
+<table>
+ <caption style="display:none">
+ <span>
+ <div id="move-me"></div>
+ </span>
+ </caption>
+</table>
+</body>
diff --git a/testing/web-platform/tests/accessibility/crashtests/validation-message.html b/testing/web-platform/tests/accessibility/crashtests/validation-message.html
new file mode 100644
index 0000000000..259c01cd3a
--- /dev/null
+++ b/testing/web-platform/tests/accessibility/crashtests/validation-message.html
@@ -0,0 +1,5 @@
+<html>
+<form><input required><input type=submit id=submit><script>
+submit.click();
+</script>
+</html><!-- Comment required for test to crash -->