Port chrome-only dialog tests to WPT part 2

Bug: 1240798
Change-Id: Id169e3ba4c0d80e9ec7a221075a78b369bc3623a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3313693
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#948157}
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html b/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html
new file mode 100644
index 0000000..0f8d40a
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-close-event-async.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>dialog element: close()</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<dialog id="d1" open>
+  <p>foobar</p>
+  <button>OK</button>
+</dialog>
+<script>
+  var d1 = document.getElementById('d1'),
+      t = async_test("close() fires a close event"),
+      was_queued = false;
+
+  d1.onclose = t.step_func_done(function(e) {
+    assert_true(was_queued, "close event should be queued");
+    assert_true(e.isTrusted, "close event is trusted");
+    assert_false(e.bubbles, "close event doesn't bubble");
+    assert_false(e.cancelable, "close event is not cancelable");
+  });
+
+  t.step(function() {
+    d1.close();
+    was_queued = true;
+  })
+</script>
+</body>
+</html>
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html
new file mode 100644
index 0000000..54c2eda
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal-inert-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<iframe id="frame"></iframe>
+<script>
+  async_test(function(t) {
+    onload = t.step_func(() => {
+      const host = document.createElement("div");
+      frame.appendChild(host);
+      frame.contentDocument.body.innerHTML = "<dialog></dialog>";
+      document.body.offsetTop;
+      const root = host.attachShadow({mode: 'open'});
+      root.innerHTML = "<content>";
+      const dialog = frame.contentDocument.querySelector("dialog");
+      dialog.showModal();
+      t.done();
+    });
+  }, "Dialog.showModal() called when we have a dirty shadow distribution should not crash.");
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html
new file mode 100644
index 0000000..ed64375
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/dialog-show-modal.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=author href="mailto:falken@chromium.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
+<link rel=help href="https://bugs.webkit.org/show_bug.cgi?id=97425">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<dialog id="mydialog">It's my dialog.</dialog>
+
+<script>
+test(() => {
+  const dialog = document.getElementById('mydialog');
+  const computedStyle = window.getComputedStyle(dialog, null);
+  assert_equals(computedStyle.display, 'none');
+
+  dialog.showModal();
+  assert_equals(computedStyle.display, 'block');
+
+  // The quoted texts output below are from <http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#dom-dialog-showmodal>.
+  assert_throws_dom('InvalidStateError', () => dialog.showModal());
+
+  dialog.close();
+  assert_equals(computedStyle.display, 'none');
+
+  dialog.parentNode.removeChild(dialog);
+  assert_throws_dom('InvalidStateError', () => dialog.showModal());
+
+  const doc = document.implementation.createHTMLDocument();
+  doc.body.appendChild(dialog);
+  assert_false(dialog.open);
+  dialog.showModal();
+  assert_true(dialog.open, 'Although the document is not attached to any pages, showModal() should execute as normal.');
+}, 'Tests that showModal() performs the steps specified in the HTML spec.');
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html b/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html
new file mode 100644
index 0000000..12fa96a
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/inert-focus-in-frames.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=author href="mailto:falken@chromium.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=242848">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe height=400 width=600 id="main-iframe">
+  <frameset rows="*" cols="50,50">
+    <frame src="resources/inert-focus-in-frames-frame1.html">
+    <frame src="resources/inert-focus-in-frames-frame2.html">
+  </frameset>
+</iframe>
+
+<script>
+let framesLoadedResolver = null;
+const framesLoadedPromise = new Promise(resolve => framesLoadedResolver = resolve);
+framesLoaded = 0;
+numFrames = 4;
+
+function frameLoaded() {
+  framesLoaded++;
+  if (framesLoaded == numFrames)
+    framesLoadedResolver();
+}
+var mainIframe = document.getElementById('main-iframe');
+mainIframe.contentDocument.write(mainIframe.textContent);
+mainIframe.contentDocument.close();
+mainIframe.contentWindow.frames[1].window.onload = frameLoaded;
+window.onload = frameLoaded;
+
+promise_test(async () => {
+  await framesLoadedPromise;
+
+  function testFocus(element, expectFocus) {
+    let focusedElement = null;
+    element.addEventListener('focus', function() { focusedElement = element; }, false);
+    element.focus();
+    assert_equals(focusedElement === element, expectFocus, element.id);
+  }
+
+  // Opening a modal dialog in frame1. It blocks other nodes in its document.
+  const frame1 = mainIframe.contentWindow.frames[0].document;
+  frame1.querySelector('dialog').showModal();
+
+  testFocus(frame1.querySelector('.target'), false);
+  const iframe = frame1.querySelector('#iframe1').contentDocument;
+  testFocus(iframe.querySelector('.target'), false);
+
+  // Even a modal dialog in the iframe is blocked by the modal dialog in the parent frame1.
+  iframe.querySelector('dialog').showModal();
+  testFocus(iframe.querySelector('button'), false);
+
+  // An iframe within a modal dialog can still be focused.
+  var dialogIframe = frame1.querySelector('#iframe-in-dialog').contentDocument;
+  testFocus(dialogIframe.querySelector('.target'), true);
+
+  // A modal dialog does not block nodes in a sibling frame.
+  var frame2 = mainIframe.contentWindow.frames[1].document;
+  testFocus(frame2.querySelector('.target'), true);
+
+  // Closing the dialog in frame1. The modal dialog in the iframe does not block nodes in its parent.
+  frame1.querySelector('dialog').close();
+  testFocus(iframe.querySelector('.target'), false);
+  testFocus(frame1.querySelector('.target'), true);
+
+}, 'Tests inert node focusing across frames and iframes.');
+</script>
diff --git a/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html
new file mode 100644
index 0000000..c5566bc
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+window.onload = parent.parent.frameLoaded;
+</script>
+</head>
+<body>
+<dialog id="dialog">
+    <button id="dialog-button" tabindex="0">Button</button>
+    <iframe id="iframe-in-dialog" srcdoc='
+        <input id="iframe-under-dialog-input" class="target" type="date">
+    '></iframe>
+</dialog>
+<input id="frame1-input" class="target" type="text">
+<iframe id="iframe1" srcdoc='
+    <dialog id="iframe-dialog">
+        <button id="iframe-dialog-button" tabindex="0">Button</button>
+    </dialog>
+    <input id="iframe-input" class="target" type="date">
+    <script>window.onload = parent.parent.parent.frameLoaded;</script>
+'>
+</body>
+</html>
diff --git a/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html
new file mode 100644
index 0000000..167c569
--- /dev/null
+++ b/html/semantics/interactive-elements/the-dialog-element/resources/inert-focus-in-frames-frame2.html
@@ -0,0 +1 @@
+<div id="frame2-div" class="target" tabindex="0">Hello</div>