use crate::test_server::TestServer;
use playwright_rs::protocol::{
BrowserContextOptions, ClearCookiesOptions, Cookie, Geolocation, GrantPermissionsOptions,
Playwright, Viewport,
};
#[tokio::test]
async fn test_context_cookies_retrieve() {
let (_pw, browser, context) = crate::common::setup_context().await;
let cookie = Cookie {
name: "test_cookie".to_string(),
value: "test_value".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: Some("Lax".to_string()),
};
context
.add_cookies(&[cookie])
.await
.expect("Failed to add cookies");
let cookies = context.cookies(None).await.expect("Failed to get cookies");
let found = cookies.iter().find(|c| c.name == "test_cookie");
assert!(found.is_some(), "Cookie should be found");
let found = found.unwrap();
assert_eq!(found.value, "test_value");
assert_eq!(found.domain, "example.com");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_cookies_with_url_filter() {
let (_pw, browser, context) = crate::common::setup_context().await;
let cookie1 = Cookie {
name: "alpha_cookie".to_string(),
value: "alpha_value".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
};
let cookie2 = Cookie {
name: "beta_cookie".to_string(),
value: "beta_value".to_string(),
domain: "playwright.dev".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
};
context
.add_cookies(&[cookie1, cookie2])
.await
.expect("Failed to add cookies");
let cookies = context
.cookies(Some(&["https://example.com"]))
.await
.expect("Failed to get cookies");
let has_alpha = cookies.iter().any(|c| c.name == "alpha_cookie");
let has_beta = cookies.iter().any(|c| c.name == "beta_cookie");
assert!(has_alpha, "Should have example.com cookie");
assert!(
!has_beta,
"Should NOT have playwright.dev cookie when filtering by example.com"
);
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_cookies_empty_initially() {
let (_pw, browser, context) = crate::common::setup_context().await;
let cookies = context.cookies(None).await.expect("Failed to get cookies");
assert!(cookies.is_empty(), "New context should have no cookies");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_clear_cookies_all() {
let (_pw, browser, context) = crate::common::setup_context().await;
let cookies = vec![
Cookie {
name: "cookie_one".to_string(),
value: "value_one".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
},
Cookie {
name: "cookie_two".to_string(),
value: "value_two".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
},
];
context
.add_cookies(&cookies)
.await
.expect("Failed to add cookies");
let before = context.cookies(None).await.expect("Failed to get cookies");
assert_eq!(before.len(), 2, "Should have 2 cookies before clear");
context
.clear_cookies(None)
.await
.expect("Failed to clear cookies");
let after = context.cookies(None).await.expect("Failed to get cookies");
assert!(
after.is_empty(),
"Should have no cookies after clear_cookies"
);
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_clear_cookies_with_name_filter() {
let (_pw, browser, context) = crate::common::setup_context().await;
let cookies = vec![
Cookie {
name: "keep_me".to_string(),
value: "keep".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
},
Cookie {
name: "delete_me".to_string(),
value: "delete".to_string(),
domain: "example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: false,
secure: false,
same_site: None,
},
];
context
.add_cookies(&cookies)
.await
.expect("Failed to add cookies");
let options = ClearCookiesOptions {
name: Some("delete_me".to_string()),
domain: None,
path: None,
};
context
.clear_cookies(Some(options))
.await
.expect("Failed to clear cookies by name");
let after = context.cookies(None).await.expect("Failed to get cookies");
let has_keep = after.iter().any(|c| c.name == "keep_me");
let has_delete = after.iter().any(|c| c.name == "delete_me");
assert!(has_keep, "keep_me cookie should still exist");
assert!(!has_delete, "delete_me cookie should have been cleared");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_set_extra_http_headers() {
let server = TestServer::start().await;
let (_pw, browser, context) = crate::common::setup_context().await;
let page = context.new_page().await.expect("Failed to create page");
let mut headers = std::collections::HashMap::new();
headers.insert(
"x-custom-header".to_string(),
"custom-value-123".to_string(),
);
context
.set_extra_http_headers(headers)
.await
.expect("Failed to set extra HTTP headers");
page.goto(&format!("{}/echo-headers", server.url()), None)
.await
.expect("Failed to navigate");
let headers_json = page
.evaluate_value("document.getElementById('headers').textContent")
.await
.expect("Failed to evaluate headers");
assert!(
headers_json.contains("x-custom-header"),
"Custom header name should be present in request. Got: {}",
headers_json
);
assert!(
headers_json.contains("custom-value-123"),
"Custom header value should be present in request. Got: {}",
headers_json
);
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
server.shutdown();
}
#[tokio::test]
async fn test_context_set_extra_http_headers_multiple() {
let server = TestServer::start().await;
let (_pw, browser, context) = crate::common::setup_context().await;
let page = context.new_page().await.expect("Failed to create page");
let mut headers = std::collections::HashMap::new();
headers.insert("x-header-one".to_string(), "value-one".to_string());
headers.insert("x-header-two".to_string(), "value-two".to_string());
context
.set_extra_http_headers(headers)
.await
.expect("Failed to set extra HTTP headers");
page.goto(&format!("{}/echo-headers", server.url()), None)
.await
.expect("Failed to navigate");
let headers_json = page
.evaluate_value("document.getElementById('headers').textContent")
.await
.expect("Failed to evaluate headers");
assert!(
headers_json.contains("x-header-one"),
"First header should be present. Got: {}",
headers_json
);
assert!(
headers_json.contains("x-header-two"),
"Second header should be present. Got: {}",
headers_json
);
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
server.shutdown();
}
#[tokio::test]
async fn test_context_grant_permissions() {
let (_pw, browser, context) = crate::common::setup_context().await;
context
.grant_permissions(&["geolocation"], None)
.await
.expect("Failed to grant geolocation permission");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_grant_permissions_with_origin() {
let (_pw, browser, context) = crate::common::setup_context().await;
let options = GrantPermissionsOptions {
origin: Some("https://example.com".to_string()),
};
context
.grant_permissions(&["geolocation"], Some(options))
.await
.expect("Failed to grant permission with origin");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_grant_and_clear_permissions() {
let (_pw, browser, context) = crate::common::setup_context().await;
context
.grant_permissions(&["notifications"], None)
.await
.expect("Failed to grant notifications");
context
.clear_permissions()
.await
.expect("Failed to clear permissions");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_grant_multiple_permissions() {
let (_pw, browser, context) = crate::common::setup_context().await;
context
.grant_permissions(&["geolocation", "notifications"], None)
.await
.expect("Failed to grant multiple permissions");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_set_geolocation() {
let server = TestServer::start().await;
let (_pw, browser, context) = crate::common::setup_context().await;
context
.grant_permissions(&["geolocation"], None)
.await
.expect("Failed to grant geolocation");
let page = context.new_page().await.expect("Failed to create page");
page.goto(&format!("{}/", server.url()), None)
.await
.expect("Failed to navigate to test server");
context
.set_geolocation(Some(Geolocation {
latitude: 48.8584,
longitude: 2.2945,
accuracy: Some(10.0),
}))
.await
.expect("Failed to set geolocation");
let lat = page
.evaluate_value(
r#"new Promise(resolve => {
navigator.geolocation.getCurrentPosition(
pos => resolve(pos.coords.latitude.toFixed(4)),
err => resolve('error:' + err.message)
)
})"#,
)
.await
.expect("Failed to evaluate geolocation");
assert_eq!(lat, "48.8584", "Latitude should match set value");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
server.shutdown();
}
#[tokio::test]
async fn test_context_set_geolocation_clear() {
let (_pw, browser, context) = crate::common::setup_context().await;
context
.set_geolocation(Some(Geolocation {
latitude: 40.7128,
longitude: -74.0060,
accuracy: None,
}))
.await
.expect("Failed to set geolocation");
context
.set_geolocation(None)
.await
.expect("Failed to clear geolocation");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_set_offline_blocks_navigation() {
let (_pw, browser, context) = crate::common::setup_context().await;
let page = context.new_page().await.expect("Failed to create page");
context
.set_offline(true)
.await
.expect("Failed to set offline");
let result = page.goto("https://example.com", None).await;
assert!(result.is_err(), "Navigation should fail when offline");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_context_set_offline_then_online() {
let server = TestServer::start().await;
let (_pw, browser, context) = crate::common::setup_context().await;
let page = context.new_page().await.expect("Failed to create page");
context
.set_offline(true)
.await
.expect("Failed to set offline");
context
.set_offline(false)
.await
.expect("Failed to set back online");
page.goto(&format!("{}/", server.url()), None)
.await
.expect("Navigation should succeed after going back online");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
server.shutdown();
}
#[tokio::test]
async fn test_page_bring_to_front() {
let (_pw, browser, context) = crate::common::setup_context().await;
let page1 = context.new_page().await.expect("Failed to create page 1");
let _page2 = context.new_page().await.expect("Failed to create page 2");
page1
.bring_to_front()
.await
.expect("Failed to bring page to front");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_page_viewport_size_with_viewport() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let browser = playwright
.chromium()
.launch()
.await
.expect("Failed to launch browser");
let options = BrowserContextOptions::builder()
.viewport(Viewport {
width: 1280,
height: 720,
})
.build();
let context = browser
.new_context_with_options(options)
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let viewport = page.viewport_size();
assert!(
viewport.is_some(),
"viewport_size() should return Some when viewport is set"
);
let vp = viewport.unwrap();
assert_eq!(vp.width, 1280, "Width should be 1280");
assert_eq!(vp.height, 720, "Height should be 720");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_page_viewport_size_no_viewport() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let browser = playwright
.chromium()
.launch()
.await
.expect("Failed to launch browser");
let options = BrowserContextOptions::builder().no_viewport(true).build();
let context = browser
.new_context_with_options(options)
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let viewport = page.viewport_size();
assert!(
viewport.is_none(),
"viewport_size() should return None when no_viewport is set"
);
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}
#[tokio::test]
async fn test_page_viewport_size_after_set() {
crate::common::init_tracing();
let playwright = Playwright::launch()
.await
.expect("Failed to launch Playwright");
let browser = playwright
.chromium()
.launch()
.await
.expect("Failed to launch browser");
let options = BrowserContextOptions::builder()
.viewport(Viewport {
width: 800,
height: 600,
})
.build();
let context = browser
.new_context_with_options(options)
.await
.expect("Failed to create context");
let page = context.new_page().await.expect("Failed to create page");
let initial = page.viewport_size().expect("Should have viewport");
assert_eq!(initial.width, 800);
assert_eq!(initial.height, 600);
page.set_viewport_size(Viewport {
width: 1920,
height: 1080,
})
.await
.expect("Failed to set viewport size");
let updated = page
.viewport_size()
.expect("Should have viewport after set");
assert_eq!(updated.width, 1920, "Width should be updated to 1920");
assert_eq!(updated.height, 1080, "Height should be updated to 1080");
context.close().await.expect("Failed to close context");
browser.close().await.expect("Failed to close browser");
}