summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute')
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-area.html22
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html29
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html16
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html21
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html31
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html31
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top.html34
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html57
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-reconnected.html22
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html26
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later.html26
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first.html24
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html24
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-autofocus-on-changing-input-type.html27
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html44
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html17
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/not-on-first-task.html22
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html20
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html20
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html18
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/erase-first.css3
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-a.html4
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-anchor.html4
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html5
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html18
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/imagemap.html5
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html10
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/utils.js51
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html48
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html17
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html19
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html18
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html19
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/supported-elements.html83
-rw-r--r--testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html40
35 files changed, 875 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-area.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-area.html
new file mode 100644
index 0000000000..e1ff72eb61
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-area.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute">
+<link rel='author' href='mailto:sefeng@mozilla.com'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<map name="mymap">
+ <area id="myarea" shape="circle" coords="100,100,80" href="#" autofocus>
+</map>
+<img style="width:200px; height: 200px"
+ usemap="#mymap"
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4%2F58BAAT%2FAf9jgNErAAAAAElFTkSuQmCC">
+<script>
+promise_test(async t => {
+ await waitForLoad(window);
+ await waitUntilStableAutofocusState(window);
+ const area = document.querySelector("area");
+ assert_equals(document.activeElement, area);
+}, 'autofocus works on area element');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html
new file mode 100644
index 0000000000..08a0913f42
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute">
+<link rel='author' href='mailto:masonf@chromium.org'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ w.document.body.innerHTML = '<dialog><div tabindex=0 autofocus></dialog><input autofocus>';
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement.tagName, 'INPUT');
+}, '<dialog> can contain autofocus, without stopping page autofocus content from working');
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ w.document.body.innerHTML = '<dialog><div tabindex=0 autofocus></dialog><input autofocus>';
+ await waitUntilStableAutofocusState(w);
+ w.document.querySelector('dialog').show();
+ assert_equals(w.document.activeElement.tagName, 'DIV');
+}, '<dialog>-contained autofocus element gets focused when the dialog is shown');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html
new file mode 100644
index 0000000000..a26a44dbfb
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ let doc = document.cloneNode(false);
+ doc.appendChild(doc.createElement('html'))
+ doc.firstChild.innerHTML = '<body><input autofocus/></body>';
+ await waitUntilStableAutofocusState();
+ assert_equals(doc.activeElement, doc.body);
+}, 'Autofocus element in not-fully-active document should not be queued.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html
new file mode 100644
index 0000000000..47e3e3fd0a
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async t => {
+ await waitForLoad(window);
+ await timeOut(t, 1000);
+ let element = document.createElement('input');
+ element.autofocus = true;
+ document.body.appendChild(element);
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, element);
+}, 'Autofocus should work if an element with autofocus is inserted into a ' +
+ 'document which was loaded some time ago.');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html
new file mode 100644
index 0000000000..ec9d16d498
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe src="resources/frame-with-autofocus-element.html#"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, document.querySelector('iframe'),
+ 'Autofocus elements in iframes should be focused.');
+
+ let input = document.createElement('input');
+ input.autofocus = true;
+ document.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(document.activeElement, input);
+}, 'Autofocus elements in iframed documents with empty fragments should work.');
+
+promise_test(async () => {
+ let w = window.open('resources/frame-with-autofocus-element.html#');
+ await waitForLoad(w);
+ await waitUntilStableAutofocusState(w);
+ assert_not_equals(w.document.activeElement, w.document.body);
+ w.close();
+}, 'Autofocus elements in top-level browsing context\'s documents with empty fragments should work.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html
new file mode 100644
index 0000000000..3f2dcc4167
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe src="resources/frame-with-autofocus-element.html#non-existent"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, document.querySelector('iframe'),
+ 'Autofocus elements in iframes should be focused.');
+
+ let input = document.createElement('input');
+ input.autofocus = true;
+ document.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(document.activeElement, input);
+}, 'Autofocus elements in iframed documents with non-existent fragments should work.');
+
+promise_test(async () => {
+ let w = window.open('resources/frame-with-autofocus-element.html#non-existent');
+ await waitForLoad(w);
+ await waitUntilStableAutofocusState(w);
+ assert_not_equals(w.document.activeElement, w.document.body);
+ w.close();
+}, 'Autofocus elements in top-level browsing context\'s documents with non-existent fragments should work.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top.html
new file mode 100644
index 0000000000..f2d2aaae60
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-top.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe src="resources/frame-with-autofocus-element.html#top"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ const iframe = document.querySelector('iframe');
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, iframe,
+ 'Autofocus elements in iframes should be focused.');
+ const doc = iframe.contentDocument;
+ assert_true(!doc.querySelector(':target'));
+
+ let input = document.createElement('input');
+ input.autofocus = true;
+ document.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(document.activeElement, input);
+}, 'Autofocus elements in iframed documents with "top" fragments should work.');
+
+promise_test(async () => {
+ let w = window.open('resources/frame-with-autofocus-element.html#top');
+ await waitForLoad(w);
+ await waitUntilStableAutofocusState(w);
+ assert_not_equals(w.document.activeElement, w.document.body);
+ w.close();
+}, 'Autofocus elements in top-level browsing context\'s documents with "top" fragments should work.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html
new file mode 100644
index 0000000000..5078f1a0ac
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/document-with-fragment-valid.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe src="resources/frame-with-anchor.html"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ const iframe = document.querySelector('iframe');
+ iframe.contentWindow.location.hash = 'anchor1';
+ await waitForEvent(iframe.contentWindow, 'hashchange');
+ const doc = iframe.contentDocument;
+ assert_true(!!doc.querySelector(':target'));
+
+ let input = doc.createElement('input');
+ input.autofocus = true;
+ doc.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(doc.activeElement, input);
+ iframe.remove();
+}, 'Autofocus elements in iframed documents with URL fragments should be skipped. (id matches)');
+
+promise_test(async () => {
+ let iframe = await waitForIframeLoad("resources/frame-with-a.html");
+ iframe.contentWindow.location.hash = 'anchor1';
+ await waitForEvent(iframe.contentWindow, 'hashchange');
+ const doc = iframe.contentDocument;
+ assert_true(!!doc.querySelector(':target'));
+
+ let input = doc.createElement('input');
+ input.autofocus = true;
+ doc.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(doc.activeElement, input);
+ iframe.remove();
+}, 'Autofocus elements in iframed documents with URL fragments should be skipped.(a element)');
+
+promise_test(async () => {
+ let w = window.open('resources/frame-with-anchor.html');
+ await waitForLoad(w);
+ w.location.hash = 'anchor1';
+ await waitForEvent(w, 'hashchange');
+ const doc = w.document;
+ assert_true(!!doc.querySelector(':target'));
+
+ let input = doc.createElement('input');
+ input.autofocus = true;
+ doc.body.appendChild(input);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(doc.activeElement, input);
+ w.close();
+}, 'Autofocus elements in top-level browsing context\'s documents with URL fragments should be skipped.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-reconnected.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-reconnected.html
new file mode 100644
index 0000000000..99ee9198d1
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-reconnected.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<input autofocus id="i1">
+<input autofocus id="i2">
+<script>
+"use strict";
+
+promise_test(async () => {
+ const input1 = document.querySelector("#i1");
+ const input2 = document.querySelector("#i2");
+ input1.remove();
+ input2.parentNode.insertBefore(input1, input2);
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, input2);
+}, 'The second autofocus element wins if the first autofocus element was ' +
+ 'disconnected and reconnected before flushing the autofocus candidates.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html
new file mode 100644
index 0000000000..f361463401
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The temporally first autofocus in the document wins, even if an element is inserted later that is previous in the document tree</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#autofocusing-a-form-control:-the-autofocus-attribute">
+<link rel="author" title="Domenic Denicola" href="d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<input autofocus>
+
+<script>
+"use strict";
+
+promise_test(async () => {
+ const input1 = document.querySelector("input");
+ const input2 = document.createElement("input");
+ input2.autofocus = true;
+ document.body.prepend(input2);
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, input1);
+ assert_not_equals(document.activeElement, input2);
+}, 'The temporally first autofocus in the document wins, even if an element is inserted later that is previous in the document tree.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later.html
new file mode 100644
index 0000000000..1d64b863a1
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first-when-later.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The first autofocus in the document wins, even if elements are inserted later</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#autofocusing-a-form-control:-the-autofocus-attribute">
+<link rel="author" title="Domenic Denicola" href="d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<input autofocus>
+
+<script>
+"use strict";
+
+promise_test(async () => {
+ const input1 = document.querySelector("input");
+ const input2 = document.createElement("input");
+ input2.autofocus = true;
+ document.body.appendChild(input2);
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, input1);
+ assert_not_equals(document.activeElement, input2);
+}, 'The first autofocus in the document wins, even if elements are inserted later.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first.html
new file mode 100644
index 0000000000..02ebb79a3e
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/first.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The first autofocus in the document wins</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#autofocusing-a-form-control:-the-autofocus-attribute">
+<link rel="author" title="Domenic Denicola" href="d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<input autofocus>
+<input autofocus>
+
+<script>
+"use strict";
+
+promise_test(async () => {
+ const [input1, input2] = document.querySelectorAll("input");
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, input1);
+ assert_not_equals(document.activeElement, input2);
+}, 'The first autofocus element in the document should win.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html
new file mode 100644
index 0000000000..327040eeee
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe srcdoc="<input><script>document.querySelector('input').focus();</script>"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ let iframe = document.querySelector('iframe');
+ assert_equals(document.activeElement, iframe, 'Prereq: IFRAME should be focused');
+
+ let input = document.createElement('input');
+ input.autofocus = true;
+ document.body.appendChild(input);
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, iframe, 'activeElement should not be changed');
+ assert_not_equals(document.activeElement, input);
+}, 'If topDocument\'s focused area is not topDocument, autofocus is not processed.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-autofocus-on-changing-input-type.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-autofocus-on-changing-input-type.html
new file mode 100644
index 0000000000..79a39ef2f9
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-autofocus-on-changing-input-type.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<body>
+
+<input id="input1" autofocus>
+<select><option>o1</option></select>
+
+<script>
+"use strict";
+
+// WebKit had a bug that reattaching RenderObject triggered autofocus again.
+// https://bugs.webkit.org/show_bug.cgi?id=68513
+promise_test(async () => {
+ const input1 = document.querySelector('input');
+ const select = document.querySelector('select');
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, input1);
+ input1.onblur = () => { input1.type = 'password'; };
+ select.focus();
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, select);
+}, 'Changing input type should not refocus on the element.');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html
new file mode 100644
index 0000000000..2cf7428f36
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+ <h1>Autofocus shouldn't work in cross-origin iframe.</h1>
+ <iframe id="child" width="200" height="100"></iframe>
+
+ <script>
+ let parent_loaded = false;
+ let child_loaded = false;
+
+ async_test(function(t) {
+ function pingChildIfBothFramesLoaded() {
+ if (parent_loaded && child_loaded)
+ frames[0].postMessage("report_focus_state", "*");
+ }
+
+ window.addEventListener("load", t.step_func(event => {
+ parent_loaded = true;
+ pingChildIfBothFramesLoaded();
+ }));
+
+ window.addEventListener("message", t.step_func(event => {
+ if (event.data == "child_loaded") {
+ child_loaded = true;
+ pingChildIfBothFramesLoaded();
+ } else if (event.data == "child_is_focused") {
+ assert_unreached("The iframe shouldn't get focus");
+ } else if (event.data == "child_is_not_focused") {
+ t.done();
+ }
+ }));
+ document.getElementById("child").src =
+ get_host_info().HTTP_REMOTE_ORIGIN + "/html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html";
+ }, "Autofocus shouldn't work in cross-origin iframe");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html
new file mode 100644
index 0000000000..991373d336
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe sandbox srcdoc="<input autofocus>"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ await waitUntilStableAutofocusState();
+ assert_not_equals(document.activeElement, document.querySelector('iframe'));
+}, 'If the sandboxed automatic features browsing context flag is set, ' +
+ 'autofocus in the browsing context should not be handled.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/not-on-first-task.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/not-on-first-task.html
new file mode 100644
index 0000000000..ab27342f4f
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/not-on-first-task.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The element is not focused during the initial parsing task</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#autofocusing-a-form-control:-the-autofocus-attribute">
+<link rel="author" title="Domenic Denicola" href="d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<input autofocus>
+<input autofocus>
+
+<script>
+"use strict";
+
+test(() => {
+ const input = document.querySelector("input");
+
+ assert_equals(document.activeElement, document.body);
+ assert_not_equals(document.activeElement, input);
+});
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html
new file mode 100644
index 0000000000..e3b556035d
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<textarea autofocus disabled></textarea>
+<select autofocus></select>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ const [textarea, select] = document.querySelectorAll('[autofocus]');
+ textarea.disabled = false;
+
+ await waitUntilStableAutofocusState();
+ assert_equals(document.activeElement, textarea);
+ assert_not_equals(document.activeElement, select);
+}, 'If the first autofocus element is not focusable, but becomes focusable before a frame, it should be focused.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html
new file mode 100644
index 0000000000..afd5601a52
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<input id="target" value="This should be unfocused!" autofocus></input>
+
+<script>
+ let got_focus = false;
+ document.getElementById("target").addEventListener("focus", () => {
+ got_focus = true;
+ });
+
+ window.addEventListener("load", () => {
+ parent.postMessage("child_loaded", "*");
+ });
+
+ window.addEventListener("message", event => {
+ if (event.data == "report_focus_state") {
+ let msg = got_focus ? "child_is_focused" : "child_is_not_focused";
+ parent.postMessage(msg, "*");
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html
new file mode 100644
index 0000000000..f60acfc871
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src="/common/get-host-info.sub.js"></script>
+<iframe id="iframe" width="200" height="100"></iframe>
+
+<script>
+ iframe.src =
+ get_host_info().ORIGIN + "/html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html";
+ window.addEventListener("message", event => {
+ if (event.data == "grand_child_loaded") {
+ parent.postMessage("ready", "*");
+ } else if (event.data == "report_focus_state") {
+ frames[0].postMessage("report_focus_state", "*");
+ } else if (event.data == "grand_child_is_focused" ||
+ event.data == "grand_child_is_not_focused") {
+ parent.postMessage(event.data, "*");
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/erase-first.css b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/erase-first.css
new file mode 100644
index 0000000000..bbbcf79939
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/erase-first.css
@@ -0,0 +1,3 @@
+#first {
+ display: none;
+}
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-a.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-a.html
new file mode 100644
index 0000000000..1f31736902
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-a.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<body>
+<a name="anchor1"></a>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-anchor.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-anchor.html
new file mode 100644
index 0000000000..b9070159e7
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-anchor.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<body>
+<div id="anchor1"></div>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html
new file mode 100644
index 0000000000..985cba4149
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<body>
+<div id="anchor1"></div>
+<input autofocus>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html
new file mode 100644
index 0000000000..88be6e0b04
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<input id="target" value="This should be focused!" autofocus></input>
+
+<script>
+ let got_focus = false;
+ target.addEventListener("focus", () => got_focus = true);
+
+ window.addEventListener("load", () => {
+ parent.postMessage("grand_child_loaded", "*");
+ });
+
+ window.addEventListener("message", event => {
+ if (event.data == "report_focus_state") {
+ let msg = got_focus ? "grand_child_is_focused" : "grand_child_is_not_focused";
+ parent.postMessage(msg, "*");
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/imagemap.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/imagemap.html
new file mode 100644
index 0000000000..fa3d95c81b
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/imagemap.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<body>
+<img src="/media/poster.png" usemap="#map">
+<map name="map"></map>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html
new file mode 100644
index 0000000000..fc6c298a46
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<body>
+<script>
+const input = document.createElement('input');
+input.autofocus = true;
+document.body.appendChild(input);
+input.autofocus = false;
+window.opener.document.body.appendChild(input);
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/utils.js b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/utils.js
new file mode 100644
index 0000000000..e928e27540
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/resources/utils.js
@@ -0,0 +1,51 @@
+'use strict';
+
+function waitForEvent(target, type, options) {
+ return new Promise((resolve, reject) => {
+ target.addEventListener(type, resolve, options);
+ });
+}
+
+function waitForAnimationFrame(w) {
+ let targetWindow = w || window;
+ return new Promise((resolve, reject) => {
+ targetWindow.requestAnimationFrame(resolve);
+ });
+}
+
+function waitForEvent(target, type, options) {
+ return new Promise((resolve, reject) => {
+ target.addEventListener(type, resolve, options);
+ });
+}
+
+function waitForLoad(target) {
+ return waitForEvent(target, 'load');
+}
+
+function timeOut(test, ms) {
+ return new Promise((resolve, reject) => {
+ test.step_timeout(resolve, ms);
+ });
+}
+
+// If an element with autofocus is connected to a document and this function
+// is called, the autofocus result is deterministic after returning from the
+// function.
+// Exception: If the document has script-blocking style sheets, this function
+// doesn't work well.
+async function waitUntilStableAutofocusState(w) {
+ let targetWindow = w || window;
+ // Awaiting one animation frame is an easy way to determine autofocus state.
+ await waitForAnimationFrame(targetWindow);
+}
+
+async function waitForIframeLoad(src, w = window) {
+ const iframe = w.document.createElement("iframe");
+ let loadPromise = new Promise(resolve => {
+ iframe.addEventListener("load", () => resolve(iframe));
+ });
+ iframe.src = src;
+ w.document.body.appendChild(iframe);
+ return loadPromise;
+}
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html
new file mode 100644
index 0000000000..1497a7d658
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<meta name="assert" content="`autofocus` should not work in the same origin iframe if there is a cross-origin iframe between the parent and the same origin iframe">
+<title>autofocus in the same origin grand child iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/utils.js"></script>
+</head>
+<body>
+ <iframe id="child" width="200" height="100"></iframe>
+ <script>
+ let parent_loaded = false;
+ let grand_child_loaded = false;
+
+ async_test(function(t) {
+ async function pingChildIfBothFramesLoaded() {
+ if (parent_loaded && grand_child_loaded) {
+ await waitUntilStableAutofocusState();
+ frames[0].postMessage("report_focus_state", "*");
+ }
+ }
+
+ window.addEventListener("load", t.step_func(event => {
+ parent_loaded = true;
+ pingChildIfBothFramesLoaded();
+ }));
+
+ window.addEventListener("message", t.step_func(event => {
+ if (event.data == "ready") {
+ grand_child_loaded = true;
+ pingChildIfBothFramesLoaded();
+ } else if (event.data == "grand_child_is_focused") {
+ assert_unreached("The grandchild iframe shouldn't get focus");
+ } else if (event.data == "grand_child_is_not_focused") {
+ t.done();
+ }
+ }));
+ document.getElementById("child").src =
+ get_host_info().HTTP_NOTSAMESITE_ORIGIN + "/html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html";
+ }, "Autofocus should not work in the same origin grand child iframe");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html
new file mode 100644
index 0000000000..d392b903f0
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<script>
+'use strict';
+
+promise_test(async () => {
+ let w = window.open('resources/moving-autofocus-to-parent.html');
+ await waitForLoad(w);
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement, w.document.body);
+ assert_equals(document.activeElement, document.body);
+ w.close();
+}, 'Autofocus elements queued in another top-level browsing context\'s ' +
+ 'documents should be skipped.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html
new file mode 100644
index 0000000000..008371d8e1
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<textarea autofocus disabled></textarea>
+<select autofocus></select>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ const [textarea, select] = document.querySelectorAll('[autofocus]');
+
+ await waitUntilStableAutofocusState();
+ assert_not_equals(document.activeElement, textarea);
+ assert_equals(document.activeElement, select);
+}, 'Non-focusable autofocus element is skipped.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html
new file mode 100644
index 0000000000..fa5b608d05
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<iframe srcdoc="<input autofocus><script>window.frameElement.remove();</script>"></iframe>
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ let iframe = document.querySelector('iframe');
+ let iframeDocument = iframe.contentDocument;
+ await waitForLoad(window);
+ assert_not_equals(document.activeElement, iframe);
+ assert_equals(iframeDocument.activeElement, iframeDocument.body);
+}, 'Autofocus element in not-fully-active document should be skipped while flusing.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html
new file mode 100644
index 0000000000..fb87eca77a
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<input id="first" autofocus>
+<input id="second" autofocus>
+
+<link rel="stylesheet" href="resources/erase-first.css?pipe=trickle(d1)">
+
+<script>
+'use strict';
+
+promise_test(async () => {
+ await waitForLoad(window);
+ await waitForAnimationFrame();
+ assert_equals(document.activeElement.id, 'second');
+}, 'Script-blocking style sheet should pause flushing autofocus candidates.');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/supported-elements.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/supported-elements.html
new file mode 100644
index 0000000000..29b3f3fb7b
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/supported-elements.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+<script>
+"use strict";
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ w.document.body.innerHTML = '<div contenteditable=true autofocus></div>';
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement.tagName, 'DIV');
+}, 'Contenteditable element should support autofocus');
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ w.document.body.innerHTML = '<span tabindex=0 autofocus></span>';
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement.tagName, 'SPAN');
+}, 'Element with tabindex should support autofocus');
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ let element = w.document.createElementNS('uri1', 'prefix:local');
+ element.setAttribute('autofocus', '');
+ w.document.body.appendChild(element);
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement.tagName, 'BODY');
+}, 'Non-HTMLElement should not support autofocus');
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ const host = w.document.createElement('div');
+ host.autofocus = true;
+ const shadow = host.attachShadow({mode:'closed', delegatesFocus:true});
+ shadow.appendChild(w.document.createElement('input'));
+ w.document.body.appendChild(host);
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement, host);
+ assert_equals(shadow.activeElement.tagName, 'INPUT');
+}, 'Host element with delegatesFocus should support autofocus');
+
+promise_test(async t => {
+ let w = window.open('/common/blank.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ const host = w.document.createElement('div');
+ host.autofocus = true;
+ host.attachShadow({mode:'closed', delegatesFocus:true});
+ w.document.body.appendChild(host);
+ const next = w.document.createElement('input');
+ next.autofocus = true;
+ w.document.body.appendChild(next);
+ await waitUntilStableAutofocusState(w);
+ assert_equals(w.document.activeElement, next);
+}, 'Host element with delegatesFocus including no focusable descendants should be skipped');
+
+promise_test(async t => {
+ let w = window.open('./resources/imagemap.html');
+ await waitForLoad(w);
+ t.add_cleanup(() => { w.close(); });
+ const area = w.document.createElement('area');
+ area.autofocus = true;
+ area.shape = 'rect';
+ area.coords = '1,1,99,99';
+ area.href = '/common/blank.html';
+ w.document.querySelector('map').appendChild(area);
+ await waitUntilStableAutofocusState(w);
+ // According to the specification, DOM anchor for an AREA shape is an IMG
+ // element, but major browsers don't follow it.
+ // See https://github.com/whatwg/html/issues/5054
+ assert_equals(w.document.activeElement, area);
+}, 'Area element should support autofocus');
+</script>
diff --git a/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html
new file mode 100644
index 0000000000..279f70d490
--- /dev/null
+++ b/testing/web-platform/tests/html/interaction/focus/the-autofocus-attribute/update-the-rendering.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/C/#update-the-rendering">
+
+<body>
+<script>
+'use strict';
+
+async_test(t => {
+ t.events = [];
+
+ let w = window.open('/common/blank.html', 'name',
+ 'width=100,height=100,menubar=no,toolbar=no,location=no');
+ t.add_cleanup(() => { w.close(); });
+ w.addEventListener('load', t.step_func(() => {
+ w.focus();
+ let element = w.document.createElement('input');
+ element.autofocus = true;
+ element.style.marginTop = '200px'; // Setting focus causes scrolling.
+ element.addEventListener('focus', t.step_func(() => {
+ t.events.push('autofocus');
+ }));
+
+ w.addEventListener('scroll', t.step_func(() => {
+ t.events.push('scroll');
+ }));
+
+ w.requestAnimationFrame(
+ () => w.requestAnimationFrame(t.step_func_done(() => {
+ t.events.push('animationFrame');
+ assert_array_equals(t.events, ['autofocus', 'scroll', 'animationFrame'], t.events);
+ })));
+
+ w.document.body.appendChild(element);
+ }));
+}, '"Flush autofocus candidates" should be happen before a scroll event and ' +
+ 'animation frame callbacks');
+</script>
+</body>