| Crates.io | viewpoint-test-macros |
| lib.rs | viewpoint-test-macros |
| version | 0.4.3 |
| created_at | 2025-12-26 15:54:43.128496+00 |
| updated_at | 2026-01-17 01:18:12.590903+00 |
| description | Procedural macros for Viewpoint test framework |
| homepage | https://github.com/stephenstubbs/viewpoint |
| repository | https://github.com/stephenstubbs/viewpoint |
| max_upload_size | |
| id | 2005894 |
| size | 34,951 |
Procedural macros for the Viewpoint test framework, providing the #[viewpoint::test] attribute macro for convenient test setup.
This crate is part of the Viewpoint browser automation framework.
This crate is typically used through viewpoint-test:
[dev-dependencies]
viewpoint-test = "0.2"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use viewpoint_test::{test, Page, expect};
#[viewpoint_test::test]
async fn my_test(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
page.goto("https://example.com").goto().await?;
let heading = page.locator("h1");
expect(&heading).to_be_visible().await?;
Ok(())
}
The macro automatically:
TestHarnesspage, context, browser)Request different fixtures by changing the parameter types:
use viewpoint_test::test;
use viewpoint_core::{Page, BrowserContext, Browser};
// Get just the page (most common)
#[viewpoint_test::test]
async fn test_with_page(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
page.goto("https://example.com").goto().await?;
Ok(())
}
// Get page and context
#[viewpoint_test::test]
async fn test_with_context(
page: &Page,
context: &BrowserContext
) -> Result<(), Box<dyn std::error::Error>> {
// Add cookies to the context
context.add_cookies(vec![/* ... */]).await?;
page.goto("https://example.com").goto().await?;
Ok(())
}
// Get page, context, and browser
#[viewpoint_test::test]
async fn test_with_browser(
page: &Page,
context: &BrowserContext,
browser: &Browser
) -> Result<(), Box<dyn std::error::Error>> {
// Create additional contexts
let another_context = browser.new_context().await?;
Ok(())
}
Configure the test with attribute arguments:
use viewpoint_test::test;
use viewpoint_core::Page;
// Run in headed mode (visible browser)
#[viewpoint_test::test(headless = false)]
async fn headed_test(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
page.goto("https://example.com").goto().await?;
Ok(())
}
// Custom timeout (in milliseconds)
#[viewpoint_test::test(timeout = 60000)]
async fn slow_test(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
// This test has a 60 second timeout
page.goto("https://slow-site.com").goto().await?;
Ok(())
}
Share browsers/contexts across tests for better performance:
Share a browser across multiple tests (each test gets a fresh context and page):
use viewpoint_test::test;
use viewpoint_core::{Browser, Page};
use std::sync::OnceLock;
// Define a shared browser
static BROWSER: OnceLock<Browser> = OnceLock::new();
async fn shared_browser() -> &'static Browser {
BROWSER.get_or_init(|| {
tokio::runtime::Handle::current().block_on(async {
Browser::launch().headless(true).launch().await.unwrap()
})
})
}
#[viewpoint_test::test(scope = "browser", browser = "shared_browser")]
async fn fast_test_1(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
// Uses shared browser, but fresh context and page
page.goto("https://example.com").goto().await?;
Ok(())
}
#[viewpoint_test::test(scope = "browser", browser = "shared_browser")]
async fn fast_test_2(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
// Same shared browser, different context and page
page.goto("https://example.org").goto().await?;
Ok(())
}
Share a context across tests (each test gets a fresh page, but shares cookies/state):
use viewpoint_test::test;
use viewpoint_core::{BrowserContext, Page};
async fn shared_context() -> &'static BrowserContext {
// Return a shared context
todo!()
}
#[viewpoint_test::test(scope = "context", context = "shared_context")]
async fn test_with_shared_context(page: &Page) -> Result<(), Box<dyn std::error::Error>> {
// Uses shared context (shares cookies, storage, etc.)
page.goto("https://example.com").goto().await?;
Ok(())
}
| Option | Type | Default | Description |
|---|---|---|---|
headless |
bool | true |
Run browser in headless mode |
timeout |
integer | 30000 | Default timeout in milliseconds |
scope |
string | - | Fixture scope: "browser" or "context" |
browser |
string | - | Function name returning shared browser (required when scope = "browser") |
context |
string | - | Function name returning shared context (required when scope = "context") |
The macro is convenient but TestHarness offers more control:
use viewpoint_test::TestHarness;
#[tokio::test]
async fn explicit_test() -> Result<(), Box<dyn std::error::Error>> {
let harness = TestHarness::new().await?;
let page = harness.page();
// More explicit setup gives you more control
page.goto("https://example.com").goto().await?;
Ok(())
}
MIT