diff options
| author | Tianren Dong <tianrendong.dtr@gmail.com> | 2026-05-16 14:01:00 -0400 |
|---|---|---|
| committer | Tianren Dong <tianrendong.dtr@gmail.com> | 2026-05-16 14:01:00 -0400 |
| commit | b792f22f2c2ef4dfb7bd300e7381a186e34e0c18 (patch) | |
| tree | a31a4e6d1213478f5ac96e2208d1a1c16fc825b9 /test-suite/challenges/40-dynamic-wait-readiness.html | |
| parent | f133011c8ecda06ae63068649a9714c88a7b901e (diff) | |
0.15.25: fix reload after stale singleton
Diffstat (limited to 'test-suite/challenges/40-dynamic-wait-readiness.html')
| -rw-r--r-- | test-suite/challenges/40-dynamic-wait-readiness.html | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/test-suite/challenges/40-dynamic-wait-readiness.html b/test-suite/challenges/40-dynamic-wait-readiness.html new file mode 100644 index 0000000..adf006d --- /dev/null +++ b/test-suite/challenges/40-dynamic-wait-readiness.html @@ -0,0 +1,41 @@ +<!doctype html> +<meta charset="utf-8"> +<title>40 dynamic wait readiness</title> +<link rel="stylesheet" href="../_style.css"> +<script src="../_lib.js"></script> +<body> +<main> + <p>Goal: wait until an async control exists and is enabled, then click it. Direct early clicks or fixed sleeps should not be required.</p> + <div id="status" role="status">Loading async action…</div> + <div id="mount" style="margin-top:20px"></div> +</main> +<script> +Challenge.init({ id: "dynamic-wait-readiness", instructions: "wait for async button, then click" }); +const start = performance.now(); +setTimeout(() => { + const btn = document.createElement("button"); + btn.id = "readyAction"; + btn.textContent = "Run ready action"; + btn.disabled = true; + btn.style.cssText = "padding:14px 22px;font-size:16px;background:#1f7a1f;color:#fff;border:0;border-radius:6px"; + document.getElementById("mount").appendChild(btn); + document.getElementById("status").textContent = "Button mounted; enabling soon…"; + Challenge.log("mounted", { at: performance.now() - start }); + setTimeout(() => { + btn.disabled = false; + btn.dataset.ready = "true"; + document.getElementById("status").textContent = "Ready."; + Challenge.log("enabled", { at: performance.now() - start }); + }, 450); + btn.addEventListener("click", (e) => { + const elapsed = performance.now() - start; + const bad = []; + if (!e.isTrusted) bad.push("click isTrusted=false"); + if (btn.disabled || btn.dataset.ready !== "true") bad.push("clicked before enabled/ready"); + if (elapsed < 650) bad.push(`clicked too early at ${elapsed.toFixed(0)}ms`); + if (bad.length) Challenge.fail(...bad); + else Challenge.pass(`waited for async ready state (${elapsed.toFixed(0)}ms)`); + }); +}, 350); +</script> +</body> |
