From e9ba792f8460907749a0a3e095ffc40627b8eb60 Mon Sep 17 00:00:00 2001 From: "Shahar \"Dawn\" Or" Date: Sun, 7 Dec 2025 21:02:41 +0700 Subject: [PATCH 1/2] test: end-to-end Co-authored-by: turbio Co-authored-by: shivaraj-bh --- Cargo.lock | 330 +++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 3 + tests/end-to-end.rs | 126 +++++++++++++++++ 3 files changed, 424 insertions(+), 35 deletions(-) create mode 100644 tests/end-to-end.rs diff --git a/Cargo.lock b/Cargo.lock index 5b1335d..c52e435 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,29 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "async-tungstenite" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f89c129ab749940f95509d84950c62092c8b4bc6e386ddb162229037a6ec91" +dependencies = [ + "atomic-waker", + "futures-core", + "futures-io", + "futures-task", + "futures-util", + "log", + "pin-project-lite", + "tokio", + "tungstenite 0.28.0", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" @@ -200,9 +223,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] [[package]] name = "cc" @@ -216,6 +242,73 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chromiumoxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c18200611490f523adb497ddd4744d6d536e243f6add13e7eeeb1c05904fbb1" +dependencies = [ + "async-tungstenite", + "base64 0.22.0", + "bytes", + "cfg-if", + "chromiumoxide_cdp", + "chromiumoxide_types", + "dunce", + "fnv", + "futures", + "futures-timer", + "pin-project-lite", + "reqwest", + "serde", + "serde_json", + "thiserror 1.0.31", + "tokio", + "tracing", + "url", + "which", + "windows-registry", +] + +[[package]] +name = "chromiumoxide_cdp" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f78027ced540595dcbaf9e2f3413cbe3708b839ff239d2858acaea73915dcb" +dependencies = [ + "chromiumoxide_pdl", + "chromiumoxide_types", + "serde", + "serde_json", +] + +[[package]] +name = "chromiumoxide_pdl" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2c7b7c6b41a0de36d00a284e619017e0f4aec5c9bc8d90614b9e1687984f20" +dependencies = [ + "chromiumoxide_types", + "either", + "heck 0.4.1", + "once_cell", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", +] + +[[package]] +name = "chromiumoxide_types" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "309ba8f378bbc093c93f06beb7bd4c5ceffdf14107ad99cacbbf063709926795" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "clap" version = "4.5.53" @@ -244,7 +337,7 @@ version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.101", @@ -338,6 +431,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.8.1" @@ -353,6 +452,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_home" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" + [[package]] name = "env_logger" version = "0.10.2" @@ -385,12 +490,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -405,9 +510,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "file-id" @@ -528,6 +633,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -556,6 +667,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "get-port" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "888123007db34fbff15b5a347d46364dfbad531d6cb43de52cc0b62558f570e2" + [[package]] name = "getrandom" version = "0.2.7" @@ -567,6 +684,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "globset" version = "0.4.18" @@ -605,6 +734,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -883,18 +1018,20 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "live-server" version = "0.11.0" dependencies = [ "axum", + "chromiumoxide", "clap", "env_logger", "futures", + "get-port", "ignore", "local-ip-address", "log", @@ -904,6 +1041,7 @@ dependencies = [ "open", "path-absolutize", "reqwest", + "tempfile", "tokio", ] @@ -1135,7 +1273,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets 0.48.0", ] @@ -1232,6 +1370,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -1239,8 +1383,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -1250,7 +1404,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -1259,23 +1423,23 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.7", ] [[package]] -name = "redox_syscall" -version = "0.3.5" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "bitflags 1.3.2", + "getrandom 0.3.4", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] @@ -1372,15 +1536,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.7.0", - "errno 0.3.8", + "errno 0.3.14", "libc", - "linux-raw-sys 0.4.12", - "windows-sys 0.52.0", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] @@ -1629,15 +1793,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", - "redox_syscall 0.4.1", - "rustix 0.38.28", - "windows-sys 0.48.0", + "getrandom 0.3.4", + "once_cell", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -1751,7 +1915,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.23.0", ] [[package]] @@ -1820,9 +1984,21 @@ checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "tracing-core" version = "0.1.32" @@ -1850,12 +2026,29 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", "thiserror 1.0.31", "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.2", + "sha1", + "thiserror 2.0.12", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -1952,6 +2145,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.89" @@ -2028,6 +2230,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" +dependencies = [ + "env_home", + "rustix 1.1.2", + "winsafe", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2059,12 +2272,47 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link 0.1.3", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -2116,7 +2364,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -2370,3 +2618,15 @@ dependencies = [ "cfg-if", "windows-sys 0.48.0", ] + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" diff --git a/Cargo.toml b/Cargo.toml index 83a2bf1..fc82f91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,7 @@ ignore = "0.4.25" path-absolutize = "3.1.1" [dev-dependencies] +chromiumoxide = "0.8.0" +get-port = "4.0.0" reqwest = "0.12.4" +tempfile = "3.23.0" diff --git a/tests/end-to-end.rs b/tests/end-to-end.rs new file mode 100644 index 0000000..e2ced58 --- /dev/null +++ b/tests/end-to-end.rs @@ -0,0 +1,126 @@ +use std::{ + collections::BTreeSet, + ffi::OsStr, + path::{Path, PathBuf}, + sync::{LazyLock, Mutex}, + time::Duration, +}; + +use chromiumoxide::{ + Browser, BrowserConfig, cdp::browser_protocol::page::EventFrameStoppedLoading, +}; +use futures::StreamExt as _; +use get_port::{Ops, tcp::TcpPort}; +use tempfile::{self, TempDir, tempdir}; +use tokio::{ + fs, + process::{Child, Command}, +}; + +async fn with_timeout( + future: impl Future, +) -> Result { + tokio::time::timeout(Duration::from_secs(6), future).await +} + +fn subject_with(args: &[impl AsRef]) -> (Child, String) { + static TAKEN_PORTS: LazyLock>> = + LazyLock::new(|| Mutex::new(BTreeSet::new())); + + const HOST: &str = "127.0.0.1"; + let mut taken_ports = TAKEN_PORTS.lock().unwrap(); + let port = TcpPort::except(HOST, taken_ports.iter().copied().collect()).unwrap(); + taken_ports.insert(port); + + let subject = Command::new(env!("CARGO_BIN_EXE_live-server")) + .kill_on_drop(true) + .args(["--host", HOST]) + .args(["--port", &port.to_string()]) + .args(args) + .spawn() + .unwrap(); + + (subject, format!("{HOST}:{port}")) +} + +async fn fresh_browser() -> (Browser, TempDir) { + let data_dir = tempdir().unwrap(); + let (browser, handler) = Browser::launch( + BrowserConfig::builder() + .user_data_dir(data_dir.path()) + .build() + .unwrap(), + ) + .await + .unwrap(); + tokio::spawn(async move { + handler.for_each(async |_| {}).await; + }); + (browser, data_dir) +} + +fn index_with(title: &str) -> String { + format!( + r#"{title}"# + ) +} + +async fn fixture_with(title: &str) -> TempDir { + let dir = tempdir().unwrap(); + let index_path: PathBuf = [dir.path(), Path::new("index.html")].iter().collect(); + fs::write(&index_path, index_with(title)).await.unwrap(); + dir +} + +#[tokio::test] +async fn page_content_is_served() { + let fixture = fixture_with("some page").await; + let (_subject, authority) = subject_with(&[fixture.path()]); + let (browser, _browser_dir) = fresh_browser().await; + let title = browser + .new_page(format!("http://{authority}/")) + .await + .unwrap() + .wait_for_navigation() + .await + .unwrap() + .get_title() + .await + .unwrap() + .unwrap(); + assert_eq!(title, "some page"); +} + +#[tokio::test] +async fn browser_reloads_on_file_change() { + let fixture = fixture_with("initial").await; + let (_subject, authority) = subject_with(&[fixture.path()]); + let (browser, _browser_dir) = fresh_browser().await; + + let page = browser + .new_page(format!("http://{authority}/")) + .await + .unwrap(); + + page.wait_for_navigation().await.unwrap(); + let title = page.get_title().await.unwrap().unwrap(); + assert_eq!(title, "initial"); + + let mut frame_stopped_loading_event_stream = page + .event_listener::() + .await + .unwrap(); + + let index_path = [fixture.path(), Path::new("index.html")] + .iter() + .collect::(); + fs::write(index_path, index_with("modified")).await.unwrap(); + + with_timeout(frame_stopped_loading_event_stream.next()) + .await + .unwrap() + .unwrap(); + + let title = page.get_title().await.unwrap().unwrap(); + assert_eq!(title, "modified"); +} From b28f4de63741b081dc110d8522813fc1ded0bcee Mon Sep 17 00:00:00 2001 From: "Shahar \"Dawn\" Or" Date: Sun, 7 Dec 2025 21:07:19 +0700 Subject: [PATCH 2/2] test: symlink swap --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + tests/end-to-end.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c52e435..e00ae17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1041,6 +1041,7 @@ dependencies = [ "open", "path-absolutize", "reqwest", + "symlink", "tempfile", "tokio", ] @@ -1736,6 +1737,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + [[package]] name = "syn" version = "1.0.98" diff --git a/Cargo.toml b/Cargo.toml index fc82f91..e401b60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ mime_guess = "2.0.5" open = "5.3.3" ignore = "0.4.25" path-absolutize = "3.1.1" +symlink = "0.1.0" [dev-dependencies] chromiumoxide = "0.8.0" diff --git a/tests/end-to-end.rs b/tests/end-to-end.rs index e2ced58..7a601ed 100644 --- a/tests/end-to-end.rs +++ b/tests/end-to-end.rs @@ -11,6 +11,7 @@ use chromiumoxide::{ }; use futures::StreamExt as _; use get_port::{Ops, tcp::TcpPort}; +use symlink::symlink_dir; use tempfile::{self, TempDir, tempdir}; use tokio::{ fs, @@ -124,3 +125,45 @@ async fn browser_reloads_on_file_change() { let title = page.get_title().await.unwrap().unwrap(); assert_eq!(title, "modified"); } + +#[tokio::test] +async fn browser_reloads_on_symlink_swap() { + let fixture = fixture_with("initial").await; + let symlink_parent = tempdir().unwrap(); + let symlink_path = [symlink_parent.path(), Path::new("symlink")] + .iter() + .collect::(); + symlink_dir(&fixture, &symlink_path).unwrap(); + let (_subject, authority) = + subject_with(&["--poll", symlink_path.as_os_str().to_str().unwrap()]); + let (browser, _browser_dir) = fresh_browser().await; + + let page = browser + .new_page(format!("http://{authority}/")) + .await + .unwrap(); + + page.wait_for_navigation().await.unwrap(); + let title = page.get_title().await.unwrap().unwrap(); + assert_eq!(title, "initial"); + + let mut frame_stopped_loading_event_stream = page + .event_listener::() + .await + .unwrap(); + + let temp_symlink_path = [symlink_parent.path(), Path::new("temp-symlink")] + .iter() + .collect::(); + let fixture = fixture_with("modified").await; + symlink_dir(&fixture, &temp_symlink_path).unwrap(); + fs::rename(&temp_symlink_path, &symlink_path).await.unwrap(); + + with_timeout(frame_stopped_loading_event_stream.next()) + .await + .unwrap() + .unwrap(); + + let title = page.get_title().await.unwrap().unwrap(); + assert_eq!(title, "modified"); +}