#![cfg(feature = "integration")]
use std::sync::Once;
use std::time::{Duration, Instant};
use viewpoint_core::{Browser, SnapshotOptions};
static TRACING_INIT: Once = Once::new();
fn init_tracing() {
TRACING_INIT.call_once(|| {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env()
.add_directive(tracing::Level::INFO.into()),
)
.with_test_writer()
.try_init()
.ok();
});
}
#[tokio::test]
async fn test_large_dom_snapshot_performance() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let mut html = String::from("<html><body><h1>Performance Test</h1>\n");
for i in 0..100 {
html.push_str(&format!("<button id=\"btn{i}\">Button {i}</button>\n"));
}
html.push_str("</body></html>");
page.set_content(&html)
.set()
.await
.expect("Failed to set content");
let start = Instant::now();
let snapshot = page.aria_snapshot().await.expect("Failed to get snapshot");
let duration = start.elapsed();
println!("Large DOM snapshot captured in {duration:?}");
println!("Snapshot has {} children at root", snapshot.children.len());
let yaml = snapshot.to_yaml();
assert!(
yaml.contains("[ref=c") && yaml.contains('p') && yaml.contains('e'),
"Snapshot should contain element refs in format c{{ctx}}p{{page}}e{{counter}}"
);
assert!(
duration < Duration::from_secs(5),
"Snapshot should complete in under 5 seconds, took {duration:?}"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_snapshot_without_refs_performance() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let mut html = String::from("<html><body>\n");
for i in 0..100 {
html.push_str(&format!("<button>Button {i}</button>\n"));
}
html.push_str("</body></html>");
page.set_content(&html)
.set()
.await
.expect("Failed to set content");
let start_with_refs = Instant::now();
let snapshot_with_refs = page.aria_snapshot().await.expect("Failed to get snapshot");
let duration_with_refs = start_with_refs.elapsed();
let options = SnapshotOptions::default().include_refs(false);
let start_without_refs = Instant::now();
let snapshot_without_refs = page
.aria_snapshot_with_options(options)
.await
.expect("Failed to get snapshot");
let duration_without_refs = start_without_refs.elapsed();
println!("Snapshot WITH refs: {duration_with_refs:?}");
println!("Snapshot WITHOUT refs: {duration_without_refs:?}");
let yaml_with = snapshot_with_refs.to_yaml();
let _yaml_without = snapshot_without_refs.to_yaml();
assert!(
yaml_with.contains("[ref=c") && yaml_with.contains('p') && yaml_with.contains('e'),
"Snapshot with refs should contain refs in format c{{ctx}}p{{page}}e{{counter}}"
);
if duration_without_refs < duration_with_refs {
println!(
"Without refs was {:?} faster",
duration_with_refs
.checked_sub(duration_without_refs)
.unwrap()
);
}
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_multi_frame_parallel_capture() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let html = r#"
<html><body>
<h1>Multi-Frame Test</h1>
<iframe name="frame1" srcdoc="<html><body><button>Frame 1 Button</button></body></html>"></iframe>
<iframe name="frame2" srcdoc="<html><body><button>Frame 2 Button</button></body></html>"></iframe>
<iframe name="frame3" srcdoc="<html><body><button>Frame 3 Button</button></body></html>"></iframe>
<iframe name="frame4" srcdoc="<html><body><button>Frame 4 Button</button></body></html>"></iframe>
<iframe name="frame5" srcdoc="<html><body><button>Frame 5 Button</button></body></html>"></iframe>
</body></html>
"#;
page.set_content(html)
.set()
.await
.expect("Failed to set content");
tokio::time::sleep(Duration::from_millis(500)).await;
let start = Instant::now();
let snapshot = page
.aria_snapshot_with_frames()
.await
.expect("Failed to get multi-frame snapshot");
let duration = start.elapsed();
println!("Multi-frame snapshot captured in {duration:?}");
let yaml = snapshot.to_yaml();
println!("Multi-frame snapshot:\n{yaml}");
assert!(
duration < Duration::from_secs(5),
"Multi-frame snapshot should complete in under 5 seconds, took {duration:?}"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_snapshot_options_max_concurrency() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let mut html = String::from("<html><body>\n");
for i in 0..50 {
html.push_str(&format!("<button>Button {i}</button>\n"));
}
html.push_str("</body></html>");
page.set_content(&html)
.set()
.await
.expect("Failed to set content");
let options_low = SnapshotOptions::default().max_concurrency(5);
let start_low = Instant::now();
let _ = page
.aria_snapshot_with_options(options_low)
.await
.expect("Failed to get snapshot");
let duration_low = start_low.elapsed();
let options_high = SnapshotOptions::default().max_concurrency(100);
let start_high = Instant::now();
let _ = page
.aria_snapshot_with_options(options_high)
.await
.expect("Failed to get snapshot");
let duration_high = start_high.elapsed();
println!("Low concurrency (5): {duration_low:?}");
println!("High concurrency (100): {duration_high:?}");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_snapshot_options_include_refs_false() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(
r##"
<html><body>
<button id="btn1">Button 1</button>
<button id="btn2">Button 2</button>
<a href="#">Link</a>
</body></html>
"##,
)
.set()
.await
.expect("Failed to set content");
let options = SnapshotOptions::default().include_refs(false);
let snapshot = page
.aria_snapshot_with_options(options)
.await
.expect("Failed to get snapshot");
let yaml = snapshot.to_yaml();
println!("Snapshot without refs:\n{yaml}");
assert!(
yaml.contains("button") || yaml.contains("link"),
"Snapshot should still contain elements, got: {yaml}"
);
assert!(
snapshot.node_ref.is_none(),
"Root node_ref should be None when include_refs is false"
);
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_frame_snapshot_with_options() {
init_tracing();
let browser = Browser::launch()
.headless(true)
.launch()
.await
.expect("Failed to launch browser");
let context = browser
.new_context()
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
page.set_content(
r#"
<html><body>
<h1>Main Page</h1>
<iframe name="contentframe" srcdoc="<html><body><button>Frame Button</button></body></html>"></iframe>
</body></html>
"#,
)
.set()
.await
.expect("Failed to set content");
tokio::time::sleep(Duration::from_millis(300)).await;
let frames = page.frames().await.expect("Failed to get frames");
let content_frame = frames
.iter()
.find(|f| f.name() == "contentframe")
.expect("Should find content frame");
let options = SnapshotOptions::default().include_refs(false);
let snapshot = content_frame
.aria_snapshot_with_options(options)
.await
.expect("Failed to get frame snapshot");
let yaml = snapshot.to_yaml();
println!("Frame snapshot without refs:\n{yaml}");
assert!(
yaml.contains("button"),
"Frame snapshot should contain button"
);
browser.close().await.expect("Failed to close browser");
}