#[cfg(target_os = "macos")]
mod common;
#[cfg(target_os = "macos")]
mod tests {
const TEST_PLATFORM: &str = "ios";
use super::common::check_request_received_using;
use std::fs;
use std::path::PathBuf;
use std::process::{Command, ExitStatus, Stdio};
use webbrowser::Browser;
#[ignore]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_ios() {
let uri = format!("/{TEST_PLATFORM}");
let ipv4 = get_ipv4_address();
let mut app_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
app_dir.push("tests/test-ios-app");
let mut glue_dir = PathBuf::from(&app_dir);
glue_dir.push("testglue");
run_cmd(&glue_dir, &["./build"]).expect("glue code build failed");
let compile_app = || {
run_cmd(
&app_dir,
&[
"xcrun",
"xcodebuild",
"-project",
"test-ios-app.xcodeproj",
"-configuration",
"Debug",
"-sdk",
"iphonesimulator",
"-destination",
"platform=iOS Simulator,name=iphone-latest",
"-arch",
if cfg!(target_arch = "aarch64") {
"arm64"
} else {
"x86_64"
},
],
)
};
compile_app().expect("compilation warm up failed for the app");
check_request_received_using(uri, &ipv4, |url, _port| {
let mut swift_src = PathBuf::from(&app_dir);
swift_src.push("test-ios-app/ContentView.swift");
let old_code =
fs::read_to_string(&swift_src).expect("failed to read ContentView.swift");
let new_code = old_code
.split('\n')
.map(|s| {
if s.starts_with("let SERVER_URL") {
format!("let SERVER_URL = \"{url}\"")
} else {
s.into()
}
})
.collect::<Vec<String>>()
.join("\n");
fs::write(&swift_src, new_code).expect("failed to modify ContentView.swift");
let revert_code = || fs::write(&swift_src, &old_code).expect("failed to revert code");
let handle_exec_result = |result: std::io::Result<ExitStatus>, err_msg: &str| {
revert_code();
let success = match result {
Ok(status) => status.success(),
Err(_) => false,
};
if !success {
eprintln!("{err_msg}");
std::process::exit(1);
}
};
let exec_result = compile_app();
handle_exec_result(exec_result, "failed to build ios app");
let exec_result = run_cmd(
&app_dir,
&[
"xcrun",
"simctl",
"install",
"booted",
"build/Debug-iphonesimulator/test-ios-app.app",
],
);
handle_exec_result(exec_result, "failed to install app on simulator");
let exec_result = run_cmd(
&app_dir,
&[
"xcrun",
"simctl",
"launch",
"booted",
"in.rootnet.webbrowser.test-ios-app",
],
);
handle_exec_result(exec_result, "failed to launch app on simulator");
revert_code();
})
.await;
}
fn get_ipv4_address() -> String {
let output = Command::new("sh")
.arg("-c")
.arg("ifconfig | grep 'inet ' | awk '{ print $2 }' | grep -v ^127.0.0")
.output()
.expect("failed to get non-local ipv4 address");
std::str::from_utf8(&output.stdout)
.expect("unable to parse output into utf8")
.split('\n')
.next()
.expect("no ip address found")
.into()
}
#[test]
fn test_existence_default() {
assert!(Browser::is_available(), "should have found a browser");
}
fn run_cmd(app_dir: &PathBuf, args: &[&str]) -> std::io::Result<ExitStatus> {
Command::new(args[0])
.args(&args[1..])
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.current_dir(app_dir)
.status()
}
}