diff --git a/.gitignore b/.gitignore
index 1865ff97..5eacf964 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ guide/book
.vscode
tests/dummy_book/book/
-test_book/book/
+tests/gui/books/*/book/
tests/testsuite/*/*/book/
# Ignore Jetbrains specific files.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1fdb589d..9597a865 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -185,9 +185,7 @@ If you want to disable the headless mode, use the `--disable-headless-test` opti
cargo test --test gui -- --disable-headless-test
```
-The GUI tests are in the directory `tests/gui` in text files with the `.goml` extension. These tests are run
-using a `node.js` framework called `browser-ui-test`. You can find documentation for this language on its
-[repository](https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md).
+The GUI tests are in the directory `tests/gui` in text files with the `.goml` extension. The books that the tests use are located in the `tests/gui/books` directory. These tests are run using a `node.js` framework called `browser-ui-test`. You can find documentation for this language on its [repository](https://github.com/GuillaumeGomez/browser-UI-test/blob/master/goml-script.md).
### Checking changes in `.js` files
@@ -215,7 +213,7 @@ The following are instructions for updating [highlight.js](https://highlightjs.o
1. Compare the language list that it spits out to the one in [`syntax-highlighting.md`](https://github.com/camelid/mdBook/blob/master/guide/src/format/theme/syntax-highlighting.md). If any are missing, add them to the list and rebuild (and update these docs). If any are added to the common set, add them to `syntax-highlighting.md`.
1. Copy `build/highlight.min.js` to mdbook's directory [`highlight.js`](https://github.com/rust-lang/mdBook/blob/master/src/theme/highlight.js).
1. Be sure to check the highlight.js [CHANGES](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md) for any breaking changes. Breaking changes that would affect users will need to wait until the next major release.
-1. Build mdbook with the new file and build some books with the new version and compare the output with a variety of languages to see if anything changes. The [test_book](https://github.com/rust-lang/mdBook/tree/master/test_book) contains a chapter with many languages to examine.
+1. Build mdbook with the new file and build some books with the new version and compare the output with a variety of languages to see if anything changes. The [syntax GUI test](https://github.com/rust-lang/mdBook/tree/master/tests/gui/books/highlighting) contains a chapter with many languages to examine. Update the test (`highlighting.goml`) to add any new languages.
## Publishing new releases
diff --git a/test_book/book.toml b/test_book/book.toml
deleted file mode 100644
index 854b5e7d..00000000
--- a/test_book/book.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-[book]
-title = "mdBook test book"
-description = "A demo book to test and validate changes"
-authors = ["YJDoc2"]
-language = "en"
-
-[rust]
-edition = "2018"
-
-[output.html]
-mathjax-support = true
-hash-files = true
-
-[output.html.playground]
-editable = true
-line-numbers = true
-
-[output.html.search]
-limit-results = 20
-use-boolean-and = true
-boost-title = 2
-boost-hierarchy = 2
-boost-paragraph = 1
-expand = true
-heading-split-level = 2
-
-[output.html.redirect]
-"/format/config.html" = "../prefix.html"
-
-# This is a source without a fragment, and one with a fragment that goes to
-# the same place. The redirect with the fragment is not necessary, since that
-# is the default behavior.
-"/pointless-fragment.html" = "prefix.html"
-"/pointless-fragment.html#foo" = "prefix.html#foo"
-
-"/rename-page-and-fragment.html" = "prefix.html"
-"/rename-page-and-fragment.html#orig" = "prefix.html#new"
-
-"/rename-page-fragment-elsewhere.html" = "prefix.html"
-"/rename-page-fragment-elsewhere.html#orig" = "suffix.html#new"
-
-# Rename fragment on an existing page.
-"/prefix.html#orig" = "prefix.html#new"
-# Rename fragment on an existing page to another page.
-"/prefix.html#orig-new-page" = "suffix.html#new"
-
-"/full-url-with-fragment.html" = "https://www.rust-lang.org/#fragment"
-
-"/full-url-with-fragment-map.html" = "https://www.rust-lang.org/"
-"/full-url-with-fragment-map.html#a" = "https://www.rust-lang.org/#new1"
-"/full-url-with-fragment-map.html#b" = "https://www.rust-lang.org/#new2"
diff --git a/test_book/src/README.md b/test_book/src/README.md
deleted file mode 100644
index 04d5afdc..00000000
--- a/test_book/src/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Demo Book
-
-This is a simple demo book, which is intended to be used for verifying and validating style changes in mdBook.
-This contains dummy examples of various markdown elements and code languages, so that one can check changes made in mdBook styles.
-
-This rough outline is :
-
-- individual : contains basic markdown elements such as headings, paragraphs, links etc.
-- languages : contains a `hello world` in each of supported language to see changes in syntax highlighting
-- rust : contains language examples specific to rust, such as play pen, runnable examples etc.
-
-This is more for checking and fixing style, rather than verifying that correct code is generated for given markdown, that is better handled in tests.
diff --git a/test_book/src/SUMMARY.md b/test_book/src/SUMMARY.md
deleted file mode 100644
index eadfd409..00000000
--- a/test_book/src/SUMMARY.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Summary
-
-[Prefix Chapter](prefix.md)
-
----
-
-- [Introduction](README.md)
-- [Draft Chapter]()
-
-# Actual Markdown Tag Examples
-
-- [Markdown Individual tags](individual/README.md)
- - [Heading](individual/heading.md)
- - [Paragraphs](individual/paragraph.md)
- - [Line Break](individual/linebreak.md)
- - [Emphasis](individual/emphasis.md)
- - [Blockquote](individual/blockquote.md)
- - [List](individual/list.md)
- - [Code](individual/code.md)
- - [Image](individual/image.md)
- - [Links and Horizontal Rule](individual/link_hr.md)
- - [Tables](individual/table.md)
- - [Tasks](individual/task.md)
- - [Strikethrough](individual/strikethrough.md)
- - [MathJax](individual/mathjax.md)
- - [Mixed](individual/mixed.md)
-- [Languages](languages/README.md)
- - [Syntax Highlight](languages/highlight.md)
-- [Rust Specific](rust/README.md)
- - [Rust Codeblocks](rust/rust_codeblock.md)
-- [Heading Navigation](headings/README.md)
- - [Empty page](headings/empty.md)
- - [Large text before first heading](headings/large-intro.md)
- - [Normal text before first heading](headings/normal-intro.md)
- - [Collapsed headings](headings/collapsed.md)
- - [Headings with markup](headings/markup.md)
- - [Current scrolls to bottom](headings/current-to-bottom.md)
-- [Last numbered chapter](last.md)
-
----
-
-[Suffix Chapter](suffix.md)
diff --git a/test_book/src/headings/README.md b/test_book/src/headings/README.md
deleted file mode 100644
index 4dd86b7e..00000000
--- a/test_book/src/headings/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Heading Navigation
diff --git a/test_book/src/individual/README.md b/test_book/src/individual/README.md
deleted file mode 100644
index 67a1e9dc..00000000
--- a/test_book/src/individual/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Individual Common mark tags
-
-This contains following tags:
-
-- Headings
-- Paragraphs
-- Line breaks
-- Emphasis
-- Blockquotes
-- Lists
-- Code blocks
-- Images
-- Links and Horizontal rules
-- Github tables
-- Github Task Lists
-- Strikethrough
-- Mixed
diff --git a/test_book/src/individual/blockquote.md b/test_book/src/individual/blockquote.md
deleted file mode 100644
index 9f8be54a..00000000
--- a/test_book/src/individual/blockquote.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Blockquote
-
-> This is a quoted sentence.
-
-> This is a quoted paragraph
->
-> separated lines
-> here
-
-> Nested
->
-> > Quoted
-> > Paragraph
-
-> ### And now,
->
-> **Let us _introduce_**
-> All kinds of
->
-> - tags
-> - etc
-> - stuff
->
-> 1. In
-> 2. The
-> 3. blockquote
->
-> > cause we can
-> >
-> > > Cause we can
diff --git a/test_book/src/individual/code.md b/test_book/src/individual/code.md
deleted file mode 100644
index 015376ce..00000000
--- a/test_book/src/individual/code.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Code
-
-This section only does simple code blocks and inline code, detailed syntax highlight and stuff is in the languages section
-
----
-
-```
-This is a codeblock
-```
-
----
-
-This line contains `inline code` mixed with some other stuff. (LTR)
-
-ושורה זו מכילה `inline code` אבל עם טקסט בשפה שנכתבת מימין לשמאל. (RTL)
-
----
-
-````
-escaping ``` in ```, fun, isn't it?
-````
-
----
-
-```bash,editable
-This is an editable codeblock
-```
-
----
-
-```rust
-// This links to a playpen
-```
diff --git a/test_book/src/individual/emphasis.md b/test_book/src/individual/emphasis.md
deleted file mode 100644
index deac5307..00000000
--- a/test_book/src/individual/emphasis.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Emphasis
-
-This has **bold text** in between normal.
-
-This has _italic text_ in between normal.
-
-A **line** having _both_, bold and italic text.
-
-**A bold line _having_ italic text**
-
-_An Italic line having **bold** text_
-
-Now this is going **_out of hands_**.
diff --git a/test_book/src/individual/heading.md b/test_book/src/individual/heading.md
deleted file mode 100644
index f9f4d5b2..00000000
--- a/test_book/src/individual/heading.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Chapter Heading
-
----
-
-# Really Big Heading
-
-## Big Heading
-
-### Normal-ish Heading
-
-#### Small Heading...?
-
-##### Really Small Heading
-
-###### Is it even a heading anymore - heading
-
-## Custom id {#example-id}
-
-## Custom class {.class1 .class2}
-
-## Both id and class {#example-id2 .class1 .class2}
diff --git a/test_book/src/individual/image.md b/test_book/src/individual/image.md
deleted file mode 100644
index 8bb66d33..00000000
--- a/test_book/src/individual/image.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Images
-
-For copyright and trademark information on these images, please check [rust-artwork repository](https://github.com/rust-lang/rust-artworkhttps://github.com/rust-lang/rust-artwork)
-
-## A 16x16 image
-
-
-
-## A 32x32 image
-
-
-
-## A 256x256 image
-
-
-
-## A 512x512 image
-
-
-
-## A large image
-
-
-
-## A SVG image
-
-
diff --git a/test_book/src/individual/linebreak.md b/test_book/src/individual/linebreak.md
deleted file mode 100644
index 4d353594..00000000
--- a/test_book/src/individual/linebreak.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Line breaks
-
-This is a long
-line with a couple of
-line breaks in
-between : both with two
-spaces and return,
-and with HTML tags.
diff --git a/test_book/src/individual/link_hr.md b/test_book/src/individual/link_hr.md
deleted file mode 100644
index cc939a26..00000000
--- a/test_book/src/individual/link_hr.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Links and Horizontal Rule
-
-This is followed by a Horizontal rule
-
----
-
-And this is preceded by a horizontal rule.
-
-[This](www.rust-lang.org) should link to rust-lang website
-[So should this][rl].
-**[This][rl]** is a strong link.
-_[This][rl]_ is italic.
-**_[This][rl]_** is both.
-
-[rl]: www.rust-lang.org
diff --git a/test_book/src/individual/list.md b/test_book/src/individual/list.md
deleted file mode 100644
index a1431f94..00000000
--- a/test_book/src/individual/list.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Lists
-
-1. A
-2. Normal
-3. Ordered
-4. List
-
----
-
-1. A
- 1. Nested
- 2. List
-2. But
-3. Still
-4. Normal
-
----
-
-- An
-- Unordered
-- Normal
-- List
-
----
-
-- Nested
- - Unordered
-- List
-
----
-
-- This
- 1. Is
- 2. Normal
-- ?!
diff --git a/test_book/src/individual/mathjax.md b/test_book/src/individual/mathjax.md
deleted file mode 100644
index 222e25a2..00000000
--- a/test_book/src/individual/mathjax.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# MathJax
-
-Fourier Transform
-
-\\[
-\begin{aligned}
-f(x) &= \int_{-\infty}^{\infty}F(s)(-1)^{ 2xs}ds \\\\
-F(s) &= \int_{-\infty}^{\infty}f(x)(-1)^{-2xs}dx
-\end{aligned}
-\\]
-
-The kernel can also be written as \\(e^{2i\pi xs}\\) which is more frequently used in literature.
-
-> Proof that \\(e^{ix} = \cos x + i\sin x\\) a.k.a Euler's Formula:
->
-> \\(
-\begin{aligned}
- e^x &= \sum_{n=0}^\infty \frac{x^n}{n!} \implies e^{ix} = \sum_{n=0}^\infty \frac{(ix)^n}{n!} \\\\
- \cos x &= \sum_{m=0}^\infty \frac{(-1)^m x^{2m}}{(2m)!} = \sum_{m=0}^\infty \frac{(ix)^{2m}}{(2m)!} \\\\
- \sin x &= \sum_{s=0}^\infty \frac{(-1)^s x^{2s+1}}{(2s+1)!} = \sum_{s=0}^\infty \frac{(ix)^{2s+1}}{i(2s+1)!} \\\\
- \cos x + i\sin x &= \sum_{l=0}^\infty \frac{(ix)^{2l}}{(2l)!} + \sum_{s=0}^\infty \frac{(ix)^{2s+1}}{(2s+1)!} = \sum_{n=0}^\infty \frac{(ix)^{n}}{n!} \\\\
- &= e^{ix}
-\end{aligned}
-\\)
->
-
-
-Pauli Matrices
-
-\\[
-\begin{aligned}
- \sigma_x &= \begin{pmatrix}
- 1 & 0 \\\\ 0 & 1
- \end{pmatrix} \\\\
- \sigma_y &= \begin{pmatrix}
- 0 & -i \\\\ i & 0
- \end{pmatrix} \\\\
- \sigma_z &= \begin{pmatrix}
- 1 & 0 \\\\ 0 & -1
- \end{pmatrix}
-\end{aligned}
-\\]
\ No newline at end of file
diff --git a/test_book/src/individual/mixed.md b/test_book/src/individual/mixed.md
deleted file mode 100644
index 10b487a0..00000000
--- a/test_book/src/individual/mixed.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Mixed
-
-This contains all tags randomly mixed together, to make sure style changes in one does not affect others.
-
-### A heading
-
-**Quite a Strong statement , to make**
-
-~~No, cross that~~
-
-> Whose **quote** is this
->
-> > And ~~this~~
-> >
-> > > - and
-> > > - this
-> > > - also
-
-```
-You encountered a wild codepen
-```
-
-```rust,editable
-// The codepen is editable and runnable
-fn main(){
- println!("Hello world!");
-}
-```
-
-Ctrl + S saves a file.
-
-A random image sprinkled in between
-
-
-
----
-
-- ~~An unordered list~~
-- **Hello**
-- _World_
-- What
- 1. Should
- 2. be
- 3. `put`
- 4. here?
- 5. **Ctrl + S saves a file.**
-
-| col1 | col2 | col 3 | col 4 | col 5 | col 6 |
-| ---- | ---- | ----- | ----- | ----- | ----- |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-
-| col1 | col2 | col 3 | An Questionable table header | col 5 | col 6 |
-| ---- | ---- | ----- | ---------------------------- | ----- | ---------------------------------------- |
-| val1 | val2 | val3 | val5 | val4 | An equally Questionable long table value |
-
-### Things to do
-
-- [x] Add individual tags
-- [ ] Add language examples
-- [ ] Add rust specific examples
-
-And another image
-
-
diff --git a/test_book/src/individual/paragraph.md b/test_book/src/individual/paragraph.md
deleted file mode 100644
index 032dd6ea..00000000
--- a/test_book/src/individual/paragraph.md
+++ /dev/null
@@ -1,25 +0,0 @@
-Just a simple paragraph.
-
-Let's stress test this.
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elit lorem, eleifend eu leo sit amet, suscipit feugiat libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin congue lectus sit amet lacus venenatis, ac sollicitudin purus condimentum. Suspendisse pretium volutpat sapien at gravida. In tincidunt, sem non accumsan consectetur, leo libero porttitor dolor, at imperdiet erat nibh quis leo. Cras dictum erat augue, quis pharetra justo porttitor posuere. Aenean sed lacinia justo, vel suscipit nisl. Etiam eleifend id mauris at gravida. Aliquam molestie cursus lorem pulvinar sollicitudin. Nam et ex dignissim, posuere sem non, pellentesque lacus. Morbi vulputate sed lorem et convallis. Duis non turpis eget elit posuere volutpat. Donec accumsan euismod enim, id consequat ex rhoncus ac. Pellentesque ac felis nisl. Duis imperdiet vel tellus ac iaculis.
-
-Vivamus nec tempus enim. Integer in ligula eget elit ornare vulputate id et est. Proin mi elit, sagittis nec urna et, iaculis imperdiet neque. Vestibulum placerat cursus dolor. Donec eu sodales nulla. Praesent ac tellus eros. Donec venenatis ligula id ex porttitor malesuada. Aliquam maximus, nisi in fringilla finibus, ante elit rhoncus dui, placerat semper nisl tellus quis odio. Cras luctus magna ultrices dolor pharetra volutpat. Maecenas non enim vitae ligula efficitur aliquet id quis quam. In sagittis mollis magna eu porta. Morbi at nulla et ante elementum pharetra in sed est. Nam commodo purus enim.
-
-Ut non elit sit amet urna luctus facilisis vel et sapien. Morbi nec metus at libero imperdiet sollicitudin eget quis lacus. Donec in ipsum at enim accumsan tempor vel sed magna. Aliquam non imperdiet neque. Etiam pharetra neque sed pretium interdum. Suspendisse potenti. Phasellus varius, lectus quis dapibus faucibus, purus mauris accumsan nibh, vel tempor quam metus nec sem. Nunc sagittis suscipit lorem eu finibus. Nullam augue leo, imperdiet vel diam et, vulputate scelerisque turpis. Nullam ut volutpat diam. Praesent cursus accumsan dui a commodo. Vivamus sed libero sed turpis facilisis rutrum id sed ligula. Ut id sollicitudin dui. Nulla pulvinar commodo lectus. Cras ut quam congue, consectetur dolor ac, consequat ante.
-
-Curabitur scelerisque sed leo eu facilisis. Nam faucibus neque eget dictum hendrerit. Duis efficitur ex sed vulputate volutpat. Praesent condimentum nisl ac sapien efficitur laoreet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut ut nibh elit. Nunc a neque lobortis, tempus diam vitae, interdum magna. Aenean eget nisl sed justo volutpat interdum. Mauris malesuada ex nisl, a dignissim dui elementum eget. Suspendisse potenti.
-
-Praesent congue fringilla sem sed faucibus. Vivamus malesuada eget mauris at molestie. In sed faucibus nulla. Vivamus elementum accumsan metus quis suscipit. Maecenas interdum est nulla. Cras volutpat cursus nibh quis sollicitudin. Morbi vitae massa laoreet, aliquet tellus quis, consectetur ipsum. Mauris euismod congue purus non condimentum. Etiam laoreet mi vel sem consectetur gravida. Vestibulum volutpat magna nunc, vitae ultrices risus commodo eu.
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elit lorem, eleifend eu leo sit amet, suscipit feugiat libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin congue lectus sit amet lacus venenatis, ac sollicitudin purus condimentum. Suspendisse pretium volutpat sapien at gravida. In tincidunt, sem non accumsan consectetur, leo libero porttitor dolor, at imperdiet erat nibh quis leo. Cras dictum erat augue, quis pharetra justo porttitor posuere. Aenean sed lacinia justo, vel suscipit nisl. Etiam eleifend id mauris at gravida. Aliquam molestie cursus lorem pulvinar sollicitudin. Nam et ex dignissim, posuere sem non, pellentesque lacus. Morbi vulputate sed lorem et convallis. Duis non turpis eget elit posuere volutpat. Donec accumsan euismod enim, id consequat ex rhoncus ac. Pellentesque ac felis nisl. Duis imperdiet vel tellus ac iaculis.
-
-Vivamus nec tempus enim. Integer in ligula eget elit ornare vulputate id et est. Proin mi elit, sagittis nec urna et, iaculis imperdiet neque. Vestibulum placerat cursus dolor. Donec eu sodales nulla. Praesent ac tellus eros. Donec venenatis ligula id ex porttitor malesuada. Aliquam maximus, nisi in fringilla finibus, ante elit rhoncus dui, placerat semper nisl tellus quis odio. Cras luctus magna ultrices dolor pharetra volutpat. Maecenas non enim vitae ligula efficitur aliquet id quis quam. In sagittis mollis magna eu porta. Morbi at nulla et ante elementum pharetra in sed est. Nam commodo purus enim.
-
-Ut non elit sit amet urna luctus facilisis vel et sapien. Morbi nec metus at libero imperdiet sollicitudin eget quis lacus. Donec in ipsum at enim accumsan tempor vel sed magna. Aliquam non imperdiet neque. Etiam pharetra neque sed pretium interdum. Suspendisse potenti. Phasellus varius, lectus quis dapibus faucibus, purus mauris accumsan nibh, vel tempor quam metus nec sem. Nunc sagittis suscipit lorem eu finibus. Nullam augue leo, imperdiet vel diam et, vulputate scelerisque turpis. Nullam ut volutpat diam. Praesent cursus accumsan dui a commodo. Vivamus sed libero sed turpis facilisis rutrum id sed ligula. Ut id sollicitudin dui. Nulla pulvinar commodo lectus. Cras ut quam congue, consectetur dolor ac, consequat ante.
-
-Curabitur scelerisque sed leo eu facilisis. Nam faucibus neque eget dictum hendrerit. Duis efficitur ex sed vulputate volutpat. Praesent condimentum nisl ac sapien efficitur laoreet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut ut nibh elit. Nunc a neque lobortis, tempus diam vitae, interdum magna. Aenean eget nisl sed justo volutpat interdum. Mauris malesuada ex nisl, a dignissim dui elementum eget. Suspendisse potenti.
-
-Praesent congue fringilla sem sed faucibus. Vivamus malesuada eget mauris at molestie. In sed faucibus nulla. Vivamus elementum accumsan metus quis suscipit. Maecenas interdum est nulla. Cras volutpat cursus nibh quis sollicitudin. Morbi vitae massa laoreet, aliquet tellus quis, consectetur ipsum. Mauris euismod congue purus non condimentum. Etiam laoreet mi vel sem consectetur gravida. Vestibulum volutpat magna nunc, vitae ultrices risus commodo eu.
-
-Hopefully everything above was rendered nicely, on both desktop and mobile.
diff --git a/test_book/src/individual/strikethrough.md b/test_book/src/individual/strikethrough.md
deleted file mode 100644
index 9a549477..00000000
--- a/test_book/src/individual/strikethrough.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Strikethrough
-
-~Single strike~
-
-~~This is Striked~~
-
-~~This is **strong**, _italic_ , **_both_** and striked~~
diff --git a/test_book/src/individual/table.md b/test_book/src/individual/table.md
deleted file mode 100644
index 43580012..00000000
--- a/test_book/src/individual/table.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Tables
-
-| col1 | col2 |
-| ---- | ---- |
-
----
-
-| col1 | col2 |
-| ---- | ---- |
-| val1 | val2 |
-
----
-
-| col1 | col2 | col 3 | col 4 | col 5 | col 6 |
-| ---- | ---- | ----- | ----- | ----- | ----- |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-
----
-
-| col1 | col2 | col 3 | col 4 | col 5 | col 6 |
-| -------------------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------- |
-| This is a simple demo book, which is intended to be used for verifying and validating style changes in mdBook. | val2 | val3 | val5 | val4 | val6 |
-| val1 | val2 | val3 | val5 | val4 | val6 |
-| val1 | val2 | val3 | val5 | val4 | This is a simple demo book, which is intended to be used for verifying and validating style changes in mdBook. |
-| val1 | val2 | This is a simple demo book, which is intended to be used for verifying and validating style changes in mdBook. | This is a simple demo book, which is intended to be used for verifying and validating style changes in mdBook. | val4 | val6 |
diff --git a/test_book/src/individual/task.md b/test_book/src/individual/task.md
deleted file mode 100644
index 84327723..00000000
--- a/test_book/src/individual/task.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Tasks
-
-- [ ] Task 1
-- [ ] Task 2
-- [x] Completed Task 1
-- [x] Completed Task 2
-
----
-
-- [ ] **Important Task**
-- [x] _Completed Important task_
diff --git a/test_book/src/languages/README.md b/test_book/src/languages/README.md
deleted file mode 100644
index 32c293f5..00000000
--- a/test_book/src/languages/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Syntax Highlighting
-
-This Currently contains following languages
-
-- apache
-- armasm
-- bash
-- c
-- coffeescript
-- cpp
-- csharp
-- css
-- d
-- diff
-- go
-- handlebars
-- haskell
-- http
-- ini
-- java
-- javascript
-- json
-- julia
-- kotlin
-- less
-- lua
-- makefile
-- markdown
-- nginx
-- nim
-- nix
-- objectivec
-- perl
-- php
-- plaintext
-- properties
-- python
-- r
-- ruby
-- rust
-- scala
-- scss
-- shell
-- sql
-- swift
-- typescript
-- x86asm
-- xml
-- yaml
diff --git a/test_book/src/last.md b/test_book/src/last.md
deleted file mode 100644
index 91aef1aa..00000000
--- a/test_book/src/last.md
+++ /dev/null
@@ -1 +0,0 @@
-# Last numbered chapter
diff --git a/test_book/src/prefix.md b/test_book/src/prefix.md
deleted file mode 100644
index 1c40c2cb..00000000
--- a/test_book/src/prefix.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Prefix Chapter
-
-This is to verify the placement and style of prefix chapter in book index.
diff --git a/test_book/src/rust/README.md b/test_book/src/rust/README.md
deleted file mode 100644
index e3bb350f..00000000
--- a/test_book/src/rust/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Rust specific code examples
diff --git a/test_book/src/rust/rust_codeblock.md b/test_book/src/rust/rust_codeblock.md
deleted file mode 100644
index 5fb2b724..00000000
--- a/test_book/src/rust/rust_codeblock.md
+++ /dev/null
@@ -1,27 +0,0 @@
-## Rust codeblocks
-
-This contains various examples of codeblocks, specific to rust
-
-## Simple
-
-```rust
-fn main(){
- println!("Hello world!");
-}
-```
-
-## With Hidden lines
-
-```rust
-# fn main(){
- println!("Hello world!");
-# }
-```
-
-## Editable
-
-```rust,editable
-fn main(){
- println!("Hello world!");
-}
-```
diff --git a/test_book/src/suffix.md b/test_book/src/suffix.md
deleted file mode 100644
index 9d86853c..00000000
--- a/test_book/src/suffix.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Suffix Chapter
-
-This is to verify the placement and style of suffix chapter in book index.
diff --git a/tests/gui/books/all-summary/README.md b/tests/gui/books/all-summary/README.md
new file mode 100644
index 00000000..41fe70ef
--- /dev/null
+++ b/tests/gui/books/all-summary/README.md
@@ -0,0 +1,3 @@
+# All summary
+
+This GUI test book tests all the different kinds of book items in the summary.
diff --git a/tests/gui/books/all-summary/book.toml b/tests/gui/books/all-summary/book.toml
new file mode 100644
index 00000000..8351df2d
--- /dev/null
+++ b/tests/gui/books/all-summary/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "all-summary"
diff --git a/tests/gui/books/all-summary/src/SUMMARY.md b/tests/gui/books/all-summary/src/SUMMARY.md
new file mode 100644
index 00000000..5835e15c
--- /dev/null
+++ b/tests/gui/books/all-summary/src/SUMMARY.md
@@ -0,0 +1,20 @@
+# Summary
+
+[Prefix 1](prefix-1.md)
+[Prefix 2](prefix-2.md)
+
+- [Introduction](intro.md)
+- [Draft]()
+
+# Part 1
+
+- [P1 C1](part-1/chapter-1.md)
+
+---
+
+# Part 2
+
+- [P2 C1](part-2/chapter-1.md)
+
+[Suffix 1](suffix-1.md)
+[Suffix 2](suffix-2.md)
diff --git a/tests/gui/books/all-summary/src/intro.md b/tests/gui/books/all-summary/src/intro.md
new file mode 100644
index 00000000..e10b99d0
--- /dev/null
+++ b/tests/gui/books/all-summary/src/intro.md
@@ -0,0 +1 @@
+# Introduction
diff --git a/tests/gui/books/all-summary/src/part-1/chapter-1.md b/tests/gui/books/all-summary/src/part-1/chapter-1.md
new file mode 100644
index 00000000..f054ae72
--- /dev/null
+++ b/tests/gui/books/all-summary/src/part-1/chapter-1.md
@@ -0,0 +1 @@
+# P1 C1
diff --git a/tests/gui/books/all-summary/src/part-2/chapter-1.md b/tests/gui/books/all-summary/src/part-2/chapter-1.md
new file mode 100644
index 00000000..fd529e4e
--- /dev/null
+++ b/tests/gui/books/all-summary/src/part-2/chapter-1.md
@@ -0,0 +1 @@
+# P2 C1
diff --git a/tests/gui/books/all-summary/src/prefix-1.md b/tests/gui/books/all-summary/src/prefix-1.md
new file mode 100644
index 00000000..4ddb4143
--- /dev/null
+++ b/tests/gui/books/all-summary/src/prefix-1.md
@@ -0,0 +1 @@
+# Prefix 1
diff --git a/tests/gui/books/all-summary/src/prefix-2.md b/tests/gui/books/all-summary/src/prefix-2.md
new file mode 100644
index 00000000..11ff4958
--- /dev/null
+++ b/tests/gui/books/all-summary/src/prefix-2.md
@@ -0,0 +1 @@
+# Prefix 2
diff --git a/tests/gui/books/all-summary/src/suffix-1.md b/tests/gui/books/all-summary/src/suffix-1.md
new file mode 100644
index 00000000..59a81900
--- /dev/null
+++ b/tests/gui/books/all-summary/src/suffix-1.md
@@ -0,0 +1 @@
+# Suffix 1
diff --git a/tests/gui/books/all-summary/src/suffix-2.md b/tests/gui/books/all-summary/src/suffix-2.md
new file mode 100644
index 00000000..2bf99ebe
--- /dev/null
+++ b/tests/gui/books/all-summary/src/suffix-2.md
@@ -0,0 +1 @@
+# Suffix 2
diff --git a/tests/gui/books/basic/book.toml b/tests/gui/books/basic/book.toml
new file mode 100644
index 00000000..305c98d7
--- /dev/null
+++ b/tests/gui/books/basic/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "basic"
diff --git a/tests/gui/books/basic/src/SUMMARY.md b/tests/gui/books/basic/src/SUMMARY.md
new file mode 100644
index 00000000..7390c828
--- /dev/null
+++ b/tests/gui/books/basic/src/SUMMARY.md
@@ -0,0 +1,3 @@
+# Summary
+
+- [Chapter 1](./chapter_1.md)
diff --git a/tests/gui/books/basic/src/chapter_1.md b/tests/gui/books/basic/src/chapter_1.md
new file mode 100644
index 00000000..b743fda3
--- /dev/null
+++ b/tests/gui/books/basic/src/chapter_1.md
@@ -0,0 +1 @@
+# Chapter 1
diff --git a/tests/gui/books/heading-nav/README.md b/tests/gui/books/heading-nav/README.md
new file mode 100644
index 00000000..f74c2b1c
--- /dev/null
+++ b/tests/gui/books/heading-nav/README.md
@@ -0,0 +1,3 @@
+# Heading nav
+
+This GUI test book is used for testing sidebar heading navigation.
diff --git a/tests/gui/books/heading-nav/book.toml b/tests/gui/books/heading-nav/book.toml
new file mode 100644
index 00000000..5ec1d181
--- /dev/null
+++ b/tests/gui/books/heading-nav/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "heading-nav"
diff --git a/tests/gui/books/heading-nav/src/SUMMARY.md b/tests/gui/books/heading-nav/src/SUMMARY.md
new file mode 100644
index 00000000..a7f68ee0
--- /dev/null
+++ b/tests/gui/books/heading-nav/src/SUMMARY.md
@@ -0,0 +1,8 @@
+# Summary
+
+- [Empty page](empty.md)
+- [Large text before first heading](large-intro.md)
+- [Normal text before first heading](normal-intro.md)
+- [Collapsed headings](collapsed.md)
+- [Headings with markup](markup.md)
+- [Current scrolls to bottom](current-to-bottom.md)
diff --git a/test_book/src/headings/collapsed.md b/tests/gui/books/heading-nav/src/collapsed.md
similarity index 100%
rename from test_book/src/headings/collapsed.md
rename to tests/gui/books/heading-nav/src/collapsed.md
diff --git a/test_book/src/headings/current-to-bottom.md b/tests/gui/books/heading-nav/src/current-to-bottom.md
similarity index 100%
rename from test_book/src/headings/current-to-bottom.md
rename to tests/gui/books/heading-nav/src/current-to-bottom.md
diff --git a/test_book/src/headings/empty.md b/tests/gui/books/heading-nav/src/empty.md
similarity index 100%
rename from test_book/src/headings/empty.md
rename to tests/gui/books/heading-nav/src/empty.md
diff --git a/test_book/src/headings/large-intro.md b/tests/gui/books/heading-nav/src/large-intro.md
similarity index 100%
rename from test_book/src/headings/large-intro.md
rename to tests/gui/books/heading-nav/src/large-intro.md
diff --git a/test_book/src/headings/markup.md b/tests/gui/books/heading-nav/src/markup.md
similarity index 100%
rename from test_book/src/headings/markup.md
rename to tests/gui/books/heading-nav/src/markup.md
diff --git a/test_book/src/headings/normal-intro.md b/tests/gui/books/heading-nav/src/normal-intro.md
similarity index 100%
rename from test_book/src/headings/normal-intro.md
rename to tests/gui/books/heading-nav/src/normal-intro.md
diff --git a/tests/gui/books/highlighting/README.md b/tests/gui/books/highlighting/README.md
new file mode 100644
index 00000000..7a048d42
--- /dev/null
+++ b/tests/gui/books/highlighting/README.md
@@ -0,0 +1,3 @@
+# Syntax Highlighting
+
+This GUI test book is used for testing syntax highlighting.
diff --git a/tests/gui/books/highlighting/book.toml b/tests/gui/books/highlighting/book.toml
new file mode 100644
index 00000000..8ac1e916
--- /dev/null
+++ b/tests/gui/books/highlighting/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "Syntax Highlighting"
diff --git a/tests/gui/books/highlighting/src/SUMMARY.md b/tests/gui/books/highlighting/src/SUMMARY.md
new file mode 100644
index 00000000..c634e325
--- /dev/null
+++ b/tests/gui/books/highlighting/src/SUMMARY.md
@@ -0,0 +1,3 @@
+# Summary
+
+- [Languages](./languages.md)
diff --git a/test_book/src/languages/highlight.md b/tests/gui/books/highlighting/src/languages.md
similarity index 100%
rename from test_book/src/languages/highlight.md
rename to tests/gui/books/highlighting/src/languages.md
diff --git a/tests/gui/books/redirect/README.md b/tests/gui/books/redirect/README.md
new file mode 100644
index 00000000..7e0bb6fe
--- /dev/null
+++ b/tests/gui/books/redirect/README.md
@@ -0,0 +1,3 @@
+# Redirect
+
+This GUI test book tests the redirect configuration.
diff --git a/tests/gui/books/redirect/book.toml b/tests/gui/books/redirect/book.toml
new file mode 100644
index 00000000..b1a3f1d3
--- /dev/null
+++ b/tests/gui/books/redirect/book.toml
@@ -0,0 +1,28 @@
+[book]
+title = "redirect"
+
+[output.html.redirect]
+"/inner/old.html" = "../new-chapter.html"
+
+# This is a source without a fragment, and one with a fragment that goes to
+# the same place. The redirect with the fragment is not necessary, since that
+# is the default behavior.
+"/pointless-fragment.html" = "new-chapter.html"
+"/pointless-fragment.html#foo" = "new-chapter.html#foo"
+
+"/rename-page-and-fragment.html" = "new-chapter.html"
+"/rename-page-and-fragment.html#orig" = "new-chapter.html#new"
+
+"/rename-page-fragment-elsewhere.html" = "new-chapter.html"
+"/rename-page-fragment-elsewhere.html#orig" = "other-chapter.html#new"
+
+# Rename fragment on an existing page.
+"/new-chapter.html#orig" = "new-chapter.html#new"
+# Rename fragment on an existing page to another page.
+"/new-chapter.html#orig-new-chapter" = "other-chapter.html#new"
+
+"/full-url-with-fragment.html" = "https://www.rust-lang.org/#fragment"
+
+"/full-url-with-fragment-map.html" = "https://www.rust-lang.org/"
+"/full-url-with-fragment-map.html#a" = "https://www.rust-lang.org/#new1"
+"/full-url-with-fragment-map.html#b" = "https://www.rust-lang.org/#new2"
diff --git a/tests/gui/books/redirect/src/SUMMARY.md b/tests/gui/books/redirect/src/SUMMARY.md
new file mode 100644
index 00000000..e034ffe3
--- /dev/null
+++ b/tests/gui/books/redirect/src/SUMMARY.md
@@ -0,0 +1,4 @@
+# Summary
+
+- [New chapter](new-chapter.md)
+- [Other chapter](other-chapter.md)
diff --git a/tests/gui/books/redirect/src/chapter_1.md b/tests/gui/books/redirect/src/chapter_1.md
new file mode 100644
index 00000000..b743fda3
--- /dev/null
+++ b/tests/gui/books/redirect/src/chapter_1.md
@@ -0,0 +1 @@
+# Chapter 1
diff --git a/tests/gui/books/redirect/src/new-chapter.md b/tests/gui/books/redirect/src/new-chapter.md
new file mode 100644
index 00000000..cb233a60
--- /dev/null
+++ b/tests/gui/books/redirect/src/new-chapter.md
@@ -0,0 +1 @@
+# New chapter
diff --git a/tests/gui/books/redirect/src/other-chapter.md b/tests/gui/books/redirect/src/other-chapter.md
new file mode 100644
index 00000000..9d4d6853
--- /dev/null
+++ b/tests/gui/books/redirect/src/other-chapter.md
@@ -0,0 +1 @@
+# Other chapter
diff --git a/tests/gui/books/search/README.md b/tests/gui/books/search/README.md
new file mode 100644
index 00000000..d087e6cd
--- /dev/null
+++ b/tests/gui/books/search/README.md
@@ -0,0 +1,3 @@
+# Search
+
+This GUI test book is used for testing basic search interaction.
diff --git a/tests/gui/books/search/book.toml b/tests/gui/books/search/book.toml
new file mode 100644
index 00000000..a7bdef3d
--- /dev/null
+++ b/tests/gui/books/search/book.toml
@@ -0,0 +1,2 @@
+[book]
+title = "search"
diff --git a/tests/gui/books/search/src/SUMMARY.md b/tests/gui/books/search/src/SUMMARY.md
new file mode 100644
index 00000000..6df575ed
--- /dev/null
+++ b/tests/gui/books/search/src/SUMMARY.md
@@ -0,0 +1,4 @@
+# Summary
+
+- [Chapter 1](./chapter_1.md)
+- [Chapter 2](./inner/chapter_2.md)
diff --git a/tests/gui/books/search/src/chapter_1.md b/tests/gui/books/search/src/chapter_1.md
new file mode 100644
index 00000000..709b8ded
--- /dev/null
+++ b/tests/gui/books/search/src/chapter_1.md
@@ -0,0 +1,7 @@
+# Chapter 1
+
+extraordinary refrigerator philosophical thunderstorm kaleidoscope
+
+## Repeat on same page
+
+kaleidoscope
diff --git a/tests/gui/books/search/src/inner/chapter_2.md b/tests/gui/books/search/src/inner/chapter_2.md
new file mode 100644
index 00000000..8c8964b7
--- /dev/null
+++ b/tests/gui/books/search/src/inner/chapter_2.md
@@ -0,0 +1,7 @@
+# Chapter 2
+
+championship mediterranean sophisticated tuberculosis photographer
+
+## Repeat from other chapter
+
+extraordinary
diff --git a/tests/gui/heading-nav-collapsed.goml b/tests/gui/heading-nav-collapsed.goml
index 66c2bff2..0985bfb6 100644
--- a/tests/gui/heading-nav-collapsed.goml
+++ b/tests/gui/heading-nav-collapsed.goml
@@ -1,7 +1,7 @@
// Tests for collapsed heading sidebar navigation.
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/collapsed.html"
+go-to: |DOC_PATH| + "heading-nav/collapsed.html"
assert-count: (".header-item", 12)
assert-count: (".current-header", 1)
diff --git a/tests/gui/heading-nav-current-to-bottom.goml b/tests/gui/heading-nav-current-to-bottom.goml
index 9375fcbe..de0cbfd9 100644
--- a/tests/gui/heading-nav-current-to-bottom.goml
+++ b/tests/gui/heading-nav-current-to-bottom.goml
@@ -2,7 +2,7 @@
// bottom.
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/current-to-bottom.html"
+go-to: |DOC_PATH| + "heading-nav/current-to-bottom.html"
assert-count: (".current-header", 1)
assert-text: (".current-header", "First header")
diff --git a/tests/gui/heading-nav-empty.goml b/tests/gui/heading-nav-empty.goml
index af7de2b7..340f4e68 100644
--- a/tests/gui/heading-nav-empty.goml
+++ b/tests/gui/heading-nav-empty.goml
@@ -1,6 +1,6 @@
// When there aren't any headings, there shouldn't be any header items in the sidebar.
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/empty.html"
+go-to: |DOC_PATH| + "heading-nav/empty.html"
assert-count: (".header-item", 0)
assert-count: (".current-header", 0)
diff --git a/tests/gui/heading-nav-large-intro.goml b/tests/gui/heading-nav-large-intro.goml
index a590d1bc..cb93c617 100644
--- a/tests/gui/heading-nav-large-intro.goml
+++ b/tests/gui/heading-nav-large-intro.goml
@@ -2,7 +2,7 @@
// you scroll down and make it visible on screen.
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/large-intro.html"
+go-to: |DOC_PATH| + "heading-nav/large-intro.html"
assert-count: (".header-item", 2)
assert-count: (".current-header", 0)
diff --git a/tests/gui/heading-nav-markup.goml b/tests/gui/heading-nav-markup.goml
index e6b37f17..c37d98d9 100644
--- a/tests/gui/heading-nav-markup.goml
+++ b/tests/gui/heading-nav-markup.goml
@@ -1,7 +1,7 @@
// When a header has various markup, the sidebar should replicate it.
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/markup.html"
+go-to: |DOC_PATH| + "heading-nav/markup.html"
assert-count: (".header-item", 5)
assert-count: (".current-header", 1)
diff --git a/tests/gui/heading-nav-normal-intro.goml b/tests/gui/heading-nav-normal-intro.goml
index c8d14a37..4a50c99d 100644
--- a/tests/gui/heading-nav-normal-intro.goml
+++ b/tests/gui/heading-nav-normal-intro.goml
@@ -2,7 +2,7 @@
// should be "current".
set-window-size: (1400, 800)
-go-to: |DOC_PATH| + "headings/normal-intro.html"
+go-to: |DOC_PATH| + "heading-nav/normal-intro.html"
assert-count: (".header-item", 4)
assert-count: (".current-header", 1)
assert-text: (".current-header", "The first heading")
diff --git a/tests/gui/help.goml b/tests/gui/help.goml
index c22eda02..d304e773 100644
--- a/tests/gui/help.goml
+++ b/tests/gui/help.goml
@@ -1,6 +1,6 @@
// This GUI test checks help popup.
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "basic/index.html"
assert-css: ("#mdbook-help-container", {"display": "none"})
press-key: '?'
wait-for-css: ("#mdbook-help-container", {"display": "flex"})
diff --git a/tests/gui/highlighting.goml b/tests/gui/highlighting.goml
new file mode 100644
index 00000000..9674afa8
--- /dev/null
+++ b/tests/gui/highlighting.goml
@@ -0,0 +1,49 @@
+// This tests syntax highlighting.
+
+go-to: |DOC_PATH| + "highlighting/index.html"
+
+assert: "#apache ~ pre > code > span.hljs-comment"
+assert: "#armasm ~ pre > code > span.hljs-symbol"
+assert: "#bash ~ pre > code > span.hljs-meta"
+assert: "#c ~ pre > code > span.hljs-meta"
+assert: "#coffeescript ~ pre > code > span.hljs-title"
+assert: "#cpp ~ pre > code > span.hljs-meta"
+assert: "#csharp ~ pre > code > span.hljs-keyword"
+assert: "#css ~ pre > code > span.hljs-keyword"
+assert: "#d ~ pre > code > span.hljs-comment"
+assert: "#diff ~ pre > code > span.hljs-comment"
+assert: "#go ~ pre > code > span.hljs-keyword"
+// Not clear why this doesn't have the hljs- prefix.
+assert: "#handlebars ~ pre > code > span.xml"
+assert: "#haskell ~ pre > code > span.hljs-title"
+assert: "#http ~ pre > code > span.hljs-keyword"
+assert: "#ini ~ pre > code > span.hljs-comment"
+assert: "#java ~ pre > code > span.hljs-class"
+assert: "#javascript ~ pre > code > span.hljs-function"
+assert: "#json ~ pre > code > span.hljs-attr"
+assert: "#julia ~ pre > code > span.hljs-comment"
+assert: "#kotlin ~ pre > code > span.hljs-keyword"
+assert: "#less ~ pre > code > span.hljs-keyword"
+assert: "#lua ~ pre > code > span.hljs-comment"
+assert: "#makefile ~ pre > code > span.hljs-comment"
+assert: "#markdown ~ pre > code > span.hljs-section"
+assert: "#nginx ~ pre > code > span.hljs-attribute"
+assert: "#nim ~ pre > code > span.hljs-keyword"
+assert: "#objectivec ~ pre > code > span.hljs-meta"
+assert: "#nix ~ pre > code > span.hljs-keyword"
+assert: "#perl ~ pre > code > span.hljs-keyword"
+assert: "#php ~ pre > code > span.hljs-meta"
+assert: "#properties ~ pre > code > span.hljs-comment"
+assert: "#python ~ pre > code > span.hljs-meta"
+assert: "#r ~ pre > code > span.hljs-keyword"
+assert: "#ruby ~ pre > code > span.hljs-comment"
+assert: "#rust ~ pre > code > span.hljs-function"
+assert: "#scala ~ pre > code > span.hljs-comment"
+assert: "#scss ~ pre > code > span.hljs-comment"
+assert: "#shell ~ pre > code > span.hljs-meta"
+assert: "#sql ~ pre > code > span.hljs-keyword"
+assert: "#swift ~ pre > code > span.hljs-keyword"
+assert: "#typescript ~ pre > code > span.hljs-keyword"
+assert: "#x86asm ~ pre > code > span.hljs-meta"
+assert: "#xml ~ pre > code > span.hljs-meta"
+assert: "#yaml ~ pre > code > span.hljs-meta"
diff --git a/tests/gui/move-between-pages.goml b/tests/gui/move-between-pages.goml
index ec71487f..227dcee6 100644
--- a/tests/gui/move-between-pages.goml
+++ b/tests/gui/move-between-pages.goml
@@ -1,36 +1,43 @@
// This tests pressing the left and right arrows moving to previous and next page.
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "all-summary/index.html"
-// default page is the first numbered page
-assert-text: ("title", "Introduction - mdBook test book")
-
-// Moving left we get to the prefix page
-press-key: 'ArrowLeft'
-assert-text: ("title", "Prefix Chapter - mdBook test book")
+// default page is the first chapter
+assert-text: ("title", "Prefix 1 - all-summary")
// Trying to move to the left beyond the prefix pages - nothing changes
press-key: 'ArrowLeft'
-assert-text: ("title", "Prefix Chapter - mdBook test book")
+assert-text: ("title", "Prefix 1 - all-summary")
-// Back to the main page
+// Move left
+go-to: |DOC_PATH| + "all-summary/intro.html"
+assert-text: ("title", "Introduction - all-summary")
+
+press-key: 'ArrowLeft'
+assert-text: ("title", "Prefix 2 - all-summary")
+
+press-key: 'ArrowLeft'
+assert-text: ("title", "Prefix 1 - all-summary")
+
+// Move right
press-key: 'ArrowRight'
-assert-text: ("title", "Introduction - mdBook test book")
+assert-text: ("title", "Prefix 2 - all-summary")
press-key: 'ArrowRight'
-assert-text: ("title", "Markdown Individual tags - mdBook test book")
+assert-text: ("title", "Introduction - all-summary")
press-key: 'ArrowRight'
-assert-text: ("title", "Heading - mdBook test book")
+assert-text: ("title", "P1 C1 - all-summary")
-// Last numbered page
-go-to: "../last.html"
-assert-text: ("title", "Last numbered chapter - mdBook test book")
-
-// Go to the suffix chapter
press-key: 'ArrowRight'
-assert-text: ("title", "Suffix Chapter - mdBook test book")
+assert-text: ("title", "P2 C1 - all-summary")
+
+press-key: 'ArrowRight'
+assert-text: ("title", "Suffix 1 - all-summary")
+
+press-key: 'ArrowRight'
+assert-text: ("title", "Suffix 2 - all-summary")
// Try to go beyond the last page
press-key: 'ArrowRight'
-assert-text: ("title", "Suffix Chapter - mdBook test book")
+assert-text: ("title", "Suffix 2 - all-summary")
diff --git a/tests/gui/redirect.goml b/tests/gui/redirect.goml
index 968f94ba..9bcd6835 100644
--- a/tests/gui/redirect.goml
+++ b/tests/gui/redirect.goml
@@ -1,41 +1,41 @@
-go-to: |DOC_PATH| + "format/config.html"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html"})
+go-to: |DOC_PATH| + "redirect/inner/old.html"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html"})
// Check that it preserves fragments when redirecting.
-go-to: |DOC_PATH| + "format/config.html#fragment"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html#fragment"})
+go-to: |DOC_PATH| + "redirect/inner/old.html#fragment"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html#fragment"})
// The fragment one here isn't necessary, but should still work.
-go-to: |DOC_PATH| + "pointless-fragment.html"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html"})
-go-to: |DOC_PATH| + "pointless-fragment.html#foo"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html#foo"})
+go-to: |DOC_PATH| + "redirect/pointless-fragment.html"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html"})
+go-to: |DOC_PATH| + "redirect/pointless-fragment.html#foo"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html#foo"})
// Page rename, and a fragment rename.
-go-to: |DOC_PATH| + "rename-page-and-fragment.html"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html"})
-go-to: |DOC_PATH| + "rename-page-and-fragment.html#orig"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html#new"})
+go-to: |DOC_PATH| + "redirect/rename-page-and-fragment.html"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html"})
+go-to: |DOC_PATH| + "redirect/rename-page-and-fragment.html#orig"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html#new"})
// Page rename, and the fragment goes to a *different* page from the default.
-go-to: |DOC_PATH| + "rename-page-fragment-elsewhere.html"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html"})
-go-to: |DOC_PATH| + "rename-page-fragment-elsewhere.html#orig"
-assert-window-property: ({"location": |DOC_PATH| + "suffix.html#new"})
+go-to: |DOC_PATH| + "redirect/rename-page-fragment-elsewhere.html"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html"})
+go-to: |DOC_PATH| + "redirect/rename-page-fragment-elsewhere.html#orig"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/other-chapter.html#new"})
// Rename fragment on an existing page.
-go-to: |DOC_PATH| + "prefix.html#orig"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html#new"})
+go-to: |DOC_PATH| + "redirect/new-chapter.html#orig"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html#new"})
// Other fragments aren't affected.
-go-to: |DOC_PATH| + "index.html" // Reset page since redirects are processed on load.
-go-to: |DOC_PATH| + "prefix.html"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html"})
-go-to: |DOC_PATH| + "index.html" // Reset page since redirects are processed on load.
-go-to: |DOC_PATH| + "prefix.html#dont-change"
-assert-window-property: ({"location": |DOC_PATH| + "prefix.html#dont-change"})
+go-to: |DOC_PATH| + "redirect/index.html" // Reset page since redirects are processed on load.
+go-to: |DOC_PATH| + "redirect/new-chapter.html"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html"})
+go-to: |DOC_PATH| + "redirect/index.html" // Reset page since redirects are processed on load.
+go-to: |DOC_PATH| + "redirect/new-chapter.html#dont-change"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/new-chapter.html#dont-change"})
// Rename fragment on an existing page to another page.
-go-to: |DOC_PATH| + "index.html" // Reset page since redirects are processed on load.
-go-to: |DOC_PATH| + "prefix.html#orig-new-page"
-assert-window-property: ({"location": |DOC_PATH| + "suffix.html#new"})
+go-to: |DOC_PATH| + "redirect/index.html" // Reset page since redirects are processed on load.
+go-to: |DOC_PATH| + "redirect/new-chapter.html#orig-new-chapter"
+assert-window-property: ({"location": |DOC_PATH| + "redirect/other-chapter.html#new"})
diff --git a/tests/gui/runner.rs b/tests/gui/runner.rs
index 8bae07a6..adecbd3c 100644
--- a/tests/gui/runner.rs
+++ b/tests/gui/runner.rs
@@ -5,9 +5,9 @@
//! information.
use serde_json::Value;
-use std::env::current_dir;
-use std::fs::{read_to_string, remove_dir_all};
-use std::process::Command;
+use std::fs::read_to_string;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output};
fn get_available_browser_ui_test_version_inner(global: bool) -> Option {
let mut command = Command::new("npm");
@@ -69,23 +69,75 @@ fn main() {
}
}
- let current_dir = current_dir().expect("failed to retrieve current directory");
- let test_book = current_dir.join("test_book");
+ let out_dir = Path::new(env!("CARGO_TARGET_TMPDIR")).join("gui");
+ build_books(&out_dir);
+ run_browser_ui_test(&out_dir);
+}
- // Result doesn't matter.
- let _ = remove_dir_all(test_book.join("book"));
+fn build_books(out_dir: &Path) {
+ let exe = build_mdbook();
+ let root = Path::new(env!("CARGO_MANIFEST_DIR"));
+ let books_dir = root.join("tests/gui/books");
+ for entry in books_dir.read_dir().unwrap() {
+ let entry = entry.unwrap();
+ let path = entry.path();
+ if !path.is_dir() {
+ continue;
+ }
+ println!("Building `{}`", path.display());
+ let mut cmd = Command::new(&exe);
+ let output = cmd
+ .arg("build")
+ .arg("--dest-dir")
+ .arg(out_dir.join(path.file_name().unwrap()))
+ .arg(&path)
+ .output()
+ .expect("mdbook should be built");
+ check_status(&cmd, &output);
+ }
+}
+fn build_mdbook() -> PathBuf {
let mut cmd = Command::new("cargo");
- cmd.arg("run").arg("build").arg(&test_book);
- // Then we run the GUI tests on it.
- assert!(cmd.status().is_ok_and(|status| status.success()));
+ let output = cmd
+ .arg("build")
+ .output()
+ .expect("cargo should be installed");
+ check_status(&cmd, &output);
+ let target_dir = detect_target_dir();
+ target_dir.join("debug/mdbook")
+}
- let book_dir = format!("file://{}", current_dir.join("test_book/book/").display());
+fn detect_target_dir() -> PathBuf {
+ let mut cmd = Command::new("cargo");
+ let output = cmd
+ .args(["metadata", "--format-version=1", "--no-deps"])
+ .output()
+ .expect("cargo should be installed");
+ check_status(&cmd, &output);
+ let v: serde_json::Value = serde_json::from_slice(&output.stdout).expect("invalid json");
+ PathBuf::from(v["target_directory"].as_str().unwrap())
+}
+fn check_status(cmd: &Command, output: &Output) {
+ if !output.status.success() {
+ eprintln!("error: `{cmd:?}` failed");
+ let stdout = std::str::from_utf8(&output.stdout).expect("stdout is not utf8");
+ let stderr = std::str::from_utf8(&output.stderr).expect("stderr is not utf8");
+ eprintln!("\n--- stdout\n{stdout}\n--- stderr\n{stderr}");
+ std::process::exit(1);
+ }
+}
+
+fn run_browser_ui_test(out_dir: &Path) {
let mut command = Command::new("npx");
+ let mut doc_path = format!("file://{}", out_dir.display());
+ if !doc_path.ends_with('/') {
+ doc_path.push('/');
+ }
command
.arg("browser-ui-test")
- .args(["--variable", "DOC_PATH", book_dir.as_str()])
+ .args(["--variable", "DOC_PATH", doc_path.as_str()])
.args(["--display-format", "compact"]);
for arg in std::env::args().skip(1) {
diff --git a/tests/gui/search.goml b/tests/gui/search.goml
index 145bbd1e..02efdf24 100644
--- a/tests/gui/search.goml
+++ b/tests/gui/search.goml
@@ -1,7 +1,7 @@
// This tests basic search behavior.
fail-on-js-error: true
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "search/index.html"
define-function: (
"open-search",
@@ -15,23 +15,23 @@ define-function: (
call-function: ("open-search", {})
assert-text: ("#mdbook-searchresults-header", "")
-write: "strikethrough"
-wait-for-text: ("#mdbook-searchresults-header", "2 search results for 'strikethrough':")
+write: "extraordinary"
+wait-for-text: ("#mdbook-searchresults-header", "2 search results for 'extraordinary':")
// Close the search display
press-key: 'Escape'
wait-for-css: ("#mdbook-search-wrapper", {"display": "none"})
// Reopening the search should show the last value
call-function: ("open-search", {})
-assert-text: ("#mdbook-searchresults-header", "2 search results for 'strikethrough':")
+assert-text: ("#mdbook-searchresults-header", "2 search results for 'extraordinary':")
// Navigate to a sub-chapter
-go-to: "./individual/strikethrough.html"
+go-to: "./inner/chapter_2.html"
assert-text: ("#mdbook-searchresults-header", "")
call-function: ("open-search", {})
-write: "strikethrough"
-wait-for-text: ("#mdbook-searchresults-header", "2 search results for 'strikethrough':")
+write: "kaleidoscope"
+wait-for-text: ("#mdbook-searchresults-header", "2 search results for 'kaleidoscope':")
// Now we test search shortcuts and more page changes.
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "search/index.html"
// This check is to ensure that the search bar is inside the search wrapper.
assert: "#mdbook-search-wrapper #mdbook-searchbar"
@@ -56,18 +56,18 @@ wait-for-css: ("#mdbook-search-wrapper", {"display": "block"})
// We ensure the search bar has the focus.
assert: "#mdbook-searchbar:focus"
-// We input "test".
-write: "test"
+// We input "thunder".
+write: "thunder"
// The results should now appear.
-wait-for-text: ("#mdbook-searchresults-header", "search results for 'test':", ENDS_WITH)
+wait-for-text: ("#mdbook-searchresults-header", "1 search result for 'thunder':")
assert: "#mdbook-searchresults"
// Ensure that the URL was updated as well.
-assert-document-property: ({"URL": "?search=test"}, ENDS_WITH)
+assert-document-property: ({"URL": "?search=thunder"}, ENDS_WITH)
// Now we ensure that when we land on the page with a "search in progress", the search results are
// loaded and that the search input has focus.
-go-to: |DOC_PATH| + "index.html?search=test"
-wait-for-text: ("#mdbook-searchresults-header", "search results for 'test':", ENDS_WITH)
+go-to: |DOC_PATH| + "search/index.html?search=thunder"
+wait-for-text: ("#mdbook-searchresults-header", "1 search result for 'thunder':")
assert: "#mdbook-searchbar:focus"
assert: "#mdbook-searchresults"
diff --git a/tests/gui/sidebar-active.goml b/tests/gui/sidebar-active.goml
index a029b2d2..f132bad5 100644
--- a/tests/gui/sidebar-active.goml
+++ b/tests/gui/sidebar-active.goml
@@ -1,17 +1,17 @@
// This GUI test checks the active page sidebar highlight.
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "all-summary/index.html"
-assert-text: ("mdbook-sidebar-scrollbox a.active", "Prefix Chapter")
+assert-text: ("mdbook-sidebar-scrollbox a.active", "Prefix 1")
-go-to: |DOC_PATH| + "individual/index.html"
+go-to: |DOC_PATH| + "all-summary/part-1/chapter-1.html"
-assert-text: ("mdbook-sidebar-scrollbox a.active", "3. Markdown Individual tags")
+assert-text: ("mdbook-sidebar-scrollbox a.active", "3. P1 C1")
-go-to: |DOC_PATH| + "index.html?highlight=test"
+go-to: |DOC_PATH| + "all-summary/index.html?highlight=test"
-assert-text: ("mdbook-sidebar-scrollbox a.active", "Prefix Chapter")
+assert-text: ("mdbook-sidebar-scrollbox a.active", "Prefix 1")
-go-to: |DOC_PATH| + "individual/index.html?highlight=test"
+go-to: |DOC_PATH| + "all-summary/part-1/chapter-1.html?highlight=test"
-assert-text: ("mdbook-sidebar-scrollbox a.active", "3. Markdown Individual tags")
+assert-text: ("mdbook-sidebar-scrollbox a.active", "3. P1 C1")
diff --git a/tests/gui/sidebar-nojs.goml b/tests/gui/sidebar-nojs.goml
index 9867b0a8..14536e0c 100644
--- a/tests/gui/sidebar-nojs.goml
+++ b/tests/gui/sidebar-nojs.goml
@@ -4,7 +4,7 @@
// We disable javascript
javascript: false
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "basic/index.html"
store-value: (height, 1028)
set-window-size: (1028, |height|)
diff --git a/tests/gui/sidebar.goml b/tests/gui/sidebar.goml
index ec44f5a4..50dc71a9 100644
--- a/tests/gui/sidebar.goml
+++ b/tests/gui/sidebar.goml
@@ -1,7 +1,7 @@
// This GUI test checks sidebar hide/show and also its behaviour on smaller
// width.
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "all-summary/index.html"
set-window-size: (1100, 600)
// Need to reload for the new size to be taken account by the JS.
reload:
@@ -44,13 +44,13 @@ define-function: (
)
// Since the sidebar is visible, we should be able to find this text.
-assert-find-text: ("3.9. Links and Horizontal Rule", {"case-sensitive": true})
+assert-find-text: ("3. P1 C1", {"case-sensitive": true})
call-function: ("hide-sidebar", {})
// Text should not be findeable anymore since the sidebar is collapsed.
-assert-find-text-false: ("3.9. Links and Horizontal Rule", {"case-sensitive": true})
+assert-find-text-false: ("3. P1 C1", {"case-sensitive": true})
call-function: ("show-sidebar", {})
// We should be able to find this text again.
-assert-find-text: ("3.9. Links and Horizontal Rule", {"case-sensitive": true})
+assert-find-text: ("3. P1 C1", {"case-sensitive": true})
// We now test on smaller width to ensure that the sidebar is collapsed by default.
set-window-size: (900, 600)
diff --git a/tests/gui/theme.goml b/tests/gui/theme.goml
index 33fde6f0..6d4feedb 100644
--- a/tests/gui/theme.goml
+++ b/tests/gui/theme.goml
@@ -2,7 +2,7 @@
debug: true
-go-to: |DOC_PATH| + "index.html"
+go-to: |DOC_PATH| + "all-summary/index.html"
// TODO: Dark mode is automatic, how to check that here?
assert-css: ("#mdbook-theme-list", {"display": "none"})
@@ -31,5 +31,5 @@ press-key: 'Escape'
assert-css: ("#mdbook-theme-list", {"display": "none"})
// Check for navigation retains theme.
-go-to: "./rust/rust_codeblock.html"
+go-to: "./part-1/chapter-1.html"
assert-attribute: ("html", {"class": "rust js"})
diff --git a/tests/testsuite/build/basic_build/README.md b/tests/testsuite/build/basic_build/README.md
new file mode 100644
index 00000000..2c574c3a
--- /dev/null
+++ b/tests/testsuite/build/basic_build/README.md
@@ -0,0 +1,3 @@
+# Basic book
+
+This GUI test book is the default book with a single chapter.