summaryrefslogtreecommitdiffstats
path: root/src/test/rustdoc-gui
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/rustdoc-gui
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/rustdoc-gui')
-rw-r--r--src/test/rustdoc-gui/README.md34
-rw-r--r--src/test/rustdoc-gui/anchor-navigable.goml11
-rw-r--r--src/test/rustdoc-gui/anchors.goml34
-rw-r--r--src/test/rustdoc-gui/auto-hide-trait-implementations.goml13
-rw-r--r--src/test/rustdoc-gui/basic-code.goml3
-rw-r--r--src/test/rustdoc-gui/basic.goml4
-rw-r--r--src/test/rustdoc-gui/check-code-blocks-margin.goml6
-rw-r--r--src/test/rustdoc-gui/check_info_sign_position.goml11
-rw-r--r--src/test/rustdoc-gui/code-blocks-overflow.goml8
-rw-r--r--src/test/rustdoc-gui/code-color.goml30
-rw-r--r--src/test/rustdoc-gui/code-sidebar-toggle.goml7
-rw-r--r--src/test/rustdoc-gui/code-tags.goml20
-rw-r--r--src/test/rustdoc-gui/default-settings.goml8
-rw-r--r--src/test/rustdoc-gui/docblock-big-code-mobile.goml9
-rw-r--r--src/test/rustdoc-gui/docblock-code-block-line-number.goml22
-rw-r--r--src/test/rustdoc-gui/docblock-details.goml23
-rw-r--r--src/test/rustdoc-gui/docblock-table-overflow.goml21
-rw-r--r--src/test/rustdoc-gui/duplicate-macro-reexport.goml14
-rw-r--r--src/test/rustdoc-gui/escape-key.goml35
-rw-r--r--src/test/rustdoc-gui/font-weight.goml44
-rw-r--r--src/test/rustdoc-gui/hash-item-expansion.goml11
-rw-r--r--src/test/rustdoc-gui/headers-color.goml117
-rw-r--r--src/test/rustdoc-gui/headings.goml258
-rw-r--r--src/test/rustdoc-gui/huge-collection-of-constants.goml9
-rw-r--r--src/test/rustdoc-gui/impl-default-expansion.goml3
-rw-r--r--src/test/rustdoc-gui/implementors.goml35
-rw-r--r--src/test/rustdoc-gui/item-info-overflow.goml31
-rw-r--r--src/test/rustdoc-gui/item-info.goml32
-rw-r--r--src/test/rustdoc-gui/item-summary-table.goml6
-rw-r--r--src/test/rustdoc-gui/javascript-disabled.goml6
-rw-r--r--src/test/rustdoc-gui/jump-to-def-background.goml43
-rw-r--r--src/test/rustdoc-gui/label-next-to-symbol.goml78
-rw-r--r--src/test/rustdoc-gui/list_code_block.goml4
-rw-r--r--src/test/rustdoc-gui/mobile.goml30
-rw-r--r--src/test/rustdoc-gui/module-items-font.goml67
-rw-r--r--src/test/rustdoc-gui/overflow-tooltip-information.goml8
-rw-r--r--src/test/rustdoc-gui/pocket-menu.goml77
-rw-r--r--src/test/rustdoc-gui/run-on-hover.goml7
-rw-r--r--src/test/rustdoc-gui/rust-logo.goml78
-rw-r--r--src/test/rustdoc-gui/search-filter.goml83
-rw-r--r--src/test/rustdoc-gui/search-input-mobile.goml11
-rw-r--r--src/test/rustdoc-gui/search-input.goml23
-rw-r--r--src/test/rustdoc-gui/search-reexport.goml33
-rw-r--r--src/test/rustdoc-gui/search-result-color.goml98
-rw-r--r--src/test/rustdoc-gui/search-result-description.goml5
-rw-r--r--src/test/rustdoc-gui/search-result-display.goml42
-rw-r--r--src/test/rustdoc-gui/search-result-go-to-first.goml19
-rw-r--r--src/test/rustdoc-gui/search-result-keyword.goml13
-rw-r--r--src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml74
-rw-r--r--src/test/rustdoc-gui/settings.goml158
-rw-r--r--src/test/rustdoc-gui/shortcuts.goml13
-rw-r--r--src/test/rustdoc-gui/sidebar-macro-reexport.goml5
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile.goml64
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code-display.goml254
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code.goml45
-rw-r--r--src/test/rustdoc-gui/sidebar.goml88
-rw-r--r--src/test/rustdoc-gui/source-anchor-scroll.goml20
-rw-r--r--src/test/rustdoc-gui/source-code-page.goml49
-rw-r--r--src/test/rustdoc-gui/src-font-size.goml11
-rw-r--r--src/test/rustdoc-gui/src/lib2/Cargo.lock14
-rw-r--r--src/test/rustdoc-gui/src/lib2/Cargo.toml10
-rw-r--r--src/test/rustdoc-gui/src/lib2/another_folder/mod.rs3
-rw-r--r--src/test/rustdoc-gui/src/lib2/another_folder/sub_mod/mod.rs1
-rw-r--r--src/test/rustdoc-gui/src/lib2/another_mod/mod.rs1
-rw-r--r--src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml7
-rw-r--r--src/test/rustdoc-gui/src/lib2/implementors/lib.rs20
-rw-r--r--src/test/rustdoc-gui/src/lib2/lib.rs145
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/Cargo.toml7
-rw-r--r--src/test/rustdoc-gui/src/link_to_definition/lib.rs35
-rw-r--r--src/test/rustdoc-gui/src/settings/.cargo/config.toml2
-rw-r--r--src/test/rustdoc-gui/src/settings/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/settings/Cargo.toml7
-rw-r--r--src/test/rustdoc-gui/src/settings/lib.rs1
-rw-r--r--src/test/rustdoc-gui/src/staged_api/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/staged_api/Cargo.toml11
-rw-r--r--src/test/rustdoc-gui/src/staged_api/lib.rs10
-rw-r--r--src/test/rustdoc-gui/src/test_docs/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/test_docs/Cargo.toml13
-rw-r--r--src/test/rustdoc-gui/src/test_docs/build.rs15
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs295
-rw-r--r--src/test/rustdoc-gui/src/test_docs/macros.rs4
-rw-r--r--src/test/rustdoc-gui/theme-change.goml32
-rw-r--r--src/test/rustdoc-gui/theme-in-history.goml28
-rw-r--r--src/test/rustdoc-gui/toggle-click-deadspace.goml12
-rw-r--r--src/test/rustdoc-gui/toggle-docs-mobile.goml33
-rw-r--r--src/test/rustdoc-gui/toggle-docs.goml42
-rw-r--r--src/test/rustdoc-gui/toggle-implementors.goml4
-rw-r--r--src/test/rustdoc-gui/toggled-open-implementations.goml5
-rw-r--r--src/test/rustdoc-gui/trait-sidebar-item-order.goml8
-rw-r--r--src/test/rustdoc-gui/type-declation-overflow.goml37
92 files changed, 3202 insertions, 0 deletions
diff --git a/src/test/rustdoc-gui/README.md b/src/test/rustdoc-gui/README.md
new file mode 100644
index 000000000..d9854e2e7
--- /dev/null
+++ b/src/test/rustdoc-gui/README.md
@@ -0,0 +1,34 @@
+The tests present here are used to test the generated HTML from rustdoc. The
+goal is to prevent unsound/unexpected GUI changes.
+
+This is using the [browser-ui-test] framework to do so. It works as follows:
+
+It wraps [puppeteer] to send commands to a web browser in order to navigate and
+test what's being currently displayed in the web page.
+
+You can find more information and its documentation in its [repository][browser-ui-test].
+
+If you need to have more information on the tests run, you can use `--test-args`:
+
+```bash
+$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --debug
+```
+
+If you don't want to run in headless mode (helpful to debug sometimes), you can use
+`--no-headless`:
+
+```bash
+$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --no-headless
+```
+
+To see the supported options, use `--help`.
+
+Important to be noted: if the chromium instance crashes when you run it, you might need to
+use `--no-sandbox` to make it work:
+
+```bash
+$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --no-sandbox
+```
+
+[browser-ui-test]: https://github.com/GuillaumeGomez/browser-UI-test/
+[puppeteer]: https://pptr.dev/
diff --git a/src/test/rustdoc-gui/anchor-navigable.goml b/src/test/rustdoc-gui/anchor-navigable.goml
new file mode 100644
index 000000000..424c31223
--- /dev/null
+++ b/src/test/rustdoc-gui/anchor-navigable.goml
@@ -0,0 +1,11 @@
+// The `impl Foo` heading underneath `Implementations` has a §
+// anchor to its left (used for linking to that heading). The anchor only shows
+// up when hovering the `impl Foo`. This test ensures there's no gap between the
+// anchor and the `impl Foo`. If there were a gap, this would cause an annoying
+// problem: you hover `impl Foo` to see the anchor, then when you move your
+// mouse to the left, the anchor disappears before you reach it.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+// We check that ".item-info" is bigger than its content.
+move-cursor-to: ".impl"
+assert-property: (".impl > a.anchor", {"offsetWidth": "9"})
+assert-css: (".impl > a.anchor", {"left": "-8px"})
diff --git a/src/test/rustdoc-gui/anchors.goml b/src/test/rustdoc-gui/anchors.goml
new file mode 100644
index 000000000..84b8bbd1b
--- /dev/null
+++ b/src/test/rustdoc-gui/anchors.goml
@@ -0,0 +1,34 @@
+// This test is to ensure that the anchors (`§`) have the expected color and position.
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+show-text: true
+
+// This is needed to ensure that the text color is computed.
+show-text: true
+
+// Set the theme to light.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: ("#toggle-all-docs", {"color": "rgb(0, 0, 0)"})
+assert-css: (".fqn .in-band a:nth-of-type(1)", {"color": "rgb(0, 0, 0)"})
+assert-css: (".fqn .in-band a:nth-of-type(2)", {"color": "rgb(173, 55, 138)"})
+assert-css: (".srclink", {"color": "rgb(56, 115, 173)"})
+
+move-cursor-to: ".main-heading .srclink"
+assert-css: (".srclink", {"text-decoration": "underline solid rgb(56, 115, 173)"})
+
+assert-css: ("#top-doc-prose-title", {"color": "rgb(0, 0, 0)"})
+
+assert-css: (".sidebar a", {"color": "rgb(53, 109, 164)"})
+assert-css: (".in-band a", {"color": "rgb(0, 0, 0)"})
+
+// We move the cursor over the "Implementations" title so the anchor is displayed.
+move-cursor-to: "h2#implementations"
+assert-css: ("h2#implementations a.anchor", {"color": "rgb(0, 0, 0)"})
+
+// Same thing with the impl block title.
+move-cursor-to: "#impl-HeavilyDocumentedStruct"
+assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(0, 0, 0)"})
+
+assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
diff --git a/src/test/rustdoc-gui/auto-hide-trait-implementations.goml b/src/test/rustdoc-gui/auto-hide-trait-implementations.goml
new file mode 100644
index 000000000..7b1358fed
--- /dev/null
+++ b/src/test/rustdoc-gui/auto-hide-trait-implementations.goml
@@ -0,0 +1,13 @@
+// Checks that the setting "auto hide trait implementations" is working as expected.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+
+// By default, the trait implementations are not collapsed.
+assert-attribute: ("#trait-implementations-list > details", {"open": ""}, ALL)
+
+// We now set the setting to auto hide all trait implementations.
+local-storage: {"rustdoc-auto-hide-trait-implementations": "true" }
+// We reload to ensure the trait implementations are collapsed as expected.
+reload:
+
+// We now check that all matching elements don't have the open attributes.
+assert-attribute-false: ("#trait-implementations-list > details", {"open": ""}, ALL)
diff --git a/src/test/rustdoc-gui/basic-code.goml b/src/test/rustdoc-gui/basic-code.goml
new file mode 100644
index 000000000..27deb2c98
--- /dev/null
+++ b/src/test/rustdoc-gui/basic-code.goml
@@ -0,0 +1,3 @@
+goto: file://|DOC_PATH|/test_docs/index.html
+click: ".srclink"
+assert-count: (".line-numbers", 1)
diff --git a/src/test/rustdoc-gui/basic.goml b/src/test/rustdoc-gui/basic.goml
new file mode 100644
index 000000000..239e51a91
--- /dev/null
+++ b/src/test/rustdoc-gui/basic.goml
@@ -0,0 +1,4 @@
+goto: file://|DOC_PATH|/test_docs/index.html
+assert: ("#functions")
+goto: ./struct.Foo.html
+assert: ("div.item-decl")
diff --git a/src/test/rustdoc-gui/check-code-blocks-margin.goml b/src/test/rustdoc-gui/check-code-blocks-margin.goml
new file mode 100644
index 000000000..f6266eba7
--- /dev/null
+++ b/src/test/rustdoc-gui/check-code-blocks-margin.goml
@@ -0,0 +1,6 @@
+// This test ensures that the docblock elements have the appropriate left margin.
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+// The top docblock elements shouldn't have left margin...
+assert-css: ("#main-content .docblock.item-decl", {"margin-left": "0px"})
+// ... but all the others should!
+assert-css: ("#main-content .docblock:not(.item-decl)", {"margin-left": "24px"})
diff --git a/src/test/rustdoc-gui/check_info_sign_position.goml b/src/test/rustdoc-gui/check_info_sign_position.goml
new file mode 100644
index 000000000..3bed7a0a0
--- /dev/null
+++ b/src/test/rustdoc-gui/check_info_sign_position.goml
@@ -0,0 +1,11 @@
+// This test checks the position of the information on the code blocks (like
+// `compile_fail` or `ignore`).
+goto: file://|DOC_PATH|/test_docs/index.html
+goto: ./fn.check_list_code_block.html
+// If the codeblock is the first element of the docblock, the information tooltip must have
+// have some top margin to avoid going over the toggle (the "[+]").
+assert-css: (".docblock > .information > .compile_fail", { "margin-top": "16px" })
+// Checks that the other codeblocks don't have this top margin.
+assert-css: ("ol > li > .information > .compile_fail", { "margin-top": "0px" })
+assert-css: ("ol > li > .information > .ignore", { "margin-top": "0px" })
+assert-css: (".docblock > .information > .ignore", { "margin-top": "0px" })
diff --git a/src/test/rustdoc-gui/code-blocks-overflow.goml b/src/test/rustdoc-gui/code-blocks-overflow.goml
new file mode 100644
index 000000000..f93f3f0ae
--- /dev/null
+++ b/src/test/rustdoc-gui/code-blocks-overflow.goml
@@ -0,0 +1,8 @@
+// This test ensures that codeblocks content don't overflow.
+goto: file://|DOC_PATH|/lib2/sub_mod/struct.Foo.html
+size: (1080, 600)
+// There should be two codeblocks: a rust one and a non-rust one.
+assert-count: (".docblock > .example-wrap", 2)
+assert: ".docblock > .example-wrap > .language-txt"
+assert: ".docblock > .example-wrap > .rust-example-rendered"
+assert-css: (".docblock > .example-wrap > pre", {"width": "785.25px", "overflow-x": "auto"}, ALL)
diff --git a/src/test/rustdoc-gui/code-color.goml b/src/test/rustdoc-gui/code-color.goml
new file mode 100644
index 000000000..2f95bfb6b
--- /dev/null
+++ b/src/test/rustdoc-gui/code-color.goml
@@ -0,0 +1,30 @@
+// The ayu theme has a different color for the "<code>" tags in the doc blocks. We need to
+// check that the rule isn't applied on other "<code>" elements.
+//
+// While we're at it, we also check it for the other themes.
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+// If the text isn't displayed, the browser doesn't compute color style correctly...
+show-text: true
+// Set the theme to dark.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (".docblock pre > code", {"color": "rgb(221, 221, 221)"}, ALL)
+assert-css: (".docblock > p > code", {"color": "rgb(221, 221, 221)"}, ALL)
+
+// Set the theme to ayu.
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (".docblock pre > code", {"color": "rgb(230, 225, 207)"}, ALL)
+assert-css: (".docblock > p > code", {"color": "rgb(255, 180, 84)"}, ALL)
+
+// Set the theme to light.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (".docblock pre > code", {"color": "rgb(0, 0, 0)"}, ALL)
+assert-css: (".docblock > p > code", {"color": "rgb(0, 0, 0)"}, ALL)
diff --git a/src/test/rustdoc-gui/code-sidebar-toggle.goml b/src/test/rustdoc-gui/code-sidebar-toggle.goml
new file mode 100644
index 000000000..867db0569
--- /dev/null
+++ b/src/test/rustdoc-gui/code-sidebar-toggle.goml
@@ -0,0 +1,7 @@
+// This test checks that the source code pages sidebar toggle is working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+click: ".srclink"
+wait-for: "#sidebar-toggle"
+click: "#sidebar-toggle"
+fail: true
+assert-css: ("#source-sidebar", { "left": "-300px" })
diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml
new file mode 100644
index 000000000..200569a28
--- /dev/null
+++ b/src/test/rustdoc-gui/code-tags.goml
@@ -0,0 +1,20 @@
+// This test ensures that items and documentation code blocks are wrapped in <pre><code>
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+size: (1080, 600)
+// There should be three doc codeblocks
+// Check that their content is inside <pre><code>
+assert-count: (".example-wrap pre > code", 3)
+// Check that function signature is inside <pre><code>
+assert: "pre.rust.fn > code"
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert: "pre.rust.struct > code"
+
+goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
+assert: "pre.rust.enum > code"
+
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
+assert: "pre.rust.trait > code"
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert: "pre.rust.typedef > code"
diff --git a/src/test/rustdoc-gui/default-settings.goml b/src/test/rustdoc-gui/default-settings.goml
new file mode 100644
index 000000000..90f0b087a
--- /dev/null
+++ b/src/test/rustdoc-gui/default-settings.goml
@@ -0,0 +1,8 @@
+// This test ensures that the default settings are correctly applied.
+//
+// The "settings" crate uses "ayu" as default setting, which is what we will
+// check.
+goto: file://|DOC_PATH|/settings/index.html
+// Wait a bit to be sure the default theme is applied.
+// If the theme isn't applied, the command will time out.
+wait-for-css: ("body", {"background-color": "rgb(15, 20, 25)"})
diff --git a/src/test/rustdoc-gui/docblock-big-code-mobile.goml b/src/test/rustdoc-gui/docblock-big-code-mobile.goml
new file mode 100644
index 000000000..02f79f1fc
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-big-code-mobile.goml
@@ -0,0 +1,9 @@
+// If we have a long `<code>`, we need to ensure that it'll be fully displayed on mobile, meaning
+// that it'll be on two lines.
+emulate: "iPhone 8" // it has the following size: (375, 667)
+goto: file://|DOC_PATH|/test_docs/long_code_block/index.html
+// We now check that the block is on two lines:
+show-text: true // We need to enable text draw to be able to have the "real" size
+// Little explanations for this test: if the text wasn't displayed on two lines, it would take
+// around 20px (which is the font size).
+assert-property: (".docblock p > code", {"offsetHeight": "44"})
diff --git a/src/test/rustdoc-gui/docblock-code-block-line-number.goml b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
new file mode 100644
index 000000000..baf9651c4
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
@@ -0,0 +1,22 @@
+// Checks that the setting "line numbers" is working as expected.
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+
+// We check that without this setting, there is no line number displayed.
+assert-false: "pre.line-number"
+
+// We now set the setting to show the line numbers on code examples.
+local-storage: {"rustdoc-line-numbers": "true" }
+// We reload to make the line numbers appear.
+reload:
+
+// We wait for them to be added into the DOM by the JS...
+wait-for: "pre.line-number"
+// If the test didn't fail, it means that it was found!
+// Let's now check some CSS properties...
+assert-css: ("pre.line-number", {
+ "margin": "0px",
+ "padding": "13px 8px",
+ "text-align": "right",
+})
+// The first code block has two lines so let's check its `<pre>` elements lists both of them.
+assert-text: ("pre.line-number", "1\n2")
diff --git a/src/test/rustdoc-gui/docblock-details.goml b/src/test/rustdoc-gui/docblock-details.goml
new file mode 100644
index 000000000..f6287ade2
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-details.goml
@@ -0,0 +1,23 @@
+// This ensures that the `<details>`/`<summary>` elements are displayed as expected.
+goto: file://|DOC_PATH|/test_docs/details/struct.Details.html
+show-text: true
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+
+// We first check that the headers in the `.top-doc` doc block still have their
+// bottom border.
+assert-text: (".top-doc .docblock > h3", "Hello")
+assert-css: (
+ ".top-doc .docblock > h3",
+ {"border-bottom": "1px solid rgb(210, 210, 210)"},
+)
+// We now check that the `<summary>` doesn't have a bottom border and has the correct display.
+assert-css: (
+ ".top-doc .docblock summary h4",
+ {"border-bottom": "0px none rgb(210, 210, 210)"},
+)
+// This allows to ensure that summary is on one line only!
+assert-property: (".top-doc .docblock summary h4", {"offsetHeight": "33"})
+assert-css: (".top-doc .docblock summary h4", {"margin-top": "15px", "margin-bottom": "5px"})
+// So `33 + 15 + 5` == `53`
+assert-property: (".top-doc .docblock summary", {"offsetHeight": "53"})
diff --git a/src/test/rustdoc-gui/docblock-table-overflow.goml b/src/test/rustdoc-gui/docblock-table-overflow.goml
new file mode 100644
index 000000000..af76d2ea4
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-table-overflow.goml
@@ -0,0 +1,21 @@
+// This test ensures that the type declaration content overflow is handled inside the <pre> directly.
+goto: file://|DOC_PATH|/lib2/long_table/struct.Foo.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"])
+assert-property: (".top-doc .docblock", {"scrollWidth": "801"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
+
+// Checking it works on other doc blocks as well...
+
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: (
+ "#implementations-list > details .docblock",
+ "#implementations-list > details .docblock > p",
+ ["scrollWidth"],
+)
+assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "801"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1573"})
diff --git a/src/test/rustdoc-gui/duplicate-macro-reexport.goml b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
new file mode 100644
index 000000000..9ea599062
--- /dev/null
+++ b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
@@ -0,0 +1,14 @@
+// This test ensures that there is no macro duplicates in the sidebar.
+goto: file://|DOC_PATH|/test_docs/macro.a.html
+// Waiting for the elements in the sidebar to be rendered.
+wait-for: ".sidebar-elems .macro"
+// Check there is only one macro named "a" listed in the sidebar.
+assert-count: (
+ "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='a']",
+ 1,
+)
+// Check there is only one macro named "b" listed in the sidebar.
+assert-count: (
+ "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='b']",
+ 1,
+)
diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml
new file mode 100644
index 000000000..a5afb037d
--- /dev/null
+++ b/src/test/rustdoc-gui/escape-key.goml
@@ -0,0 +1,35 @@
+// This test ensures that the "Escape" shortcut is handled correctly based on the
+// current content displayed.
+goto: file://|DOC_PATH|/test_docs/index.html
+// First, we check that the search results are hidden when the Escape key is pressed.
+write: (".search-input", "test")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "#search h1" // The search element is empty before the first search
+// Check that the currently displayed element is search.
+wait-for: "#alternative-display #search"
+assert-attribute: ("#main-content", {"class": "content hidden"})
+assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
+press-key: "Escape"
+// Checks that search is no longer in the displayed content.
+wait-for: "#not-displayed #search"
+assert-false: "#alternative-display #search"
+assert-attribute: ("#main-content", {"class": "content"})
+assert-document-property: ({"URL": "index.html"}, [ENDS_WITH])
+
+// Check that focusing the search input brings back the search results
+focus: ".search-input"
+wait-for: "#alternative-display #search"
+assert-attribute: ("#main-content", {"class": "content hidden"})
+assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
+
+// Check that Escape hides the search results when a search result is focused.
+focus: ".search-input"
+assert: ".search-input:focus"
+press-key: "ArrowDown"
+assert-false: ".search-input:focus"
+assert: "#results a:focus"
+press-key: "Escape"
+wait-for: "#not-displayed #search"
+assert-false: "#alternative-display #search"
+assert-attribute: ("#main-content", {"class": "content"})
diff --git a/src/test/rustdoc-gui/font-weight.goml b/src/test/rustdoc-gui/font-weight.goml
new file mode 100644
index 000000000..5f29fde66
--- /dev/null
+++ b/src/test/rustdoc-gui/font-weight.goml
@@ -0,0 +1,44 @@
+// This test checks that the font weight is correctly applied.
+goto: file://|DOC_PATH|/lib2/struct.Foo.html
+assert-css: ("//*[@class='docblock item-decl']//a[text()='Alias']", {"font-weight": "400"})
+assert-css: (
+ "//*[@class='structfield small-section-header']//a[text()='Alias']",
+ {"font-weight": "400"},
+)
+assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"})
+assert-css: ("#associatedtype\.X > .code-header", {"font-weight": "600"})
+assert-css: ("#associatedconstant\.Y > .code-header", {"font-weight": "600"})
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert-css: (".top-doc .docblock p", {"font-weight": "400"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-css: (".impl-items .method", {"font-weight": "600"}, ALL)
+
+goto: file://|DOC_PATH|/lib2/trait.Trait.html
+
+// This is a complex selector, so here's how it works:
+//
+// * //*[@class='docblock item-decl'] — selects element of any tag with classes docblock and item-decl
+// * /pre[@class='rust trait'] — selects immediate child with tag pre and classes rust and trait
+// * /code — selects immediate child with tag code
+// * /a[@class='constant'] — selects immediate child with tag a and class constant
+// * //text() — selects child that is text node
+// * /parent::* — selects immediate parent of the text node (the * means it can be any tag)
+//
+// This uses '/parent::*' as a proxy for the style of the text node.
+// We can't just select the '<a>' because intermediate tags could be added.
+assert-count: (
+ "//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*",
+ 1,
+)
+assert-css: (
+ "//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*",
+ {"font-weight": "400"},
+)
+
+assert-count: (".methods .associatedtype", 1)
+assert-css: (".methods .associatedtype", {"font-weight": "600"})
+assert-count: (".methods .constant", 1)
+assert-css: (".methods .constant", {"font-weight": "600"})
+assert-css: (".methods .method", {"font-weight": "600"})
diff --git a/src/test/rustdoc-gui/hash-item-expansion.goml b/src/test/rustdoc-gui/hash-item-expansion.goml
new file mode 100644
index 000000000..861f69283
--- /dev/null
+++ b/src/test/rustdoc-gui/hash-item-expansion.goml
@@ -0,0 +1,11 @@
+// This test ensures that the element corresponding to the hash is displayed.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.borrow
+// In the blanket implementations list, "Borrow" is the second one, hence the ":nth(2)".
+assert-attribute: ("#blanket-implementations-list > details:nth-child(2)", {"open": ""})
+// We first check that the impl block is open by default.
+assert-attribute: ("#implementations-list details", {"open": ""})
+// To ensure that we will click on the currently hidden method.
+assert-text: (".sidebar-elems section .block li > a", "must_use")
+click: ".sidebar-elems section .block li > a"
+// We check that the impl block was opened as expected so that we can see the method.
+assert-attribute: ("#implementations-list > details", {"open": ""})
diff --git a/src/test/rustdoc-gui/headers-color.goml b/src/test/rustdoc-gui/headers-color.goml
new file mode 100644
index 000000000..a47a9c8a1
--- /dev/null
+++ b/src/test/rustdoc-gui/headers-color.goml
@@ -0,0 +1,117 @@
+// This test check for headers text and background colors for the different themes.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+
+// This is needed so that the text color is computed.
+show-text: true
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-preferred-dark-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".impl",
+ {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
+ ALL,
+)
+assert-css: (
+ ".impl .code-header",
+ {"color": "rgb(230, 225, 207)", "background-color": "rgb(15, 20, 25)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
+assert-css: (
+ "#impl-Foo",
+ {"color": "rgb(197, 197, 197)", "background-color": "rgba(255, 236, 164, 0.06)"},
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use
+assert-css: (
+ "#method\.must_use",
+ {"color": "rgb(197, 197, 197)", "background-color": "rgba(255, 236, 164, 0.06)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (".small-section-header a", {"color": "rgb(197, 197, 197)"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+// We select headings (h2, h3, h...).
+assert-css: (".docblock > :not(p) > a", {"color": "rgb(57, 175, 215)"}, ALL)
+
+// Dark theme
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+
+assert-css: (
+ ".impl",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+ ALL,
+)
+assert-css: (
+ ".impl .code-header",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(53, 53, 53)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
+assert-css: (
+ "#impl-Foo",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(73, 74, 61)"},
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use
+assert-css: (
+ "#method\.must_use",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(73, 74, 61)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (".small-section-header a", {"color": "rgb(221, 221, 221)"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+// We select headings (h2, h3, h...).
+assert-css: (".docblock > :not(p) > a", {"color": "rgb(210, 153, 29)"}, ALL)
+
+// Light theme
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+
+assert-css: (
+ ".impl",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+ ALL,
+)
+assert-css: (
+ ".impl .code-header",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
+assert-css: ("#impl-Foo", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"})
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use
+assert-css: (
+ "#method\.must_use",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"},
+ ALL,
+)
+
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (".small-section-header a", {"color": "rgb(0, 0, 0)"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+// We select headings (h2, h3, h...).
+assert-css: (".docblock > :not(p) > a", {"color": "rgb(56, 115, 173)"}, ALL)
diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml
new file mode 100644
index 000000000..8c2c3df15
--- /dev/null
+++ b/src/test/rustdoc-gui/headings.goml
@@ -0,0 +1,258 @@
+// This test checks that headers (a) have the correct heading level, (b) are the right size,
+// and (c) have the correct underlining (or absence of underlining).
+// The sizes may change as design changes, but try to make sure a lower header is never bigger than
+// its parent headers. Also make sure lower headers don't have underlines when their parents lack
+// an underline.
+// Most of these sizes are set in CSS in `em` units, so here's a conversion chart based on our
+// default 16px font size:
+// 24px 1.5em
+// 22px 1.375rem
+// 20px 1.25rem
+// 18px 1.125em
+// 16px 1rem
+// 14px 0.875rem
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+
+assert-css: ("h1.fqn", {"font-size": "24px"})
+
+assert-css: ("h2#top-doc-prose-title", {"font-size": "22px"})
+assert-css: ("h2#top-doc-prose-title", {"border-bottom-width": "1px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"font-size": "20px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"border-bottom-width": "1px"})
+assert-css: ("h4#top-doc-prose-sub-sub-heading", {"font-size": "18px"})
+assert-css: ("h4#top-doc-prose-sub-sub-heading", {"border-bottom-width": "1px"})
+
+assert-css: ("h2#fields", {"font-size": "22px"})
+assert-css: ("h2#fields", {"border-bottom-width": "1px"})
+assert-css: ("h3#title-for-field", {"font-size": "20px"})
+assert-css: ("h3#title-for-field", {"border-bottom-width": "0px"})
+assert-css: ("h4#sub-heading-for-field", {"font-size": "16px"})
+assert-css: ("h4#sub-heading-for-field", {"border-bottom-width": "0px"})
+
+assert-css: ("h2#implementations", {"font-size": "22px"})
+assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
+
+assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"font-size": "18px"})
+assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"border-bottom-width": "0px"})
+assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
+assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
+
+assert-css: ("h4#title-for-struct-impl-doc", {"font-size": "16px"})
+assert-css: ("h4#title-for-struct-impl-doc", {"border-bottom-width": "0px"})
+assert-css: ("h5#sub-heading-for-struct-impl-doc", {"font-size": "16px"})
+assert-css: ("h5#sub-heading-for-struct-impl-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-sub-heading-for-struct-impl-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-sub-heading-for-struct-impl-doc", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#title-for-struct-impl-item-doc", {"font-size": "16px"})
+assert-css: ("h5#title-for-struct-impl-item-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-heading-for-struct-impl-item-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-heading-for-struct-impl-item-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-sub-heading-for-struct-impl-item-doc", {"font-size": "14px"})
+
+goto: file://|DOC_PATH|/test_docs/enum.HeavilyDocumentedEnum.html
+
+assert-css: ("h1.fqn", {"font-size": "24px"})
+
+assert-css: ("h2#top-doc-prose-title", {"font-size": "22px"})
+assert-css: ("h2#top-doc-prose-title", {"border-bottom-width": "1px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"font-size": "20px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"border-bottom-width": "1px"})
+assert-css: ("h4#top-doc-prose-sub-sub-heading", {"font-size": "18px"})
+assert-css: ("h4#top-doc-prose-sub-sub-heading", {"border-bottom-width": "1px"})
+
+assert-css: ("h2#variants", {"font-size": "22px"})
+assert-css: ("h2#variants", {"border-bottom-width": "1px"})
+
+assert-css: ("h4#none-prose-title", {"font-size": "16px"})
+assert-css: ("h4#none-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h5#none-prose-sub-heading", {"font-size": "16px"})
+assert-css: ("h5#none-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h4#wrapped-prose-title", {"font-size": "16px"})
+assert-css: ("h4#wrapped-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h5#wrapped-prose-sub-heading", {"font-size": "16px"})
+assert-css: ("h5#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#wrapped0-prose-title", {"font-size": "16px"})
+assert-css: ("h5#wrapped0-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h6#wrapped0-prose-sub-heading", {"font-size": "14px"})
+assert-css: ("h6#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#structy-prose-title", {"font-size": "16px"})
+assert-css: ("h5#structy-prose-title", {"border-bottom-width": "0px"})
+assert-css: ("h6#structy-prose-sub-heading", {"font-size": "14px"})
+assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})
+
+assert-css: ("h2#implementations", {"font-size": "22px"})
+assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
+
+assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"font-size": "18px"})
+assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"border-bottom-width": "0px"})
+assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
+assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
+
+assert-css: ("h4#title-for-enum-impl-doc", {"font-size": "16px"})
+assert-css: ("h4#title-for-enum-impl-doc", {"border-bottom-width": "0px"})
+assert-css: ("h5#sub-heading-for-enum-impl-doc", {"font-size": "16px"})
+assert-css: ("h5#sub-heading-for-enum-impl-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-sub-heading-for-enum-impl-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-sub-heading-for-enum-impl-doc", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#title-for-enum-impl-item-doc", {"font-size": "16px"})
+assert-css: ("h5#title-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-heading-for-enum-impl-item-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
+
+assert-text: (".sidebar .mod h3", "Modules")
+assert-css: (".sidebar .mod h3", {"border-bottom-width": "0px"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/union.HeavilyDocumentedUnion.html
+
+assert-css: ("h1.fqn", {"font-size": "24px"})
+
+assert-css: ("h2#top-doc-prose-title", {"font-size": "22px"})
+assert-css: ("h2#top-doc-prose-title", {"border-bottom-width": "1px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"font-size": "20px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"border-bottom-width": "1px"})
+
+assert-css: ("h2#fields", {"font-size": "22px"})
+assert-css: ("h2#fields", {"border-bottom-width": "1px"})
+
+assert-css: ("h3#title-for-union-variant", {"font-size": "20px"})
+assert-css: ("h3#title-for-union-variant", {"border-bottom-width": "0px"})
+assert-css: ("h4#sub-heading-for-union-variant", {"font-size": "16px"})
+assert-css: ("h4#sub-heading-for-union-variant", {"border-bottom-width": "0px"})
+
+assert-css: ("h2#implementations", {"font-size": "22px"})
+assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
+
+assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"font-size": "18px"})
+assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"border-bottom-width": "0px"})
+assert-css: ("h4#title-for-union-impl-doc", {"font-size": "16px"})
+assert-css: ("h4#title-for-union-impl-doc", {"border-bottom-width": "0px"})
+assert-css: ("h5#sub-heading-for-union-impl-doc", {"font-size": "16px"})
+assert-css: ("h5#sub-heading-for-union-impl-doc", {"border-bottom-width": "0px"})
+
+assert-css: ("h5#title-for-union-impl-item-doc", {"font-size": "16px"})
+assert-css: ("h5#title-for-union-impl-item-doc", {"border-bottom-width": "0px"})
+assert-css: ("h6#sub-heading-for-union-impl-item-doc", {"font-size": "14px"})
+assert-css: ("h6#sub-heading-for-union-impl-item-doc", {"border-bottom-width": "0px"})
+
+goto: file://|DOC_PATH|/test_docs/macro.heavily_documented_macro.html
+
+assert-css: ("h1.fqn", {"font-size": "24px"})
+
+assert-css: ("h2#top-doc-prose-title", {"font-size": "22px"})
+assert-css: ("h2#top-doc-prose-title", {"border-bottom-width": "1px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"font-size": "20px"})
+assert-css: ("h3#top-doc-prose-sub-heading", {"border-bottom-width": "1px"})
+
+// Checking colors now.
+show-text: true
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
+assert-css: (
+ ".top-doc .docblock h2",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "1px solid rgb(221, 221, 221)"},
+)
+assert-css: (
+ ".top-doc .docblock h3",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "1px solid rgb(221, 221, 221)"},
+)
+assert-css: (
+ ".top-doc .docblock h4",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "1px solid rgb(221, 221, 221)"},
+)
+assert-css: (
+ ".top-doc .docblock h5",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "0px none rgb(221, 221, 221)"},
+)
+assert-css: (
+ "#implementations-list .docblock h4",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "0px none rgb(221, 221, 221)"},
+)
+assert-css: (
+ "#implementations-list .docblock h5",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "0px none rgb(221, 221, 221)"},
+)
+assert-css: (
+ "#implementations-list .docblock h6",
+ {"color": "rgb(0, 0, 0)", "border-bottom": "0px none rgb(221, 221, 221)"},
+)
+
+local-storage: {"rustdoc-theme": "dark"}
+reload:
+assert-css: (
+ ".top-doc .docblock h2",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "1px solid rgb(210, 210, 210)"},
+)
+assert-css: (
+ ".top-doc .docblock h3",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "1px solid rgb(210, 210, 210)"},
+)
+assert-css: (
+ ".top-doc .docblock h4",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "1px solid rgb(210, 210, 210)"},
+)
+assert-css: (
+ ".top-doc .docblock h5",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "0px none rgb(210, 210, 210)"},
+)
+assert-css: (
+ "#implementations-list .docblock h4",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "0px none rgb(210, 210, 210)"},
+)
+assert-css: (
+ "#implementations-list .docblock h5",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "0px none rgb(210, 210, 210)"},
+)
+assert-css: (
+ "#implementations-list .docblock h6",
+ {"color": "rgb(221, 221, 221)", "border-bottom": "0px none rgb(210, 210, 210)"},
+)
+
+local-storage: {"rustdoc-theme": "ayu"}
+reload:
+assert-css: (
+ ".top-doc .docblock h2",
+ {"color": "rgb(255, 255, 255)", "border-bottom": "1px solid rgb(92, 103, 115)"},
+)
+assert-css: (
+ ".top-doc .docblock h2",
+ {"color": "rgb(255, 255, 255)", "border-bottom": "1px solid rgb(92, 103, 115)"},
+)
+assert-css: (
+ ".top-doc .docblock h4",
+ {"color": "rgb(255, 255, 255)", "border-bottom": "1px solid rgb(92, 103, 115)"},
+)
+assert-css: (
+ ".top-doc .docblock h5",
+ {"color": "rgb(197, 197, 197)", "border-bottom": "0px none rgb(92, 103, 115)"},
+)
+assert-css: (
+ "#implementations-list .docblock h4",
+ {"color": "rgb(255, 255, 255)", "border-bottom": "0px none rgb(92, 103, 115)"},
+)
+assert-css: (
+ "#implementations-list .docblock h5",
+ {"color": "rgb(197, 197, 197)", "border-bottom": "0px none rgb(92, 103, 115)"},
+)
+assert-css: (
+ "#implementations-list .docblock h6",
+ {"color": "rgb(197, 197, 197)", "border-bottom": "0px none rgb(92, 103, 115)"},
+)
+
+local-storage: {"rustdoc-theme": "light"}
+goto: file://|DOC_PATH|/staged_api/struct.Foo.html
+assert-css: (".since", {"color": "rgb(128, 128, 128)"})
+
+local-storage: {"rustdoc-theme": "dark"}
+reload:
+assert-css: (".since", {"color": "rgb(128, 128, 128)"})
+
+local-storage: {"rustdoc-theme": "ayu"}
+reload:
+assert-css: (".since", {"color": "rgb(128, 128, 128)"})
diff --git a/src/test/rustdoc-gui/huge-collection-of-constants.goml b/src/test/rustdoc-gui/huge-collection-of-constants.goml
new file mode 100644
index 000000000..4f75b5841
--- /dev/null
+++ b/src/test/rustdoc-gui/huge-collection-of-constants.goml
@@ -0,0 +1,9 @@
+// Make sure that the last two entries are more than 12 pixels apart and not stacked on each other.
+
+goto: file://|DOC_PATH|/test_docs/huge_amount_of_consts/index.html
+
+compare-elements-position-near-false: (
+ "//*[@class='item-table']//div[last()-1]",
+ "//*[@class='item-table']//div[last()-3]",
+ {"y": 12},
+)
diff --git a/src/test/rustdoc-gui/impl-default-expansion.goml b/src/test/rustdoc-gui/impl-default-expansion.goml
new file mode 100644
index 000000000..6df2661e6
--- /dev/null
+++ b/src/test/rustdoc-gui/impl-default-expansion.goml
@@ -0,0 +1,3 @@
+// This test ensures that the impl blocks are open by default.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-attribute: ("#implementations-list details.implementors-toggle", {"open": ""})
diff --git a/src/test/rustdoc-gui/implementors.goml b/src/test/rustdoc-gui/implementors.goml
new file mode 100644
index 000000000..666a6e125
--- /dev/null
+++ b/src/test/rustdoc-gui/implementors.goml
@@ -0,0 +1,35 @@
+// The goal of this test is to check that the external trait implementors, generated with JS,
+// have the same display than the "local" ones.
+goto: file://|DOC_PATH|/implementors/trait.Whatever.html
+assert: "#implementors-list"
+// There are supposed to be two implementors listed.
+assert-count: ("#implementors-list .impl", 2)
+// Now we check that both implementors have an anchor, an ID and a similar DOM.
+assert: ("#implementors-list .impl:nth-child(1) > a.anchor")
+assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"})
+assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"})
+assert: "#implementors-list .impl:nth-child(1) > .code-header.in-band"
+
+assert: ("#implementors-list .impl:nth-child(2) > a.anchor")
+assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"})
+assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
+assert: "#implementors-list .impl:nth-child(2) > .code-header.in-band"
+
+goto: file://|DOC_PATH|/test_docs/struct.HasEmptyTraits.html
+compare-elements-position-near-false: (
+ "#impl-EmptyTrait1-for-HasEmptyTraits",
+ "#impl-EmptyTrait2-for-HasEmptyTraits",
+ {"y": 30},
+)
+compare-elements-position-near: (
+ "#impl-EmptyTrait3-for-HasEmptyTraits h3",
+ "#impl-EmptyTrait3-for-HasEmptyTraits .item-info",
+ {"y": 30},
+)
+
+// Now check that re-exports work correctly.
+// There should be exactly one impl shown on both of these pages.
+goto: file://|DOC_PATH|/lib2/trait.TraitToReexport.html
+assert-count: ("#implementors-list .impl", 1)
+goto: file://|DOC_PATH|/implementors/trait.TraitToReexport.html
+assert-count: ("#implementors-list .impl", 1)
diff --git a/src/test/rustdoc-gui/item-info-overflow.goml b/src/test/rustdoc-gui/item-info-overflow.goml
new file mode 100644
index 000000000..b7095a3c5
--- /dev/null
+++ b/src/test/rustdoc-gui/item-info-overflow.goml
@@ -0,0 +1,31 @@
+// This test ensures that the "item-info" elements don't overflow.
+goto: file://|DOC_PATH|/lib2/struct.LongItemInfo.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1200, 870)
+// Logically, the "item-decl" and the "item-info" should have the same scroll width.
+compare-elements-property: (".docblock.item-decl", ".item-info", ["scrollWidth"])
+assert-property: (".item-info", {"scrollWidth": "890"})
+// Just to be sure we're comparing the correct "item-info":
+assert-text: (
+ ".item-info",
+ "Available on Android or Linux or Emscripten or DragonFly BSD",
+ STARTS_WITH,
+)
+
+// Checking the "item-info" on an impl block as well:
+goto: file://|DOC_PATH|/lib2/struct.LongItemInfo2.html
+compare-elements-property: (
+ "#impl-SimpleTrait-for-LongItemInfo2 .item-info",
+ "#impl-SimpleTrait-for-LongItemInfo2 + .docblock",
+ ["scrollWidth"],
+)
+assert-property: (
+ "#impl-SimpleTrait-for-LongItemInfo2 .item-info",
+ {"scrollWidth": "866"},
+)
+// Just to be sure we're comparing the correct "item-info":
+assert-text: (
+ "#impl-SimpleTrait-for-LongItemInfo2 .item-info",
+ "Available on Android or Linux or Emscripten or DragonFly BSD",
+ STARTS_WITH,
+)
diff --git a/src/test/rustdoc-gui/item-info.goml b/src/test/rustdoc-gui/item-info.goml
new file mode 100644
index 000000000..50c45b76b
--- /dev/null
+++ b/src/test/rustdoc-gui/item-info.goml
@@ -0,0 +1,32 @@
+// This test ensures a few things for item info elements.
+goto: file://|DOC_PATH|/lib2/struct.Foo.html
+// Ensuring that the item information don't take 100% of the width if unnecessary.
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// We check that ".item-info" is bigger than its content.
+assert-css: (".item-info", {"width": "790px"})
+assert-css: (".item-info .stab", {"width": "289px"})
+assert-position: (".item-info .stab", {"x": 295})
+
+// Now we ensure that they're not rendered on the same line.
+goto: file://|DOC_PATH|/lib2/trait.Trait.html
+// We first ensure that there are two item info on the trait.
+assert-count: ("#main-content > .item-info .stab", 2)
+// They should not have the same `y` position!
+compare-elements-position-false: (
+ "#main-content > .item-info .stab:nth-of-type(1)",
+ "#main-content > .item-info .stab:nth-of-type(2)",
+ ("y"),
+)
+// But they should have the same `x` position.
+compare-elements-position: (
+ "#main-content > .item-info .stab:nth-of-type(1)",
+ "#main-content > .item-info .stab:nth-of-type(2)",
+ ("x"),
+)
+// They are supposed to have the same height too.
+compare-elements-css: (
+ "#main-content > .item-info .stab:nth-of-type(1)",
+ "#main-content > .item-info .stab:nth-of-type(2)",
+ ["height"],
+)
diff --git a/src/test/rustdoc-gui/item-summary-table.goml b/src/test/rustdoc-gui/item-summary-table.goml
new file mode 100644
index 000000000..6bf4e288c
--- /dev/null
+++ b/src/test/rustdoc-gui/item-summary-table.goml
@@ -0,0 +1,6 @@
+// This test ensures that <table> elements aren't display in items summary.
+goto: file://|DOC_PATH|/lib2/summary_table/index.html
+// We check that we picked the right item first.
+assert-text: (".item-table .item-left", "Foo")
+// Then we check that its summary is empty.
+assert-text: (".item-table .item-right", "")
diff --git a/src/test/rustdoc-gui/javascript-disabled.goml b/src/test/rustdoc-gui/javascript-disabled.goml
new file mode 100644
index 000000000..1693f7b64
--- /dev/null
+++ b/src/test/rustdoc-gui/javascript-disabled.goml
@@ -0,0 +1,6 @@
+// When JavaScript is disabled, we hide the search bar, because it
+// can't be used without JS.
+javascript: false
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-css: (".sub", {"display": "none"})
diff --git a/src/test/rustdoc-gui/jump-to-def-background.goml b/src/test/rustdoc-gui/jump-to-def-background.goml
new file mode 100644
index 000000000..d17400f5b
--- /dev/null
+++ b/src/test/rustdoc-gui/jump-to-def-background.goml
@@ -0,0 +1,43 @@
+// We check the background color on the jump to definition links in the source code page.
+goto: file://|DOC_PATH|/src/link_to_definition/lib.rs.html
+
+// Set the theme to dark.
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (
+ "body.source .example-wrap pre.rust a",
+ {"background-color": "rgb(51, 51, 51)"},
+ ALL,
+)
+
+// Set the theme to ayu.
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-preferred-dark-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (
+ "body.source .example-wrap pre.rust a",
+ {"background-color": "rgb(51, 51, 51)"},
+ ALL,
+)
+
+// Set the theme to light.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-css: (
+ "body.source .example-wrap pre.rust a",
+ {"background-color": "rgb(238, 238, 238)"},
+ ALL,
+)
diff --git a/src/test/rustdoc-gui/label-next-to-symbol.goml b/src/test/rustdoc-gui/label-next-to-symbol.goml
new file mode 100644
index 000000000..ca3994a08
--- /dev/null
+++ b/src/test/rustdoc-gui/label-next-to-symbol.goml
@@ -0,0 +1,78 @@
+// These tests verify that labels like "UNIX" and "Deprecated" stay on the same line as their symbol.
+// It also verifies the staggered layout on mobile.
+goto: file://|DOC_PATH|/test_docs/index.html
+
+// Desktop view
+size: (1080, 600)
+assert: (".stab.deprecated")
+assert: (".stab.portability")
+
+// make sure that deprecated and portability are different colours
+assert-css: (
+ ".item-table .item-left .stab.deprecated",
+ { "background-color": "rgb(255, 196, 196)" },
+)
+assert-css: (
+ ".item-table .item-left .stab.portability",
+ { "background-color": "rgb(243, 223, 255)" },
+)
+
+// table like view
+assert-css: (".item-right.docblock-short", { "padding-left": "0px" })
+compare-elements-position-near: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']",
+ ".item-left .stab.deprecated",
+ {"y": 2},
+)
+compare-elements-position: (
+ ".item-left .stab.deprecated",
+ ".item-left .stab.portability",
+ ("y"),
+)
+
+// Ensure no wrap
+compare-elements-position-near: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']",
+ "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
+ {"y": 2},
+)
+// compare parent elements
+compare-elements-position: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']/..",
+ "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..",
+ ("y"),
+)
+
+
+// Mobile view
+size: (600, 600)
+// staggered layout with 2em spacing
+assert-css: (".item-right.docblock-short", { "padding-left": "32px" })
+compare-elements-position-near: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']",
+ ".item-left .stab.deprecated",
+ {"y": 1},
+)
+compare-elements-position: (
+ ".item-left .stab.deprecated",
+ ".item-left .stab.portability",
+ ("y"),
+)
+
+// Ensure wrap
+compare-elements-position-near-false: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']",
+ "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
+ {"y": 12},
+)
+// compare parent elements
+compare-elements-position-false: (
+ "//*[@class='item-left module-item']//a[text()='replaced_function']/..",
+ "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..",
+ ("y"),
+)
+compare-elements-position-false: (
+ ".item-left .stab.deprecated",
+ "//*[@class='item-right docblock-short']//p[text()='a thing with a label']",
+ ("y"),
+)
diff --git a/src/test/rustdoc-gui/list_code_block.goml b/src/test/rustdoc-gui/list_code_block.goml
new file mode 100644
index 000000000..eba1a662b
--- /dev/null
+++ b/src/test/rustdoc-gui/list_code_block.goml
@@ -0,0 +1,4 @@
+// This test checks that code blocks in list are supported.
+goto: file://|DOC_PATH|/test_docs/index.html
+goto: ./fn.check_list_code_block.html
+assert: ("pre.rust.fn")
diff --git a/src/test/rustdoc-gui/mobile.goml b/src/test/rustdoc-gui/mobile.goml
new file mode 100644
index 000000000..13b9b563d
--- /dev/null
+++ b/src/test/rustdoc-gui/mobile.goml
@@ -0,0 +1,30 @@
+// Test various properties of the mobile UI
+goto: file://|DOC_PATH|/staged_api/struct.Foo.html
+size: (400, 600)
+
+font-size: 18
+wait-for: 100 // wait a bit for the resize and the font-size change to be fully taken into account.
+
+// The out-of-band info (source, stable version, collapse) should be below the
+// h1 when the screen gets narrow enough.
+assert-css: (".main-heading", {
+ "display": "flex",
+ "flex-direction": "column"
+})
+
+assert-property: (".mobile-topbar h2.location", {"offsetHeight": 36})
+
+// Note: We can't use assert-text here because the 'Since' is set by CSS and
+// is therefore not part of the DOM.
+assert-css: (".content .out-of-band .since::before", { "content": "\"Since \"" })
+
+size: (1000, 1000)
+wait-for: 100 // wait a bit for the resize to be fully taken into account.
+assert-css-false: (".content .out-of-band .since::before", { "content": "\"Since \"" })
+
+// On the settings page, the theme buttons should not line-wrap. Instead, they should
+// all be placed as a group on a line below the setting name "Theme."
+goto: file://|DOC_PATH|/settings.html
+size: (400, 600)
+// Ignored for now https://github.com/rust-lang/rust/issues/93784.
+// compare-elements-position-near-false: ("#preferred-light-theme .setting-name", "#preferred-light-theme .choice", {"y": 16})
diff --git a/src/test/rustdoc-gui/module-items-font.goml b/src/test/rustdoc-gui/module-items-font.goml
new file mode 100644
index 000000000..758ee391a
--- /dev/null
+++ b/src/test/rustdoc-gui/module-items-font.goml
@@ -0,0 +1,67 @@
+// This test checks that the correct font is used on module items (in index.html pages).
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (
+ ".item-table .module-item a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+ ALL,
+)
+assert-css: (
+ ".item-table .docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+ ALL,
+)
+
+// modules
+assert-css: (
+ "#modules + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#modules + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
+// structs
+assert-css: (
+ "#structs + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#structs + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
+// enums
+assert-css: (
+ "#enums + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#enums + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
+// traits
+assert-css: (
+ "#traits + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#traits + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
+// functions
+assert-css: (
+ "#functions + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#functions + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
+// keywords
+assert-css: (
+ "#keywords + .item-table .item-left a",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+ "#keywords + .item-table .item-right.docblock-short",
+ {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
diff --git a/src/test/rustdoc-gui/overflow-tooltip-information.goml b/src/test/rustdoc-gui/overflow-tooltip-information.goml
new file mode 100644
index 000000000..7ef85a4c4
--- /dev/null
+++ b/src/test/rustdoc-gui/overflow-tooltip-information.goml
@@ -0,0 +1,8 @@
+// The goal of this test is to ensure that the tooltip `.information` class doesn't
+// have overflow and max-width CSS rules set because they create a bug in firefox on
+// mac. For more information: https://github.com/rust-lang/rust/issues/89185
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+assert-css: (".docblock > .information", {
+ "overflow-x": "visible",
+ "max-width": "none"
+}, ALL)
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
new file mode 100644
index 000000000..54f3790a7
--- /dev/null
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -0,0 +1,77 @@
+// This test ensures that the "pocket menus" are working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+// First we check that the help menu doesn't exist yet.
+assert-false: "#help-button .popover"
+// Then we display the help menu.
+click: "#help-button"
+assert: "#help-button .popover"
+assert-css: ("#help-button .popover", {"display": "block"})
+
+// Now we click somewhere else on the page to ensure it is handling the blur event
+// correctly.
+click: ".sidebar"
+assert-css: ("#help-button .popover", {"display": "none"})
+
+// Now we will check that we cannot have two "pocket menus" displayed at the same time.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+click: "#settings-menu"
+assert-css: ("#help-button .popover", {"display": "none"})
+assert-css: ("#settings-menu .popover", {"display": "block"})
+
+// Now the other way.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
+// Now verify that clicking the help menu again closes it.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "none"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
+// We check the borders color now:
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(92, 103, 115)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Dark theme
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(210, 210, 210)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Light theme
+local-storage: {
+ "rustdoc-theme": "light",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+ "#help-button .popover",
+ {"display": "block", "border-color": "rgb(221, 221, 221)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
diff --git a/src/test/rustdoc-gui/run-on-hover.goml b/src/test/rustdoc-gui/run-on-hover.goml
new file mode 100644
index 000000000..b8efa8e30
--- /dev/null
+++ b/src/test/rustdoc-gui/run-on-hover.goml
@@ -0,0 +1,7 @@
+// Example code blocks sometimes have a "Run" button to run them on the
+// Playground. That button is hidden until the user hovers over the code block.
+// This test checks that it is hidden, and that it shows on hover.
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+assert-css: (".test-arrow", {"visibility": "hidden"})
+move-cursor-to: ".example-wrap"
+assert-css: (".test-arrow", {"visibility": "visible"})
diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml
new file mode 100644
index 000000000..4a9dcf735
--- /dev/null
+++ b/src/test/rustdoc-gui/rust-logo.goml
@@ -0,0 +1,78 @@
+// This test ensures that the correct style is applied to the rust logo in the sidebar.
+goto: file://|DOC_PATH|/test_docs/index.html
+
+// First we start with the dark theme.
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"},
+)
+
+// In the source view page now.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"},
+)
+
+// Then with the ayu theme.
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-preferred-dark-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"},
+)
+
+// In the source view page now.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-preferred-dark-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"},
+)
+
+// And finally with the light theme.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "none"},
+)
+
+// In the source view page now.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+
+assert-css: (
+ ".rust-logo",
+ {"filter": "none"},
+)
diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml
new file mode 100644
index 000000000..d645e2370
--- /dev/null
+++ b/src/test/rustdoc-gui/search-filter.goml
@@ -0,0 +1,83 @@
+// Checks that the crate search filtering is handled correctly and changes the results.
+goto: file://|DOC_PATH|/test_docs/index.html
+show-text: true
+write: (".search-input", "test")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-text: ("#results .externcrate", "test_docs")
+
+wait-for: "#crate-search"
+// We now want to change the crate filter.
+click: "#crate-search"
+// We select "lib2" option then press enter to change the filter.
+press-key: "ArrowDown"
+press-key: "ArrowDown"
+press-key: "Enter"
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-document-property: ({"URL": "&filter-crate="}, CONTAINS)
+// We check that there is no more "test_docs" appearing.
+assert-false: "#results .externcrate"
+// We also check that "lib2" is the filter crate.
+assert-property: ("#crate-search", {"value": "lib2"})
+
+// Now we check that leaving the search results and putting them back keeps the
+// crate filtering.
+press-key: "Escape"
+wait-for-css: ("#main-content", {"display": "block"})
+focus: ".search-input"
+wait-for-css: ("#main-content", {"display": "none"})
+// We check that there is no more "test_docs" appearing.
+assert-false: "#results .externcrate"
+assert-property: ("#crate-search", {"value": "lib2"})
+
+// Selecting back "All crates"
+click: "#crate-search"
+press-key: "ArrowUp"
+press-key: "ArrowUp"
+press-key: "Enter"
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-property: ("#crate-search", {"value": "All crates"})
+
+// Checking that the URL parameter is taken into account for crate filtering.
+goto: file://|DOC_PATH|/test_docs/index.html?search=test&filter-crate=lib2
+wait-for: "#crate-search"
+assert-property: ("#crate-search", {"value": "lib2"})
+assert-false: "#results .externcrate"
+
+// Checking that the text for the "title" is correct (the "All" comes from the "<select>").
+assert-text: ("#search-settings", "Results for test in All", STARTS_WITH)
+
+// Checking the display of the crate filter.
+// We start with the light theme.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+
+timeout: 2000
+wait-for: "#crate-search"
+assert-css: ("#crate-search", {
+ "border": "1px solid rgb(224, 224, 224)",
+ "color": "rgb(0, 0, 0)",
+ "background-color": "rgb(255, 255, 255)",
+})
+
+// We now check the dark theme.
+click: "#settings-menu"
+wait-for: "#settings"
+click: "#theme-dark"
+wait-for-css: ("#crate-search", {
+ "border": "1px solid rgb(240, 240, 240)",
+ "color": "rgb(17, 17, 17)",
+ "background-color": "rgb(240, 240, 240)",
+})
+
+// And finally we check the ayu theme.
+click: "#theme-ayu"
+wait-for-css: ("#crate-search", {
+ "border": "1px solid rgb(66, 76, 87)",
+ "color": "rgb(197, 197, 197)",
+ "background-color": "rgb(20, 25, 32)",
+})
diff --git a/src/test/rustdoc-gui/search-input-mobile.goml b/src/test/rustdoc-gui/search-input-mobile.goml
new file mode 100644
index 000000000..5c95db70a
--- /dev/null
+++ b/src/test/rustdoc-gui/search-input-mobile.goml
@@ -0,0 +1,11 @@
+// Test to ensure that you can click on the search input, whatever the width.
+// The PR which fixed it is: https://github.com/rust-lang/rust/pull/81592
+goto: file://|DOC_PATH|/test_docs/index.html
+size: (463, 700)
+// We first check that the search input isn't already focused.
+assert-false: ("input.search-input:focus")
+click: "input.search-input"
+reload:
+size: (750, 700)
+click: "input.search-input"
+assert: ("input.search-input:focus")
diff --git a/src/test/rustdoc-gui/search-input.goml b/src/test/rustdoc-gui/search-input.goml
new file mode 100644
index 000000000..44123b702
--- /dev/null
+++ b/src/test/rustdoc-gui/search-input.goml
@@ -0,0 +1,23 @@
+// Ensures that the search input border color changes on focus.
+goto: file://|DOC_PATH|/test_docs/index.html
+local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
+reload:
+
+assert-css: (".search-input", {"border-color": "rgb(224, 224, 224)"})
+click: ".search-input"
+focus: ".search-input"
+assert-css: (".search-input", {"border-color": "rgb(0, 141, 253)"})
+
+local-storage: {"rustdoc-theme": "light"}
+reload:
+
+assert-css: (".search-input", {"border-color": "rgb(224, 224, 224)"})
+click: ".search-input"
+assert-css: (".search-input", {"border-color": "rgb(102, 175, 233)"})
+
+local-storage: {"rustdoc-theme": "ayu"}
+reload:
+
+assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
+click: ".search-input"
+assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
diff --git a/src/test/rustdoc-gui/search-reexport.goml b/src/test/rustdoc-gui/search-reexport.goml
new file mode 100644
index 000000000..5ef890d47
--- /dev/null
+++ b/src/test/rustdoc-gui/search-reexport.goml
@@ -0,0 +1,33 @@
+// Checks that the reexports are present in the search index, can have
+// doc aliases and are highligted when their ID is the hash of the page.
+goto: file://|DOC_PATH|/test_docs/index.html
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+// First we check that the reexport has the correct ID and no background color.
+assert-text: ("//*[@id='reexport.TheStdReexport']", "pub use ::std as TheStdReexport;")
+assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0, 0, 0, 0)"})
+write: (".search-input", "TheStdReexport")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "//a[@class='result-import']"
+assert-attribute: (
+ "//a[@class='result-import']",
+ {"href": "../test_docs/index.html#reexport.TheStdReexport"},
+)
+assert-text: ("//a[@class='result-import']", "test_docs::TheStdReexport")
+click: "//a[@class='result-import']"
+// We check that it has the background modified thanks to the focus.
+wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"})
+
+// We now check that the alias is working as well on the reexport.
+// To be SURE that the search will be run.
+press-key: 'Enter'
+write: (".search-input", "AliasForTheStdReexport")
+wait-for: "//a[@class='result-import']"
+assert-text: (
+ "//a[@class='result-import']",
+ "AliasForTheStdReexport - see test_docs::TheStdReexport",
+)
+// Same thing again, we click on it to ensure the background is once again set as expected.
+click: "//a[@class='result-import']"
+wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"})
diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml
new file mode 100644
index 000000000..9a49ae2c6
--- /dev/null
+++ b/src/test/rustdoc-gui/search-result-color.goml
@@ -0,0 +1,98 @@
+// The goal of this test is to ensure the color of the text is the one expected.
+goto: file://|DOC_PATH|/test_docs/index.html?search=coo
+
+// This is needed so that the text color is computed.
+show-text: true
+
+// Ayu theme
+local-storage: {
+ "rustdoc-theme": "ayu",
+ "rustdoc-preferred-dark-theme": "ayu",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-css: (
+ "//*[@class='desc']//*[text()='Just a normal struct.']",
+ {"color": "rgb(197, 197, 197)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(0, 150, 207)"},
+)
+
+// Checking the color for "keyword".
+assert-css: (
+ "//*[@class='result-name']//*[text()='(keyword)']",
+ {"color": "rgb(120, 135, 151)"},
+)
+
+// Dark theme
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+reload:
+
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-css: (
+ "//*[@class='desc']//*[text()='Just a normal struct.']",
+ {"color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(221, 221, 221)"},
+)
+
+// Checking the color for "keyword".
+assert-css: (
+ "//*[@class='result-name']//*[text()='(keyword)']",
+ {"color": "rgb(221, 221, 221)"},
+)
+
+// Light theme
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-css: (
+ "//*[@class='desc']//*[text()='Just a normal struct.']",
+ {"color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+ "//*[@class='result-name']/*[text()='test_docs::']",
+ {"color": "rgb(0, 0, 0)"},
+)
+
+// Checking the color for "keyword".
+assert-css: (
+ "//*[@class='result-name']//*[text()='(keyword)']",
+ {"color": "rgb(0, 0, 0)"},
+)
+
+// Check the alias more specifically in the dark theme.
+goto: file://|DOC_PATH|/test_docs/index.html
+// We set the theme so we're sure that the correct values will be used, whatever the computer
+// this test is running on.
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+// If the text isn't displayed, the browser doesn't compute color style correctly...
+show-text: true
+// We reload the page so the local storage settings are being used.
+reload:
+write: (".search-input", "thisisanalias")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+// Checking that the colors for the alias element are the ones expected.
+assert-css: (".result-name > .alias", {"color": "rgb(255, 255, 255)"})
+assert-css: (".result-name > .alias > .grey", {"color": "rgb(204, 204, 204)"})
diff --git a/src/test/rustdoc-gui/search-result-description.goml b/src/test/rustdoc-gui/search-result-description.goml
new file mode 100644
index 000000000..d8cb6ee57
--- /dev/null
+++ b/src/test/rustdoc-gui/search-result-description.goml
@@ -0,0 +1,5 @@
+// This test is to ensure that the codeblocks are correctly rendered in the search results.
+goto: file://|DOC_PATH|/test_docs/index.html?search=some_more_function
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-text: (".search-results .desc code", "format!")
diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml
new file mode 100644
index 000000000..8464ba7c2
--- /dev/null
+++ b/src/test/rustdoc-gui/search-result-display.goml
@@ -0,0 +1,42 @@
+// Checks that the search results have the expected width.
+goto: file://|DOC_PATH|/test_docs/index.html
+size: (900, 1000)
+write: (".search-input", "test")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "#search-settings"
+// The width is returned by "getComputedStyle" which returns the exact number instead of the
+// CSS rule which is "50%"...
+assert-css: (".search-results div.desc", {"width": "295px"})
+size: (600, 100)
+// As counter-intuitive as it may seem, in this width, the width is "100%", which is why
+// when computed it's larger.
+assert-css: (".search-results div.desc", {"width": "570px"})
+
+// Check that the crate filter `<select>` is correctly handled when it goes to next line.
+// To do so we need to update the length of one of its `<option>`.
+size: (900, 900)
+
+// First we check the current width and position.
+assert-css: ("#crate-search", {"width": "218px"})
+compare-elements-position-near: (
+ "#crate-search",
+ "#search-settings .search-results-title",
+ {"y": 5},
+)
+
+// Then we update the text of one of the `<option>`.
+text: (
+ "#crate-search option",
+ "sdjfaksdjfaksjdbfkadsbfkjsadbfkdsbkfbsadkjfbkdsabfkadsfkjdsafa",
+)
+
+// Then we compare again.
+assert-css: ("#crate-search", {"width": "640px"})
+compare-elements-position-near-false: (
+ "#crate-search",
+ "#search-settings .search-results-title",
+ {"y": 5},
+)
+// And we check that the `<select>` isn't bigger than its container.
+assert-css: ("#search", {"width": "640px"})
diff --git a/src/test/rustdoc-gui/search-result-go-to-first.goml b/src/test/rustdoc-gui/search-result-go-to-first.goml
new file mode 100644
index 000000000..255470a3e
--- /dev/null
+++ b/src/test/rustdoc-gui/search-result-go-to-first.goml
@@ -0,0 +1,19 @@
+// This test ensures that the "go_to_first" feature is working as expected.
+
+// First, we check that the first page doesn't have the string we're looking for to ensure
+// that the feature is changing page as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-text-false: (".fqn .in-band", "Struct test_docs::Foo")
+
+// We now check that we land on the search result page if "go_to_first" isn't set.
+goto: file://|DOC_PATH|/test_docs/index.html?search=struct%3AFoo
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-text-false: (".fqn .in-band", "Struct test_docs::Foo")
+// Ensure that the search results are displayed, not the "normal" content.
+assert-css: ("#main-content", {"display": "none"})
+
+// Now we can check that the feature is working as expected!
+goto: file://|DOC_PATH|/test_docs/index.html?search=struct%3AFoo&go_to_first=true
+// Waiting for the page to load...
+wait-for-text: (".fqn .in-band", "Struct test_docs::Foo")
diff --git a/src/test/rustdoc-gui/search-result-keyword.goml b/src/test/rustdoc-gui/search-result-keyword.goml
new file mode 100644
index 000000000..16ae10431
--- /dev/null
+++ b/src/test/rustdoc-gui/search-result-keyword.goml
@@ -0,0 +1,13 @@
+// Checks that the "keyword" results have the expected text alongside them.
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "CookieMonster")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+// Note: The two next assert commands could be merged as one but readability would be
+// less good.
+//
+// Checking that the CSS is displaying " (keyword)" in italic.
+assert-text: (".result-name span.keyword > i", "(keyword)")
+assert-text: (".result-name span.keyword", "CookieMonster (keyword)")
diff --git a/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml b/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml
new file mode 100644
index 000000000..9d506c151
--- /dev/null
+++ b/src/test/rustdoc-gui/search-tab-change-title-fn-sig.goml
@@ -0,0 +1,74 @@
+// Checks that the search tab results work correctly with function signature syntax
+// First, try a search-by-name
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "Foo")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Names", STARTS_WITH)
+assert: "input.search-input:focus"
+// Use left-right keys
+press-key: "ArrowDown"
+assert: "#results > .search-results.active > a:nth-of-type(1):focus"
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(2)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(3)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowLeft"
+wait-for-attribute: ("#titles > button:nth-of-type(3)", {"class": "selected"})
+
+// Now try search-by-return
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "-> String")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Return Types", STARTS_WITH)
+assert: "input.search-input:focus"
+// Use left-right keys
+press-key: "ArrowDown"
+assert: "#results > .search-results.active > a:nth-of-type(1):focus"
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowRight"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+press-key: "ArrowLeft"
+wait-for-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+
+// Try with a search-by-return with no results
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "-> Something")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Return Types", STARTS_WITH)
+
+// Try with a search-by-parameter
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "usize pattern")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Parameters", STARTS_WITH)
+
+// Try with a search-by-parameter-and-return
+goto: file://|DOC_PATH|/test_docs/index.html
+write: (".search-input", "pattern -> str")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-attribute: ("#titles > button:nth-of-type(1)", {"class": "selected"})
+assert-text: ("#titles > button:nth-of-type(1)", "In Function Signatures", STARTS_WITH)
diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml
new file mode 100644
index 000000000..d9cf5ee66
--- /dev/null
+++ b/src/test/rustdoc-gui/settings.goml
@@ -0,0 +1,158 @@
+// This test ensures that the settings menu display is working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+show-text: true // needed when we check for colors below.
+// First, we check that the settings page doesn't exist.
+assert-false: "#settings"
+// We now click on the settings button.
+click: "#settings-menu"
+wait-for: "#settings"
+assert-css: ("#settings", {"display": "block"})
+// Let's close it by clicking on the same button.
+click: "#settings-menu"
+wait-for-css: ("#settings", {"display": "none"})
+
+// Let's check that pressing "ESCAPE" is closing it.
+click: "#settings-menu"
+wait-for-css: ("#settings", {"display": "block"})
+press-key: "Escape"
+wait-for-css: ("#settings", {"display": "none"})
+
+// Let's click on it when the search results are displayed.
+focus: ".search-input"
+write: "test"
+// To be SURE that the search will be run.
+press-key: 'Enter'
+wait-for: "#alternative-display #search"
+click: "#settings-menu"
+wait-for-css: ("#settings", {"display": "block"})
+// Ensure that the search is still displayed.
+wait-for: "#alternative-display #search"
+assert: "#main-content.hidden"
+
+// Now let's check the content of the settings menu.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+click: "#settings-menu"
+wait-for: "#settings"
+
+// We check that the "Use system theme" is disabled.
+assert-property: ("#use-system-theme", {"checked": "false"})
+assert: "//*[@class='setting-line']//span[text()='Use system theme']"
+// Meaning that only the "theme" menu is showing up.
+assert: ".setting-line:not(.hidden) #theme"
+assert: ".setting-line.hidden #preferred-dark-theme"
+assert: ".setting-line.hidden #preferred-light-theme"
+
+// We check that the correct theme is selected.
+assert-property: ("#theme .choices #theme-dark", {"checked": "true"})
+
+// Some style checks...
+// First we check the "default" display.
+assert-css: (
+ "#theme-dark",
+ {
+ "border-color": "rgb(221, 221, 221)",
+ "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset",
+ },
+)
+assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"})
+// Let's start with the hover.
+move-cursor-to: "#theme-dark"
+assert-css: (
+ "#theme-dark",
+ {
+ "border-color": "rgb(33, 150, 243)",
+ "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset",
+ },
+)
+move-cursor-to: "#theme-light"
+assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"})
+move-cursor-to: "#theme-ayu"
+// Let's now check with the focus.
+focus: "#theme-dark"
+assert-css: (
+ "#theme-dark",
+ {
+ "border-color": "rgb(221, 221, 221)",
+ "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset, rgb(33, 150, 243) 0px 0px 2px 2px",
+ },
+)
+focus: "#theme-light"
+assert-css: (
+ "#theme-light",
+ {
+ "border-color": "rgb(221, 221, 221)",
+ "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
+ },
+)
+// Now we check we both focus and hover.
+move-cursor-to: "#theme-dark"
+focus: "#theme-dark"
+assert-css: (
+ "#theme-dark",
+ {
+ "border-color": "rgb(33, 150, 243)",
+ "box-shadow": "rgb(53, 53, 53) 0px 0px 0px 3px inset, rgb(33, 150, 243) 0px 0px 2px 2px",
+ },
+)
+move-cursor-to: "#theme-light"
+focus: "#theme-light"
+assert-css: (
+ "#theme-light",
+ {
+ "border-color": "rgb(33, 150, 243)",
+ "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
+ },
+)
+
+// We now switch the display.
+click: "#use-system-theme"
+// Wait for the hidden element to show up.
+wait-for: ".setting-line:not(.hidden) #preferred-dark-theme"
+assert: ".setting-line:not(.hidden) #preferred-light-theme"
+// Check that the theme picking is hidden.
+assert: ".setting-line.hidden #theme"
+
+// We check their text as well.
+assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
+assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme")
+
+// We now check that clicking on the "sliders"' text is like clicking on the slider.
+// To test it, we use the "Disable keyboard shortcuts".
+local-storage: {"rustdoc-disable-shortcuts": "false"}
+click: ".setting-line:last-child .toggle .label"
+assert-local-storage: {"rustdoc-disable-shortcuts": "true"}
+
+// Make sure that "Disable keyboard shortcuts" actually took effect.
+press-key: "Escape"
+press-key: "?"
+assert-false: "#help-button .popover"
+wait-for-css: ("#settings-menu .popover", {"display": "block"})
+
+// Now turn keyboard shortcuts back on, and see if they work.
+click: ".setting-line:last-child .toggle .label"
+assert-local-storage: {"rustdoc-disable-shortcuts": "false"}
+press-key: "Escape"
+press-key: "?"
+wait-for-css: ("#help-button .popover", {"display": "block"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
+// Now we go to the settings page to check that the CSS is loaded as expected.
+goto: file://|DOC_PATH|/settings.html
+wait-for: "#settings"
+assert-css: (".setting-line .toggle .slider", {"width": "45px", "margin-right": "20px"})
+
+// We now check the display with JS disabled.
+assert-false: "noscript section"
+javascript: false
+reload:
+assert-css: ("noscript section", {"display": "block"})
+javascript: true
+
+// Check for the display on small screen
+show-text: true
+reload:
+size: (300, 1000)
+click: "#settings-menu"
+wait-for: "#settings"
+assert-css: ("#settings .slider", {"width": "45px"}, ALL)
diff --git a/src/test/rustdoc-gui/shortcuts.goml b/src/test/rustdoc-gui/shortcuts.goml
new file mode 100644
index 000000000..1f20a0eaa
--- /dev/null
+++ b/src/test/rustdoc-gui/shortcuts.goml
@@ -0,0 +1,13 @@
+// Check that the various shortcuts are working.
+goto: file://|DOC_PATH|/test_docs/index.html
+// We first check that the search input isn't already focused.
+assert-false: "input.search-input:focus"
+press-key: "s"
+assert: "input.search-input:focus"
+press-key: "Escape"
+assert-false: "input.search-input:focus"
+// We now check for the help popup.
+press-key: "?"
+assert-css: ("#help-button .popover", {"display": "block"})
+press-key: "Escape"
+assert-css: ("#help-button .popover", {"display": "none"})
diff --git a/src/test/rustdoc-gui/sidebar-macro-reexport.goml b/src/test/rustdoc-gui/sidebar-macro-reexport.goml
new file mode 100644
index 000000000..a3a62fe54
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-macro-reexport.goml
@@ -0,0 +1,5 @@
+// This test ensures that the reexport of a macro doesn't make the original macro
+// displayed twice in the sidebar.
+goto: file://|DOC_PATH|/test_docs/macro.repro.html
+wait-for: ".sidebar-elems .macro .macro"
+assert-count: ("//*[@class='sidebar-elems']//*[@class='block macro']//a[text()='repro']", 1)
diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml
new file mode 100644
index 000000000..033c65783
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-mobile.goml
@@ -0,0 +1,64 @@
+// This test ensure that the sidebar isn't "hidden" on mobile but instead moved out of the viewport.
+// This is especially important for devices for "text-first" content (like for users with
+// sight issues).
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+// Switching to "mobile view" by reducing the width to 600px.
+size: (600, 600)
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+// Opening the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"display": "block", "left": "0px"})
+// Closing the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+// Force the sidebar open by focusing a link inside it.
+// This makes it easier for keyboard users to get to it.
+focus: ".sidebar-title a"
+assert-css: (".sidebar", {"display": "block", "left": "0px"})
+// When we tab out of the sidebar, close it.
+focus: ".search-input"
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+
+// Open the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"left": "0px"})
+
+// Click elsewhere.
+click: "body"
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+
+// Check that the topbar is visible
+assert-property: (".mobile-topbar", {"clientHeight": "45"})
+
+// Check that clicking an element from the sidebar scrolls to the right place
+// so the target is not obscured by the topbar.
+click: ".sidebar-menu-toggle"
+click: ".sidebar-elems section .block li > a"
+assert-position: ("#method\.must_use", {"y": 45})
+
+// Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
+click: ".sidebar-menu-toggle"
+scroll-to: ".block.keyword li:nth-child(1)"
+compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 543})
+
+// Now checking the background color of the sidebar.
+local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
+reload:
+
+// Open the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)"})
+
+local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"}
+reload:
+
+// Open the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)"})
+
+local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"}
+reload:
+
+// Open the sidebar menu.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)"})
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
new file mode 100644
index 000000000..fa322574f
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -0,0 +1,254 @@
+// This test ensures that the elements in the sidebar are displayed correctly.
+javascript: false
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+// Since the javascript is disabled, there shouldn't be a toggle.
+assert-false: "#sidebar-toggle"
+// For some reason, we need to wait a bit here because it seems like the transition on opacity
+// is being applied whereas it can't be reproduced in a browser...
+wait-for-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0})
+
+// Let's retry with javascript enabled.
+javascript: true
+reload:
+wait-for: "#sidebar-toggle"
+assert-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden", "opacity": 0})
+// Let's expand the sidebar now.
+click: "#sidebar-toggle"
+// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`.
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+
+// We now check that opening the sidebar and clicking a link will leave it open.
+// The behavior here on desktop is different than the behavior on mobile,
+// but since the sidebar doesn't fill the entire screen here, it makes sense to have the
+// sidebar stay resident.
+wait-for-css: (".sidebar", {"width": "300px"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+click: ".sidebar a.selected"
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+wait-for-css: (".sidebar", {"width": "300px"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+
+// Now we check the display of the sidebar items.
+show-text: true
+
+// First we start with the light theme.
+local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
+reload:
+// Waiting for the sidebar to be displayed...
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+assert-css: (
+ "#source-sidebar details[open] > .files a.selected",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
+)
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
+assert-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+
+// Now with the dark theme.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+// Waiting for the sidebar to be displayed...
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+assert-css: (
+ "#source-sidebar details[open] > .files > a.selected",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
+)
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .files > a:not(.selected)",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
+assert-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+
+// And finally with the ayu theme.
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
+reload:
+// Waiting for the sidebar to be displayed...
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+assert-css: (
+ "#source-sidebar details[open] > .files a.selected",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
+assert-css: (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+// Without hover.
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
+assert-css: (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+
+// Now checking on mobile devices.
+size: (500, 700)
+reload:
+// Waiting for the sidebar to be displayed...
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+
+// We now check it takes the full size of the display.
+assert-property: ("body", {"clientWidth": "500", "clientHeight": "700"})
+assert-property: (".sidebar", {"clientWidth": "500", "clientHeight": "700"})
+
+// We now check the display of the toggle once the sidebar is expanded.
+assert-property: ("#sidebar-toggle", {"clientWidth": "500", "clientHeight": "39"})
+assert-css: (
+ "#sidebar-toggle",
+ {
+ "border-top-width": "0px",
+ "border-right-width": "0px",
+ "border-left-width": "0px",
+ "border-bottom-width": "1px",
+ },
+)
+
+// We now check that the scroll position is kept when opening the sidebar.
+click: "#sidebar-toggle"
+wait-for-css: (".sidebar", {"width": "0px"})
+// We scroll to line 117 to change the scroll position.
+scroll-to: '//*[@id="117"]'
+assert-window-property: {"pageYOffset": "2519"}
+// Expanding the sidebar...
+click: "#sidebar-toggle"
+wait-for-css: (".sidebar", {"width": "500px"})
+click: "#sidebar-toggle"
+wait-for-css: (".sidebar", {"width": "0px"})
+// The "scrollTop" property should be the same.
+assert-window-property: {"pageYOffset": "2519"}
+
+// We now check that opening the sidebar and clicking a link will close it.
+// The behavior here on mobile is different than the behavior on desktop,
+// but common sense dictates that if you have a list of files that fills the entire screen, and
+// you click one of them, you probably want to actually see the file's contents, and not just
+// make it the current selection.
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "visible"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
+click: ".sidebar a.selected"
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
+// Resize back to desktop size, to check that the sidebar doesn't spontaneously open.
+size: (1000, 1000)
+wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
+click: "#sidebar-toggle"
+wait-for-css: ("#source-sidebar", {"visibility": "visible"})
+assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml
new file mode 100644
index 000000000..e882080c7
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-source-code.goml
@@ -0,0 +1,45 @@
+// The goal of this test is to ensure that the sidebar is working as expected in the source
+// code pages.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+// First: desktop mode.
+size: (1100, 800)
+// We check that the sidebar isn't expanded and has the expected width.
+assert-css: ("nav.sidebar", {"width": "50px"})
+// We now click on the button to expand the sidebar.
+click: (10, 10)
+// We wait for the sidebar to be expanded.
+wait-for-css: (".source-sidebar-expanded nav.sidebar", {"width": "300px"})
+assert-css: (".source-sidebar-expanded nav.sidebar a", {"font-size": "14px"})
+// We collapse the sidebar.
+click: (10, 10)
+// We ensure that the class has been removed.
+wait-for: "html:not(.expanded)"
+assert: "nav.sidebar"
+
+// Checking that only the path to the current file is "open".
+goto: file://|DOC_PATH|/src/lib2/another_folder/sub_mod/mod.rs.html
+// First we expand the sidebar again.
+click: (10, 10)
+// We wait for the sidebar to be expanded.
+wait-for-css: (".source-sidebar-expanded nav.sidebar", {"width": "300px"})
+assert: "//*[@class='dir-entry' and @open]/*[text()='lib2']"
+assert: "//*[@class='dir-entry' and @open]/*[text()='another_folder']"
+assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']"
+// Only "another_folder" should be "open" in "lib2".
+assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
+// All other trees should be collapsed.
+assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 5)
+
+// We now switch to mobile mode.
+size: (600, 600)
+wait-for-css: (".source-sidebar-expanded nav.sidebar", {"width": "600px"})
+// We collapse the sidebar.
+click: (10, 10)
+// We check that the sidebar has the expected width (0).
+assert-css: ("nav.sidebar", {"width": "0px"})
+// We ensure that the class has been removed.
+assert-false: ".source-sidebar-expanded"
+assert: "nav.sidebar"
+
+// Check that the topbar is not visible
+assert-property: (".mobile-topbar", {"offsetParent": "null"})
diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml
new file mode 100644
index 000000000..32fe3334f
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar.goml
@@ -0,0 +1,88 @@
+// Checks multiple things on the sidebar display (width of its elements, colors, etc).
+goto: file://|DOC_PATH|/test_docs/index.html
+show-text: true
+local-storage: {"rustdoc-theme": "light"}
+// We reload the page so the local storage settings are being used.
+reload:
+
+assert-text: (".sidebar > .location", "Crate test_docs")
+// In modules, we only have one "location" element.
+assert-count: (".sidebar .location", 1)
+assert-text: ("#all-types", "All Items")
+assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"})
+// We check that we have the crates list and that the "current" on is "test_docs".
+assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
+// And we're also supposed to have the list of items in the current module.
+assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports")
+assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules")
+assert-text: (".sidebar-elems section ul > li:nth-child(3)", "Macros")
+assert-text: (".sidebar-elems section ul > li:nth-child(4)", "Structs")
+assert-text: (".sidebar-elems section ul > li:nth-child(5)", "Enums")
+assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Traits")
+assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Functions")
+assert-text: (".sidebar-elems section ul > li:nth-child(8)", "Type Definitions")
+assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Unions")
+assert-text: (".sidebar-elems section ul > li:nth-child(10)", "Keywords")
+assert-text: ("#structs + .item-table .item-left > a", "Foo")
+click: "#structs + .item-table .item-left > a"
+
+// PAGE: struct.Foo.html
+assert-count: (".sidebar .location", 2)
+// We check that there is no crate listed outside of the top level.
+assert-false: ".sidebar-elems > .crate"
+
+click: ".sidebar-elems section .block li > a"
+assert-property-false: ("html", {"scrollTop": "0"})
+
+click: ".sidebar h2.location a"
+assert-property: ("html", {"scrollTop": "0"})
+
+// We now go back to the crate page to click on the "lib2" crate link.
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (".sidebar-elems .crate > ul > li:first-child > a", {"color": "rgb(53, 109, 164)"})
+click: ".sidebar-elems .crate > ul > li:first-child > a"
+
+// PAGE: lib2/index.html
+goto: file://|DOC_PATH|/lib2/index.html
+assert-text: (".sidebar > .location", "Crate lib2")
+// We check that we have the crates list and that the "current" on is now "lib2".
+assert-text: (".sidebar-elems .crate > ul > li > a.current", "lib2")
+// We now go to the "foobar" function page.
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(1)", "Modules")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(2)", "Structs")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(3)", "Traits")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(4)", "Functions")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(5)", "Type Definitions")
+assert-text: ("#functions + .item-table .item-left > a", "foobar")
+click: "#functions + .item-table .item-left > a"
+
+// PAGE: fn.foobar.html
+// In items containing no items (like functions or constants) and in modules, we have one
+// "location" elements.
+assert-count: (".sidebar .location", 1)
+assert-text: (".sidebar .sidebar-elems .location", "In lib2")
+// We check that we don't have the crate list.
+assert-false: ".sidebar-elems > .crate"
+
+goto: ./module/index.html
+assert-text: (".sidebar > .location", "Module module")
+// We check that we don't have the crate list.
+assert-false: ".sidebar-elems > .crate"
+
+goto: ./sub_module/sub_sub_module/index.html
+assert-text: (".sidebar > .location", "Module sub_sub_module")
+// We check that we don't have the crate list.
+assert-false: ".sidebar-elems .crate"
+assert-text: (".sidebar-elems > section ul > li:nth-child(1)", "Functions")
+assert-text: ("#functions + .item-table .item-left > a", "foo")
+
+// Links to trait implementations in the sidebar should not wrap even if they are long.
+goto: file://|DOC_PATH|/lib2/struct.HasALongTraitWithParams.html
+assert-property: (".sidebar-elems section .block li > a", {"offsetHeight": 29})
+
+// Test that clicking on of the "In <module>" headings in the sidebar links to the
+// appropriate anchor in index.html.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+click: ".block.mod h3 a"
+// PAGE: index.html
+assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})
diff --git a/src/test/rustdoc-gui/source-anchor-scroll.goml b/src/test/rustdoc-gui/source-anchor-scroll.goml
new file mode 100644
index 000000000..4e51c8dca
--- /dev/null
+++ b/src/test/rustdoc-gui/source-anchor-scroll.goml
@@ -0,0 +1,20 @@
+// We check that when the anchor changes and is output of the displayed content,
+// the page is scrolled to it.
+goto: file://|DOC_PATH|/src/link_to_definition/lib.rs.html
+
+// We reduce the window size to make it easier to make an element "out of the page".
+size: (600, 800)
+// We check that the scroll is at the top first.
+assert-property: ("html", {"scrollTop": "0"})
+
+click: '//a[text() = "barbar"]'
+assert-property: ("html", {"scrollTop": "125"})
+click: '//a[text() = "bar"]'
+assert-property: ("html", {"scrollTop": "166"})
+click: '//a[text() = "sub_fn"]'
+assert-property: ("html", {"scrollTop": "53"})
+
+// We now check that clicking on lines doesn't change the scroll
+// Extra information: the "sub_fn" function header is on line 1.
+click: '//*[@id="6"]'
+assert-property: ("html", {"scrollTop": "53"})
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
new file mode 100644
index 000000000..581f826a3
--- /dev/null
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -0,0 +1,49 @@
+// Checks that the interactions with the source code pages are working as expected.
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+// Check that we can click on the line number.
+click: ".line-numbers > span:nth-child(4)" // This is the span for line 4.
+// Ensure that the page URL was updated.
+assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH)
+assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
+// We now check that the good spans are highlighted
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html#4-6
+assert-attribute-false: (".line-numbers > span:nth-child(3)", {"class": "line-highlighted"})
+assert-attribute: (".line-numbers > span:nth-child(4)", {"class": "line-highlighted"})
+assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
+assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
+assert-attribute-false: (".line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
+// This is to ensure that the content is correctly align with the line numbers.
+compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
+
+// Assert that the line numbers text is aligned to the right.
+assert-css: (".line-numbers", {"text-align": "right"})
+
+// Now let's check that clicking on something else than the line number doesn't
+// do anything (and certainly not add a `#NaN` to the URL!).
+show-text: true
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
+// We use this assert-position to know where we will click.
+assert-position: ("//*[@id='1']", {"x": 104, "y": 103})
+// We click on the left of the "1" span but still in the "line-number" `<pre>`.
+click: (103, 103)
+assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
+
+// Checking the source code sidebar.
+
+// First we "open" it.
+click: "#sidebar-toggle"
+assert: ".source-sidebar-expanded"
+
+// We check that the first entry of the sidebar is collapsed
+assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
+assert-text: ("#source-sidebar details:first-of-type > summary", "implementors")
+// We now click on it.
+click: "#source-sidebar details:first-of-type > summary"
+assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})
+
+// And now we collapse it again.
+click: "#source-sidebar details:first-of-type > summary"
+assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
+
+// Check the spacing.
+assert-css: ("#source-sidebar > details.dir-entry", {"padding-left": "4px"})
diff --git a/src/test/rustdoc-gui/src-font-size.goml b/src/test/rustdoc-gui/src-font-size.goml
new file mode 100644
index 000000000..0c01e2545
--- /dev/null
+++ b/src/test/rustdoc-gui/src-font-size.goml
@@ -0,0 +1,11 @@
+// This test ensures that the "[src]" have the same font size as their headers
+// to avoid having some weird height difference in the background when the element
+// is selected.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+show-text: true
+// Check the impl headers.
+assert-css: (".impl.has-srclink .srclink", {"font-size": "16px"}, ALL)
+assert-css: (".impl.has-srclink .code-header.in-band", {"font-size": "18px"}, ALL)
+// Check the impl items.
+assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px"}, ALL)
+assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px"}, ALL)
diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.lock b/src/test/rustdoc-gui/src/lib2/Cargo.lock
new file mode 100644
index 000000000..a5873ceb3
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/Cargo.lock
@@ -0,0 +1,14 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
+
+[[package]]
+name = "lib2"
+version = "0.1.0"
+dependencies = [
+ "implementors",
+]
diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.toml b/src/test/rustdoc-gui/src/lib2/Cargo.toml
new file mode 100644
index 000000000..2e37f3f66
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "lib2"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+implementors = { path = "./implementors" }
diff --git a/src/test/rustdoc-gui/src/lib2/another_folder/mod.rs b/src/test/rustdoc-gui/src/lib2/another_folder/mod.rs
new file mode 100644
index 000000000..ec9a20859
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/another_folder/mod.rs
@@ -0,0 +1,3 @@
+pub fn another_fn() {}
+
+pub mod sub_mod;
diff --git a/src/test/rustdoc-gui/src/lib2/another_folder/sub_mod/mod.rs b/src/test/rustdoc-gui/src/lib2/another_folder/sub_mod/mod.rs
new file mode 100644
index 000000000..f16722cf3
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/another_folder/sub_mod/mod.rs
@@ -0,0 +1 @@
+pub fn subsubsub() {}
diff --git a/src/test/rustdoc-gui/src/lib2/another_mod/mod.rs b/src/test/rustdoc-gui/src/lib2/another_mod/mod.rs
new file mode 100644
index 000000000..9a4f007a2
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/another_mod/mod.rs
@@ -0,0 +1 @@
+pub fn tadam() {}
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock
new file mode 100644
index 000000000..cad99a991
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml
new file mode 100644
index 000000000..7ef1052c4
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "implementors"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
new file mode 100644
index 000000000..1620e8422
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs
@@ -0,0 +1,20 @@
+pub trait Whatever {
+ type Foo;
+
+ fn method() {}
+}
+
+pub struct Struct;
+
+impl Whatever for Struct {
+ type Foo = u8;
+}
+
+mod traits {
+ pub trait TraitToReexport {
+ fn method() {}
+ }
+}
+
+#[doc(inline)]
+pub use traits::TraitToReexport;
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
new file mode 100644
index 000000000..87f91be3a
--- /dev/null
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -0,0 +1,145 @@
+// ignore-tidy-linelength
+
+#![feature(doc_cfg)]
+
+pub mod another_folder;
+pub mod another_mod;
+
+pub mod module {
+ pub mod sub_module {
+ pub mod sub_sub_module {
+ pub fn foo() {}
+ }
+ pub fn bar() {}
+ }
+ pub fn whatever() {}
+}
+
+pub fn foobar() {}
+
+pub type Alias = u32;
+
+#[doc(cfg(feature = "foo-method"))]
+pub struct Foo {
+ pub x: Alias,
+}
+
+impl Foo {
+ /// Some documentation
+ /// # A Heading
+ pub fn a_method(&self) {}
+}
+
+#[doc(cfg(feature = "foo-method"))]
+#[deprecated = "Whatever [`Foo::a_method`](#method.a_method)"]
+pub trait Trait {
+ type X;
+ const Y: u32;
+
+ #[deprecated = "Whatever [`Foo`](#tadam)"]
+ fn foo() {}
+}
+
+impl Trait for Foo {
+ type X = u32;
+ const Y: u32 = 0;
+}
+
+impl implementors::Whatever for Foo {
+ type Foo = u32;
+}
+
+#[doc(inline)]
+pub use implementors::TraitToReexport;
+
+pub struct StructToImplOnReexport;
+
+impl TraitToReexport for StructToImplOnReexport {}
+
+pub mod sub_mod {
+ /// ```txt
+ /// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ /// ```
+ ///
+ /// ```
+ /// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ /// ```
+ pub struct Foo;
+}
+
+pub mod long_trait {
+ use std::ops::DerefMut;
+
+ pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem:
+ DerefMut<Target = u32> + From<u128> + Send + Sync + AsRef<str> + 'static
+ {
+ }
+}
+
+pub mod long_table {
+ /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+ /// | ----------- | ----------- | ----------- | ----------- |
+ /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+ ///
+ /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+ pub struct Foo;
+
+ /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+ /// | ----------- | ----------- | ----------- | ----------- |
+ /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+ ///
+ /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+ impl Foo {
+ pub fn foo(&self) {}
+ }
+}
+
+pub mod summary_table {
+ /// | header 1 | header 2 |
+ /// | -------- | -------- |
+ /// | content | content |
+ pub struct Foo;
+}
+
+pub mod too_long {
+ pub type ReallyLongTypeNameLongLongLong =
+ Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>;
+
+ pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0;
+
+ /// This also has a really long doccomment. Lorem ipsum dolor sit amet,
+ /// consectetur adipiscing elit. Suspendisse id nibh malesuada, hendrerit
+ /// massa vel, tincidunt est. Nulla interdum, sem ac efficitur ornare, arcu
+ /// nunc dignissim nibh, at rutrum diam augue ac mauris. Fusce tincidunt et
+ /// ligula sed viverra. Aenean sed facilisis dui, non volutpat felis. In
+ /// vitae est dui. Donec felis nibh, blandit at nibh eu, tempor suscipit
+ /// nisl. Vestibulum ornare porta libero, eu faucibus purus iaculis ut. Ut
+ /// quis tincidunt nunc, in mollis purus. Nulla sed interdum quam. Nunc
+ /// vitae cursus ex.
+ pub struct SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName {
+ pub a: u32,
+ }
+
+ impl SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName {
+ /// ```
+ /// let x = SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { a: 0 };
+ /// ```
+ pub fn foo(&self) {}
+ }
+}
+
+pub struct HasALongTraitWithParams {}
+
+pub trait LongTraitWithParamsBananaBananaBanana<T> {}
+
+impl LongTraitWithParamsBananaBananaBanana<usize> for HasALongTraitWithParams {}
+
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
+pub struct LongItemInfo;
+
+pub trait SimpleTrait {}
+pub struct LongItemInfo2;
+
+/// Some docs.
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
+impl SimpleTrait for LongItemInfo2 {}
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock b/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
new file mode 100644
index 000000000..e4b4e52d0
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "link_to_definition"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml b/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
new file mode 100644
index 000000000..cdd294d74
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "link_to_definition"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/link_to_definition/lib.rs b/src/test/rustdoc-gui/src/link_to_definition/lib.rs
new file mode 100644
index 000000000..419a9ccee
--- /dev/null
+++ b/src/test/rustdoc-gui/src/link_to_definition/lib.rs
@@ -0,0 +1,35 @@
+pub fn sub_fn() {
+ barbar();
+}
+fn barbar() {
+ bar(vec![], vec![], vec![], vec![], Bar { a: "a".into(), b: 0 });
+}
+
+pub struct Bar {
+ pub a: String,
+ pub b: u32,
+}
+
+pub fn foo(_b: &Bar) {}
+
+// The goal now is to add
+// a lot of lines so
+// that the next content
+// will be out of the screen
+// to allow us to test that
+// if the anchor changes to
+// something outside of the
+// current view, it'll
+// scroll to it as expected.
+
+// More filling content.
+
+pub fn bar(
+ _a: Vec<String>,
+ _b: Vec<String>,
+ _c: Vec<String>,
+ _d: Vec<String>,
+ _e: Bar,
+) {
+ sub_fn();
+}
diff --git a/src/test/rustdoc-gui/src/settings/.cargo/config.toml b/src/test/rustdoc-gui/src/settings/.cargo/config.toml
new file mode 100644
index 000000000..bbb8d11a2
--- /dev/null
+++ b/src/test/rustdoc-gui/src/settings/.cargo/config.toml
@@ -0,0 +1,2 @@
+[build]
+rustdocflags = ["--default-theme", "ayu"]
diff --git a/src/test/rustdoc-gui/src/settings/Cargo.lock b/src/test/rustdoc-gui/src/settings/Cargo.lock
new file mode 100644
index 000000000..6f0de1ac1
--- /dev/null
+++ b/src/test/rustdoc-gui/src/settings/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "settings"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/settings/Cargo.toml b/src/test/rustdoc-gui/src/settings/Cargo.toml
new file mode 100644
index 000000000..c8a211a47
--- /dev/null
+++ b/src/test/rustdoc-gui/src/settings/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "settings"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
diff --git a/src/test/rustdoc-gui/src/settings/lib.rs b/src/test/rustdoc-gui/src/settings/lib.rs
new file mode 100644
index 000000000..b76b4321d
--- /dev/null
+++ b/src/test/rustdoc-gui/src/settings/lib.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/src/test/rustdoc-gui/src/staged_api/Cargo.lock b/src/test/rustdoc-gui/src/staged_api/Cargo.lock
new file mode 100644
index 000000000..6e8eba56c
--- /dev/null
+++ b/src/test/rustdoc-gui/src/staged_api/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "staged_api"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/staged_api/Cargo.toml b/src/test/rustdoc-gui/src/staged_api/Cargo.toml
new file mode 100644
index 000000000..117c4134e
--- /dev/null
+++ b/src/test/rustdoc-gui/src/staged_api/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "staged_api"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+path = "lib.rs"
+
+[features]
+default = ["some_feature"]
+some_feature = []
diff --git a/src/test/rustdoc-gui/src/staged_api/lib.rs b/src/test/rustdoc-gui/src/staged_api/lib.rs
new file mode 100644
index 000000000..0cb460f03
--- /dev/null
+++ b/src/test/rustdoc-gui/src/staged_api/lib.rs
@@ -0,0 +1,10 @@
+#![feature(staged_api)]
+#![stable(feature = "some_feature", since = "1.3.5")]
+
+#[stable(feature = "some_feature", since = "1.3.5")]
+pub struct Foo {}
+
+impl Foo {
+ #[stable(feature = "some_feature", since = "1.3.5")]
+ pub fn bar() {}
+}
diff --git a/src/test/rustdoc-gui/src/test_docs/Cargo.lock b/src/test/rustdoc-gui/src/test_docs/Cargo.lock
new file mode 100644
index 000000000..6b80f6e88
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "test_docs"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/test_docs/Cargo.toml b/src/test/rustdoc-gui/src/test_docs/Cargo.toml
new file mode 100644
index 000000000..8be819b76
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "test_docs"
+version = "0.1.0"
+edition = "2018"
+
+build = "build.rs"
+
+[lib]
+path = "lib.rs"
+
+[features]
+default = ["some-feature"]
+some-feature = []
diff --git a/src/test/rustdoc-gui/src/test_docs/build.rs b/src/test/rustdoc-gui/src/test_docs/build.rs
new file mode 100644
index 000000000..16c96ded9
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/build.rs
@@ -0,0 +1,15 @@
+//! generate 2000 constants for testing
+
+use std::{fs::write, path::PathBuf};
+
+fn main() -> std::io::Result<()> {
+ let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is not defined");
+
+ let mut output = String::new();
+ for i in 0..2000 {
+ let line = format!("/// Some const A{0}\npub const A{0}: isize = 0;\n", i);
+ output.push_str(&*line);
+ };
+
+ write(&[&*out_dir, "huge_amount_of_consts.rs"].iter().collect::<PathBuf>(), output)
+}
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
new file mode 100644
index 000000000..1b26aaecb
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -0,0 +1,295 @@
+//! The point of this crate is to be able to have enough different "kinds" of
+//! documentation generated so we can test each different features.
+#![doc(html_playground_url="https://play.rust-lang.org/")]
+
+#![crate_name = "test_docs"]
+#![feature(rustdoc_internals)]
+#![feature(doc_cfg)]
+
+use std::convert::AsRef;
+use std::fmt;
+
+/// Basic function with some code examples:
+///
+/// ```
+/// println!("nothing fancy");
+/// println!("but with two lines!");
+/// ```
+///
+/// A failing to compile one:
+///
+/// ```compile_fail
+/// println!("where did my argument {} go? :'(");
+/// ```
+///
+/// An ignored one:
+///
+/// ```ignore (it's a test)
+/// Let's say I'm just some text will ya?
+/// ```
+///
+/// An inlined `code`!
+pub fn foo() {}
+
+/// Just a normal struct.
+pub struct Foo;
+
+impl Foo {
+ #[must_use]
+ pub fn must_use(&self) -> bool {
+ true
+ }
+}
+
+impl AsRef<str> for Foo {
+ fn as_ref(&self) -> &str {
+ "hello"
+ }
+}
+
+/// Just a normal enum.
+///
+/// # title!
+#[doc(alias = "ThisIsAnAlias")]
+pub enum WhoLetTheDogOut {
+ /// Woof!
+ Woof,
+ /// Meoooooooow...
+ Meow,
+}
+
+/// Who doesn't love to wrap a `format!` call?
+pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
+ format!("{:?}", t)
+}
+
+/// Woohoo! A trait!
+pub trait AnotherOne {
+ /// Some func 3.
+ fn func3();
+
+ /// Some func 1.
+ fn func1();
+
+ fn another();
+ fn why_not();
+
+ /// Some func 2.
+ fn func2();
+
+ fn hello();
+}
+
+/// ```compile_fail
+/// whatever
+/// ```
+///
+/// Check for "i" signs in lists!
+///
+/// 1. elem 1
+/// 2. test 1
+/// ```compile_fail
+/// fn foo() {}
+/// ```
+/// 3. elem 3
+/// 4. ```ignore (it's a test)
+/// fn foo() {}
+/// ```
+/// 5. elem 5
+///
+/// Final one:
+///
+/// ```ignore (still a test)
+/// let x = 12;
+/// ```
+pub fn check_list_code_block() {}
+
+/// a thing with a label
+#[deprecated(since = "1.0.0", note = "text why this deprecated")]
+#[doc(cfg(unix))]
+pub fn replaced_function() {}
+
+/// Some doc with `code`!
+pub enum AnEnum {
+ WithVariants { and: usize, sub: usize, variants: usize },
+}
+
+#[doc(keyword = "CookieMonster")]
+/// Some keyword.
+pub mod keyword {}
+
+/// Just some type alias.
+pub type SomeType = u32;
+
+pub mod huge_amount_of_consts {
+ include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs"));
+}
+
+/// Very long code text `hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`.
+pub mod long_code_block {}
+
+#[macro_export]
+macro_rules! repro {
+ () => {};
+}
+
+pub use crate::repro as repro2;
+
+/// # Top-doc Prose title
+///
+/// Text below title.
+///
+/// ## Top-doc Prose sub-heading
+///
+/// Text below sub-heading.
+///
+/// ### Top-doc Prose sub-sub-heading
+///
+/// Text below sub-sub-heading
+///
+/// #### You know the drill.
+///
+/// More text.
+pub struct HeavilyDocumentedStruct {
+ /// # Title for field
+ /// ## Sub-heading for field
+ pub nothing: (),
+}
+
+/// # Title for struct impl doc
+///
+/// Text below heading.
+///
+/// ## Sub-heading for struct impl doc
+///
+/// Text below sub-heading.
+///
+/// ### Sub-sub-heading for struct impl doc
+///
+/// Text below sub-sub-heading.
+///
+impl HeavilyDocumentedStruct {
+ /// # Title for struct impl-item doc
+ /// Text below title.
+ /// ## Sub-heading for struct impl-item doc
+ /// Text below sub-heading.
+ /// ### Sub-sub-heading for struct impl-item doc
+ /// Text below sub-sub-heading.
+ pub fn do_nothing() {}
+}
+
+/// # Top-doc Prose title
+///
+/// Text below title.
+///
+/// ## Top-doc Prose sub-heading
+///
+/// Text below sub-heading.
+///
+/// ### Top-doc Prose sub-sub-heading
+///
+/// Text below sub-sub-heading
+pub enum HeavilyDocumentedEnum {
+ /// # None prose title
+ /// ## None prose sub-heading
+ None,
+ /// # Wrapped prose title
+ /// ## Wrapped prose sub-heading
+ Wrapped(
+ /// # Wrapped.0 prose title
+ /// ## Wrapped.0 prose sub-heading
+ String,
+ String,
+ ),
+ Structy {
+ /// # Structy prose title
+ /// ## Structy prose sub-heading
+ alpha: String,
+ beta: String,
+ },
+}
+
+/// # Title for enum impl doc
+///
+/// Text below heading.
+///
+/// ## Sub-heading for enum impl doc
+///
+/// Text below sub-heading.
+///
+/// ### Sub-sub-heading for enum impl doc
+///
+/// Text below sub-sub-heading.
+///
+impl HeavilyDocumentedEnum {
+ /// # Title for enum impl-item doc
+ /// Text below title.
+ /// ## Sub-heading for enum impl-item doc
+ /// Text below sub-heading.
+ /// ### Sub-sub-heading for enum impl-item doc
+ /// Text below sub-sub-heading.
+ pub fn do_nothing() {}
+}
+
+/// # Top-doc prose title
+///
+/// Text below heading.
+///
+/// ## Top-doc prose sub-heading
+///
+/// Text below heading.
+pub union HeavilyDocumentedUnion {
+ /// # Title for union variant
+ /// ## Sub-heading for union variant
+ pub nothing: (),
+ pub something: f32,
+}
+
+/// # Title for union impl doc
+/// ## Sub-heading for union impl doc
+impl HeavilyDocumentedUnion {
+ /// # Title for union impl-item doc
+ /// ## Sub-heading for union impl-item doc
+ pub fn do_nothing() {}
+}
+
+/// # Top-doc prose title
+///
+/// Text below heading.
+///
+/// ## Top-doc prose sub-heading
+///
+/// Text below heading.
+#[macro_export]
+macro_rules! heavily_documented_macro {
+ () => {};
+}
+
+pub trait EmptyTrait1 {}
+pub trait EmptyTrait2 {}
+pub trait EmptyTrait3 {}
+
+pub struct HasEmptyTraits{}
+
+impl EmptyTrait1 for HasEmptyTraits {}
+impl EmptyTrait2 for HasEmptyTraits {}
+#[doc(cfg(feature = "some-feature"))]
+impl EmptyTrait3 for HasEmptyTraits {}
+
+mod macros;
+pub use macros::*;
+
+#[doc(alias = "AliasForTheStdReexport")]
+pub use ::std as TheStdReexport;
+
+pub mod details {
+ /// We check the appearance of the `<details>`/`<summary>` in here.
+ ///
+ /// ## Hello
+ ///
+ /// <details>
+ /// <summary><h4>I'm a summary</h4></summary>
+ /// <div>I'm the content of the details!</div>
+ /// </details>
+ pub struct Details;
+}
diff --git a/src/test/rustdoc-gui/src/test_docs/macros.rs b/src/test/rustdoc-gui/src/test_docs/macros.rs
new file mode 100644
index 000000000..07b2b9792
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/macros.rs
@@ -0,0 +1,4 @@
+#[macro_export]
+macro_rules! a{ () => {}}
+#[macro_export]
+macro_rules! b{ () => {}}
diff --git a/src/test/rustdoc-gui/theme-change.goml b/src/test/rustdoc-gui/theme-change.goml
new file mode 100644
index 000000000..fb1c37ae6
--- /dev/null
+++ b/src/test/rustdoc-gui/theme-change.goml
@@ -0,0 +1,32 @@
+// Ensures that the theme change is working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
+reload:
+click: "#settings-menu"
+wait-for: "#theme-ayu"
+click: "#theme-ayu"
+// should be the ayu theme so let's check the color.
+wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
+assert-local-storage: { "rustdoc-theme": "ayu" }
+click: "#theme-light"
+// should be the light theme so let's check the color.
+wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-local-storage: { "rustdoc-theme": "light" }
+click: "#theme-dark"
+// Should be the dark theme so let's check the color.
+wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+assert-local-storage: { "rustdoc-theme": "dark" }
+
+goto: file://|DOC_PATH|/settings.html
+wait-for: "#settings"
+click: "#theme-light"
+wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-local-storage: { "rustdoc-theme": "light" }
+
+click: "#theme-dark"
+wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+assert-local-storage: { "rustdoc-theme": "dark" }
+
+click: "#theme-ayu"
+wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
+assert-local-storage: { "rustdoc-theme": "ayu" }
diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml
new file mode 100644
index 000000000..f576ced1c
--- /dev/null
+++ b/src/test/rustdoc-gui/theme-in-history.goml
@@ -0,0 +1,28 @@
+// Ensures that the theme is working when going back in history.
+goto: file://|DOC_PATH|/test_docs/index.html
+// Set the theme to dark.
+local-storage: {
+ "rustdoc-theme": "dark",
+ "rustdoc-preferred-dark-theme": "dark",
+ "rustdoc-use-system-theme": "false",
+}
+// We reload the page so the local storage settings are being used.
+reload:
+assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+assert-local-storage: { "rustdoc-theme": "dark" }
+
+// Now we go to the settings page.
+goto: file://|DOC_PATH|/settings.html
+wait-for: "#settings"
+// We change the theme to "light".
+click: "#theme-light"
+wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-local-storage: { "rustdoc-theme": "light" }
+
+// We go back in history.
+history-go-back:
+// Confirm that we're not on the settings page.
+assert-false: "#settings"
+// Check that the current theme is still "light".
+assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-local-storage: { "rustdoc-theme": "light" }
diff --git a/src/test/rustdoc-gui/toggle-click-deadspace.goml b/src/test/rustdoc-gui/toggle-click-deadspace.goml
new file mode 100644
index 000000000..4a328c9f9
--- /dev/null
+++ b/src/test/rustdoc-gui/toggle-click-deadspace.goml
@@ -0,0 +1,12 @@
+// This test ensures that clicking on a method summary, but not on the "[-]",
+// doesn't toggle the <details>.
+goto: file://|DOC_PATH|/lib2/struct.Foo.html
+assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
+click: "h4.code-header" // This is the position of "pub" in "pub fn a_method"
+assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""})
+click: ".impl-items .rustdoc-toggle summary::before" // This is the position of "[-]" next to that pub fn.
+assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""})
+
+// Click the "Trait" part of "impl Trait" and verify it navigates.
+click: "#impl-Trait-for-Foo h3 a:first-of-type"
+assert-text: (".fqn .in-band", "Trait lib2::Trait")
diff --git a/src/test/rustdoc-gui/toggle-docs-mobile.goml b/src/test/rustdoc-gui/toggle-docs-mobile.goml
new file mode 100644
index 000000000..ee6bc3cf7
--- /dev/null
+++ b/src/test/rustdoc-gui/toggle-docs-mobile.goml
@@ -0,0 +1,33 @@
+// Checks that the documentation toggles on mobile have the correct position, style and work
+// as expected.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+size: (433, 600)
+assert-attribute: (".top-doc", {"open": ""})
+click: (4, 270) // This is the position of the top doc comment toggle
+assert-attribute-false: (".top-doc", {"open": ""})
+click: (4, 270)
+assert-attribute: (".top-doc", {"open": ""})
+// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
+click: (3, 270)
+assert-attribute: (".top-doc", {"open": ""})
+
+// Assert the position of the toggle on the top doc block.
+assert-position: (".top-doc summary::before", {"x": 4})
+// Assert the position of the toggle on the impl block.
+assert-position: ("#implementations-list > details > summary::before", {"x": 4})
+// Assert the position of the toggle on a method.
+assert-position: (
+ "#trait-implementations-list .impl-items .method-toggle > summary::before",
+ {"x": 4},
+)
+
+// Now we do the same but with a little bigger width
+size: (600, 600)
+assert-attribute: (".top-doc", {"open": ""})
+click: (4, 270) // New Y position since all search elements are back on one line.
+assert-attribute-false: (".top-doc", {"open": ""})
+click: (4, 270)
+assert-attribute: (".top-doc", {"open": ""})
+// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
+click: (3, 270)
+assert-attribute: (".top-doc", {"open": ""})
diff --git a/src/test/rustdoc-gui/toggle-docs.goml b/src/test/rustdoc-gui/toggle-docs.goml
new file mode 100644
index 000000000..63962b576
--- /dev/null
+++ b/src/test/rustdoc-gui/toggle-docs.goml
@@ -0,0 +1,42 @@
+// Checks that the documentation toggles have the correct position, style and work as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-attribute: ("#main-content > details.top-doc", {"open": ""})
+assert-text: ("#toggle-all-docs", "[−]")
+click: "#toggle-all-docs"
+wait-for: 50
+// This is now collapsed so there shouldn't be the "open" attribute on details.
+assert-attribute-false: ("#main-content > details.top-doc", {"open": ""})
+assert-text: ("#toggle-all-docs", "[+]")
+click: "#toggle-all-docs"
+// Not collapsed anymore so the "open" attribute should be back.
+wait-for-attribute: ("#main-content > details.top-doc", {"open": ""})
+assert-text: ("#toggle-all-docs", "[−]")
+
+// Check that it works on non-module pages as well.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+// We first check that everything is visible.
+assert-text: ("#toggle-all-docs", "[−]")
+assert-attribute: ("#implementations-list details.rustdoc-toggle", {"open": ""}, ALL)
+assert-attribute: ("#trait-implementations-list details.rustdoc-toggle", {"open": ""}, ALL)
+assert-attribute-false: (
+ "#blanket-implementations-list > details.rustdoc-toggle",
+ {"open": ""},
+ ALL,
+)
+
+// We collapse them all.
+click: "#toggle-all-docs"
+wait-for-text: ("#toggle-all-docs", "[+]")
+// We check that all <details> are collapsed (except for the impl block ones).
+assert-attribute-false: ("details.rustdoc-toggle:not(.implementors-toggle)", {"open": ""}, ALL)
+assert-attribute: ("#implementations-list > details.implementors-toggle", {"open": ""})
+// We now check that the other impl blocks are collapsed.
+assert-attribute-false: (
+ "#blanket-implementations-list > details.rustdoc-toggle.implementors-toggle",
+ {"open": ""},
+ ALL,
+)
+// We open them all again.
+click: "#toggle-all-docs"
+wait-for-text: ("#toggle-all-docs", "[−]")
+assert-attribute: ("details.rustdoc-toggle", {"open": ""}, ALL)
diff --git a/src/test/rustdoc-gui/toggle-implementors.goml b/src/test/rustdoc-gui/toggle-implementors.goml
new file mode 100644
index 000000000..15521ff0f
--- /dev/null
+++ b/src/test/rustdoc-gui/toggle-implementors.goml
@@ -0,0 +1,4 @@
+// This test ensures that the implementors toggle are not open by default.
+goto: file://|DOC_PATH|/implementors/trait.Whatever.html
+
+assert-attribute-false: ("#implementors-list > details", {"open": ""}, ALL)
diff --git a/src/test/rustdoc-gui/toggled-open-implementations.goml b/src/test/rustdoc-gui/toggled-open-implementations.goml
new file mode 100644
index 000000000..bc97b38c8
--- /dev/null
+++ b/src/test/rustdoc-gui/toggled-open-implementations.goml
@@ -0,0 +1,5 @@
+// This tests that the "implementations" section on struct/enum pages
+// has all the implementations toggled open by default, so users can
+// find method names in those implementations with Ctrl-F.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-attribute: (".rustdoc-toggle.implementors-toggle", {"open": ""})
diff --git a/src/test/rustdoc-gui/trait-sidebar-item-order.goml b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
new file mode 100644
index 000000000..d77d1dca4
--- /dev/null
+++ b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
@@ -0,0 +1,8 @@
+// Checks that the elements in the sidebar are alphabetically sorted.
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
+assert-text: (".sidebar-elems section .block li:nth-of-type(1) > a", "another")
+assert-text: (".sidebar-elems section .block li:nth-of-type(2) > a", "func1")
+assert-text: (".sidebar-elems section .block li:nth-of-type(3) > a", "func2")
+assert-text: (".sidebar-elems section .block li:nth-of-type(4) > a", "func3")
+assert-text: (".sidebar-elems section .block li:nth-of-type(5) > a", "hello")
+assert-text: (".sidebar-elems section .block li:nth-of-type(6) > a", "why_not")
diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml
new file mode 100644
index 000000000..22212a317
--- /dev/null
+++ b/src/test/rustdoc-gui/type-declation-overflow.goml
@@ -0,0 +1,37 @@
+// This test ensures that the items declaration content overflow is handled inside the <pre> directly.
+goto: file://|DOC_PATH|/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// Logically, the <body> scroll width should be the width of the window.
+assert-property: ("body", {"scrollWidth": "1100"})
+// However, since there is overflow in the type declaration, its scroll width is bigger.
+assert-property: (".item-decl pre", {"scrollWidth": "1324"})
+
+// In the table-ish view on the module index, the name should not be wrapped more than necessary.
+goto: file://|DOC_PATH|/lib2/too_long/index.html
+assert-property: (".item-table .struct", {"offsetWidth": "684"})
+
+// We now make the same check on type declaration...
+goto: file://|DOC_PATH|/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html
+assert-property: ("body", {"scrollWidth": "1100"})
+// We now check that the section width hasn't grown because of it.
+assert-property: ("#main-content", {"scrollWidth": "825"})
+// And now checking that it has scrollable content.
+assert-property: (".item-decl pre", {"scrollWidth": "1103"})
+
+// ... and constant.
+// On a sidenote, it also checks that the (very) long title isn't changing the docblock width.
+goto: file://|DOC_PATH|/lib2/too_long/constant.ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong.html
+assert-property: ("body", {"scrollWidth": "1100"})
+// We now check that the section width hasn't grown because of it.
+assert-property: ("#main-content", {"scrollWidth": "825"})
+// And now checking that it has scrollable content.
+assert-property: (".item-decl pre", {"scrollWidth": "950"})
+
+// On mobile:
+size: (600, 600)
+goto: file://|DOC_PATH|/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html
+// It shouldn't have an overflow in the topbar either.
+assert-property: (".mobile-topbar .location", {"scrollWidth": "492"})
+assert-property: (".mobile-topbar .location", {"clientWidth": "492"})
+assert-css: (".mobile-topbar .location", {"overflow-x": "hidden"})