e2e: add basic tests for additional pages

Adds e2e tests for additonal routes on pkgsite.
Tests are all made suitable to be run against the
staging environment.

Change-Id: Ia549e487490eb0bd47049ba306143db45905726a
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/304590
Trust: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/e2e/__image_snapshots__/badge-test-ts-badge-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/badge-test-ts-badge-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..1afa20d
--- /dev/null
+++ b/e2e/__image_snapshots__/badge-test-ts-badge-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/badge-test-ts-badge-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/badge-test-ts-badge-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..6f95974
--- /dev/null
+++ b/e2e/__image_snapshots__/badge-test-ts-badge-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/error-test-ts-error-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/error-test-ts-error-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..000c0f3
--- /dev/null
+++ b/e2e/__image_snapshots__/error-test-ts-error-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/error-test-ts-error-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/error-test-ts-error-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..9ec4d5d
--- /dev/null
+++ b/e2e/__image_snapshots__/error-test-ts-error-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..e52f15a
--- /dev/null
+++ b/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..178b0bd
--- /dev/null
+++ b/e2e/__image_snapshots__/fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png
deleted file mode 100644
index 0c746e6..0000000
--- a/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-desktop-viewport-matches-image-snapshot-1-snap.png
+++ /dev/null
Binary files differ
diff --git a/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png
deleted file mode 100644
index b6baf73..0000000
--- a/e2e/__image_snapshots__/frontend-fetch-test-ts-frontend-fetch-mobile-viewport-matches-image-snapshot-1-snap.png
+++ /dev/null
Binary files differ
diff --git a/e2e/__image_snapshots__/license-policy-test-ts-license-policy-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/license-policy-test-ts-license-policy-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..0a303c2
--- /dev/null
+++ b/e2e/__image_snapshots__/license-policy-test-ts-license-policy-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/license-policy-test-ts-license-policy-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/license-policy-test-ts-license-policy-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..d438b5f
--- /dev/null
+++ b/e2e/__image_snapshots__/license-policy-test-ts-license-policy-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-fixed-header-appears-after-scrolling-1-snap.png b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-fixed-header-appears-after-scrolling-1-snap.png
index d64d165..905ea4a 100644
--- a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-fixed-header-appears-after-scrolling-1-snap.png
+++ b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-fixed-header-appears-after-scrolling-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-viewport-matches-image-snapshot-1-snap.png
index 29877ba..f842b3a 100644
--- a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-viewport-matches-image-snapshot-1-snap.png
+++ b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-fixed-header-appears-after-scrolling-1-snap.png b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-fixed-header-appears-after-scrolling-1-snap.png
index 85a869d..711df32 100644
--- a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-fixed-header-appears-after-scrolling-1-snap.png
+++ b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-fixed-header-appears-after-scrolling-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-viewport-matches-image-snapshot-1-snap.png
index 8fe9eeb..04573ff 100644
--- a/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-viewport-matches-image-snapshot-1-snap.png
+++ b/e2e/__image_snapshots__/pkgsite-test-ts-golang-org-x-pkgsite-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/search-help-test-ts-search-help-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/search-help-test-ts-search-help-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..307cc8a
--- /dev/null
+++ b/e2e/__image_snapshots__/search-help-test-ts-search-help-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/search-help-test-ts-search-help-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/search-help-test-ts-search-help-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..c17fac1
--- /dev/null
+++ b/e2e/__image_snapshots__/search-help-test-ts-search-help-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/search-test-ts-search-desktop-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/search-test-ts-search-desktop-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..cd0a408
--- /dev/null
+++ b/e2e/__image_snapshots__/search-test-ts-search-desktop-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__image_snapshots__/search-test-ts-search-mobile-viewport-matches-image-snapshot-1-snap.png b/e2e/__image_snapshots__/search-test-ts-search-mobile-viewport-matches-image-snapshot-1-snap.png
new file mode 100644
index 0000000..60c1fe9
--- /dev/null
+++ b/e2e/__image_snapshots__/search-test-ts-search-mobile-viewport-matches-image-snapshot-1-snap.png
Binary files differ
diff --git a/e2e/__snapshots__/frontend-fetch.test.ts.snap b/e2e/__snapshots__/badge.test.ts.snap
similarity index 85%
copy from e2e/__snapshots__/frontend-fetch.test.ts.snap
copy to e2e/__snapshots__/badge.test.ts.snap
index 93655ea..fbb8cce 100644
--- a/e2e/__snapshots__/frontend-fetch.test.ts.snap
+++ b/e2e/__snapshots__/badge.test.ts.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`Frontend Fetch accessibility tree matches snapshot 1`] = `
+exports[`Badge accessibility tree matches snapshot 1`] = `
 Object {
   "children": Array [
     Object {
@@ -44,31 +44,43 @@
       "role": "link",
     },
     Object {
+      "level": 1,
+      "name": "Create a badge",
+      "role": "heading",
+    },
+    Object {
+      "name": "Create a badge to link to pkg.go.dev from your project website or README file.",
+      "role": "text",
+    },
+    Object {
+      "name": "Badge",
+      "role": "text",
+    },
+    Object {
+      "name": "Go Reference",
+      "role": "link",
+    },
+    Object {
+      "name": "URL",
+      "role": "text",
+    },
+    Object {
+      "name": "URL",
+      "role": "textbox",
+    },
+    Object {
+      "name": "",
+      "role": "button",
+    },
+    Object {
       "name": "The Go Gopher",
       "role": "img",
     },
     Object {
-      "level": 3,
-      "name": "Oops! We couldn't find “rsc.io/quote”.",
-      "role": "heading",
-    },
-    Object {
-      "name": "Check that you entered the URL correctly, try fetching it following the",
+      "name": "Type a pkg.go.dev URL above to create a badge link.",
       "role": "text",
     },
     Object {
-      "name": "instructions here",
-      "role": "link",
-    },
-    Object {
-      "name": ", or request to add “rsc.io/quote” to pkg.go.dev.",
-      "role": "text",
-    },
-    Object {
-      "name": "Request “rsc.io/quote”",
-      "role": "button",
-    },
-    Object {
       "description": "Why Go",
       "name": "Why Go",
       "role": "link",
@@ -180,7 +192,7 @@
       "role": "link",
     },
   ],
-  "name": "404 Not Found · pkg.go.dev",
+  "name": "Badge generation tool · pkg.go.dev",
   "role": "WebArea",
 }
 `;
diff --git a/e2e/__snapshots__/frontend-fetch.test.ts.snap b/e2e/__snapshots__/error.test.ts.snap
similarity index 84%
copy from e2e/__snapshots__/frontend-fetch.test.ts.snap
copy to e2e/__snapshots__/error.test.ts.snap
index 93655ea..9da179f 100644
--- a/e2e/__snapshots__/frontend-fetch.test.ts.snap
+++ b/e2e/__snapshots__/error.test.ts.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`Frontend Fetch accessibility tree matches snapshot 1`] = `
+exports[`Error accessibility tree matches snapshot 1`] = `
 Object {
   "children": Array [
     Object {
@@ -49,26 +49,10 @@
     },
     Object {
       "level": 3,
-      "name": "Oops! We couldn't find “rsc.io/quote”.",
+      "name": "400 Bad Request",
       "role": "heading",
     },
     Object {
-      "name": "Check that you entered the URL correctly, try fetching it following the",
-      "role": "text",
-    },
-    Object {
-      "name": "instructions here",
-      "role": "link",
-    },
-    Object {
-      "name": ", or request to add “rsc.io/quote” to pkg.go.dev.",
-      "role": "text",
-    },
-    Object {
-      "name": "Request “rsc.io/quote”",
-      "role": "button",
-    },
-    Object {
       "description": "Why Go",
       "name": "Why Go",
       "role": "link",
@@ -180,7 +164,7 @@
       "role": "link",
     },
   ],
-  "name": "404 Not Found · pkg.go.dev",
+  "name": "400 Bad Request · pkg.go.dev",
   "role": "WebArea",
 }
 `;
diff --git a/e2e/__snapshots__/frontend-fetch.test.ts.snap b/e2e/__snapshots__/fetch.test.ts.snap
similarity index 95%
rename from e2e/__snapshots__/frontend-fetch.test.ts.snap
rename to e2e/__snapshots__/fetch.test.ts.snap
index 93655ea..8ad8f5a 100644
--- a/e2e/__snapshots__/frontend-fetch.test.ts.snap
+++ b/e2e/__snapshots__/fetch.test.ts.snap
@@ -49,7 +49,7 @@
     },
     Object {
       "level": 3,
-      "name": "Oops! We couldn't find “rsc.io/quote”.",
+      "name": "Oops! We couldn't find “fetch.test”.",
       "role": "heading",
     },
     Object {
@@ -61,11 +61,11 @@
       "role": "link",
     },
     Object {
-      "name": ", or request to add “rsc.io/quote” to pkg.go.dev.",
+      "name": ", or request to add “fetch.test” to pkg.go.dev.",
       "role": "text",
     },
     Object {
-      "name": "Request “rsc.io/quote”",
+      "name": "Request “fetch.test”",
       "role": "button",
     },
     Object {
diff --git a/e2e/__snapshots__/license_policy.test.ts.snap b/e2e/__snapshots__/license_policy.test.ts.snap
new file mode 100644
index 0000000..6d2f52a
--- /dev/null
+++ b/e2e/__snapshots__/license_policy.test.ts.snap
@@ -0,0 +1,626 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`License Policy accessibility tree matches snapshot 1`] = `
+Object {
+  "children": Array [
+    Object {
+      "name": "Black Lives Matter",
+      "role": "text",
+    },
+    Object {
+      "name": "Support the Equal Justice Initiative",
+      "role": "link",
+    },
+    Object {
+      "name": "Link to Go homepage",
+      "role": "link",
+    },
+    Object {
+      "name": "Search for a package",
+      "role": "button",
+    },
+    Object {
+      "description": "Search for a package",
+      "name": "Search for a package",
+      "role": "textbox",
+    },
+    Object {
+      "description": "Why Go",
+      "name": "Why Go",
+      "role": "link",
+    },
+    Object {
+      "description": "Getting Started",
+      "name": "Getting Started",
+      "role": "link",
+    },
+    Object {
+      "description": "Discover Packages",
+      "name": "Discover Packages",
+      "role": "link",
+    },
+    Object {
+      "name": "About",
+      "role": "link",
+    },
+    Object {
+      "level": 1,
+      "name": "License Disclaimer",
+      "role": "heading",
+    },
+    Object {
+      "name": "The Go website displays license information in order to help users evaluate packages for their intended use. Licenses are detected using heuristics based on their file name and contents. We hope this information is helpful, but this is not legal advice and we do not make any guarantees regarding the accuracy of our license detection.",
+      "role": "text",
+    },
+    Object {
+      "name": "If we are not able to detect one of the licenses below, only limited package and module information will be made available. If you are a package author seeking to make your content available on the Go website, please be aware that our detection algorithms can be affected by any modifications of the license text, or by the use of an uncommon license file name.",
+      "role": "text",
+    },
+    Object {
+      "name": "We currently use",
+      "role": "text",
+    },
+    Object {
+      "name": "github.com/google/licensecheck",
+      "role": "link",
+    },
+    Object {
+      "name": "for license detection, and look for licenses in files with the following names: COPYING, COPYING.md, COPYING.markdown, COPYING.txt, LICENCE, LICENCE.md, LICENCE.markdown, LICENCE.txt, LICENSE, LICENSE.md, LICENSE.markdown, LICENSE.txt, LICENSE-2.0.txt, LICENCE-2.0.txt, LICENSE-APACHE, LICENCE-APACHE, LICENSE-APACHE-2.0.txt, LICENCE-APACHE-2.0.txt, LICENSE-MIT, LICENCE-MIT, LICENSE.MIT, LICENCE.MIT, LICENSE.code, LICENCE.code, LICENSE.docs, LICENCE.docs, LICENSE.rst, LICENCE.rst, MIT-LICENSE, MIT-LICENCE, MIT-LICENSE.md, MIT-LICENCE.md, MIT-LICENSE.markdown, MIT-LICENCE.markdown, MIT-LICENSE.txt, MIT-LICENCE.txt, MIT_LICENSE, MIT_LICENCE, UNLICENSE, UNLICENCE. The match is case-insensitive.",
+      "role": "text",
+    },
+    Object {
+      "name": "We currently detect and recognize the following licenses:",
+      "role": "text",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "0BSD",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "AFL-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "AGPL-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "AGPL-3.0-only",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "AGPL-3.0-or-later",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Apache-1.1",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Apache-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Artistic-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-1-Clause",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-2-Clause",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-2-Clause-Views",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause-Clear",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause-Open-MPI",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-4-Clause",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-4-Clause-UC",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BSL-1.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "BlueOak-1.0.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "CC-BY-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "CC-BY-4.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "CC-BY-SA-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "CC-BY-SA-4.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "CC0-1.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "EPL-1.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "EPL-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "EUPL-1.2",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-2.0-only",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-2.0-or-later",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-3.0-only",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "GPL-3.0-or-later",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "HPND",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "ISC",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "JSON",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "LGPL-2.1",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "LGPL-2.1-or-later",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "LGPL-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "LGPL-3.0-or-later",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "MIT",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "MIT-0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "MPL-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "MPL-2.0-no-copyleft-exception",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "NCSA",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "NIST-PD",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "NIST-PD-fallback",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "OSL-3.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "OpenSSL",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "PostgreSQL",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Python-2.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "UPL-1.0",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Unlicense",
+      "role": "link",
+    },
+    Object {
+      "name": "•",
+      "role": "text",
+    },
+    Object {
+      "name": "Zlib",
+      "role": "link",
+    },
+    Object {
+      "name": "If you use a package whose license is not detected, please inform the package author. If you are a package author who believes a license for one of your packages should have been detected and was not, please check for discrepancies between your license and the official text. If you still believe there is an error, please",
+      "role": "text",
+    },
+    Object {
+      "name": "file an issue",
+      "role": "link",
+    },
+    Object {
+      "name": ".",
+      "role": "text",
+    },
+    Object {
+      "description": "Why Go",
+      "name": "Why Go",
+      "role": "link",
+    },
+    Object {
+      "description": "Use Cases",
+      "name": "Use Cases",
+      "role": "link",
+    },
+    Object {
+      "description": "Case Studies",
+      "name": "Case Studies",
+      "role": "link",
+    },
+    Object {
+      "description": "Getting Started",
+      "name": "Getting Started",
+      "role": "link",
+    },
+    Object {
+      "name": "Playground",
+      "role": "link",
+    },
+    Object {
+      "name": "Tour",
+      "role": "link",
+    },
+    Object {
+      "name": "Stack Overflow",
+      "role": "link",
+    },
+    Object {
+      "description": "Discover Packages",
+      "name": "Discover Packages",
+      "role": "link",
+    },
+    Object {
+      "description": "About",
+      "name": "About",
+      "role": "link",
+    },
+    Object {
+      "name": "Download",
+      "role": "link",
+    },
+    Object {
+      "name": "Blog",
+      "role": "link",
+    },
+    Object {
+      "name": "Release Notes",
+      "role": "link",
+    },
+    Object {
+      "name": "Brand Guidelines",
+      "role": "link",
+    },
+    Object {
+      "name": "Code of Conduct",
+      "role": "link",
+    },
+    Object {
+      "description": "Connect",
+      "name": "Connect",
+      "role": "link",
+    },
+    Object {
+      "name": "Twitter",
+      "role": "link",
+    },
+    Object {
+      "name": "GitHub",
+      "role": "link",
+    },
+    Object {
+      "name": "Slack",
+      "role": "link",
+    },
+    Object {
+      "name": "Meetup",
+      "role": "link",
+    },
+    Object {
+      "name": "Gopher in flight goggles",
+      "role": "img",
+    },
+    Object {
+      "name": "Copyright",
+      "role": "link",
+    },
+    Object {
+      "name": "Terms of Service",
+      "role": "link",
+    },
+    Object {
+      "name": "Privacy Policy",
+      "role": "link",
+    },
+    Object {
+      "name": "Report an Issue",
+      "role": "link",
+    },
+    Object {
+      "name": "golang.org",
+      "role": "link",
+    },
+    Object {
+      "name": "Google logo",
+      "role": "link",
+    },
+  ],
+  "name": "Licenses · pkg.go.dev",
+  "role": "WebArea",
+}
+`;
diff --git a/e2e/__snapshots__/pkgsite.test.ts.snap b/e2e/__snapshots__/pkgsite.test.ts.snap
index 242ced7..40d4a63 100644
--- a/e2e/__snapshots__/pkgsite.test.ts.snap
+++ b/e2e/__snapshots__/pkgsite.test.ts.snap
@@ -60,6 +60,10 @@
       "role": "button",
     },
     Object {
+      "name": "Go",
+      "role": "img",
+    },
+    Object {
       "level": 1,
       "name": "pkgsite",
       "role": "heading",
@@ -69,7 +73,7 @@
       "role": "text",
     },
     Object {
-      "name": "Version v0.0.0-...-5867665",
+      "name": "Version: v0.0.0-...-4500fee",
       "role": "link",
     },
     Object {
@@ -81,7 +85,7 @@
       "role": "text",
     },
     Object {
-      "name": "Feb 16, 2021",
+      "name": "Published: Mar 23, 2021",
       "role": "text",
     },
     Object {
@@ -89,6 +93,10 @@
       "role": "text",
     },
     Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
       "name": "BSD-3-Clause",
       "role": "link",
     },
@@ -504,7 +512,7 @@
       "role": "text",
     },
     Object {
-      "name": "3 more from devtools",
+      "name": "4 more from devtools",
       "role": "button",
     },
     Object {
@@ -512,7 +520,7 @@
       "role": "text",
     },
     Object {
-      "name": "37 more from internal",
+      "name": "39 more from internal",
       "role": "button",
     },
     Object {
diff --git a/e2e/__snapshots__/search.test.ts.snap b/e2e/__snapshots__/search.test.ts.snap
new file mode 100644
index 0000000..33bd102
--- /dev/null
+++ b/e2e/__snapshots__/search.test.ts.snap
@@ -0,0 +1,727 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Search accessibility tree matches snapshot 1`] = `
+Object {
+  "children": Array [
+    Object {
+      "name": "Black Lives Matter",
+      "role": "text",
+    },
+    Object {
+      "name": "Support the Equal Justice Initiative",
+      "role": "link",
+    },
+    Object {
+      "name": "Link to Go homepage",
+      "role": "link",
+    },
+    Object {
+      "name": "Search for a package",
+      "role": "button",
+    },
+    Object {
+      "description": "Search for a package",
+      "name": "Search for a package",
+      "role": "textbox",
+      "value": "http",
+    },
+    Object {
+      "description": "Why Go",
+      "name": "Why Go",
+      "role": "link",
+    },
+    Object {
+      "description": "Getting Started",
+      "name": "Getting Started",
+      "role": "link",
+    },
+    Object {
+      "description": "Discover Packages",
+      "name": "Discover Packages",
+      "role": "link",
+    },
+    Object {
+      "name": "About",
+      "role": "link",
+    },
+    Object {
+      "level": 1,
+      "name": "Results for “http”",
+      "role": "heading",
+    },
+    Object {
+      "name": "Search help",
+      "role": "link",
+    },
+    Object {
+      "name": "1 – 10 of 13 results",
+      "role": "text",
+    },
+    Object {
+      "name": "Previous",
+      "role": "text",
+    },
+    Object {
+      "name": "1",
+      "role": "text",
+    },
+    Object {
+      "name": "2",
+      "role": "link",
+    },
+    Object {
+      "name": "Next",
+      "role": "link",
+    },
+    Object {
+      "name": "net/http",
+      "role": "link",
+    },
+    Object {
+      "name": "Package http provides HTTP client and server implementations.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "net/http/httptest",
+      "role": "link",
+    },
+    Object {
+      "name": "Package httptest provides utilities for HTTP testing.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "net/http/httptrace",
+      "role": "link",
+    },
+    Object {
+      "name": "Package httptrace provides mechanisms to trace the events within HTTP client requests.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "net/http/httputil",
+      "role": "link",
+    },
+    Object {
+      "name": "Package httputil provides HTTP utility functions, complementing the more common ones in the net/http package.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "net/http/pprof",
+      "role": "link",
+    },
+    Object {
+      "name": "Package pprof serves via its HTTP server runtime profiling data in the format expected by the pprof visualization tool.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "golang.org/x/tools/go/analysis/passes/httpresponse",
+      "role": "link",
+    },
+    Object {
+      "name": "Package httpresponse defines an Analyzer that checks for mistakes using HTTP responses.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "v0.1.0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "Jan 19, 2021",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "golang.org/x/tools/godoc/redirect",
+      "role": "link",
+    },
+    Object {
+      "name": "Package redirect provides hooks to register HTTP handlers that redirect old godoc paths to their new equivalents and assist in accessing the issue tracker, wiki, code review system, etc.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "v0.1.0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "Jan 19, 2021",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "golang.org/x/tools/playground",
+      "role": "link",
+    },
+    Object {
+      "name": "Package playground registers HTTP handlers at \\"/compile\\" and \\"/share\\" that proxy requests to the golang.org playground service.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "v0.1.0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "Jan 19, 2021",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "github.com/gin-gonic/gin",
+      "role": "link",
+    },
+    Object {
+      "name": "Package gin implements a HTTP web framework called gin.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "v1.6.3",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 3, 2020",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "MIT",
+      "role": "text",
+    },
+    Object {
+      "name": "net/http/cgi",
+      "role": "link",
+    },
+    Object {
+      "name": "Package cgi implements CGI (Common Gateway Interface) as specified in RFC 3875.",
+      "role": "text",
+    },
+    Object {
+      "name": "Version:",
+      "role": "text",
+    },
+    Object {
+      "name": "go1.12.5",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Published:",
+      "role": "text",
+    },
+    Object {
+      "name": "May 6, 2019",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "Imported by:",
+      "role": "text",
+    },
+    Object {
+      "name": "0",
+      "role": "text",
+    },
+    Object {
+      "name": "|",
+      "role": "text",
+    },
+    Object {
+      "name": "License:",
+      "role": "text",
+    },
+    Object {
+      "name": "BSD-3-Clause",
+      "role": "text",
+    },
+    Object {
+      "name": "Previous",
+      "role": "text",
+    },
+    Object {
+      "name": "1",
+      "role": "text",
+    },
+    Object {
+      "name": "2",
+      "role": "link",
+    },
+    Object {
+      "name": "Next",
+      "role": "link",
+    },
+    Object {
+      "description": "Why Go",
+      "name": "Why Go",
+      "role": "link",
+    },
+    Object {
+      "description": "Use Cases",
+      "name": "Use Cases",
+      "role": "link",
+    },
+    Object {
+      "description": "Case Studies",
+      "name": "Case Studies",
+      "role": "link",
+    },
+    Object {
+      "description": "Getting Started",
+      "name": "Getting Started",
+      "role": "link",
+    },
+    Object {
+      "name": "Playground",
+      "role": "link",
+    },
+    Object {
+      "name": "Tour",
+      "role": "link",
+    },
+    Object {
+      "name": "Stack Overflow",
+      "role": "link",
+    },
+    Object {
+      "description": "Discover Packages",
+      "name": "Discover Packages",
+      "role": "link",
+    },
+    Object {
+      "description": "About",
+      "name": "About",
+      "role": "link",
+    },
+    Object {
+      "name": "Download",
+      "role": "link",
+    },
+    Object {
+      "name": "Blog",
+      "role": "link",
+    },
+    Object {
+      "name": "Release Notes",
+      "role": "link",
+    },
+    Object {
+      "name": "Brand Guidelines",
+      "role": "link",
+    },
+    Object {
+      "name": "Code of Conduct",
+      "role": "link",
+    },
+    Object {
+      "description": "Connect",
+      "name": "Connect",
+      "role": "link",
+    },
+    Object {
+      "name": "Twitter",
+      "role": "link",
+    },
+    Object {
+      "name": "GitHub",
+      "role": "link",
+    },
+    Object {
+      "name": "Slack",
+      "role": "link",
+    },
+    Object {
+      "name": "Meetup",
+      "role": "link",
+    },
+    Object {
+      "name": "Gopher in flight goggles",
+      "role": "img",
+    },
+    Object {
+      "name": "Copyright",
+      "role": "link",
+    },
+    Object {
+      "name": "Terms of Service",
+      "role": "link",
+    },
+    Object {
+      "name": "Privacy Policy",
+      "role": "link",
+    },
+    Object {
+      "name": "Report an Issue",
+      "role": "link",
+    },
+    Object {
+      "name": "golang.org",
+      "role": "link",
+    },
+    Object {
+      "name": "Google logo",
+      "role": "link",
+    },
+  ],
+  "name": "http - Search Results · pkg.go.dev",
+  "role": "WebArea",
+}
+`;
diff --git a/e2e/__snapshots__/frontend-fetch.test.ts.snap b/e2e/__snapshots__/search_help.test.ts.snap
similarity index 67%
copy from e2e/__snapshots__/frontend-fetch.test.ts.snap
copy to e2e/__snapshots__/search_help.test.ts.snap
index 93655ea..9afb55a 100644
--- a/e2e/__snapshots__/frontend-fetch.test.ts.snap
+++ b/e2e/__snapshots__/search_help.test.ts.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`Frontend Fetch accessibility tree matches snapshot 1`] = `
+exports[`Search Help accessibility tree matches snapshot 1`] = `
 Object {
   "children": Array [
     Object {
@@ -44,29 +44,76 @@
       "role": "link",
     },
     Object {
-      "name": "The Go Gopher",
-      "role": "img",
-    },
-    Object {
-      "level": 3,
-      "name": "Oops! We couldn't find “rsc.io/quote”.",
+      "level": 1,
+      "name": "Search help",
       "role": "heading",
     },
     Object {
-      "name": "Check that you entered the URL correctly, try fetching it following the",
+      "name": "You can use symbols or words in your search to make your search results more precise.",
       "role": "text",
     },
     Object {
-      "name": "instructions here",
+      "level": 2,
+      "name": "Search for an exact match",
+      "role": "heading",
+    },
+    Object {
+      "name": "Put a word or phrase inside quotes. For example,",
+      "role": "text",
+    },
+    Object {
+      "name": "\\"go cloud\\"",
       "role": "link",
     },
     Object {
-      "name": ", or request to add “rsc.io/quote” to pkg.go.dev.",
+      "name": ".",
       "role": "text",
     },
     Object {
-      "name": "Request “rsc.io/quote”",
-      "role": "button",
+      "level": 2,
+      "name": "Combine searches",
+      "role": "heading",
+    },
+    Object {
+      "name": "Put OR between each search query. For example,",
+      "role": "text",
+    },
+    Object {
+      "name": "yaml OR json",
+      "role": "link",
+    },
+    Object {
+      "name": ".",
+      "role": "text",
+    },
+    Object {
+      "level": 2,
+      "name": "Search by package path",
+      "role": "heading",
+    },
+    Object {
+      "name": "You can search for a package by its full or partial import path. For example,",
+      "role": "text",
+    },
+    Object {
+      "name": "go/packages",
+      "role": "link",
+    },
+    Object {
+      "name": ".",
+      "role": "text",
+    },
+    Object {
+      "name": "If the query matches a package import path, you will be redirected to the package details page for the latest version of that package. For example,",
+      "role": "text",
+    },
+    Object {
+      "name": "golang.org/x/tools/go/packages",
+      "role": "link",
+    },
+    Object {
+      "name": ".",
+      "role": "text",
     },
     Object {
       "description": "Why Go",
@@ -180,7 +227,7 @@
       "role": "link",
     },
   ],
-  "name": "404 Not Found · pkg.go.dev",
+  "name": "Search Help · pkg.go.dev",
   "role": "WebArea",
 }
 `;
diff --git a/e2e/badge.test.ts b/e2e/badge.test.ts
new file mode 100644
index 0000000..06f57b3
--- /dev/null
+++ b/e2e/badge.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+import './global-types';
+import puppeteer, { Page } from 'puppeteer';
+
+const baseUrl = process.env.FRONTEND_URL ?? '';
+
+describe('Badge', () => {
+  let page: Page;
+
+  beforeEach(async () => {
+    page = await browser.newPage();
+    await page.goto(baseUrl + '/badge');
+  });
+
+  afterEach(async () => {
+    await page.close();
+  });
+
+  test('accessibility tree matches snapshot', async () => {
+    const a11yTree = await page.accessibility.snapshot();
+    expect(a11yTree).toMatchSnapshot();
+  });
+
+  test('desktop viewport matches image snapshot', async () => {
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+
+  test('mobile viewport matches image snapshot', async () => {
+    await page.emulate(puppeteer.devices['Pixel 2']);
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+});
diff --git a/e2e/error.test.ts b/e2e/error.test.ts
new file mode 100644
index 0000000..d1e17f7
--- /dev/null
+++ b/e2e/error.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+import './global-types';
+import puppeteer, { Page } from 'puppeteer';
+
+const baseUrl = process.env.FRONTEND_URL ?? '';
+
+describe('Error', () => {
+  let page: Page;
+
+  beforeEach(async () => {
+    page = await browser.newPage();
+    await page.goto(baseUrl + '/@bad-request');
+  });
+
+  afterEach(async () => {
+    await page.close();
+  });
+
+  test('accessibility tree matches snapshot', async () => {
+    const a11yTree = await page.accessibility.snapshot();
+    expect(a11yTree).toMatchSnapshot();
+  });
+
+  test('desktop viewport matches image snapshot', async () => {
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+
+  test('mobile viewport matches image snapshot', async () => {
+    await page.emulate(puppeteer.devices['Pixel 2']);
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+});
diff --git a/e2e/frontend-fetch.test.ts b/e2e/fetch.test.ts
similarity index 61%
rename from e2e/frontend-fetch.test.ts
rename to e2e/fetch.test.ts
index 551c8cb..f03ff31 100644
--- a/e2e/frontend-fetch.test.ts
+++ b/e2e/fetch.test.ts
@@ -5,22 +5,17 @@
  * license that can be found in the LICENSE file.
  */
 
-import './globals';
+import './global-types';
 import puppeteer, { Page } from 'puppeteer';
 
 const baseUrl = process.env.FRONTEND_URL ?? '';
-const el = (id: string) => `[data-test-id="${id}"]`;
-const selectors = {
-  fetchButton: el('fetch-button'),
-  fetchMessage: el('fetch-message'),
-};
 
 describe('Frontend Fetch', () => {
   let page: Page;
 
   beforeAll(async () => {
     page = await browser.newPage();
-    await page.goto(baseUrl + '/rsc.io/quote');
+    await page.goto(baseUrl + '/fetch.test');
   });
 
   afterAll(async () => {
@@ -42,15 +37,4 @@
     const image = await page.screenshot({ fullPage: true });
     expect(image).toMatchImageSnapshot();
   });
-
-  test('clicking fetch button fetches module and navigates to page', async () => {
-    expect(await page.title()).toBe('404 Not Found · pkg.go.dev');
-
-    await page.click(selectors.fetchButton);
-    const message = await page.$eval(selectors.fetchMessage, el => el.textContent);
-    expect(message).toBe('Fetching rsc.io/quote');
-
-    await page.waitForNavigation();
-    expect(await page.title()).toBe('quote · pkg.go.dev');
-  }, 30000);
 });
diff --git a/e2e/license_policy.test.ts b/e2e/license_policy.test.ts
new file mode 100644
index 0000000..57375d5
--- /dev/null
+++ b/e2e/license_policy.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+import './global-types';
+import puppeteer, { Page } from 'puppeteer';
+
+const baseUrl = process.env.FRONTEND_URL ?? '';
+
+describe('License Policy', () => {
+  let page: Page;
+
+  beforeEach(async () => {
+    page = await browser.newPage();
+    await page.goto(baseUrl + '/license-policy');
+  });
+
+  afterEach(async () => {
+    await page.close();
+  });
+
+  test('accessibility tree matches snapshot', async () => {
+    const a11yTree = await page.accessibility.snapshot();
+    expect(a11yTree).toMatchSnapshot();
+  });
+
+  test('desktop viewport matches image snapshot', async () => {
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+
+  test('mobile viewport matches image snapshot', async () => {
+    await page.emulate(puppeteer.devices['Pixel 2']);
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+});
diff --git a/e2e/search.test.ts b/e2e/search.test.ts
new file mode 100644
index 0000000..efcf45f
--- /dev/null
+++ b/e2e/search.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+import './global-types';
+import puppeteer, { Page } from 'puppeteer';
+
+const baseUrl = process.env.FRONTEND_URL ?? '';
+
+describe('Search', () => {
+  let page: Page;
+
+  beforeEach(async () => {
+    page = await browser.newPage();
+    await page.goto(baseUrl + '/search?q=http');
+  });
+
+  afterEach(async () => {
+    await page.close();
+  });
+
+  test('accessibility tree matches snapshot', async () => {
+    const a11yTree = await page.accessibility.snapshot();
+    expect(a11yTree).toMatchSnapshot();
+  });
+
+  test('desktop viewport matches image snapshot', async () => {
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+
+  test('mobile viewport matches image snapshot', async () => {
+    await page.emulate(puppeteer.devices['Pixel 2']);
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+});
diff --git a/e2e/search_help.test.ts b/e2e/search_help.test.ts
new file mode 100644
index 0000000..7faa8b2
--- /dev/null
+++ b/e2e/search_help.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+import './global-types';
+import puppeteer, { Page } from 'puppeteer';
+
+const baseUrl = process.env.FRONTEND_URL ?? '';
+
+describe('Search Help', () => {
+  let page: Page;
+
+  beforeEach(async () => {
+    page = await browser.newPage();
+    await page.goto(baseUrl + '/search-help');
+  });
+
+  afterEach(async () => {
+    await page.close();
+  });
+
+  test('accessibility tree matches snapshot', async () => {
+    const a11yTree = await page.accessibility.snapshot();
+    expect(a11yTree).toMatchSnapshot();
+  });
+
+  test('desktop viewport matches image snapshot', async () => {
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+
+  test('mobile viewport matches image snapshot', async () => {
+    await page.emulate(puppeteer.devices['Pixel 2']);
+    const image = await page.screenshot({ fullPage: true });
+    expect(image).toMatchImageSnapshot();
+  });
+});
diff --git a/e2e/unit_details.test.ts b/e2e/unit_details.test.ts
new file mode 100644
index 0000000..c7077fc
--- /dev/null
+++ b/e2e/unit_details.test.ts
@@ -0,0 +1,3 @@
+describe('Unit Details', () => {
+  test.todo('todo');
+});
diff --git a/e2e/unit_importedby.test.ts b/e2e/unit_importedby.test.ts
new file mode 100644
index 0000000..56ce9aa
--- /dev/null
+++ b/e2e/unit_importedby.test.ts
@@ -0,0 +1,3 @@
+describe('Unit Imported By', () => {
+  test.todo('todo');
+});
diff --git a/e2e/unit_imports.test.ts b/e2e/unit_imports.test.ts
new file mode 100644
index 0000000..f8ca993
--- /dev/null
+++ b/e2e/unit_imports.test.ts
@@ -0,0 +1,3 @@
+describe('Unit Imports', () => {
+  test.todo('todo');
+});
diff --git a/e2e/unit_licenses.test.ts b/e2e/unit_licenses.test.ts
new file mode 100644
index 0000000..93a05d4
--- /dev/null
+++ b/e2e/unit_licenses.test.ts
@@ -0,0 +1,3 @@
+describe('Unit Licenses', () => {
+  test.todo('todo');
+});
diff --git a/e2e/unit_versions.test.ts b/e2e/unit_versions.test.ts
new file mode 100644
index 0000000..1408ce9
--- /dev/null
+++ b/e2e/unit_versions.test.ts
@@ -0,0 +1,3 @@
+describe('Unit Version', () => {
+  test.todo('todo');
+});