Merge pull request #2885 from ehuss/multiple-gui-books

Support multiple books in the GUI tests
This commit is contained in:
Eric Huss 2025-10-15 14:09:15 +00:00 committed by GitHub
commit 5e7b6d7d9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
81 changed files with 328 additions and 665 deletions

2
.gitignore vendored
View file

@ -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.

View file

@ -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

View file

@ -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"

View file

@ -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.

View file

@ -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)

View file

@ -1 +0,0 @@
# Heading Navigation

View file

@ -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

View file

@ -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

View file

@ -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
```

View file

@ -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_**.

View file

@ -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}

View file

@ -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
![16x16 rust-lang logo](https://rust-lang.org/logos/rust-logo-16x16.png)
## A 32x32 image
![32x32 rust-lang logo](https://rust-lang.org/logos/rust-logo-32x32-blk.png)
## A 256x256 image
![256x256 rust-lang logo](https://rust-lang.org/logos/rust-logo-256x256.png)
## A 512x512 image
![512x512 rust-lang logo](https://rust-lang.org/logos/rust-logo-512x512-blk.png)
## A large image
![2018 rust-conf art](https://raw.githubusercontent.com/rust-lang/rust-artwork/master/2018-RustConf/lucy-mountain-climber.png)
## A SVG image
![2018 rust-conf art svg](https://raw.githubusercontent.com/rust-lang/rust-artwork/461afe27d8e02451cf9f46e507f2c2a71d2b276b/2018-RustConf/lucy-mountain-climber.svg)

View file

@ -1,8 +0,0 @@
# Line breaks
This is a long
line with a couple of
line breaks in <br/>
between : both with two
spaces and return, <br/>
and with HTML tags.

View file

@ -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

View file

@ -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
- ?!

View file

@ -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}
\\]

View file

@ -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!");
}
```
<kbd>Ctrl</kbd> + <kbd>S</kbd> saves a file.
A random image sprinkled in between
![16x16 rust-lang logo](https://rust-lang.org/logos/rust-logo-16x16.png)
---
- ~~An unordered list~~
- **Hello**
- _World_
- What
1. Should
2. be
3. `put`
4. here?
5. **<kbd>Ctrl</kbd> + <kbd>S</kbd> 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
![2018 rust-conf art svg](https://raw.githubusercontent.com/rust-lang/rust-artwork/461afe27d8e02451cf9f46e507f2c2a71d2b276b/2018-RustConf/lucy-mountain-climber.svg)

View file

@ -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.

View file

@ -1,7 +0,0 @@
# Strikethrough
~Single strike~
~~This is Striked~~
~~This is **strong**, _italic_ , **_both_** and striked~~

View file

@ -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 |

View file

@ -1,11 +0,0 @@
# Tasks
- [ ] Task 1
- [ ] Task 2
- [x] Completed Task 1
- [x] Completed Task 2
---
- [ ] **Important Task**
- [x] _Completed Important task_

View file

@ -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

View file

@ -1 +0,0 @@
# Last numbered chapter

View file

@ -1,3 +0,0 @@
# Prefix Chapter
This is to verify the placement and style of prefix chapter in book index.

View file

@ -1 +0,0 @@
# Rust specific code examples

View file

@ -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!");
}
```

View file

@ -1,3 +0,0 @@
# Suffix Chapter
This is to verify the placement and style of suffix chapter in book index.

View file

@ -0,0 +1,3 @@
# All summary
This GUI test book tests all the different kinds of book items in the summary.

View file

@ -0,0 +1,2 @@
[book]
title = "all-summary"

View file

@ -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)

View file

@ -0,0 +1 @@
# Introduction

View file

@ -0,0 +1 @@
# P1 C1

View file

@ -0,0 +1 @@
# P2 C1

View file

@ -0,0 +1 @@
# Prefix 1

View file

@ -0,0 +1 @@
# Prefix 2

View file

@ -0,0 +1 @@
# Suffix 1

View file

@ -0,0 +1 @@
# Suffix 2

View file

@ -0,0 +1,2 @@
[book]
title = "basic"

View file

@ -0,0 +1,3 @@
# Summary
- [Chapter 1](./chapter_1.md)

View file

@ -0,0 +1 @@
# Chapter 1

View file

@ -0,0 +1,3 @@
# Heading nav
This GUI test book is used for testing sidebar heading navigation.

View file

@ -0,0 +1,2 @@
[book]
title = "heading-nav"

View file

@ -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)

View file

@ -0,0 +1,3 @@
# Syntax Highlighting
This GUI test book is used for testing syntax highlighting.

View file

@ -0,0 +1,2 @@
[book]
title = "Syntax Highlighting"

View file

@ -0,0 +1,3 @@
# Summary
- [Languages](./languages.md)

View file

@ -0,0 +1,3 @@
# Redirect
This GUI test book tests the redirect configuration.

View file

@ -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"

View file

@ -0,0 +1,4 @@
# Summary
- [New chapter](new-chapter.md)
- [Other chapter](other-chapter.md)

View file

@ -0,0 +1 @@
# Chapter 1

View file

@ -0,0 +1 @@
# New chapter

View file

@ -0,0 +1 @@
# Other chapter

View file

@ -0,0 +1,3 @@
# Search
This GUI test book is used for testing basic search interaction.

View file

@ -0,0 +1,2 @@
[book]
title = "search"

View file

@ -0,0 +1,4 @@
# Summary
- [Chapter 1](./chapter_1.md)
- [Chapter 2](./inner/chapter_2.md)

View file

@ -0,0 +1,7 @@
# Chapter 1
extraordinary refrigerator philosophical thunderstorm kaleidoscope
## Repeat on same page
kaleidoscope

View file

@ -0,0 +1,7 @@
# Chapter 2
championship mediterranean sophisticated tuberculosis photographer
## Repeat from other chapter
extraordinary

View file

@ -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)

View file

@ -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")

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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")

View file

@ -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"})

View file

@ -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"

View file

@ -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")

View file

@ -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"})

View file

@ -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<String> {
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) {

View file

@ -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"

View file

@ -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")

View file

@ -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|)

View file

@ -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)

View file

@ -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"})

View file

@ -0,0 +1,3 @@
# Basic book
This GUI test book is the default book with a single chapter.