mod common;
use std::rc::Rc;
use euclid::Point2D;
use servo::{InputEvent, JSValue, MouseMoveEvent, WebViewBuilder};
use servo_config::prefs::Preferences;
use url::Url;
use webrender_api::units::DevicePoint;
use crate::common::{
ServoTest, WebViewDelegateImpl, click_at_point, evaluate_javascript,
show_webview_and_wait_for_rendering_to_be_ready,
};
static DATA_URL_FOR_PAGE_WITH_SINGLE_RED_SQUARE: &str = "data:text/html,<!DOCTYPE html>\
<div><img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEklEQVQIW2P8z8AARAwMjDAGACwBA/+8RVWvAAAAAElFTkSuQmCC'\
style='width: 50px; height: 50px;'></div>";
#[test]
fn test_largest_contentful_paint_js_api() {
let servo_test = ServoTest::new_with_builder(|builder| {
let mut preferences = Preferences::default();
preferences.largest_contentful_paint_enabled = true;
builder.preferences(preferences)
});
let delegate = Rc::new(WebViewDelegateImpl::default());
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.delegate(delegate.clone())
.url(Url::parse(DATA_URL_FOR_PAGE_WITH_SINGLE_RED_SQUARE).unwrap())
.build();
show_webview_and_wait_for_rendering_to_be_ready(&servo_test, &webview, &delegate);
let lcp_script = "(async () => {
window.lcp = await new Promise(resolve => {
(new PerformanceObserver(entryList => {
resolve(entryList.getEntries()[0]);
}))
.observe({type: 'largest-contentful-paint', buffered: true});
})
})();";
if let Err(err) = evaluate_javascript(&servo_test, webview.clone(), lcp_script) {
panic!("Failed to evaluate LCP setup script: {:?}", err);
}
let lcp = evaluate_javascript(&servo_test, webview.clone(), "window.lcp.toJSON();");
if let Ok(JSValue::Object(obj)) = lcp {
assert_eq!(obj.get("name"), Some(JSValue::String("".into())).as_ref());
assert_eq!(obj.get("duration"), Some(JSValue::Number(0.0)).as_ref());
assert_eq!(
obj.get("entryType"),
Some(JSValue::String("largest-contentful-paint".into())).as_ref()
);
assert_eq!(obj.get("size"), Some(JSValue::Number(2500.0)).as_ref());
assert!(obj.get("renderTime").is_some());
assert!(obj.get("loadTime").is_some());
} else {
panic!("No entries for Largest Contentful Paint were recorded.");
}
}
#[test]
fn test_largest_contentful_paint_js_api_with_mouse_move() {
let servo_test = ServoTest::new_with_builder(|builder| {
let mut preferences = Preferences::default();
preferences.largest_contentful_paint_enabled = true;
builder.preferences(preferences)
});
let delegate = Rc::new(WebViewDelegateImpl::default());
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.delegate(delegate.clone())
.url(Url::parse(DATA_URL_FOR_PAGE_WITH_SINGLE_RED_SQUARE).unwrap())
.build();
webview.notify_input_event(InputEvent::MouseMove(MouseMoveEvent::new(
DevicePoint::new(10., 10.).into(),
)));
show_webview_and_wait_for_rendering_to_be_ready(&servo_test, &webview, &delegate);
let lcp_script = "(async () => {
window.lcp = await new Promise(resolve => {
(new PerformanceObserver(entryList => {
resolve(entryList.getEntries()[0]);
}))
.observe({type: 'largest-contentful-paint', buffered: true});
})
})();";
if let Err(err) = evaluate_javascript(&servo_test, webview.clone(), lcp_script) {
panic!("Failed to evaluate LCP setup script: {:?}", err);
}
let lcp = evaluate_javascript(&servo_test, webview.clone(), "window.lcp;");
assert_eq!(lcp, Ok(JSValue::Object(std::collections::HashMap::new())));
}
#[test]
fn test_largest_contentful_paint_js_api_with_mouse_click_and_reload() {
let servo_test = ServoTest::new_with_builder(|builder| {
let mut preferences = Preferences::default();
preferences.largest_contentful_paint_enabled = true;
builder.preferences(preferences)
});
let delegate = Rc::new(WebViewDelegateImpl::default());
let webview = WebViewBuilder::new(servo_test.servo(), servo_test.rendering_context.clone())
.delegate(delegate.clone())
.url(Url::parse(DATA_URL_FOR_PAGE_WITH_SINGLE_RED_SQUARE).unwrap())
.build();
click_at_point(&webview, Point2D::new(1., 1.));
show_webview_and_wait_for_rendering_to_be_ready(&servo_test, &webview, &delegate);
let lcp_script = "(async () => {
window.lcp = await new Promise(resolve => {
(new PerformanceObserver(entryList => {
resolve(entryList.getEntries()[0]);
}))
.observe({type: 'largest-contentful-paint', buffered: true});
})
})();";
if let Err(err) = evaluate_javascript(&servo_test, webview.clone(), lcp_script) {
panic!("Failed to evaluate LCP setup script: {:?}", err);
}
let lcp = evaluate_javascript(&servo_test, webview.clone(), "window.lcp;");
assert_eq!(lcp, Ok(JSValue::Undefined));
webview.reload();
show_webview_and_wait_for_rendering_to_be_ready(&servo_test, &webview, &delegate);
if let Err(err) = evaluate_javascript(&servo_test, webview.clone(), lcp_script) {
panic!("Failed to evaluate LCP setup script: {:?}", err);
}
let lcp = evaluate_javascript(&servo_test, webview.clone(), "window.lcp;");
assert_eq!(lcp, Ok(JSValue::Object(std::collections::HashMap::new())));
}