Expand description
§leptos-browser-test
Leptos test-app launcher for browser-driven integration tests.
This crate owns the cargo leptos serve / cargo leptos watch process management for a local Leptos test app:
- starts cargo-leptos for you, letting it serve your application
- waits until the app is fully started
- keeps a recent tail of stdout/stderr logs for failure diagnostics
- provides a handle to the launched application
- terminates the started cargo-leptos process gracefully when the handle is dropped, which in turn gracefully terminates the Leptos app
- the handle provides
.base_url(), conveniently telling you where (randomized port) the app is reachable
Test orchestration is intentionally left to the consumer. Take a look at
browser-test, for a convenient Rust-native integration test runner using
thirtyfour.
§Installation
[dev-dependencies]
leptos-browser-test = "0.2.0"§cargo-leptos requirement
leptos-browser-test v0.2.0 sets LEPTOS_GRACEFUL_SHUTDOWN_TIMEOUT_SECS and LEPTOS_GRACEFUL_SHUTDOWN_UNIX_SIGNAL on
the managed cargo-leptos child to drive the Leptos app’s graceful-shutdown path on drop. These env vars require
cargo-leptos PR #648, which has not yet shipped. Until it lands
upstream, install cargo-leptos from here:
cargo install --locked --git https://github.com/lpotthast/cargo-leptos --branch graceful-shutdown-v2 cargo-leptos§Runtime requirements
LeptosTestApp terminates the managed cargo leptos process when it is dropped, using
tokio_process_tools::TerminateOnDrop. This requires an active multithreaded Tokio runtime, so browser tests must use:
#[tokio::test(flavor = "multi_thread")]§Usage
§Starting an app
use leptos_browser_test::{LeptosTestAppConfig, Report};
#[tokio::main]
async fn main() -> Result<(), Report> {
let app = LeptosTestAppConfig::new("testing/test-app")
.with_app_name("my test app")
.start()
.await
.map_err(Report::into_dynamic)?;
let url = app.base_url();
// run tests...
Ok(())
}Report::into_dynamic erases the typed Report<LeptosBrowserTestError> into a generic Report so it composes with
the test harness’s own error type.
§Running browser-test
Start the app, pass its base URL into the runner context, and let drop-based cleanup handle the app process after
BrowserTestRunner::run(...) returns:
use browser_test::{BrowserTestRunner, BrowserTests};
use leptos_browser_test::{LeptosTestAppConfig, Report};
struct Context {
base_url: String,
}
#[tokio::test(flavor = "multi_thread")]
async fn browser_tests() -> Result<(), Report> {
let app = LeptosTestAppConfig::new("testing/test-app")
.with_app_name("my test app")
.start()
.await
.map_err(Report::into_dynamic)?;
let context = Context {
base_url: app.base_url().to_owned(),
};
BrowserTestRunner::new()
.run(&context, BrowserTests::new().with(MyFirstTest))
.await
.map_err(Report::into_dynamic)?;
Ok(())
}
pub struct MyFirstTest {}
#[async_trait]
impl BrowserTest<Context> for MyFirstTest {
fn name(&self) -> Cow<'_, str> {
"classes_tests".into()
}
async fn run(&self, driver: &WebDriver, ctx: &Context) -> Result<(), Report> {
// TODO: Use `driver` to query the page and run assertions.
Ok(())
}
}§HTTPS
For apps served over HTTPS, override the URL scheme before starting:
use leptos_browser_test::{LeptosTestAppConfig, SiteScheme};
async fn example() -> Result<(), leptos_browser_test::Report> {
let app = LeptosTestAppConfig::new("testing/test-app")
.with_site_scheme(SiteScheme::Https)
.start()
.await
.map_err(leptos_browser_test::Report::into_dynamic)?;
let _ = app;
Ok(())
}SiteScheme only affects the base_url() returned to your harness. Configuring TLS on the served app itself is the
app’s responsibility.
§Tuning graceful shutdown
By default, the managed Leptos app gets 10 seconds to shut down on drop and is signalled with SIGINT on Unix (always
CTRL_BREAK_EVENT on Windows). Override this via:
use std::time::Duration;
use leptos_browser_test::{LeptosTestAppConfig, UnixGracefulSignal};
async fn example() -> Result<(), leptos_browser_test::Report> {
let app = LeptosTestAppConfig::new("testing/test-app")
.with_graceful_shutdown_timeout(Duration::from_secs(30))
.with_graceful_shutdown_unix_signal(UnixGracefulSignal::Terminate)
.start()
.await
.map_err(leptos_browser_test::Report::into_dynamic)?;
let _ = app;
Ok(())
}The timeout is forwarded to cargo leptos via LEPTOS_GRACEFUL_SHUTDOWN_TIMEOUT_SECS, the signal via
LEPTOS_GRACEFUL_SHUTDOWN_UNIX_SIGNAL. The signal selector is ignored on Windows.
§Manual debugging
Run the integration-test target from the consuming crate with --nocapture so the managed app’s forwarded
stdout/stderr stays visible:
cargo test --test your_integration_test -- --nocaptureMacros§
Structs§
- Leptos
Test App - A running Leptos test app process.
- Leptos
Test AppConfig - Configuration for a Leptos test app process.
- Report
- An error report that contains a context, child reports, and attachments.
Enums§
- Cargo
Leptos Mode cargo leptosmode used to start the test app.- Leptos
Browser Test Error - Error contexts reported by Leptos test app startup operations.
- Site
Scheme - URL scheme used for the browser-facing Leptos app URL.
- Unix
Graceful Signal - Graceful-shutdown signal that can be the first or escalation step on Unix before the implicit SIGKILL fallback.
Traits§
- Result
Ext - Extension trait for
Resultthat provides error handling and reporting functionality.