#[cfg(feature = "integration")]
mod emulator {
use podium::{DeviceBuilder, Direction, Platform, PodiumDevice, Selector};
const SETTINGS_PKG: &str = "com.android.settings";
async fn device() -> PodiumDevice {
DeviceBuilder::default()
.platform(Platform::Android {
serial: std::env::var("PODIUM_SERIAL").ok(),
})
.app_id(SETTINGS_PKG)
.build()
.await
.expect("connect to emulator — is one running? (`emulator -avd <name>`)")
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn driver_apk_auto_installed() {
let _d = device().await;
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn launch_settings_cold() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.assert_visible(Selector::text("Search Settings"))
.await
.expect("Settings root visible");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn launch_settings_warm() {
let d = device().await;
d.launch_app(SETTINGS_PKG, false).await.expect("launch_app");
d.assert_visible(Selector::text("Search Settings"))
.await
.expect("Settings root visible");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn assert_not_visible_nonexistent_element() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.assert_not_visible(Selector::text("zz_podium_sentinel_zz"))
.await
.expect("sentinel must not be visible");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn tap_network_and_internet() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.assert_visible(Selector::text("Network & internet"))
.await
.expect("row visible");
d.tap(Selector::text("Network & internet"))
.await
.expect("tap");
d.assert_visible(Selector::text("Internet"))
.await
.expect("sub-screen open");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn tap_then_back_returns_to_root() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.assert_visible(Selector::text("Network & internet"))
.await
.expect("root loaded");
d.tap(Selector::text("Network & internet"))
.await
.expect("tap");
d.assert_visible(Selector::text("Internet"))
.await
.expect("network sub-screen open");
d.back().await.expect("back");
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
d.assert_visible(Selector::text("Connected devices"))
.await
.expect("back at root");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn scroll_to_about_phone() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
let r = d
.scroll_until_visible(Selector::text("About emulated device"))
.await;
if r.is_ok() {
return;
}
d.launch_app(SETTINGS_PKG, true).await.expect("relaunch");
d.scroll_until_visible(Selector::text("About phone"))
.await
.expect("About phone / About emulated device reachable by scrolling");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn swipe_down_stays_in_settings() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.swipe(Direction::Down).await.expect("swipe down");
d.assert_visible(Selector::text("Search Settings"))
.await
.expect("Settings still visible");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn screenshot_writes_file() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
let name = "podium_test_screenshot";
d.take_screenshot(name).await.expect("take_screenshot");
let png = format!("{name}.png");
let path = std::path::Path::new(&png);
assert!(path.exists(), "{png} not found");
assert!(path.metadata().unwrap().len() > 0, "{png} is empty");
std::fs::remove_file(path).ok();
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn wait_for_animation_after_tap() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch_app");
d.assert_visible(Selector::text("Network & internet"))
.await
.expect("root loaded");
d.tap(Selector::text("Network & internet"))
.await
.expect("tap");
d.wait_for_animation().await.expect("wait_for_animation");
}
#[tokio::test]
#[ignore = "requires running emulator"]
async fn full_settings_flow() {
let d = device().await;
d.launch_app(SETTINGS_PKG, true).await.expect("launch");
d.assert_visible(Selector::text("Search Settings"))
.await
.expect("root visible");
d.tap(Selector::text("Network & internet"))
.await
.expect("tap network");
d.wait_for_animation().await.expect("settle");
d.assert_visible(Selector::text("Internet"))
.await
.expect("network screen open");
d.take_screenshot("podium_e2e_network")
.await
.expect("screenshot");
std::fs::remove_file("podium_e2e_network.png").ok();
d.back().await.expect("back");
d.assert_visible(Selector::text("Search Settings"))
.await
.expect("back at root");
let r = d
.scroll_until_visible(Selector::text("About emulated device"))
.await;
if r.is_err() {
d.launch_app(SETTINGS_PKG, true)
.await
.expect("relaunch for scroll");
d.scroll_until_visible(Selector::text("About phone"))
.await
.expect("scrolled to bottom");
}
}
}