use std::time::Duration;
use crate::browser::Page;
use crate::{require_fixture, App};
const WAIT: Duration = Duration::from_secs(20);
const INDEX: &str = r#"<!doctype html><html><head><title>t</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>"#;
fn app_src(class: &str) -> String {
format!(
"import {{ useState }} from \"react\";\n\
export function App() {{\n const [n, setN] = useState(0);\n\
\x20 return (<div><h1 className=\"{class}\">hi</h1><button onClick={{() => setN(n + 1)}}>Clicks: {{n}}</button></div>);\n}}\n"
)
}
#[tokio::test(flavor = "multi_thread")]
async fn js_imported_tailwind_hot_swaps_on_class_edit() {
require_fixture!(
"react",
"react-dom",
"scheduler",
"tailwindcss",
"@tailwindcss"
);
if crate::browser::skip() {
return;
}
let app = App::new(&[
("package.json", r#"{"name":"tw-js-import","version":"1.0.0"}"#),
("src/index.css", "@import \"tailwindcss\";\n"),
(
"src/main.tsx",
"import \"./index.css\";\nimport { createRoot } from \"react-dom/client\";\nimport { App } from \"./App\";\n\
createRoot(document.getElementById(\"root\")!).render(<App />);\n",
),
("src/App.tsx", &app_src("underline")),
("index.html", INDEX),
]);
for pkg in [
"react",
"react-dom",
"scheduler",
"tailwindcss",
"@tailwindcss",
] {
app.link_fixture(pkg);
}
let server = app.serve().await;
let listening = server.listen().await;
let page = Page::open(&format!("http://127.0.0.1:{}/", listening.addr.port())).await;
page.wait_for(r#"document.querySelector("h1")"#, WAIT).await;
page.wait_for(
r#"getComputedStyle(document.querySelector("h1")).textDecorationLine === "underline""#,
WAIT,
)
.await;
assert_eq!(
page.eval::<u32>(r#"document.querySelectorAll("link[rel=stylesheet]").length"#)
.await,
0,
"no <link>: css is JS-imported"
);
page.eval::<bool>(r#"document.querySelector("button").click(), true"#)
.await;
page.eval::<bool>(r#"document.querySelector("button").click(), true"#)
.await;
page.eval::<bool>("window.__NOT_RELOADED = true").await;
app.write(&[("src/App.tsx", &app_src("underline italic"))]);
page.wait_for(
r#"getComputedStyle(document.querySelector("h1")).fontStyle === "italic""#,
WAIT,
)
.await;
assert!(
page.eval::<bool>("window.__NOT_RELOADED === true").await,
"page was reloaded"
);
let clicks: String = page
.eval(r#"document.querySelector("button").textContent"#)
.await;
assert!(
clicks.contains("Clicks: 2"),
"component state lost: {clicks}"
);
assert_eq!(page.errors(), Vec::<String>::new(), "page errors");
page.close().await;
}