Harden PRD live-site smoke
This commit is contained in:
@@ -248,6 +248,12 @@ pub struct SidecarSnapshot {
|
|||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
|
#[cfg(test)]
|
||||||
|
non_white_pixel_count: u64,
|
||||||
|
#[cfg(test)]
|
||||||
|
content_pixel_count: u64,
|
||||||
|
#[cfg(test)]
|
||||||
|
sample_hash: u64,
|
||||||
rgba_bytes: Vec<u8>,
|
rgba_bytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +287,12 @@ impl SidecarSnapshot {
|
|||||||
title: report.title,
|
title: report.title,
|
||||||
width: report.width,
|
width: report.width,
|
||||||
height: report.height,
|
height: report.height,
|
||||||
|
#[cfg(test)]
|
||||||
|
non_white_pixel_count: report.non_white_pixel_count,
|
||||||
|
#[cfg(test)]
|
||||||
|
content_pixel_count: report.content_pixel_count,
|
||||||
|
#[cfg(test)]
|
||||||
|
sample_hash: report.sample_hash,
|
||||||
rgba_bytes,
|
rgba_bytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -379,6 +391,8 @@ struct SidecarReport {
|
|||||||
rgba_byte_count: usize,
|
rgba_byte_count: usize,
|
||||||
non_white_pixel_count: u64,
|
non_white_pixel_count: u64,
|
||||||
content_pixel_count: u64,
|
content_pixel_count: u64,
|
||||||
|
#[cfg(test)]
|
||||||
|
sample_hash: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_sidecar_command() -> Result<SidecarCommandTarget, ServoSidecarError> {
|
fn default_sidecar_command() -> Result<SidecarCommandTarget, ServoSidecarError> {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const LIVE_SITE_WIDTH: u32 = 934;
|
|||||||
#[cfg(feature = "live-site-smoke")]
|
#[cfg(feature = "live-site-smoke")]
|
||||||
const LIVE_SITE_HEIGHT: u32 = 657;
|
const LIVE_SITE_HEIGHT: u32 = 657;
|
||||||
#[cfg(feature = "live-site-smoke")]
|
#[cfg(feature = "live-site-smoke")]
|
||||||
|
const MINIMUM_CONTENT_PIXELS: u64 = 1_000;
|
||||||
|
#[cfg(feature = "live-site-smoke")]
|
||||||
const PRD_TOP_SITE_CASES: &[LiveSiteCase] = &[
|
const PRD_TOP_SITE_CASES: &[LiveSiteCase] = &[
|
||||||
LiveSiteCase { url: "https://github.com", title_fragment: "GitHub" },
|
LiveSiteCase { url: "https://github.com", title_fragment: "GitHub" },
|
||||||
LiveSiteCase { url: "https://example.com", title_fragment: "Example Domain" },
|
LiveSiteCase { url: "https://example.com", title_fragment: "Example Domain" },
|
||||||
@@ -90,6 +92,9 @@ fn accepts_loading_report_with_visible_content() -> Result<(), ServoSidecarError
|
|||||||
assert_eq!(snapshot.title(), Some("Example Domain"));
|
assert_eq!(snapshot.title(), Some("Example Domain"));
|
||||||
assert_eq!(snapshot.width(), 2);
|
assert_eq!(snapshot.width(), 2);
|
||||||
assert_eq!(snapshot.height(), 1);
|
assert_eq!(snapshot.height(), 1);
|
||||||
|
assert_eq!(snapshot.non_white_pixel_count, 1);
|
||||||
|
assert_eq!(snapshot.content_pixel_count, 1);
|
||||||
|
assert_eq!(snapshot.sample_hash, 42);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +152,9 @@ fn assert_live_sites_render(cases: &[LiveSiteCase]) -> Result<(), Box<dyn Error>
|
|||||||
assert_eq!(snapshot.height(), LIVE_SITE_HEIGHT, "{}", case.url);
|
assert_eq!(snapshot.height(), LIVE_SITE_HEIGHT, "{}", case.url);
|
||||||
assert_loaded_url_contains(&snapshot, case.url)?;
|
assert_loaded_url_contains(&snapshot, case.url)?;
|
||||||
assert_title_contains(&snapshot, case.title_fragment)?;
|
assert_title_contains(&snapshot, case.title_fragment)?;
|
||||||
|
assert!(snapshot.non_white_pixel_count > 0, "{}", case.url);
|
||||||
|
assert!(snapshot.content_pixel_count >= MINIMUM_CONTENT_PIXELS, "{}", case.url);
|
||||||
|
assert!(snapshot.sample_hash > 0, "{}", case.url);
|
||||||
|
|
||||||
let rgba_bytes = snapshot.into_rgba_bytes();
|
let rgba_bytes = snapshot.into_rgba_bytes();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -155,7 +163,6 @@ fn assert_live_sites_render(cases: &[LiveSiteCase]) -> Result<(), Box<dyn Error>
|
|||||||
"{}",
|
"{}",
|
||||||
case.url
|
case.url
|
||||||
);
|
);
|
||||||
assert!(non_white_pixel_count(&rgba_bytes) > 0, "{}", case.url);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -178,14 +185,6 @@ fn assert_title_contains(snapshot: &SidecarSnapshot, fragment: &str) -> Result<(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "live-site-smoke")]
|
|
||||||
fn non_white_pixel_count(rgba_bytes: &[u8]) -> usize {
|
|
||||||
rgba_bytes
|
|
||||||
.chunks_exact(4)
|
|
||||||
.filter(|pixel| pixel[3] > 0 && (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 255))
|
|
||||||
.count()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn report_with_state(state: &str) -> SidecarReport {
|
fn report_with_state(state: &str) -> SidecarReport {
|
||||||
SidecarReport {
|
SidecarReport {
|
||||||
requested_url: "https://example.com".to_string(),
|
requested_url: "https://example.com".to_string(),
|
||||||
@@ -197,6 +196,7 @@ fn report_with_state(state: &str) -> SidecarReport {
|
|||||||
rgba_byte_count: 8,
|
rgba_byte_count: 8,
|
||||||
non_white_pixel_count: 1,
|
non_white_pixel_count: 1,
|
||||||
content_pixel_count: 1,
|
content_pixel_count: 1,
|
||||||
|
sample_hash: 42,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ fn render_profile_row(
|
|||||||
.child(render_profile_default_action(
|
.child(render_profile_default_action(
|
||||||
index,
|
index,
|
||||||
default_profile_id,
|
default_profile_id,
|
||||||
|
profile.kind() == &ProfileKind::Standard,
|
||||||
default_for_active_space,
|
default_for_active_space,
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
@@ -172,6 +173,7 @@ fn profile_color_swatch(color_hex: u32) -> AnyElement {
|
|||||||
fn render_profile_default_action(
|
fn render_profile_default_action(
|
||||||
index: usize,
|
index: usize,
|
||||||
profile_id: ProfileId,
|
profile_id: ProfileId,
|
||||||
|
allows_default: bool,
|
||||||
default_for_active_space: bool,
|
default_for_active_space: bool,
|
||||||
cx: &mut Context<ElyShell>,
|
cx: &mut Context<ElyShell>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
@@ -184,6 +186,16 @@ fn render_profile_default_action(
|
|||||||
.into_any_element();
|
.into_any_element();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !allows_default {
|
||||||
|
return Button::new(("default-profile", index))
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.disabled(true)
|
||||||
|
.label("Private")
|
||||||
|
.tooltip("Private Profiles stay opt-in")
|
||||||
|
.into_any_element();
|
||||||
|
}
|
||||||
|
|
||||||
Button::new(("default-profile", index))
|
Button::new(("default-profile", index))
|
||||||
.ghost()
|
.ghost()
|
||||||
.xsmall()
|
.xsmall()
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ pub enum CoreError {
|
|||||||
#[error("private profile keeps sync paused: {id}")]
|
#[error("private profile keeps sync paused: {id}")]
|
||||||
PrivateProfileSyncLocked { id: ProfileId },
|
PrivateProfileSyncLocked { id: ProfileId },
|
||||||
|
|
||||||
|
#[error("private profile cannot be a space default profile: {id}")]
|
||||||
|
PrivateProfileDefaultLocked { id: ProfileId },
|
||||||
|
|
||||||
#[error("download not found: {id}")]
|
#[error("download not found: {id}")]
|
||||||
DownloadNotFound { id: DownloadId },
|
DownloadNotFound { id: DownloadId },
|
||||||
|
|
||||||
|
|||||||
@@ -289,8 +289,13 @@ impl BrowserCore {
|
|||||||
space_id: &SpaceId,
|
space_id: &SpaceId,
|
||||||
profile_id: &ProfileId,
|
profile_id: &ProfileId,
|
||||||
) -> Result<(), CoreError> {
|
) -> Result<(), CoreError> {
|
||||||
if !self.profiles.iter().any(|profile| profile.id() == profile_id) {
|
let profile = self
|
||||||
return Err(CoreError::ProfileNotFound { id: profile_id.clone() });
|
.profiles
|
||||||
|
.iter()
|
||||||
|
.find(|profile| profile.id() == profile_id)
|
||||||
|
.ok_or_else(|| CoreError::ProfileNotFound { id: profile_id.clone() })?;
|
||||||
|
if profile.kind() == &ProfileKind::Private {
|
||||||
|
return Err(CoreError::PrivateProfileDefaultLocked { id: profile_id.clone() });
|
||||||
}
|
}
|
||||||
|
|
||||||
let space = self
|
let space = self
|
||||||
|
|||||||
@@ -233,6 +233,28 @@ fn space_default_profile_updates_with_profile_validation() -> Result<(), Box<dyn
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn space_default_profile_rejects_private_profile() -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||||
|
let snapshot = core.snapshot()?;
|
||||||
|
let work_space_id = snapshot.active_space_id;
|
||||||
|
let default_profile_id = snapshot.active_profile_id;
|
||||||
|
let private_profile_id = core.create_profile("Private", 0x807d72, ProfileKind::Private)?;
|
||||||
|
|
||||||
|
let error = match core.set_space_default_profile(&work_space_id, &private_profile_id) {
|
||||||
|
Err(error) => error,
|
||||||
|
Ok(_) => return Err("space default profile accepted a private profile".into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(error, CoreError::PrivateProfileDefaultLocked { id: private_profile_id.clone() });
|
||||||
|
let snapshot = core.snapshot()?;
|
||||||
|
let Some(work_space) = snapshot.spaces.iter().find(|space| space.id() == &work_space_id) else {
|
||||||
|
return Err("missing work space".into());
|
||||||
|
};
|
||||||
|
assert_eq!(work_space.default_profile_id(), &default_profile_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn active_space_default_profile_updates_current_space() -> Result<(), Box<dyn Error>> {
|
fn active_space_default_profile_updates_current_space() -> Result<(), Box<dyn Error>> {
|
||||||
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user