Skip to content
Closed
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
34 changes: 34 additions & 0 deletions packages/yew-test-runner/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "yew-test-runner"
version = "0.19.0"
edition = "2021"
authors = [
"Martin Molzer <WorldSEnder@users.noreply.github.com>",
]
repository = "https://github.com/yewstack/yew"
homepage = "https://github.com/yewstack/yew"
documentation = "https://docs.rs/yew/"
license = "MIT OR Apache-2.0"
keywords = ["web", "webasm", "javascript"]
categories = ["gui", "wasm", "web-programming"]
description = "A framework for testing client-side single-page apps"
readme = "./README.md"

[dependencies]
gloo = "0.8"
tracing = "0.1.36"
yew = { version = "0.19", path = "../yew", features = ["csr"] }

[dependencies.web-sys]
version = "^0.3.59"

[dev-dependencies]
wasm-bindgen-test = "0.3"

[features]
default = ["hydration"]
hydration = ["yew/ssr", "yew/hydration"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "documenting"]
13 changes: 13 additions & 0 deletions packages/yew-test-runner/Makefile.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[tasks.wasm-test]
command = "wasm-pack"
args = [
"test",
"--firefox",
"--headless",
"--",
"--all-features",
]

[tasks.test]
args = ["test", "--all-targets", "--all-features"]
dependencies = ["wasm-test"]
15 changes: 15 additions & 0 deletions packages/yew-test-runner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div align="center">
<img src="https://yew.rs/img/logo.png" width="150" />

<h1>Yew Test Runner</h1>

<p>
<strong>Testing framework for Yew components</strong>
</p>

<p>
<a href="https://crates.io/crates/yew-test-runner"><img alt="Crate Info" src="https://img.shields.io/crates/v/yew.svg"/></a>
<a href="https://docs.rs/yew-test-runner/"><img alt="API Docs" src="https://img.shields.io/badge/docs.rs-yew-green"/></a>
<a href="https://discord.gg/VQck8X4"><img alt="Discord Chat" src="https://img.shields.io/discord/701068342760570933"/></a>
</p>
</div>
101 changes: 101 additions & 0 deletions packages/yew-test-runner/src/layout_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! Snapshot testing of Yew components

use yew::virtual_dom::VNode;
use yew::{Html, Renderer};

use crate::scaffold::{TestScaffold, TestScaffoldProps};

#[derive(Debug)]
pub struct TestLayout<'a> {
pub name: &'a str,
pub node: VNode,
pub expected: &'a str,
}

pub fn diff_layouts(layouts: Vec<TestLayout<'_>>) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add documentation here for what diff_layouts does, steps it goes through and an example on how to use it?

Module level documentation for those who are unfamiliar with layout/snapshot testing would be good to have as well. We don't need to thoroughly explain what it is, a link to somewhere that explains it well alongside a short summary would be enough

Also, changing the signature to accept IntoIterator would be better.

Suggested change
pub fn diff_layouts(layouts: Vec<TestLayout<'_>>) {
pub fn diff_layouts<'a>(layouts: impl IntoIterator<Item = TestLayout<'a>>) {

This will allow the following to compile:

diff_layouts([layout]);
diff_layouts(vec![layout]);

let document = gloo::utils::document();
let parent_element = document.create_element("div").unwrap();

// start with empty children
let mut test_host = Renderer::<TestScaffold>::with_root(parent_element.clone()).render();
yew::scheduler::__unstable_start_now();

// Tests each layout independently
for layout in layouts.iter() {
// Apply the layout
tracing::debug!(name = layout.name, "Independently apply layout");

let vnode = layout.node.clone();
test_host.update(TestScaffoldProps { test_case: vnode });
yew::scheduler::__unstable_start_now();
assert_eq!(
parent_element.inner_html(),
format!("{}", layout.expected),
"Independent apply failed for layout '{}'",
layout.name,
);

// Diff with no changes
tracing::debug!(name = layout.name, "Independently reapply layout");

let vnode = layout.node.clone();
test_host.update(TestScaffoldProps { test_case: vnode });
yew::scheduler::__unstable_start_now();
assert_eq!(
parent_element.inner_html(),
format!("{}", layout.expected),
"Independent reapply failed for layout '{}'",
layout.name,
);

// Detach
test_host.update(TestScaffoldProps {
test_case: Html::default(),
});
yew::scheduler::__unstable_start_now();
assert_eq!(
parent_element.inner_html(),
"",
"Independent detach failed for layout '{}'",
layout.name,
);
}

// Sequentially apply each layout
for layout in layouts.iter() {
tracing::debug!(name = layout.name, "Sequentially apply layout");

let vnode = layout.node.clone();
test_host.update(TestScaffoldProps { test_case: vnode });
yew::scheduler::__unstable_start_now();
assert_eq!(
parent_element.inner_html(),
format!("{}", layout.expected),
"Sequential apply failed for layout '{}'",
layout.name,
);
}

// Sequentially detach each layout
for layout in layouts.into_iter().rev() {
let vnode = layout.node.clone();

tracing::debug!(name = layout.name, "Sequentially detach layout");
test_host.update(TestScaffoldProps { test_case: vnode });
yew::scheduler::__unstable_start_now();
assert_eq!(
parent_element.inner_html(),
format!("{}", layout.expected),
"Sequential detach failed for layout '{}'",
layout.name,
);
}

// Detach last layout
test_host.destroy();
assert_eq!(
parent_element.inner_html(),
"",
"Failed to detach last layout"
);
}
5 changes: 5 additions & 0 deletions packages/yew-test-runner/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Yew test runner

pub mod layout_tests;
pub mod procedural;
mod scaffold;
Loading