feat(wasm): suppress stale client completions
req: client_local/011\nreq: client_local/012\nreq: operations/003
This commit is contained in:
@@ -15,6 +15,7 @@ const STARTUP_TIMEOUT: Duration = Duration::from_secs(12);
|
||||
#[tokio::test]
|
||||
async fn client_handler_applies_effect_batch_without_network() -> WebDriverResult<()> {
|
||||
// req: client_local/005 req: client_local/009 req: client_local/010
|
||||
// req: client_local/011 req: client_local/012
|
||||
// test: client_local/014
|
||||
let workspace = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
@@ -45,11 +46,47 @@ async fn client_handler_applies_effect_batch_without_network() -> WebDriverResul
|
||||
)
|
||||
.await?;
|
||||
let network_before = resource_count(&driver).await?;
|
||||
|
||||
driver
|
||||
.execute(
|
||||
r#"
|
||||
window.__resolveClientRuns = [];
|
||||
const actual = window.hemx.registerClientHandler('increment', (...args) => new Promise((resolve) => {
|
||||
window.__resolveClientRuns.push(() => resolve(actual(...args)));
|
||||
}));
|
||||
window.__actualClientHandler = actual;
|
||||
return true;
|
||||
"#,
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
let button = driver
|
||||
.find(By::Css("[data-hemx-client='increment']"))
|
||||
.await?
|
||||
.click()
|
||||
.await?;
|
||||
button.click().await?;
|
||||
button.click().await?;
|
||||
wait_until(&driver, "return window.__resolveClientRuns.length === 2").await?;
|
||||
driver
|
||||
.execute(
|
||||
"window.__resolveClientRuns[0](); return true",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
assert_eq!(
|
||||
driver
|
||||
.find(By::Css("[data-sid]"))
|
||||
.await?
|
||||
.prop("textContent")
|
||||
.await?
|
||||
.unwrap_or_default(),
|
||||
"idle",
|
||||
"superseded completion applied stale effects"
|
||||
);
|
||||
driver
|
||||
.execute(
|
||||
"window.__resolveClientRuns[1](); return true",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
wait_until(
|
||||
&driver,
|
||||
@@ -63,6 +100,12 @@ async fn client_handler_applies_effect_batch_without_network() -> WebDriverResul
|
||||
"client handler made a network request"
|
||||
);
|
||||
|
||||
driver
|
||||
.execute(
|
||||
"window.hemx.registerClientHandler('increment', window.__actualClientHandler); return true",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
driver
|
||||
.execute(
|
||||
"document.querySelector('[data-hemx-root]').setAttribute('data-hemx-client-state-version', '2'); return true",
|
||||
@@ -102,6 +145,44 @@ async fn client_handler_applies_effect_batch_without_network() -> WebDriverResul
|
||||
.unwrap_or(false),
|
||||
"invalid input must restore pending UI"
|
||||
);
|
||||
|
||||
driver
|
||||
.execute(
|
||||
r#"
|
||||
window.__resolveUnmount = null;
|
||||
const actual = window.hemx.registerClientHandler('increment', (...args) => new Promise((resolve) => {
|
||||
window.__resolveUnmount = () => resolve(actual(...args));
|
||||
}));
|
||||
document.querySelector('[data-hemx-root]').setAttribute('data-hemx-client-state-version', '1');
|
||||
return true;
|
||||
"#,
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
driver
|
||||
.find(By::Css("[data-hemx-client='increment']"))
|
||||
.await?
|
||||
.click()
|
||||
.await?;
|
||||
driver
|
||||
.execute(
|
||||
"const root = document.querySelector('[data-hemx-root]'); window.__removedRoot = root; root.remove(); window.__resolveUnmount(); return true",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
assert!(
|
||||
driver
|
||||
.execute(
|
||||
"return !window.__removedRoot.textContent.includes('updated by Rust/WASM')",
|
||||
Vec::new(),
|
||||
)
|
||||
.await?
|
||||
.json()
|
||||
.as_bool()
|
||||
.unwrap_or(false),
|
||||
"unmounted root accepted a late effect"
|
||||
);
|
||||
Ok::<(), WebDriverError>(())
|
||||
}
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user