Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rustdoc gui tests #79979

Merged
merged 4 commits into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ Session.vim
.cargo
!/src/test/run-make/thumb-none-qemu/example/.cargo
no_llvm_build
**node_modules
**package-lock.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is valid syntax. At least I can't find it in man gitignore and ripgrep complains about it:

rust/.gitignore: line 55: error parsing glob '**node_modules': invalid use of **; must be one path component
rust/.gitignore: line 56: error parsing glob '**package-lock.json': invalid use of **; must be one path component

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

** is to look for all subfolders, whatever the level.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that would be **/node_modules

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works for me as is but don't hesitate to send an update.

# Before adding new lines, see the comment at the top.
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ impl<'a> Builder<'a> {
test::CompiletestTest,
test::RustdocJSStd,
test::RustdocJSNotStd,
test::RustdocGUI,
test::RustdocTheme,
test::RustdocUi,
test::RustdocJson,
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub struct Config {
pub mandir: Option<PathBuf>,
pub codegen_tests: bool,
pub nodejs: Option<PathBuf>,
pub npm: Option<PathBuf>,
pub gdb: Option<PathBuf>,
pub python: Option<PathBuf>,
pub cargo_native_static: bool,
Expand Down Expand Up @@ -364,6 +365,7 @@ struct Build {
fast_submodules: Option<bool>,
gdb: Option<String>,
nodejs: Option<String>,
npm: Option<String>,
python: Option<String>,
locked_deps: Option<bool>,
vendor: Option<bool>,
Expand Down Expand Up @@ -654,6 +656,7 @@ impl Config {
};

config.nodejs = build.nodejs.map(PathBuf::from);
config.npm = build.npm.map(PathBuf::from);
config.gdb = build.gdb.map(PathBuf::from);
config.python = build.python.map(PathBuf::from);
set(&mut config.low_priority, build.low_priority);
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,10 @@ impl Build {
self.out.join(&*target.triple).join("doc")
}

fn test_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("test")
}

/// Output directory for all documentation for a target
fn compiler_doc_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("compiler-doc")
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/mk/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ check-aux:
src/tools/cargo \
src/tools/cargotest \
$(BOOTSTRAP_ARGS)
check-aux-and-gui: check-aux
$(Q)$(BOOTSTRAP) test --stage 2 \
src/test/rustdoc-gui \
$(BOOTSTRAP_ARGS)
check-bootstrap:
$(Q)$(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap_test.py
dist:
Expand Down
7 changes: 7 additions & 0 deletions src/bootstrap/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ pub fn check(build: &mut Build) {
.or_else(|| cmd_finder.maybe_have("node"))
.or_else(|| cmd_finder.maybe_have("nodejs"));

build.config.npm = build
.config
.npm
.take()
.map(|p| cmd_finder.must_have(p))
.or_else(|| cmd_finder.maybe_have("npm"));

build.config.gdb = build
.config
.gdb
Expand Down
75 changes: 75 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,78 @@ impl Step for RustdocJSNotStd {
}
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocGUI {
pub target: TargetSelection,
pub compiler: Compiler,
}

impl Step for RustdocGUI {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/test/rustdoc-gui")
}

fn make_run(run: RunConfig<'_>) {
let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
run.builder.ensure(RustdocGUI { target: run.target, compiler });
}

fn run(self, builder: &Builder<'_>) {
if let (Some(nodejs), Some(npm)) = (&builder.config.nodejs, &builder.config.npm) {
builder.ensure(compile::Std { compiler: self.compiler, target: self.target });

// The goal here is to check if the necessary packages are installed, and if not, we
// display a warning and move on.
let mut command = Command::new(&npm);
command.arg("list").arg("--depth=0");
let lines = command
.output()
.map(|output| String::from_utf8_lossy(&output.stdout).to_string())
.unwrap_or(String::new());
if !lines.contains(&" browser-ui-test@") {
println!(
"warning: rustdoc-gui test suite cannot be run because npm `browser-ui-test` \
dependency is missing",
);
println!(
"If you want to install the `{0}` dependency, run `npm install {0}`",
"browser-ui-test",
);
return;
}

let out_dir = builder.test_out(self.target).join("rustdoc-gui");
let mut command = builder.rustdoc_cmd(self.compiler);
command.arg("src/test/rustdoc-gui/lib.rs").arg("-o").arg(&out_dir);
builder.run(&mut command);

for file in fs::read_dir("src/test/rustdoc-gui").unwrap() {
let file = file.unwrap();
let file_path = file.path();
let file_name = file.file_name();

if !file_name.to_str().unwrap().ends_with(".goml") {
continue;
}
let mut command = Command::new(&nodejs);
command
.arg("src/tools/rustdoc-gui/tester.js")
.arg("--doc-folder")
.arg(out_dir.join("test_docs"))
.arg("--test-file")
.arg(file_path);
builder.run(&mut command);
}
} else {
builder.info("No nodejs found, skipping \"src/test/rustdoc-gui\" tests");
}
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Tidy;

Expand Down Expand Up @@ -1048,6 +1120,9 @@ note: if you're sure you want to do this, please open an issue as to why. In the
if let Some(ref nodejs) = builder.config.nodejs {
cmd.arg("--nodejs").arg(nodejs);
}
if let Some(ref npm) = builder.config.npm {
cmd.arg("--npm").arg(npm);
}

let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
if !is_rustdoc {
Expand Down
24 changes: 22 additions & 2 deletions src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,30 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libgl1-mesa-dev \
llvm-dev \
libfreetype6-dev \
libexpat1-dev
libexpat1-dev \
libexpat1-dev \
gnupg \
apt-utils \
wget \
fonts-ipafont-gothic \
fonts-wqy-zenhei \
fonts-thai-tlwg \
fonts-kacst \
fonts-freefont-ttf \
libxss1 \
libxtst6

RUN curl -sL https://nodejs.org/dist/v14.4.0/node-v14.4.0-linux-x64.tar.xz | tar -xJ
ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"

# Install required dependencies from browser-UI-test framework
# For now, we need to use `--unsafe-perm=true` to go around an issue when npm tries
# to create a new folder. For reference:
# https://github.com/puppeteer/puppeteer/issues/375
RUN npm install browser-ui-test -g --unsafe-perm=true
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved

COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
ENV RUST_CHECK_TARGET check-aux
ENV RUST_CHECK_TARGET check-aux-and-gui
3 changes: 3 additions & 0 deletions src/test/rustdoc-gui/basic-code.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
goto: file://|DOC_PATH|/index.html
click: ".srclink"
assert: (".line-numbers", 1)
4 changes: 4 additions & 0 deletions src/test/rustdoc-gui/basic.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
goto: file://|DOC_PATH|/index.html
assert: ("#functions")
goto: ./struct.Foo.html
assert: ("div.type-decl")
6 changes: 6 additions & 0 deletions src/test/rustdoc-gui/code-sidebar-toggle.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
goto: file://|DOC_PATH|/index.html
click: ".srclink"
click: "#sidebar-toggle"
wait-for: 500
fail: true
assert: ("#source-sidebar", { "left": "-300px" })
67 changes: 67 additions & 0 deletions src/test/rustdoc-gui/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! The point of this crate is to be able to have enough different "kinds" of
//! documentation generated so we can test each different features.

#![crate_name = "test_docs"]

use std::fmt;

/// Basic function with some code examples:
///
/// ```
/// println!("nothing fancy");
/// ```
///
/// A failing to compile one:
///
/// ```compile_fail
/// println!("where did my argument {} go? :'(");
/// ```
///
/// An ignored one:
///
/// ```ignore (it's a test)
/// Let's say I'm just some text will ya?
/// ```
pub fn foo() {}

/// Just a normal struct.
pub struct Foo;

/// Just a normal enum.
pub enum WhoLetTheDogOut {
/// Woof!
Woof,
/// Meoooooooow...
Meow,
}

/// Who doesn't love to wrap a `format!` call?
pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
format!("{:?}", t)
}

/// Woohoo! A trait!
pub trait AnotherOne {
/// Some func 1.
fn func1();

/// Some func 2.
fn func2();

/// Some func 3.
fn func3();
}

/// Check for "i" signs in lists!
///
/// 1. elem 1
/// 2.test 1
/// ```compile_fail
/// fn foo() {}
/// ```
/// 3. elem 3
/// 4. ```ignore (it's a test)
/// fn foo() {}
/// ```
/// 5. elem 5
pub fn check_list_code_block() {}
3 changes: 3 additions & 0 deletions src/test/rustdoc-gui/list_code_block.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
goto: file://|DOC_PATH|/index.html
goto: ./fn.check_list_code_block.html
assert: ("pre.rust.fn")
10 changes: 10 additions & 0 deletions src/test/rustdoc-gui/theme-change.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
goto: file://|DOC_PATH|/index.html
click: "#theme-picker"
click: "#theme-choices > button:first-child"
wait-for: 500
// should be the ayu theme so let's check the color
assert: ("body", { "background-color": "rgb(15, 20, 25)" })
click: "#theme-choices > button:last-child"
wait-for: 500
// should be the light theme so let's check the color
assert: ("body", { "background-color": "rgb(255, 255, 255)" })
7 changes: 7 additions & 0 deletions src/test/rustdoc-gui/toggle-docs.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
goto: file://|DOC_PATH|/index.html
click: "#toggle-all-docs"
wait-for: 5000
assert: ("#main > div.docblock.hidden-by-usual-hider")
click: "#toggle-all-docs"
wait-for: 5000
assert: ("#main > div.docblock.hidden-by-usual-hider", 0)
2 changes: 2 additions & 0 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ pub struct Config {

/// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests
pub nodejs: Option<String>,
/// Path to a npm executable. Used for rustdoc GUI tests
pub npm: Option<String>,
}

#[derive(Debug, Clone)]
Expand Down
2 changes: 2 additions & 0 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
.reqopt("", "llvm-components", "list of LLVM components built in", "LIST")
.optopt("", "llvm-bin-dir", "Path to LLVM's `bin` directory", "PATH")
.optopt("", "nodejs", "the name of nodejs", "PATH")
.optopt("", "npm", "the name of npm", "PATH")
.optopt("", "remote-test-client", "path to the remote test client", "PATH")
.optopt(
"",
Expand Down Expand Up @@ -264,6 +265,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
linker: matches.opt_str("linker"),
llvm_components: matches.opt_str("llvm-components").unwrap(),
nodejs: matches.opt_str("nodejs"),
npm: matches.opt_str("npm"),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1585,7 +1585,7 @@ impl<'test> TestCx<'test> {

let aux_dir = self.aux_output_dir_name();

let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path passed");
let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path not passed");
let mut rustdoc = Command::new(rustdoc_path);

rustdoc
Expand Down
Loading