mod common;
use std::cell::RefCell;
use std::rc::Rc;
use net::test_util::{make_body, make_server};
use servo::user_contents::UserStyleSheet;
use servo::{
CreateNewWebViewRequest, JSValue, LoadStatus, RenderingContext, Servo, UserContentManager,
UserScript, WebView, WebViewBuilder, WebViewDelegate,
};
use url::Url;
use crate::common::{ServoTest, evaluate_javascript};
#[test]
fn test_user_content_manager_empty() {
let servo_test = ServoTest::new();
let user_content_manager = UserContentManager::new(servo_test.servo());
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.user_content_manager(Rc::new(user_content_manager))
.url(Url::parse("data:text/html,Hello World").unwrap())
.build();
let result = evaluate_javascript(&servo_test, webview.clone(), "window.fromUserContentScript");
assert_eq!(result, Ok(JSValue::Undefined));
}
#[test]
fn test_user_content_manager_user_script() {
let servo_test = ServoTest::new();
let (_, url) = make_server(move |_, response| {
*response.body_mut() = make_body(b"<!DOCTYPE html>\nHello".to_vec());
});
let user_content_manager = Rc::new(UserContentManager::new(servo_test.servo()));
user_content_manager.add_script(Rc::new("window.fromUserContentScript = 42;".into()));
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.user_content_manager(user_content_manager.clone())
.url(url.into_url())
.build();
let result = evaluate_javascript(&servo_test, webview.clone(), "window.fromUserContentScript");
assert_eq!(result, Ok(JSValue::Number(42.0)));
let second_user_script = Rc::new(UserScript::from("window.fromSecondUserContentScript = 32;"));
user_content_manager.add_script(second_user_script.clone());
let new_webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.user_content_manager(user_content_manager.clone())
.url(Url::parse("data:text/html,<!DOCTYPE html>").unwrap())
.build();
let result = evaluate_javascript(
&servo_test,
new_webview,
"window.fromSecondUserContentScript",
);
assert_eq!(result, Ok(JSValue::Number(32.0)));
let result = evaluate_javascript(
&servo_test,
webview.clone(),
"window.fromSecondUserContentScript",
);
assert_eq!(result, Ok(JSValue::Undefined));
webview.reload();
let result = evaluate_javascript(
&servo_test,
webview.clone(),
"window.fromSecondUserContentScript",
);
assert_eq!(result, Ok(JSValue::Number(32.0)));
user_content_manager.remove_script(second_user_script);
webview.reload();
let result = evaluate_javascript(&servo_test, webview, "window.fromSecondUserContentScript");
assert_eq!(result, Ok(JSValue::Undefined));
}
#[test]
fn test_user_content_manager_for_auxiliary_webviews() {
let servo_test = ServoTest::new();
struct WebViewAuxiliaryTestDelegate {
servo: Servo,
rendering_context: Rc<dyn RenderingContext>,
auxiliary_webview: RefCell<Option<WebView>>,
}
impl WebViewDelegate for WebViewAuxiliaryTestDelegate {
fn request_create_new(&self, _parent_webview: WebView, request: CreateNewWebViewRequest) {
let user_content_manager_for_auxiliary_webview = UserContentManager::new(&self.servo);
user_content_manager_for_auxiliary_webview.add_script(Rc::new(
"window.fromAuxiliaryUserContentScript = 32;".into(),
));
let auxiliary_webview = request
.builder(self.rendering_context.clone())
.user_content_manager(Rc::new(user_content_manager_for_auxiliary_webview))
.build();
self.auxiliary_webview
.borrow_mut()
.replace(auxiliary_webview.clone());
}
}
let delegate = Rc::new(WebViewAuxiliaryTestDelegate {
servo: servo_test.servo.clone(),
rendering_context: servo_test.rendering_context.clone(),
auxiliary_webview: RefCell::new(None),
});
let user_content_manager = UserContentManager::new(servo_test.servo());
user_content_manager.add_script(Rc::new("window.fromUserContentScript = 42;".into()));
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.delegate(delegate.clone())
.user_content_manager(Rc::new(user_content_manager))
.url(
Url::parse(
"data:text/html,<!DOCTYPE html>\
<script>\
onload = () => window.open('data:text/html,<title>Auxiliary WebView</title>')\
</script>",
)
.unwrap(),
)
.build();
let load_webview = webview.clone();
let delegate_clone = delegate.clone();
let _ = servo_test.spin(move || {
load_webview.load_status() != LoadStatus::Complete ||
delegate_clone
.auxiliary_webview
.borrow()
.as_ref()
.is_none_or(|auxiliary_webview| {
auxiliary_webview.page_title() != Some("Auxiliary WebView".into())
})
});
let result = evaluate_javascript(
&servo_test,
webview.clone(),
"[ window.fromUserContentScript, window.fromAuxiliaryUserContentScript ]",
);
assert_eq!(
result,
Ok(JSValue::Array(vec![
JSValue::Number(42.0),
JSValue::Undefined
]))
);
let auxiliary_webview = delegate
.auxiliary_webview
.borrow_mut()
.take()
.expect("Gauranteed by spin");
let result = evaluate_javascript(
&servo_test,
auxiliary_webview.clone(),
"[ window.fromUserContentScript, window.fromAuxiliaryUserContentScript ]",
);
assert_eq!(
result,
Ok(JSValue::Array(vec![
JSValue::Undefined,
JSValue::Number(32.0),
]))
);
}
#[test]
fn test_user_content_manager_for_user_stylesheets() {
let servo_test = ServoTest::new();
let user_content_manager = Rc::new(UserContentManager::new(servo_test.servo()));
#[cfg(not(target_os = "windows"))]
let url = Url::from_file_path("/test/test.css").unwrap();
#[cfg(target_os = "windows")]
let url = Url::from_file_path("C:\\test\\test.css").unwrap();
let user_stylesheet = Rc::new(UserStyleSheet::new(
"div { width: 100px; height: 50px }\
p { width: 200px; height: 200px }"
.into(),
url,
));
user_content_manager.add_stylesheet(user_stylesheet.clone());
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.user_content_manager(user_content_manager.clone())
.url(
Url::parse(
"data:text/html,<!DOCTYPE html>\
<style>p { width: 300px; height: 300px }</style>\
<div id='div1'></div><p id='p1'>test paragraph</p>",
)
.unwrap(),
)
.build();
let result = evaluate_javascript(
&servo_test,
webview.clone(),
"[ div1.offsetWidth, div1.offsetHeight, p1.offsetWidth, p1.offsetHeight ]",
);
assert_eq!(
result,
Ok(JSValue::Array(vec![
JSValue::Number(100.0),
JSValue::Number(50.0),
JSValue::Number(300.0),
JSValue::Number(300.0),
]))
);
user_content_manager.remove_stylesheet(user_stylesheet);
webview.reload();
let result = evaluate_javascript(&servo_test, webview.clone(), "div1.offsetHeight");
assert_eq!(result, Ok(JSValue::Number(0.0)));
}