summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview/src/androidTest/assets/www
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview/src/androidTest/assets/www')
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-aria-comboboxes.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-checkbox.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-clipboard.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-collection.html21
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-expandable.html13
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-headings.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-links.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-atomic.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-descendant.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image-labeled-by.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-local-iframe.html21
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-move-caret-accessibility-focus.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-mutation.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-range.html23
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-remote-iframe.html24
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-scroll.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-selectable.html22
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-text-entry-node.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-tree.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/address_form.html21
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/audio/owl.mp3bin0 -> 67430 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/autoplay.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/badVideoPath.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/beforeunload.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/cc_form.html22
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/clickToReload.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/clipboard_read.html22
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/color_grid.html40
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/color_orange_background.html29
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/colors.html23
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_audio.html20
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html44
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html22
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_image.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_image_nested.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_link.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/context_menu_video.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/data_uri.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/dnd.html27
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/download.html18
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fedcm_accounts_endpoint.json12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_manifest.json18
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_metadata.json4
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fedcm_idtokens_endpoint.json3
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fedcm_rp.html8
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fixedbottom.html36
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fixedpercent.html25
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fixedvh.html25
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/form_blank.html20
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms.html34
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms2.html17
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms2_iframe.html16
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms3.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms4.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms5.html24
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete.html16
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete_iframe.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms_id_value.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms_iframe.html58
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/forms_xorigin.html77
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/fullscreen.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_container.html58
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_iframe.html39
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/hello.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/hello2.html9
-rwxr-xr-xmobile/android/geckoview/src/androidTest/assets/www/helloPDFWorld.pdfbin0 -> 10414 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/hsts_header.sjs6
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/hungScript.html16
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_no_scrollable.html60
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_scrollable.html60
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_no_scrollable.html55
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_scrollable.html55
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_hello.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_http_only.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_automation.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_local.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/iframe_unknown_protocol.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/images/test.gifbin0 -> 23961 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/inputs.html66
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/links.html28
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/loremIpsum.html17
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/manifest.webmanifest17
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/media_session_default1.html15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/media_session_dom1.html109
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/metatags.html19
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/mouseToReload.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/mp4.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/newSession.html22
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/newSession_child.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/no-meta-viewport.html5
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/ogg.html11
-rwxr-xr-xmobile/android/geckoview/src/androidTest/assets/www/orange.pdfbin0 -> 16829 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto-none.html28
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto.html28
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-auto.html28
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html37
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/popup.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/print_content_change.html37
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/print_iframe.html39
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/prompts.html31
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html82
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/push/push.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/push/push.js44
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/push/sw.js30
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/red-background-body-fully-covered-by-green-element.html23
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/reflect_local_storage_into_title.html17
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/resubmit.html12
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/root_100_percent_height.html37
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/root_100vh.html36
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/root_98vh.html36
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/saveState.html18
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/scroll-handoff.html40
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/scroll.html59
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/select-listbox.html7
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/select-multiple.html7
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/select.html6
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame.html6
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame_xorigin.html47
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/showDynamicToolbar.html96
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/simple_redirect.sjs4
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/titleChange.html16
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch-action-wheel-listener.html33
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch-action.html48
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch.html58
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touch_xorigin.html16
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/touchstart.html37
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/tracemonkey.pdfbin0 -> 178030 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/trackers.html14
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/translations-tester-en.html62
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/translations-tester-es.html83
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/transparent.gifbin0 -> 43 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/update_manifest.json40
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/videos/gizmo.webmbin0 -> 159035 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/videos/short.mp4bin0 -> 13651 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/videos/video.oggbin0 -> 285310 bytes
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/viewport.html19
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/webm.html11
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.html10
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.js15
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/worker/open_window_target.html9
-rw-r--r--mobile/android/geckoview/src/androidTest/assets/www/worker/service-worker.js15
143 files changed, 3251 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-aria-comboboxes.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-aria-comboboxes.html
new file mode 100644
index 0000000000..8816879c1a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-aria-comboboxes.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div contenteditable role="combobox" aria-label="ARIA 1.0 combobox"></div>
+ <div role="combobox">
+ <input type="text" aria-label="ARIA 1.1 combobox" />
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-checkbox.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-checkbox.html
new file mode 100644
index 0000000000..a45cfed92b
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-checkbox.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <label>
+ <input type="checkbox" aria-describedby="desc" />many option
+ </label>
+ <div id="desc">description</div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-clipboard.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-clipboard.html
new file mode 100644
index 0000000000..c33b48f4e5
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-clipboard.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <input value="hello cruel world" id="input" />
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-collection.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-collection.html
new file mode 100644
index 0000000000..865594ae5b
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-collection.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <ul>
+ <li>One</li>
+ <li><a href="#">Two</a></li>
+ </ul>
+ <ul>
+ <li>
+ 1
+ <ul>
+ <li>1.1</li>
+ <li>1.2</li>
+ </ul>
+ </li>
+ </ul>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-expandable.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-expandable.html
new file mode 100644
index 0000000000..8b416cf882
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-expandable.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <button
+ onclick="this.setAttribute('aria-expanded', this.getAttribute('aria-expanded') == 'false')"
+ aria-expanded="false"
+ >
+ button
+ </button>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-headings.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-headings.html
new file mode 100644
index 0000000000..280bbd89d7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-headings.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html><html>
+<head>
+ <meta charset="utf-8">
+</head>
+<body>
+ <a href=\"%23\">preamble</a>
+ <h1>Fried cheese</h1><p>with club sauce.</p>
+ <a href="#"><h2>Popcorn shrimp</h2></a><button>with club sauce.</button>
+ <h3>Chicken fingers</h3><p>with spicy club sauce.</p>
+</body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-links.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-links.html
new file mode 100644
index 0000000000..a108925dc1
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-links.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <a href="/">a with href</a>
+ <a>a with no attributes</a>
+ <a name="anchor">a with name</a>
+ <a onclick=";">a with onclick</a>
+ <span role="link">span with role link</span>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-atomic.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-atomic.html
new file mode 100644
index 0000000000..85f9f6ccd2
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-atomic.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div aria-live="polite" aria-atomic="true" id="container">
+ The time is
+ <p>3pm</p>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-descendant.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-descendant.html
new file mode 100644
index 0000000000..82d88613f0
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-descendant.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div aria-live="polite"><p id="to_show">I will be shown</p></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image-labeled-by.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image-labeled-by.html
new file mode 100644
index 0000000000..5b91f1f6c2
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image-labeled-by.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <img
+ src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
+ aria-live="polite"
+ aria-labelledby="l1"
+ />
+ <span id="l1">Hello</span>
+ <span id="l2">Goodbye</span>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image.html
new file mode 100644
index 0000000000..da05b33c9a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region-image.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div aria-live="polite" aria-atomic="true">
+ This picture is
+ <img
+ src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
+ alt="happy"
+ />
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region.html
new file mode 100644
index 0000000000..c73fb91966
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-live-region.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div id="to_change" aria-live="polite"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-local-iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-local-iframe.html
new file mode 100644
index 0000000000..0aff253395
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-local-iframe.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <style>
+ body {
+ margin: 0;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ }
+ iframe {
+ height: 100%;
+ }
+ </style>
+ </head>
+ <body>
+ Some stuff
+ <iframe src="../hello.html" id="iframe"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-move-caret-accessibility-focus.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-move-caret-accessibility-focus.html
new file mode 100644
index 0000000000..d9d1597991
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-move-caret-accessibility-focus.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <p>Hello <a href="foo">sweet</a>, sweet <span>world</span></p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-mutation.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-mutation.html
new file mode 100644
index 0000000000..5c9c68aca0
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-mutation.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <div><p id="to_show">I will be shown</p></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-range.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-range.html
new file mode 100644
index 0000000000..70ef76e624
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-range.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <input type="range" aria-label="Rating" min="1" max="10" value="4" /><input
+ type="range"
+ aria-label="Stars"
+ min="1"
+ max="5"
+ step="0.5"
+ value="4.5"
+ /><input
+ type="range"
+ aria-label="Percent"
+ min="0"
+ max="1"
+ step="0.01"
+ value="0.83"
+ />
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-remote-iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-remote-iframe.html
new file mode 100644
index 0000000000..7e3e5da1ca
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-remote-iframe.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <style>
+ body {
+ margin: 0;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ }
+ iframe {
+ height: 100%;
+ }
+ </style>
+ </head>
+ <body>
+ Some stuff
+ <iframe
+ src="https://example.org/tests/junit/hello.html"
+ id="iframe"
+ ></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-scroll.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-scroll.html
new file mode 100644
index 0000000000..912aab9143
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-scroll.html
@@ -0,0 +1,10 @@
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width initial-scale=1" />
+<body style="margin: 0">
+ <div style="height: 100vh"></div>
+ <button>Hello</button>
+ <p style="margin: 0">
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua.
+ </p>
+</body>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-selectable.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-selectable.html
new file mode 100644
index 0000000000..f30951ff83
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-selectable.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <ul style="list-style-type: none" role="listbox">
+ <li
+ id="li"
+ role="option"
+ onclick="this.setAttribute('aria-selected',
+ this.getAttribute('aria-selected') == 'true' ? 'false' : 'true')"
+ >
+ 1
+ </li>
+ <li role="option" aria-selected="false">2</li>
+ </ul>
+ <li id="outsideSelectable" role="option" tabindex="0">
+ outside selectable
+ </li>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-text-entry-node.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-text-entry-node.html
new file mode 100644
index 0000000000..002efc9f14
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-text-entry-node.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <input aria-label="Name" aria-describedby="desc" value="Tobias" />
+ <div id="desc">description</div>
+ <input aria-label="Last" value="Funke" required />
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-tree.html b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-tree.html
new file mode 100644
index 0000000000..81ab105c7d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-tree.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <label for="name">Name:</label
+ ><input id="name" type="text" value="Julie" /><button>Submit</button>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/address_form.html b/mobile/android/geckoview/src/androidTest/assets/www/address_form.html
new file mode 100644
index 0000000000..d247c5ce79
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/address_form.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Address form</title>
+ </head>
+ <body>
+ <form>
+ <input autocomplete="name" id="name" />
+ <input autocomplete="given-name" id="givenName" />
+ <input autocomplete="additional-name" id="additionalName" />
+ <input autocomplete="family-name" id="familyName" />
+ <input autocomplete="street-address" id="streetAddress" />
+ <input autocomplete="country" id="country" />
+ <input autocomplete="postal-code" id="postalCode" />
+ <input autocomplete="organization" id="organization" />
+ <input autocomplete="email" id="email" />
+ <input autocomplete="tel" id="tel" />
+ <input type="submit" value="Submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/audio/owl.mp3 b/mobile/android/geckoview/src/androidTest/assets/www/audio/owl.mp3
new file mode 100644
index 0000000000..9fafa32f93
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/audio/owl.mp3
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/autoplay.html b/mobile/android/geckoview/src/androidTest/assets/www/autoplay.html
new file mode 100644
index 0000000000..24cbf474bd
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/autoplay.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>WEBM Video</title>
+ </head>
+ <body>
+ <video preload autoplay>
+ <source src="videos/gizmo.webm"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/badVideoPath.html b/mobile/android/geckoview/src/androidTest/assets/www/badVideoPath.html
new file mode 100644
index 0000000000..d9b34843fd
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/badVideoPath.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Bad Video Path</title>
+ </head>
+ <body>
+ <video controls preload>
+ <source src="videos/fileDoesNotExist.ogg"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/beforeunload.html b/mobile/android/geckoview/src/androidTest/assets/www/beforeunload.html
new file mode 100644
index 0000000000..d521afe532
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/beforeunload.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body onbeforeunload="return beforeUnload()">
+ <a id="navigateAway" href="./hello.html">Click Me</a>
+ <a id="navigateAway2" href="./hello2.html">Click Me</a>
+ <script>
+ function beforeUnload() {
+ return "Please don't leave.";
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/cc_form.html b/mobile/android/geckoview/src/androidTest/assets/www/cc_form.html
new file mode 100644
index 0000000000..7b3ea2a1bb
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/cc_form.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Form Autofill Test: Credit Card</title>
+ </head>
+ <body>
+ <form id="form1">
+ <input autocomplete="cc-name" id="name" />
+ <input autocomplete="cc-number" id="number" />
+ <input autocomplete="cc-exp-month" id="expMonth" />
+ <input autocomplete="cc-exp-year" id="expYear" />
+ <input type="submit" value="Submit" />
+ </form>
+ <!-- form2 uses a single expiration date field -->
+ <form id="form2">
+ <input autocomplete="cc-name" id="name" />
+ <input autocomplete="cc-number" id="number" />
+ <input autocomplete="cc-exp" id="exp" />
+ <input type="submit" value="Submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/clickToReload.html b/mobile/android/geckoview/src/androidTest/assets/www/clickToReload.html
new file mode 100644
index 0000000000..47bdceccee
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/clickToReload.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="initial-scale=1.0" />
+ </head>
+ <body style="height: 100%" onclick="window.location.reload()">
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/clipboard_read.html b/mobile/android/geckoview/src/androidTest/assets/www/clipboard_read.html
new file mode 100644
index 0000000000..19a034a23d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/clipboard_read.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="initial-scale=1.0" />
+ </head>
+ <body style="height: 100%">
+ <p>Hello, world!</p>
+ <script>
+ document.body.addEventListener("click", () => {
+ navigator.clipboard
+ .readText()
+ .then(() => {
+ window.alert("allow");
+ })
+ .catch(() => {
+ window.alert("deny");
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/color_grid.html b/mobile/android/geckoview/src/androidTest/assets/www/color_grid.html
new file mode 100644
index 0000000000..ebc989acdb
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/color_grid.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Color Grid</title>
+ </head>
+ <style>
+ body {
+ margin: 0;
+ }
+ .container {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ }
+ .box {
+ height: 100vh;
+ width: 33.33vw;
+ }
+ .red {
+ background-color: rgb(255, 0, 0);
+ color-adjust: exact;
+ }
+ .green {
+ background-color: rgb(0, 255, 0);
+ color-adjust: exact;
+ }
+ .blue {
+ background-color: rgb(0, 0, 255);
+ color-adjust: exact;
+ }
+ </style>
+
+ <body>
+ <div class="container">
+ <div class="red box"></div>
+ <div class="green box"></div>
+ <div class="blue box"></div>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/color_orange_background.html b/mobile/android/geckoview/src/androidTest/assets/www/color_orange_background.html
new file mode 100644
index 0000000000..8a682d79a7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/color_orange_background.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Orange Print Background</title>
+ </head>
+ <style>
+ .box {
+ height: 100vh;
+ width: 100vw;
+ }
+ @media screen {
+ .background {
+ background-color: rgb(0, 0, 255);
+ color-adjust: exact;
+ }
+ }
+ @media print {
+ .background {
+ background-color: rgb(255, 113, 57);
+ color-adjust: exact;
+ }
+ }
+ </style>
+
+ <body>
+ <div class="box background"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/colors.html b/mobile/android/geckoview/src/androidTest/assets/www/colors.html
new file mode 100644
index 0000000000..b00da3ed9c
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/colors.html
@@ -0,0 +1,23 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Colours</title>
+ </head>
+ <!-- background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. !-->
+ <body
+ style="
+ overflow: hidden;
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ background: url('/assets/www/transparent.gif'),
+ linear-gradient(135deg, red, white);
+ "
+ ></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_audio.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_audio.html
new file mode 100644
index 0000000000..b26323a13e
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_audio.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Audio</title>
+ </head>
+ <style>
+ body {
+ margin: 0;
+ }
+ </style>
+ <body>
+ <div class="center-audio">
+ <audio controls src="audio/owl.mp3">
+ Your browser does not support the
+ <code>audio</code> element.
+ </audio>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html
new file mode 100644
index 0000000000..9849747a41
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_buffered.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Blob Buffered</title>
+ </head>
+ <body>
+ <video id="video" controls preload></video>
+ </body>
+ <script>
+ window.addEventListener("DOMContentLoaded", function (e) {
+ const video = document.getElementById("video");
+ const mediaSource = new MediaSource();
+ video.src = URL.createObjectURL(mediaSource);
+ mediaSource.addEventListener("sourceopen", createBuffer);
+
+ function createBuffer(event) {
+ const mediaSource = event.target;
+ const assetURL = "/assets/www/videos/gizmo.webm";
+ const codec = 'video/webm; codecs="opus"';
+ const sourceBuffer = mediaSource.addSourceBuffer(codec);
+
+ function addBuffer(response) {
+ sourceBuffer.addEventListener("updateend", function () {
+ mediaSource.endOfStream();
+ });
+ sourceBuffer.appendBuffer(response);
+ }
+
+ fetchVideoData(assetURL, addBuffer);
+ }
+
+ function fetchVideoData(assetURL, videoArrayBuffer) {
+ const request = new XMLHttpRequest();
+ request.open("get", assetURL);
+ request.responseType = "arraybuffer";
+ request.onload = function () {
+ videoArrayBuffer(request.response);
+ };
+ request.send();
+ }
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html
new file mode 100644
index 0000000000..5ebc2bddba
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_blob_full.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Blob</title>
+ </head>
+ <body>
+ <div id="image_container"></div>
+ </body>
+ <script>
+ window.addEventListener("DOMContentLoaded", function (e) {
+ const svg = `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <circle cx="50" cy="50" r="50" stroke="orange" fill="transparent" stroke-width="5"/>
+ </svg>`;
+ const image = document.createElement("img");
+ const blob = new Blob([svg], { type: "image/svg+xml" });
+ image.src = URL.createObjectURL(blob);
+ image.alt = "An orange circle.";
+ document.getElementById("image_container").appendChild(image);
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image.html
new file mode 100644
index 0000000000..9564f94628
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Image</title>
+ </head>
+ <body>
+ <img id="image" src="images/test.gif" alt="Test Image" />
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image_nested.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image_nested.html
new file mode 100644
index 0000000000..99563d66f5
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_image_nested.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Nested Image</title>
+ </head>
+ <body>
+ <div>
+ <div>
+ <img id="image" src="images/test.gif" alt="Test Image" />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_link.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_link.html
new file mode 100644
index 0000000000..e5b0d0d316
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_link.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Context Menu Test Link</title>
+ </head>
+ <style>
+ #hello {
+ font-size: 20vw;
+ }
+ </style>
+ <body>
+ <a href="hello.html" title="Hello Link Title" id="hello">Hello World</a>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/context_menu_video.html b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_video.html
new file mode 100644
index 0000000000..bca8e46afe
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/context_menu_video.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height">
+ <title>Context Menu Test Video</title>
+ </head>
+ <body>
+ <video controls preload>
+ <source src="videos/short.mp4"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/data_uri.html b/mobile/android/geckoview/src/androidTest/assets/www/data_uri.html
new file mode 100644
index 0000000000..638e4c754c
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/data_uri.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Link with a giant data URI</title>
+ </head>
+ <body>
+ <a href="insert uri here" id="smallLink">Open small link</a>
+ <a href="insert uri here" id="largeLink">Open large link</a>
+ <img src="/assets/www/images/test.gif" id="image" />
+ <script language="JavaScript">
+ var imageLoaded = false;
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/dnd.html b/mobile/android/geckoview/src/androidTest/assets/www/dnd.html
new file mode 100644
index 0000000000..0dc36b4f9a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/dnd.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <script>
+ document.addEventListener("DOMContentLoaded", () =>
+ document
+ .querySelector("#drop")
+ .addEventListener("dragover", e => e.preventDefault())
+ );
+ </script>
+ </head>
+ <body>
+ <img
+ id="drag"
+ draggable="true"
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2PwmvDoPwAFoAK895OuoAAAAABJRU5ErkJggg=="
+ width="200"
+ height="100"
+ />
+ <br />
+ <div id="drop" style="border: 1px solid red; width: 200px; height: 100px">
+ drop
+ </div>
+ <textarea id="textarea" style="width: 200px; height: 100px"></textarea>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/download.html b/mobile/android/geckoview/src/androidTest/assets/www/download.html
new file mode 100644
index 0000000000..4f06323dc6
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/download.html
@@ -0,0 +1,18 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <script>
+ const blob = new Blob(["Downloaded Data"], { type: "text/plain" });
+ const element = document.createElement("a");
+ const uri = URL.createObjectURL(blob);
+ element.href = uri;
+ element.download = "download.txt";
+ element.style.display = "none";
+ document.body.appendChild(element);
+ element.click();
+ URL.revokeObjectURL(uri);
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fedcm_accounts_endpoint.json b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_accounts_endpoint.json
new file mode 100644
index 0000000000..5a8f6eeb30
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_accounts_endpoint.json
@@ -0,0 +1,12 @@
+{
+ "accounts": [
+ {
+ "id": "$RANDOM_ID",
+ "given_name": "",
+ "name": " ",
+ "email": "demo",
+ "picture": "http://localhost:4245/assets/www/images/test.gif",
+ "approved_clients": ["fedcm_rp.html"]
+ }
+ ]
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_manifest.json b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_manifest.json
new file mode 100644
index 0000000000..bc66100e6a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_manifest.json
@@ -0,0 +1,18 @@
+{
+ "accounts_endpoint": "fedcm_accounts_endpoint.json",
+ "client_metadata_endpoint": "fedcm_idp_metadata.json",
+ "id_assertion_endpoint": "fedcm_idtokens_endpoint.json",
+ "id_token_endpoint": "fedcm_idtokens_endpoint.json",
+ "revocation_endpoint": "revocation_endpoint",
+ "branding": {
+ "background_color": "0x6200ee",
+ "color": "0xffffff",
+ "icons": [
+ {
+ "url": "http://localhost:4245/assets/www/images/test.gif",
+ "size": 256
+ }
+ ],
+ "name": "Demo IDP"
+ }
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_metadata.json b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_metadata.json
new file mode 100644
index 0000000000..db9b9deaf8
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idp_metadata.json
@@ -0,0 +1,4 @@
+{
+ "privacy_policy_url": "privacy_policy",
+ "terms_of_service_url": "terms_of_service"
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idtokens_endpoint.json b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idtokens_endpoint.json
new file mode 100644
index 0000000000..ba6edfe281
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_idtokens_endpoint.json
@@ -0,0 +1,3 @@
+{
+ "token": "token"
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fedcm_rp.html b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_rp.html
new file mode 100644
index 0000000000..4d1fddee7f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fedcm_rp.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <link rel="manifest" href="manifest.webmanifest" />
+ </head>
+ <body></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fixedbottom.html b/mobile/android/geckoview/src/androidTest/assets/www/fixedbottom.html
new file mode 100644
index 0000000000..b802bb335b
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fixedbottom.html
@@ -0,0 +1,36 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>Fixed bottom element</title>
+ </head>
+ <!-- background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. !-->
+ <body
+ style="
+ overflow: hidden;
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ background: url('/assets/www/transparent.gif'),
+ linear-gradient(135deg, blue, blue);
+ "
+ >
+ <div
+ id="bottom-banner"
+ style="
+ width: 100%;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ background-color: lime;
+ height: 10%;
+ "
+ ></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fixedpercent.html b/mobile/android/geckoview/src/androidTest/assets/www/fixedpercent.html
new file mode 100644
index 0000000000..587df00473
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fixedpercent.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, minimum-scale=0.5" />
+<style>
+ html {
+ width: 100%;
+ height: 100%;
+ scrollbar-width: none;
+ }
+ body {
+ width: 200%;
+ height: 2000px;
+ margin: 0;
+ padding: 0;
+ }
+
+ #fixed-element {
+ width: 100%;
+ height: 200%;
+ position: fixed;
+ top: 0px;
+ background-color: green;
+ }
+</style>
+<div id="fixed-element"></div>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fixedvh.html b/mobile/android/geckoview/src/androidTest/assets/www/fixedvh.html
new file mode 100644
index 0000000000..fd6661c2cd
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fixedvh.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, minimum-scale=0.5" />
+<style>
+ html {
+ width: 100%;
+ height: 100%;
+ scrollbar-width: none;
+ }
+ body {
+ width: 200%;
+ height: 2000px;
+ margin: 0;
+ padding: 0;
+ }
+
+ #fixed-element {
+ width: 100%;
+ height: 200vh;
+ position: fixed;
+ top: 0px;
+ background-color: green;
+ }
+</style>
+<div id="fixed-element"></div>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/form_blank.html b/mobile/android/geckoview/src/androidTest/assets/www/form_blank.html
new file mode 100644
index 0000000000..918cc4cb7a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/form_blank.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form
+ id="form1"
+ name="form1"
+ action="form_blank.html"
+ method="get"
+ target="_blank"
+ >
+ <input type="text" id="search" value="foo" />
+ <input type="submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms.html b/mobile/android/geckoview/src/androidTest/assets/www/forms.html
new file mode 100644
index 0000000000..06c2ed64db
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms.html
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" />
+ <input type="email" id="email1" value="@" />
+ <input type="number" id="number1" value="0" />
+ <input type="tel" id="tel1" value="0" />
+ <input type="submit" value="submit" />
+ </form>
+ <input type="Text" id="user2" value="foo" />
+ <input type="PassWord" id="pass2" maxlength="8" value="foo" />
+ <input type="button" id="button1" value="foo" />
+ <input type="checkbox" id="checkbox1" />
+ <input type="search" id="search1" />
+ <input type="url" id="url1" />
+ <input type="hidden" id="hidden1" value="foo" />
+
+ <iframe id="iframe"></iframe>
+ </body>
+ <script>
+ addEventListener("load", function (e) {
+ if (window.parent === window) {
+ document.getElementById("iframe").contentWindow.location.href =
+ window.location.href;
+ }
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms2.html b/mobile/android/geckoview/src/androidTest/assets/www/forms2.html
new file mode 100644
index 0000000000..06ab5ec448
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms2.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms2</title>
+ </head>
+ <body>
+ <form>
+ <fieldset>
+ <input type="text" id="firstname" />
+ <input type="text" id="lastname" />
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" autofocus />
+ </fieldset>
+ </form>
+ <iframe id="iframe" src="forms2_iframe.html"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms2_iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/forms2_iframe.html
new file mode 100644
index 0000000000..849fa43271
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms2_iframe.html
@@ -0,0 +1,16 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms2 iframe</title>
+ </head>
+ <body>
+ <form>
+ <fieldset>
+ <input type="text" id="firstname" />
+ <input type="text" id="lastname" />
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" autofocus />
+ </fieldset>
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms3.html b/mobile/android/geckoview/src/androidTest/assets/www/forms3.html
new file mode 100644
index 0000000000..91bceb3943
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms3.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" placeholder="username" />
+ <input type="password" id="pass1" placeholder="password" />
+ <input type="submit" value="submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms4.html b/mobile/android/geckoview/src/androidTest/assets/www/forms4.html
new file mode 100644
index 0000000000..3650635396
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms4.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" />
+ <input type="password" id="pass1" autocomplete="new-password" />
+ <input type="submit" value="submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms5.html b/mobile/android/geckoview/src/androidTest/assets/www/forms5.html
new file mode 100644
index 0000000000..b9da67f343
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms5.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" />
+ <input type="email" id="email1" value="@" />
+ <input type="number" id="number1" value="0" />
+ <input type="tel" id="tel1" value="0" />
+ <input type="submit" value="submit" />
+ </form>
+ <input type="Text" id="user2" value="foo" />
+ <input type="PassWord" id="pass2" maxlength="8" value="foo" />
+ <input type="button" id="button1" value="foo" />
+ <input type="checkbox" id="checkbox1" />
+ <input type="search" id="search1" />
+ <input type="url" id="url1" />
+ <input type="hidden" id="hidden1" value="foo" />
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete.html b/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete.html
new file mode 100644
index 0000000000..81401a1d27
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete.html
@@ -0,0 +1,16 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form>
+ <input type="text" autocomplete="email" autofocus />
+ <input type="text" autocomplete="username" />
+ <input type="password" />
+ <input type="submit" value="submit" />
+ </form>
+ <iframe id="iframe" src="forms_autocomplete_iframe.html"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete_iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete_iframe.html
new file mode 100644
index 0000000000..11137531ba
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms_autocomplete_iframe.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form>
+ <input type="text" autocomplete="email" autofocus />
+ <input type="text" autocomplete="username" />
+ <input type="password" />
+ <input type="submit" value="submit" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms_id_value.html b/mobile/android/geckoview/src/androidTest/assets/www/forms_id_value.html
new file mode 100644
index 0000000000..522dbc1600
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms_id_value.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms ID Value</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="password" id="value" />
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms_iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/forms_iframe.html
new file mode 100644
index 0000000000..2c0ef7dff5
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms_iframe.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms iframe</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" />
+ <input type="email" id="email1" value="@" />
+ <input type="number" id="number1" value="0" />
+ <input type="tel" id="tel1" value="0" />
+ <input type="submit" value="submit" />
+ </form>
+ <input type="Text" id="user2" value="foo" />
+ <input type="PassWord" id="pass2" maxlength="8" value="foo" />
+ <input type="button" id="button1" value="foo" />
+ <input type="checkbox" id="checkbox1" />
+ <input type="search" id="search1" />
+ <input type="url" id="url1" />
+ <input type="hidden" id="hidden1" value="foo" />
+ </body>
+ <script>
+ const params = new URL(document.location).searchParams;
+
+ function getEventInterface(event) {
+ if (event instanceof document.defaultView.InputEvent) {
+ return "InputEvent";
+ }
+ if (event instanceof document.defaultView.UIEvent) {
+ return "UIEvent";
+ }
+ if (event instanceof document.defaultView.Event) {
+ return "Event";
+ }
+ return "Unknown";
+ }
+
+ function getData(key, value) {
+ return new Promise(resolve =>
+ document.querySelector(key).addEventListener(
+ "input",
+ event => {
+ resolve([key, event.target.value, value, getEventInterface(event)]);
+ },
+ { once: true }
+ )
+ );
+ }
+
+ window.addEventListener("message", async event => {
+ const { data, source, origin } = event;
+ source.postMessage(await getData(data.key, data.value), origin);
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/forms_xorigin.html b/mobile/android/geckoview/src/androidTest/assets/www/forms_xorigin.html
new file mode 100644
index 0000000000..ebd86c59a1
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms_xorigin.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Forms</title>
+ <meta name="viewport" content="minimum-scale=1,width=device-width" />
+ </head>
+ <body>
+ <form id="form1">
+ <input type="text" id="user1" value="foo" />
+ <input type="password" id="pass1" value="foo" />
+ <input type="email" id="email1" value="@" />
+ <input type="number" id="number1" value="0" />
+ <input type="tel" id="tel1" value="0" />
+ <input type="submit" value="submit" />
+ </form>
+ <input type="Text" id="user2" value="foo" />
+ <input type="PassWord" id="pass2" maxlength="8" value="foo" />
+ <input type="button" id="button1" value="foo" />
+ <input type="checkbox" id="checkbox1" />
+ <input type="search" id="search1" />
+ <input type="url" id="url1" />
+ <input type="hidden" id="hidden1" value="foo" />
+
+ <iframe
+ id="iframe"
+ src="http://example.org/tests/junit/forms_iframe.html"
+ ></iframe>
+ </body>
+ <script>
+ const params = new URL(document.location).searchParams;
+ const iframe = document.getElementById("iframe").contentWindow;
+
+ function getEventInterface(event) {
+ if (event instanceof document.defaultView.InputEvent) {
+ return "InputEvent";
+ }
+ if (event instanceof document.defaultView.UIEvent) {
+ return "UIEvent";
+ }
+ if (event instanceof document.defaultView.Event) {
+ return "Event";
+ }
+ return "Unknown";
+ }
+
+ function getData(key, value) {
+ return new Promise(resolve =>
+ document.querySelector(key).addEventListener(
+ "input",
+ event => {
+ resolve([key, event.target.value, value, getEventInterface(event)]);
+ },
+ { once: true }
+ )
+ );
+ }
+
+ window.getDataForAllFrames = function (key, value) {
+ const data = [];
+ data.push(
+ new Promise(resolve =>
+ window.addEventListener(
+ "message",
+ event => {
+ resolve(event.data);
+ },
+ { once: true }
+ )
+ )
+ );
+ iframe.postMessage({ key, value }, "*");
+ data.push(getData(key, value));
+ return Promise.all(data);
+ };
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/fullscreen.html b/mobile/android/geckoview/src/androidTest/assets/www/fullscreen.html
new file mode 100644
index 0000000000..f7d4feb3a4
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/fullscreen.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Fullscreen</title>
+ </head>
+ <body>
+ <div id="fullscreen">Fullscreen Div</div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_container.html b/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_container.html
new file mode 100644
index 0000000000..2ba4a89b54
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_container.html
@@ -0,0 +1,58 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>GetUserMedia from cross-origin iframe: the container document</title>
+ </head>
+ <body>
+ <iframe
+ id="iframe_no_allow"
+ src="http://127.0.0.1:4245/assets/www/getusermedia_xorigin_iframe.html"
+ ></iframe>
+ <iframe
+ id="iframe"
+ allow="camera;microphone"
+ src="http://127.0.0.1:4245/assets/www/getusermedia_xorigin_iframe.html"
+ ></iframe>
+ <script>
+ "use strict";
+
+ let iframeWindow;
+ let generation = 1;
+
+ async function Send(obj) {
+ obj.gen = generation++;
+ iframeWindow.postMessage(obj, "http://127.0.0.1:4245");
+ while (true) {
+ const {
+ data: { gen, result },
+ } = await new Promise(r => (window.onmessage = r));
+ if (gen == obj.gen) {
+ return result;
+ }
+ }
+ }
+
+ function Start(constraints) {
+ if (iframeWindow) {
+ return "iframe mode already decided";
+ }
+ iframeWindow = document.getElementById("iframe").contentWindow;
+ return Send({ name: "start", constraints });
+ }
+
+ function StartNoAllow(constraints) {
+ if (iframeWindow) {
+ return "iframe mode already decided";
+ }
+ iframeWindow = document.getElementById("iframe_no_allow").contentWindow;
+ return Send({ name: "start", constraints });
+ }
+
+ async function Stop() {
+ const result = await Send({ name: "stop" });
+ iframeWindow = undefined;
+ return result;
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_iframe.html
new file mode 100644
index 0000000000..3649167c25
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/getusermedia_xorigin_iframe.html
@@ -0,0 +1,39 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>GetUserMedia from cross-origin iframe: the iframe document</title>
+ </head>
+ <body>
+ <script>
+ "use strict";
+
+ let stream;
+ window.addEventListener(
+ "message",
+ async ({ data: { name, gen, constraints } }) => {
+ if (name == "start") {
+ try {
+ stream = await navigator.mediaDevices.getUserMedia(constraints);
+ Send({ gen, result: "ok" });
+ } catch (e) {
+ Send({ gen, result: `${e}` });
+ }
+ } else if (name == "stop") {
+ const result = !!stream;
+ if (stream) {
+ for (const t of stream.getTracks()) {
+ t.stop();
+ }
+ stream = undefined;
+ }
+ Send({ gen, result });
+ }
+ }
+ );
+
+ function Send(obj) {
+ window.parent.postMessage(obj, "http://localhost:4245");
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/hello.html b/mobile/android/geckoview/src/androidTest/assets/www/hello.html
new file mode 100644
index 0000000000..5ebd20f929
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/hello.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <link rel="manifest" href="manifest.webmanifest" />
+ </head>
+ <body>
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/hello2.html b/mobile/android/geckoview/src/androidTest/assets/www/hello2.html
new file mode 100644
index 0000000000..d03c2d5521
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/hello2.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world! Again!</title>
+ </head>
+ <body>
+ <p>Hello, world! Again!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/helloPDFWorld.pdf b/mobile/android/geckoview/src/androidTest/assets/www/helloPDFWorld.pdf
new file mode 100755
index 0000000000..0f429e1a90
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/helloPDFWorld.pdf
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/hsts_header.sjs b/mobile/android/geckoview/src/androidTest/assets/www/hsts_header.sjs
new file mode 100644
index 0000000000..e53ad908fa
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/hsts_header.sjs
@@ -0,0 +1,6 @@
+function handleRequest(request, response) {
+ response.setHeader(
+ "Strict-Transport-Security",
+ "max-age=60; includeSubDomains"
+ );
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/hungScript.html b/mobile/android/geckoview/src/androidTest/assets/www/hungScript.html
new file mode 100644
index 0000000000..6b56f4e2e7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/hungScript.html
@@ -0,0 +1,16 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hung Script</title>
+ </head>
+ <body>
+ <div id="content"></div>
+ </body>
+ <script>
+ var start = new Date().getTime();
+ document.getElementById("content").innerHTML = "Started";
+ // eslint-disable-next-line no-empty
+ while (new Date().getTime() - start < 5000) {}
+ document.getElementById("content").innerHTML = "Finished";
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_no_scrollable.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_no_scrollable.html
new file mode 100644
index 0000000000..3e7bd5cdd0
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_no_scrollable.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ iframe {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ border: none;
+ display: block;
+ }
+ </style>
+ <iframe
+ frameborder="0"
+ srcdoc="<!DOCTYPE HTML>
+ <html>
+ <style>
+ html, body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style='width: 100%; height: 100%; background-color: green;'></div>
+ <script>
+ if (parent.document.location.search.startsWith('?event')) {
+ document.querySelector('div').addEventListener('touchstart', e => {
+ if (parent.document.location.search == '?event-prevent') {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+ </html>"
+ >
+ </iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_scrollable.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_scrollable.html
new file mode 100644
index 0000000000..e7517c5f12
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_100_percent_height_scrollable.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ iframe {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ border: none;
+ display: block;
+ }
+ </style>
+ <iframe
+ frameborder="0"
+ srcdoc="<!DOCTYPE HTML>
+ <html>
+ <style>
+ html, body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style='width: 100%; height: 500vh; background-color: green;'></div>
+ <script>
+ if (parent.document.location.search.startsWith('?event')) {
+ document.querySelector('div').addEventListener('touchstart', e => {
+ if (parent.document.location.search == '?event-prevent') {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+ </html>"
+ >
+ </iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_no_scrollable.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_no_scrollable.html
new file mode 100644
index 0000000000..9766f41b7f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_no_scrollable.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html,
+ body {
+ margin: 0px;
+ padding: 0px;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ iframe {
+ margin: 0px;
+ padding: 0px;
+ height: 98vh;
+ width: 100%;
+ border: none;
+ display: block;
+ }
+ </style>
+ <iframe
+ frameborder="0"
+ srcdoc="<!DOCTYPE HTML>
+ <html>
+ <style>
+ html, body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style='width: 100%; height: 100%; background-color: green;'></div>
+ <script>
+ if (parent.document.location.search.startsWith('?event')) {
+ document.querySelector('div').addEventListener('touchstart', e => {
+ if (parent.document.location.search == '?event-prevent') {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+ </html>"
+ >
+ </iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_scrollable.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_scrollable.html
new file mode 100644
index 0000000000..ca356958df
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_98vh_scrollable.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html,
+ body {
+ margin: 0px;
+ padding: 0px;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ iframe {
+ margin: 0px;
+ padding: 0px;
+ height: 98vh;
+ width: 100%;
+ border: none;
+ display: block;
+ }
+ </style>
+ <iframe
+ frameborder="0"
+ srcdoc="<!DOCTYPE HTML>
+ <html>
+ <style>
+ html, body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style='width: 100%; height: 500vh; background-color: green;'></div>
+ <script>
+ if (parent.document.location.search.startsWith('?event')) {
+ document.querySelector('div').addEventListener('touchstart', e => {
+ if (parent.document.location.search == '?event-prevent') {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+ </html>"
+ >
+ </iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_hello.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_hello.html
new file mode 100644
index 0000000000..ee4962a2b7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_hello.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ </head>
+ <body>
+ <p>Hello, world! From Top Level.</p>
+ <iframe src="hello.html"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_http_only.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_http_only.html
new file mode 100644
index 0000000000..8f94d6c86d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_http_only.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ </head>
+ <body>
+ Some stuff
+ <iframe
+ src="http://expired.example.com/"
+ width="100%"
+ height="100%"
+ ></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_automation.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_automation.html
new file mode 100644
index 0000000000..c708687a3e
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_automation.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ </head>
+ <body>
+ Some stuff
+ <iframe
+ src="https://example.org/tests/junit/simple_redirect.sjs?https://example.org"
+ ></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_local.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_local.html
new file mode 100644
index 0000000000..eb109536f0
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_redirect_local.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ </head>
+ <body>
+ Some stuff
+ <iframe src="http://jigsaw.w3.org/HTTP/300/301.html"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/iframe_unknown_protocol.html b/mobile/android/geckoview/src/androidTest/assets/www/iframe_unknown_protocol.html
new file mode 100644
index 0000000000..81fb616b60
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/iframe_unknown_protocol.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ </head>
+ <body>
+ <p>Hello, world! From Top Level.</p>
+ <iframe src="foo://bar"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/images/test.gif b/mobile/android/geckoview/src/androidTest/assets/www/images/test.gif
new file mode 100644
index 0000000000..ba3b541c31
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/images/test.gif
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/inputs.html b/mobile/android/geckoview/src/androidTest/assets/www/inputs.html
new file mode 100644
index 0000000000..554c6c8143
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/inputs.html
@@ -0,0 +1,66 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Inputs</title>
+ <script>
+ class CustomTextBox extends HTMLElement {
+ constructor() {
+ super();
+
+ this.attachShadow({ mode: "open" });
+ const wrapper = document.createElement("span");
+ this.textbox = wrapper.appendChild(document.createElement("input"));
+ this.textbox.value = "adipisci";
+ this.shadowRoot.append(wrapper);
+ }
+
+ focus() {
+ this.textbox.focus();
+ }
+
+ select() {
+ this.textbox.select();
+ }
+
+ setSelectionRange(start, end) {
+ this.textbox.setSelectionRange(start, end);
+ }
+
+ get selectionStart() {
+ return this.textbox.selectionStart;
+ }
+
+ get selectionEnd() {
+ return this.textbox.selectionEnd;
+ }
+
+ get value() {
+ return this.textbox.value;
+ }
+ }
+ customElements.define("x-input", CustomTextBox);
+ </script>
+ </head>
+ <body>
+ <div id="text">lorem</div>
+ <input type="text" id="input" value="ipsum" />
+ <textarea id="textarea">dolor</textarea>
+ <div id="contenteditable" contenteditable="true">sit</div>
+ <iframe id="iframe" src="selectionAction_frame.html"></iframe>
+ <iframe id="designmode" src="selectionAction_frame.html"></iframe>
+ <iframe
+ id="iframe-xorigin"
+ src="http://127.0.0.1:4245/assets/www/selectionAction_frame_xorigin.html"
+ ></iframe>
+ <x-input id="x-input"></x-input>
+ </body>
+ <script>
+ addEventListener("load", function () {
+ document.getElementById("iframe").contentDocument.body.textContent =
+ "amet";
+ var designmode = document.getElementById("designmode");
+ designmode.contentDocument.body.textContent = "consectetur";
+ designmode.contentDocument.designMode = "on";
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/links.html b/mobile/android/geckoview/src/androidTest/assets/www/links.html
new file mode 100644
index 0000000000..186426b0e2
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/links.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Links</title>
+ <style>
+ :link {
+ color: rgb(0, 0, 255);
+ }
+
+ :visited {
+ color: rgb(255, 0, 0);
+ }
+ </style>
+ </head>
+ <body>
+ <ul>
+ <li><a id="mozilla" href="https://mozilla.org">Mozilla</a></li>
+ <li><a id="firefox" href="https://getfirefox.com">Get Firefox!</a></li>
+ <li><a id="bugzilla" href="https://bugzilla.mozilla.org">Bugzilla</a></li>
+ <li>
+ <a id="testpilot" href="https://testpilot.firefox.com">Test Pilot</a>
+ </li>
+ <li>
+ <a id="fxa" href="https://accounts.firefox.com">Firefox Accounts</a>
+ </li>
+ </ul>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/loremIpsum.html b/mobile/android/geckoview/src/androidTest/assets/www/loremIpsum.html
new file mode 100644
index 0000000000..e772f605f0
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/loremIpsum.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Lorem ipsum</title>
+ </head>
+ <body>
+ <p style="font-family: monospace; width: 20ch">
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
+ velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ cupidatat non proident, sunt in culpa qui officia deserunt mollit
+ <a href="#">anim id</a> est laborum.
+ </p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/manifest.webmanifest b/mobile/android/geckoview/src/androidTest/assets/www/manifest.webmanifest
new file mode 100644
index 0000000000..5528465ba2
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/manifest.webmanifest
@@ -0,0 +1,17 @@
+{
+ "name": "App",
+ "short_name": "app",
+ "start_url": "./start/index.html",
+ "display": "standalone",
+ "background_color": "#c0ffeeee",
+ "theme_color": "cadetblue",
+ "icons": [{
+ "src": "images/test.gif",
+ "sizes": "192x192",
+ "type": "image/gif"
+ }],
+ "related_applications": [{
+ "platform": "play",
+ "url": "https://play.google.com/store/apps/details?id=my.first.webapp"
+ }]
+} \ No newline at end of file
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/media_session_default1.html b/mobile/android/geckoview/src/androidTest/assets/www/media_session_default1.html
new file mode 100644
index 0000000000..3d6554012b
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/media_session_default1.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <title>MediaSessionDefaultTest1</title>
+ </head>
+ <body>
+ <script>
+ const audio1 = document.createElement("audio");
+ audio1.src = "audio/owl.mp3";
+
+ window.onload = () => {
+ audio1.play();
+ };
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/media_session_dom1.html b/mobile/android/geckoview/src/androidTest/assets/www/media_session_dom1.html
new file mode 100644
index 0000000000..8fa9584428
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/media_session_dom1.html
@@ -0,0 +1,109 @@
+<html>
+ <head>
+ <title>MediaSessionDOMTest1</title>
+ </head>
+ <body>
+ <script>
+ function updatePositionState(event) {
+ if (event.target != active) {
+ return;
+ }
+ navigator.mediaSession.setPositionState({
+ duration: parseFloat(event.target.duration),
+ position: parseFloat(event.target.currentTime),
+ playbackRate: 1,
+ });
+ }
+
+ function updateMetadata() {
+ navigator.mediaSession.metadata = active.metadata;
+ }
+
+ function getTrack(offset) {
+ console.log("" + active.id + " " + offset);
+ const nextId = Math.min(
+ tracks.length - 1,
+ Math.max(0, parseInt(active.id) + offset)
+ );
+ return tracks[nextId];
+ }
+
+ navigator.mediaSession.setActionHandler("play", async () => {
+ updateMetadata();
+ await active.play();
+ });
+
+ navigator.mediaSession.setActionHandler("pause", () => {
+ active.pause();
+ });
+
+ navigator.mediaSession.setActionHandler("previoustrack", () => {
+ active = getTrack(-1);
+ });
+
+ navigator.mediaSession.setActionHandler("nexttrack", () => {
+ active = getTrack(1);
+ });
+
+ const audio1 = document.createElement("audio");
+ audio1.src = "audio/owl.mp3";
+ audio1.addEventListener("timeupdate", updatePositionState);
+ audio1.metadata = new window.MediaMetadata({
+ title: "hoot",
+ artist: "owl",
+ album: "hoots",
+ artwork: [
+ {
+ src: "images/test.gif",
+ type: "image/gif",
+ sizes: "265x199",
+ },
+ ],
+ });
+ audio1.id = 0;
+
+ const audio2 = document.createElement("audio");
+ audio2.src = "audio/owl.mp3";
+ audio2.addEventListener("timeupdate", updatePositionState);
+ audio2.metadata = new window.MediaMetadata({
+ title: "hoot2",
+ artist: "stillowl",
+ album: "dahoots",
+ artwork: [
+ {
+ src: "images/test.gif",
+ type: "image/gif",
+ sizes: "265x199",
+ },
+ ],
+ });
+ audio2.id = 1;
+
+ const audio3 = document.createElement("audio");
+ audio3.src = "audio/owl.mp3";
+ audio3.addEventListener("timeupdate", updatePositionState);
+ audio3.metadata = new window.MediaMetadata({
+ title: "hoot3",
+ artist: "immaowl",
+ album: "mahoots",
+ artwork: [
+ {
+ src: "images/test.gif",
+ type: "image/gif",
+ sizes: "265x199",
+ },
+ ],
+ });
+ audio3.id = 2;
+
+ const tracks = [audio1, audio2, audio3];
+ let active = audio1;
+
+ window.onload = async () => {
+ active = getTrack(0);
+ updateMetadata();
+ await active.play();
+ };
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/metatags.html b/mobile/android/geckoview/src/androidTest/assets/www/metatags.html
new file mode 100644
index 0000000000..946c9faf27
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/metatags.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <title>MetaTags</title>
+ <meta property="twitter:description" content="twitter:description" />
+ <meta property="og:description" content="og:description" />
+ <meta name="description" content="description" />
+ <meta name="unknown:tag" content="unknown:tag" />
+ <meta property="og:image" content="https://test.com/og-image.jpg" />
+ <meta
+ property="twitter:image"
+ content="https://test.com/twitter-image.jpg"
+ />
+ <meta property="og:image:url" content="https://test.com/og-image-url" />
+ <meta name="thumbnail" content="https://test.com/thumbnail.jpg" />
+ </head>
+ <body></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/mouseToReload.html b/mobile/android/geckoview/src/androidTest/assets/www/mouseToReload.html
new file mode 100644
index 0000000000..4ef3626119
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/mouseToReload.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="initial-scale=1.0" />
+ </head>
+ <body style="height: 100%">
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/mp4.html b/mobile/android/geckoview/src/androidTest/assets/www/mp4.html
new file mode 100644
index 0000000000..09909fac69
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/mp4.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>MP4 Video</title>
+ </head>
+ <body>
+ <video controls preload>
+ <source src="videos/short.mp4"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/newSession.html b/mobile/android/geckoview/src/androidTest/assets/www/newSession.html
new file mode 100644
index 0000000000..b92657430c
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/newSession.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ </head>
+ <body>
+ <a
+ id="targetBlankLink"
+ target="_blank"
+ rel="opener"
+ href="newSession_child.html"
+ >target="_blank"</a
+ >
+ <a
+ id="noOpenerLink"
+ target="_blank"
+ rel="noopener"
+ href="http://example.com"
+ >rel="noopener"</a
+ >
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/newSession_child.html b/mobile/android/geckoview/src/androidTest/assets/www/newSession_child.html
new file mode 100644
index 0000000000..28fd019804
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/newSession_child.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ </head>
+ <body>
+ <p>I'm the child</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/no-meta-viewport.html b/mobile/android/geckoview/src/androidTest/assets/www/no-meta-viewport.html
new file mode 100644
index 0000000000..8f1cb8fa80
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/no-meta-viewport.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <h3>Nothing here</h3>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/ogg.html b/mobile/android/geckoview/src/androidTest/assets/www/ogg.html
new file mode 100644
index 0000000000..dd478d3b3f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/ogg.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>OGG Video</title>
+ </head>
+ <body>
+ <video controls preload>
+ <source src="videos/video.ogg"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/orange.pdf b/mobile/android/geckoview/src/androidTest/assets/www/orange.pdf
new file mode 100755
index 0000000000..684582176a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/orange.pdf
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto-none.html b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto-none.html
new file mode 100644
index 0000000000..ff180f961a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto-none.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ overscroll-behavior: auto none;
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 100vh"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto.html b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto.html
new file mode 100644
index 0000000000..6f2b3ee92a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-auto.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ overscroll-behavior: auto;
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 100vh"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-auto.html b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-auto.html
new file mode 100644
index 0000000000..ff6366ccda
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-auto.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ overscroll-behavior: none auto;
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 100vh"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html
new file mode 100644
index 0000000000..fbe2269c19
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div
+ id="scroll"
+ style="
+ width: 100%;
+ height: 100vh;
+ overscroll-behavior: none;
+ overflow-y: scroll;
+ "
+ >
+ <div style="height: 200vh"></div>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/popup.html b/mobile/android/geckoview/src/androidTest/assets/www/popup.html
new file mode 100644
index 0000000000..7e52870df5
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/popup.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ </head>
+ <body>
+ <p>Launching popup...</p>
+ <script>
+ window.open("hello.html");
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/print_content_change.html b/mobile/android/geckoview/src/androidTest/assets/www/print_content_change.html
new file mode 100644
index 0000000000..ae36a6c6b8
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/print_content_change.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Orange Print Background Removal</title>
+ </head>
+ <style>
+ .box {
+ height: 200vh;
+ width: 100vw;
+ }
+ @media screen {
+ .background {
+ background-color: rgb(0, 0, 255);
+ color-adjust: exact;
+ }
+ }
+ @media print {
+ .background {
+ background-color: rgb(255, 113, 57);
+ color-adjust: exact;
+ }
+ }
+ </style>
+
+ <body>
+ <div id="content" class="box background"></div>
+ </body>
+
+ <!-- The window.print should freeze the page before removing the content, so the background should remain present. -->
+ <button
+ id="print-button"
+ onclick="window.print(); document.getElementById('content').remove()"
+ >
+ Print
+ </button>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/print_iframe.html b/mobile/android/geckoview/src/androidTest/assets/www/print_iframe.html
new file mode 100644
index 0000000000..b7dd83f2a5
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/print_iframe.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" content="width=device-width, height=device-height" />
+ <title>Print iframes</title>
+ </head>
+ <style>
+ .box {
+ height: 200vh;
+ width: 100vw;
+ }
+ @media screen {
+ .background {
+ background-color: rgb(255, 0, 0);
+ color-adjust: exact;
+ }
+ }
+ @media print {
+ .background {
+ background-color: rgb(0, 255, 0);
+ color-adjust: exact;
+ }
+ }
+ </style>
+
+ <body>
+ <div id="content" class="box background"></div>
+ </body>
+
+ <!-- The window.print should freeze the page before removing the content, so the background should remain present. -->
+ <button
+ id="print-button-page"
+ onclick="window.print(); document.getElementById('content').remove()"
+ >
+ Print
+ </button>
+
+ <iframe id="iframe" src="print_content_change.html"></iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/prompts.html b/mobile/android/geckoview/src/androidTest/assets/www/prompts.html
new file mode 100644
index 0000000000..53e8f96b04
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/prompts.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <select id="selectexample">
+ <option>1</option>
+ <option>2</option>
+ </select>
+
+ <input type="date" id="dateexample" />
+
+ <input type="month" id="monthexample" />
+
+ <input type="week" id="weekexample" />
+
+ <input type="time" id="timeexample" />
+
+ <input type="datetime-local" id="datetimelocalexample" />
+
+ <input type="color" id="colorexample" value="#ffffff" />
+
+ <input type="file" id="fileexample" accept="image/*,.pdf" capture="user" />
+
+ <datalist id="colorlist">
+ <option>#000000</option>
+ <option>#808080</option>
+ </datalist>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html b/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html
new file mode 100644
index 0000000000..d1a421c0a3
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/pull-to-refresh-subframe.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta
+ name="viewport"
+ content="height=device-height,width=device-width,initial-scale=1.0"
+ />
+ <style type="text/css">
+ html,
+ body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+
+ .container {
+ width: 100%;
+ height: 25%;
+ overflow: scroll;
+ }
+
+ .subframe {
+ width: 100%;
+ height: 100vh;
+ }
+
+ #one > .subframe {
+ background-color: red;
+ }
+
+ #two > .subframe {
+ background-color: green;
+ }
+
+ #three > .subframe {
+ background-color: blue;
+ }
+
+ #four > .subframe {
+ background-color: yellow;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="one" class="container">
+ <div class="subframe"></div>
+ </div>
+ <div id="two" class="container">
+ <div class="subframe"></div>
+ </div>
+ <div id="three" class="container">
+ <div class="subframe"></div>
+ </div>
+ <div id="four" class="container">
+ <div class="subframe"></div>
+ </div>
+ </body>
+ <script>
+ document
+ .getElementById("three")
+ .scrollTo({ top: 200, behavior: "instant" });
+
+ document.getElementById("four").addEventListener("touchstart", e => {
+ console.log("not preventing default");
+ });
+
+ document.getElementById("two").addEventListener("touchstart", e => {
+ console.log("preventing default");
+ e.preventDefault();
+ });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/push/push.html b/mobile/android/geckoview/src/androidTest/assets/www/push/push.html
new file mode 100644
index 0000000000..ccd091eaea
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/push/push.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Push API test</title>
+ </head>
+ <body>
+ <p>Hello, world!</p>
+ <script src="push.js"></script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/push/push.js b/mobile/android/geckoview/src/androidTest/assets/www/push/push.js
new file mode 100644
index 0000000000..d9322d11cc
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/push/push.js
@@ -0,0 +1,44 @@
+window.doSubscribe = async function (applicationServerKey) {
+ const registration = await navigator.serviceWorker.register("./sw.js");
+ const sub = await registration.pushManager.subscribe({
+ applicationServerKey,
+ });
+ return sub.toJSON();
+};
+
+window.doGetSubscription = async function () {
+ const registration = await navigator.serviceWorker.register("./sw.js");
+ const sub = await registration.pushManager.getSubscription();
+ if (sub) {
+ return sub.toJSON();
+ }
+
+ return null;
+};
+
+window.doUnsubscribe = async function () {
+ const registration = await navigator.serviceWorker.register("./sw.js");
+ const sub = await registration.pushManager.getSubscription();
+ sub.unsubscribe();
+ return {};
+};
+
+window.doWaitForPushEvent = function () {
+ return new Promise(resolve => {
+ navigator.serviceWorker.addEventListener("message", function (e) {
+ if (e.data.type === "push") {
+ resolve(e.data.payload);
+ }
+ });
+ });
+};
+
+window.doWaitForSubscriptionChange = function () {
+ return new Promise(resolve => {
+ navigator.serviceWorker.addEventListener("message", function (e) {
+ if (e.data.type === "pushsubscriptionchange") {
+ resolve(e.data.type);
+ }
+ });
+ });
+};
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js b/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
new file mode 100644
index 0000000000..2e51383205
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
@@ -0,0 +1,30 @@
+self.addEventListener("install", function () {
+ self.skipWaiting();
+});
+
+self.addEventListener("activate", function (e) {
+ e.waitUntil(self.clients.claim());
+});
+
+self.addEventListener("push", async function (e) {
+ const clients = await self.clients.matchAll();
+ let text = "";
+ if (e.data) {
+ text = e.data.text();
+ }
+ clients.forEach(function (client) {
+ client.postMessage({ type: "push", payload: text });
+ });
+
+ try {
+ const { title, body } = e.data.json();
+ self.registration.showNotification(title, { body });
+ } catch (e) {}
+});
+
+self.addEventListener("pushsubscriptionchange", async function (e) {
+ const clients = await self.clients.matchAll();
+ clients.forEach(function (client) {
+ client.postMessage({ type: "pushsubscriptionchange" });
+ });
+});
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/red-background-body-fully-covered-by-green-element.html b/mobile/android/geckoview/src/androidTest/assets/www/red-background-body-fully-covered-by-green-element.html
new file mode 100644
index 0000000000..ad6c96599e
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/red-background-body-fully-covered-by-green-element.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=windows-1252" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <style>
+ html {
+ scrollbar-width: none;
+ }
+ body {
+ background: red;
+ margin: 0;
+ }
+ .tall {
+ height: 600vh;
+ background: green;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="tall"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/reflect_local_storage_into_title.html b/mobile/android/geckoview/src/androidTest/assets/www/reflect_local_storage_into_title.html
new file mode 100644
index 0000000000..749678c668
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/reflect_local_storage_into_title.html
@@ -0,0 +1,17 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>no title</title>
+ <script>
+ // If we have a query string, save it to the local storage.
+ if (window.location.search.length) {
+ const value = window.location.search.substr(1);
+ localStorage.setItem("ctx", value);
+ }
+
+ // Set the title to reflect the local storage value.
+ document.title = "storage=" + localStorage.getItem("ctx");
+ </script>
+ </head>
+ <body></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/resubmit.html b/mobile/android/geckoview/src/androidTest/assets/www/resubmit.html
new file mode 100644
index 0000000000..6155270f1b
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/resubmit.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body>
+ <form action="hello.html" method="post">
+ <input id="text" />
+ <button id="submit">Submit</button>
+ </form>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/root_100_percent_height.html b/mobile/android/geckoview/src/androidTest/assets/www/root_100_percent_height.html
new file mode 100644
index 0000000000..e91c997bbb
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/root_100_percent_height.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ height: 100%;
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 100%; background-color: green"></div>
+ <script>
+ if (document.location.search.startsWith("?event")) {
+ document.querySelector("div").addEventListener("touchstart", e => {
+ if (document.location.search == "?event-prevent") {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/root_100vh.html b/mobile/android/geckoview/src/androidTest/assets/www/root_100vh.html
new file mode 100644
index 0000000000..e6c7fef374
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/root_100vh.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 100vh; background-color: green"></div>
+ <script>
+ if (document.location.search.startsWith("?event")) {
+ document.querySelector("div").addEventListener("touchstart", e => {
+ if (document.location.search == "?event-prevent") {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/root_98vh.html b/mobile/android/geckoview/src/androidTest/assets/www/root_98vh.html
new file mode 100644
index 0000000000..a654353d64
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/root_98vh.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 98vh; background-color: green"></div>
+ <script>
+ if (document.location.search.startsWith("?event")) {
+ document.querySelector("div").addEventListener("touchstart", e => {
+ if (document.location.search == "?event-prevent") {
+ e.preventDefault();
+ }
+ });
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/saveState.html b/mobile/android/geckoview/src/androidTest/assets/www/saveState.html
new file mode 100644
index 0000000000..c85b528f01
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/saveState.html
@@ -0,0 +1,18 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello, world!</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <style>
+ p {
+ height: 300vh;
+ }
+ </style>
+ </head>
+ <body>
+ <form id="form">
+ <input type="text" id="name" />
+ </form>
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/scroll-handoff.html b/mobile/android/geckoview/src/androidTest/assets/www/scroll-handoff.html
new file mode 100644
index 0000000000..c8f0fe9e95
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/scroll-handoff.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ overscroll-behavior: auto;
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ #scroll {
+ /* set a different overscroll-behavior to make this container different from
+ the root scrollElement. */
+ overscroll-behavior: contain auto;
+ }
+ </style>
+ <body>
+ <div id="scroll" style="width: 100%; height: 100vh; overflow-y: scroll">
+ <div style="height: 300vh"></div>
+ </div>
+ </body>
+ <script>
+ document
+ .getElementById("scroll")
+ .scrollTo({ top: 50, behavior: "instant" });
+ </script>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/scroll.html b/mobile/android/geckoview/src/androidTest/assets/www/scroll.html
new file mode 100644
index 0000000000..e906e45686
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/scroll.html
@@ -0,0 +1,59 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=0.5" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+
+ #one {
+ background-color: red;
+ width: 200vw;
+ height: 33vh;
+ }
+
+ #two {
+ background-color: green;
+ width: 200vw;
+ height: 33vh;
+ }
+
+ #three {
+ background-color: blue;
+ width: 200vw;
+ height: 33vh;
+ }
+
+ #four {
+ background-color: purple;
+ width: 200vw;
+ height: 200vh;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="one"></div>
+ <div id="two"></div>
+ <div id="three"></div>
+ <div id="four"></div>
+ <script>
+ document.getElementById("two").addEventListener("touchstart", e => {
+ console.log("preventing default");
+ e.preventDefault();
+ });
+
+ document.getElementById("three").addEventListener("touchstart", e => {
+ console.log("not preventing default");
+ });
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/select-listbox.html b/mobile/android/geckoview/src/androidTest/assets/www/select-listbox.html
new file mode 100644
index 0000000000..5832954d2e
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/select-listbox.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<select size="2" id="multiple">
+ <option>ABC</option>
+ <option>DEF</option>
+ <option>GHI</option>
+</select>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/select-multiple.html b/mobile/android/geckoview/src/androidTest/assets/www/select-multiple.html
new file mode 100644
index 0000000000..bb9470fffd
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/select-multiple.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<select multiple id="multiple">
+ <option>ABC</option>
+ <option>DEF</option>
+ <option>GHI</option>
+</select>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/select.html b/mobile/android/geckoview/src/androidTest/assets/www/select.html
new file mode 100644
index 0000000000..e8d28253d2
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/select.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<select id="simple">
+ <option>ABC</option>
+ <option>DEF</option>
+</select>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame.html b/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame.html
new file mode 100644
index 0000000000..132155c6a1
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame.html
@@ -0,0 +1,6 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <body></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame_xorigin.html b/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame_xorigin.html
new file mode 100644
index 0000000000..87a4d6039e
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/selectionAction_frame_xorigin.html
@@ -0,0 +1,47 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <script>
+ window.addEventListener("message", e => {
+ switch (e.data.type) {
+ case "focus":
+ window.focus();
+ break;
+
+ case "select": {
+ <!-- On fission, there's no way to wait for parent position change. -->
+ <!-- So we use requestAnimationFrame as a workaround. -->
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => {
+ const text = document.body.firstChild;
+ document
+ .getSelection()
+ .setBaseAndExtent(text, 0, text, e.data.length);
+ });
+ });
+ break;
+ }
+
+ case "selectedOffset": {
+ const sel = document.getSelection();
+ const text = document.body.firstChild;
+ if (sel.anchorNode !== text || sel.focusNode !== text) {
+ window.parent.postMessage([-1, -1], "*");
+ } else {
+ window.parent.postMessage(
+ [sel.anchorOffset, sel.focusOffset],
+ "*"
+ );
+ }
+ break;
+ }
+
+ case "content":
+ window.parent.postMessage(document.body.textContent, "*");
+ break;
+ }
+ });
+ </script>
+ </head>
+ <body onload="document.body.textContent = 'elit'"></body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/showDynamicToolbar.html b/mobile/android/geckoview/src/androidTest/assets/www/showDynamicToolbar.html
new file mode 100644
index 0000000000..f6b0dd340c
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/showDynamicToolbar.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>showDynamicToolbar test content</title>
+ <script>
+ document.addEventListener("click", function () {
+ document.body.style.position = "fixed";
+ });
+ </script>
+ </head>
+ <body>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/simple_redirect.sjs b/mobile/android/geckoview/src/androidTest/assets/www/simple_redirect.sjs
new file mode 100644
index 0000000000..43fec90b5a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/simple_redirect.sjs
@@ -0,0 +1,4 @@
+function handleRequest(request, response) {
+ response.setStatusLine(request.httpVersion, 301, "Moved Permanently");
+ response.setHeader("Location", request.queryString, false);
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/titleChange.html b/mobile/android/geckoview/src/androidTest/assets/www/titleChange.html
new file mode 100644
index 0000000000..51f8c936b6
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/titleChange.html
@@ -0,0 +1,16 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ </head>
+ <header><title>Title1</title></header>
+ <body>
+ <script>
+ addEventListener("load", function () {
+ setTimeout(function () {
+ document.title = "Title2";
+ }, 100);
+ });
+ </script>
+ </body>
+ <iframe src="hello.html"></iframe>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch-action-wheel-listener.html b/mobile/android/geckoview/src/androidTest/assets/www/touch-action-wheel-listener.html
new file mode 100644
index 0000000000..cfc9489d17
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch-action-wheel-listener.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div id="one" style="width: 100%; height: 100vh; touch-action: none"></div>
+ <script>
+ document.getElementById("one").addEventListener("wheel", e => {
+ console.log("preventing default");
+ e.preventDefault();
+ });
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html b/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html
new file mode 100644
index 0000000000..62266b6ef7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch-action.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+ <style>
+ html {
+ height: 100%;
+ width: 100%;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+ body {
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+ <body>
+ <div style="width: 100%; height: 50vh; touch-action: auto"></div>
+ <script>
+ const searchParams = new URLSearchParams(location.search);
+ let div = document.querySelector("div");
+ if (searchParams.has("subframe")) {
+ const scrolledContents = document.createElement("div");
+ scrolledContents.style.height = "100%";
+
+ div.appendChild(scrolledContents);
+ div.style.overflow = "auto";
+
+ div = scrolledContents;
+ }
+ if (searchParams.has("scrollable")) {
+ // Scrollable for dynamic toolbar purposes.
+ div.style.height = "100vh";
+ }
+ div.style.touchAction = searchParams.get("touch-action");
+ if (searchParams.has("event")) {
+ div.addEventListener("touchstart", e => {});
+ }
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch.html b/mobile/android/geckoview/src/androidTest/assets/www/touch.html
new file mode 100644
index 0000000000..ba3bc098a9
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch.html
@@ -0,0 +1,58 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta
+ name="viewport"
+ content="height=device-height,width=device-width,initial-scale=1.0"
+ />
+ <style type="text/css">
+ body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0px;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+
+ #one {
+ background-color: red;
+ width: 100%;
+ height: 33%;
+ }
+
+ #two {
+ background-color: green;
+ width: 100%;
+ height: 33%;
+ }
+
+ #three {
+ background-color: blue;
+ width: 100%;
+ height: 33%;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="one"></div>
+ <div id="two"></div>
+ <div id="three"></div>
+ <script>
+ document.getElementById("two").addEventListener("touchstart", e => {
+ console.log("preventing default");
+ e.preventDefault();
+ });
+
+ document.getElementById("three").addEventListener("touchstart", e => {
+ console.log("not preventing default");
+ });
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touch_xorigin.html b/mobile/android/geckoview/src/androidTest/assets/www/touch_xorigin.html
new file mode 100644
index 0000000000..89f3762aef
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touch_xorigin.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <style>
+ body,
+ html {
+ margin: 0;
+ padding: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <iframe src="http://127.0.0.1:4245/assets/www/touch.html"></iframe>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html b/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html
new file mode 100644
index 0000000000..9ee1f461a7
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/touchstart.html
@@ -0,0 +1,37 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=0.5" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ /* background contains one extra transparent.gif because we want trick the
+ contentful paint detection; We want to make sure the background is loaded
+ before the test starts so we always wait for the contentful paint timestamp
+ to exist, however, gradient isn't considered as contentful per spec, so Gecko
+ wouldn't generate a timestamp for it. Hence, we added a transparent gif
+ to the image list to trick the detection. */
+ background: url("/assets/www/transparent.gif"),
+ linear-gradient(135deg, red, white);
+ }
+
+ #one {
+ background-color: red;
+ width: 200%;
+ height: 100vh;
+ }
+ #two {
+ background-color: blue;
+ width: 200%;
+ height: 800vh;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="one"></div>
+ <div id="two"></div>
+ <script>
+ document.getElementById("two").addEventListener("touchstart", e => {});
+ </script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/tracemonkey.pdf b/mobile/android/geckoview/src/androidTest/assets/www/tracemonkey.pdf
new file mode 100644
index 0000000000..4dcf129d65
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/tracemonkey.pdf
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/trackers.html b/mobile/android/geckoview/src/androidTest/assets/www/trackers.html
new file mode 100644
index 0000000000..56ea43979a
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/trackers.html
@@ -0,0 +1,14 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Trackers</title>
+ </head>
+ <body>
+ <p>Trackers</p>
+
+ <!-- test-track-simple -->
+ <script src="http://trackertest.org/tracker.js"></script>
+ <script src="https://tracking.example.com/tracker.js"></script>
+ <script src="https://itisatracker.org/tracker.js"></script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-en.html b/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-en.html
new file mode 100644
index 0000000000..3e5f8e6303
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-en.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+ <!-- See toolkit for original test.-->
+ <head>
+ <meta charset="utf-8" />
+ <title>Translations Test</title>
+ <style>
+ div {
+ margin: 10px auto;
+ width: 300px;
+ }
+ p {
+ margin: 47px 0;
+ font-size: 21px;
+ line-height: 2;
+ }
+ </style>
+ </head>
+ <body>
+ <div>
+ <!-- The following is an excerpt from The Wondeful Wizard of Oz, which is in the public domain -->
+ <h1>"The Wonderful Wizard of Oz" by L. Frank Baum</h1>
+ <p>
+ The little girl, seeing she had lost one of her pretty shoes, grew
+ angry, and said to the Witch, “Give me back my shoe!”
+ </p>
+ <p>
+ “I will not,” retorted the Witch, “for it is now my shoe, and not
+ yours.”
+ </p>
+ <p>
+ “You are a wicked creature!” cried Dorothy. “You have no right to take
+ my shoe from me.”
+ </p>
+ <p>
+ “I shall keep it, just the same,” said the Witch, laughing at her, “and
+ someday I shall get the other one from you, too.”
+ </p>
+ <p>
+ This made Dorothy so very angry that she picked up the bucket of water
+ that stood near and dashed it over the Witch, wetting her from head to
+ foot.
+ </p>
+ <p>
+ Instantly the wicked woman gave a loud cry of fear, and then, as Dorothy
+ looked at her in wonder, the Witch began to shrink and fall away.
+ </p>
+ <p>
+ “See what you have done!” she screamed. “In a minute I shall melt away.”
+ </p>
+ <p>
+ “I’m very sorry, indeed,” said Dorothy, who was truly frightened to see
+ the Witch actually melting away like brown sugar before her very eyes.
+ </p>
+ <p>
+ “Didn’t you know water would be the end of me?” asked the Witch, in a
+ wailing, despairing voice.
+ </p>
+ <p>“Of course not,” answered Dorothy. “How should I?”</p>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-es.html b/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-es.html
new file mode 100644
index 0000000000..e9d39585ee
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/translations-tester-es.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html lang="es">
+ <!-- See toolkit for original test.-->
+ <head>
+ <meta charset="utf-8" />
+ <title>Translations Test</title>
+ <style>
+ div {
+ margin: 10px auto;
+ width: 300px;
+ }
+ p {
+ margin: 47px 0;
+ font-size: 21px;
+ line-height: 2;
+ }
+ </style>
+ </head>
+ <body>
+ <div>
+ <header lang="en">
+ The following is an excerpt from Don Quijote de la Mancha, which is in
+ the public domain
+ </header>
+ <h1>Don Quijote de La Mancha</h1>
+ <h2>Capítulo VIII.</h2>
+ <p>
+ Del buen suceso que el valeroso don Quijote tuvo en la espantable y
+ jamás imaginada aventura de los molinos de viento, con otros sucesos
+ dignos de felice recordación
+ </p>
+ <p>
+ En esto, descubrieron treinta o cuarenta molinos de viento que hay en
+ aquel campo; y, así como don Quijote los vio, dijo a su escudero:
+ </p>
+ <p>
+ — La ventura va guiando nuestras cosas mejor de lo que acertáramos a
+ desear, porque ves allí, amigo Sancho Panza, donde se descubren treinta,
+ o pocos más, desaforados gigantes, con quien pienso hacer batalla y
+ quitarles a todos las vidas, con cuyos despojos comenzaremos a
+ enriquecer; que ésta es buena guerra, y es gran servicio de Dios quitar
+ tan mala simiente de sobre la faz de la tierra.
+ </p>
+ <p>— ¿Qué gigantes? —dijo Sancho Panza.</p>
+ <p>
+ — Aquellos que allí ves —respondió su amo— de los brazos largos, que los
+ suelen tener algunos de casi dos leguas.
+ </p>
+ <p>
+ — Mire vuestra merced —respondió Sancho— que aquellos que allí se
+ parecen no son gigantes, sino molinos de viento, y lo que en ellos
+ parecen brazos son las aspas, que, volteadas del viento, hacen andar la
+ piedra del molino.
+ </p>
+ <p>
+ — Bien parece —respondió don Quijote— que no estás cursado en esto de
+ las aventuras: ellos son gigantes; y si tienes miedo, quítate de ahí, y
+ ponte en oración en el espacio que yo voy a entrar con ellos en fiera y
+ desigual batalla.
+ </p>
+ <p>
+ Y, diciendo esto, dio de espuelas a su caballo Rocinante, sin atender a
+ las voces que su escudero Sancho le daba, advirtiéndole que, sin duda
+ alguna, eran molinos de viento, y no gigantes, aquellos que iba a
+ acometer. Pero él iba tan puesto en que eran gigantes, que ni oía las
+ voces de su escudero Sancho ni echaba de ver, aunque estaba ya bien
+ cerca, lo que eran; antes, iba diciendo en voces altas:
+ </p>
+ <p>
+ — Non fuyades, cobardes y viles criaturas, que un solo caballero es el
+ que os acomete.
+ </p>
+ <p>
+ Levantóse en esto un poco de viento y las grandes aspas comenzaron a
+ moverse, lo cual visto por don Quijote, dijo:
+ </p>
+ <p>
+ — Pues, aunque mováis más brazos que los del gigante Briareo, me lo
+ habéis de pagar.
+ </p>
+ </div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/transparent.gif b/mobile/android/geckoview/src/androidTest/assets/www/transparent.gif
new file mode 100644
index 0000000000..e565824aaf
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/transparent.gif
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/update_manifest.json b/mobile/android/geckoview/src/androidTest/assets/www/update_manifest.json
new file mode 100644
index 0000000000..7b2de1f278
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/update_manifest.json
@@ -0,0 +1,40 @@
+{
+ "addons": {
+ "update@example.com": {
+ "updates": [
+ {
+ "version": "1.0",
+ "update_link": "https://example.org/tests/junit/update-1.xpi"
+ },
+ {
+ "version": "2.0",
+ "update_link": "https://example.org/tests/junit/update-2.xpi"
+ }
+ ]
+ },
+ "update-postpone@example.com": {
+ "updates": [
+ {
+ "version": "1.0",
+ "update_link": "https://example.org/tests/junit/update-postpone-1.xpi"
+ },
+ {
+ "version": "2.0",
+ "update_link": "https://example.org/tests/junit/update-postpone-2.xpi"
+ }
+ ]
+ },
+ "update-with-perms@example.com": {
+ "updates": [
+ {
+ "version": "1.0",
+ "update_link": "https://example.org/tests/junit/update-with-perms-1.xpi"
+ },
+ {
+ "version": "2.0",
+ "update_link": "https://example.org/tests/junit/update-with-perms-2.xpi"
+ }
+ ]
+ }
+ }
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/videos/gizmo.webm b/mobile/android/geckoview/src/androidTest/assets/www/videos/gizmo.webm
new file mode 100644
index 0000000000..518531a93f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/videos/gizmo.webm
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/videos/short.mp4 b/mobile/android/geckoview/src/androidTest/assets/www/videos/short.mp4
new file mode 100644
index 0000000000..a674b7eb68
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/videos/short.mp4
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/videos/video.ogg b/mobile/android/geckoview/src/androidTest/assets/www/videos/video.ogg
new file mode 100644
index 0000000000..ac7ece3519
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/videos/video.ogg
Binary files differ
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/viewport.html b/mobile/android/geckoview/src/androidTest/assets/www/viewport.html
new file mode 100644
index 0000000000..a5dfa0f64f
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/viewport.html
@@ -0,0 +1,19 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta
+ name="viewport"
+ content="width=device-width, initial-scale=1.0, viewport-fit=cover"
+ />
+ <style type="text/css">
+ #wide {
+ background-color: rgb(200, 0, 0);
+ width: 100%;
+ height: 40px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="wide"></div>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/webm.html b/mobile/android/geckoview/src/androidTest/assets/www/webm.html
new file mode 100644
index 0000000000..f329582575
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/webm.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>WebM Video</title>
+ </head>
+ <body>
+ <video controls preload>
+ <source src="videos/gizmo.webm"></source>
+ </video>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.html b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.html
new file mode 100644
index 0000000000..d71eb0484d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Open Window test</title>
+ </head>
+ <body>
+ <p>Hello, world!</p>
+ <script type="text/javascript" src="./open_window.js"></script>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.js b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.js
new file mode 100644
index 0000000000..921cff5b09
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window.js
@@ -0,0 +1,15 @@
+navigator.serviceWorker.register("./service-worker.js", {
+ scope: ".",
+});
+
+function showNotification() {
+ Notification.requestPermission(function (result) {
+ if (result === "granted") {
+ navigator.serviceWorker.ready.then(function (registration) {
+ registration.showNotification("Open Window Notification", {
+ body: "Hello",
+ });
+ });
+ }
+ });
+}
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window_target.html b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window_target.html
new file mode 100644
index 0000000000..14775aafac
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/worker/open_window_target.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Open Window test target</title>
+ </head>
+ <body>
+ <p>Hello, world!</p>
+ </body>
+</html>
diff --git a/mobile/android/geckoview/src/androidTest/assets/www/worker/service-worker.js b/mobile/android/geckoview/src/androidTest/assets/www/worker/service-worker.js
new file mode 100644
index 0000000000..e3fbbb6388
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/worker/service-worker.js
@@ -0,0 +1,15 @@
+self.addEventListener("install", function () {
+ console.log("install");
+ self.skipWaiting();
+});
+
+self.addEventListener("activate", function (e) {
+ console.log("activate");
+ e.waitUntil(self.clients.claim());
+});
+
+self.onnotificationclick = function (event) {
+ console.log("onnotificationclick");
+ self.clients.openWindow("open_window_target.html");
+ event.notification.close();
+};