aboutsummaryrefslogtreecommitdiff
path: root/test-suite/challenges/40-dynamic-wait-readiness.html
diff options
context:
space:
mode:
authorTianren Dong <tianrendong.dtr@gmail.com>2026-05-16 14:01:00 -0400
committerTianren Dong <tianrendong.dtr@gmail.com>2026-05-16 14:01:00 -0400
commitb792f22f2c2ef4dfb7bd300e7381a186e34e0c18 (patch)
treea31a4e6d1213478f5ac96e2208d1a1c16fc825b9 /test-suite/challenges/40-dynamic-wait-readiness.html
parentf133011c8ecda06ae63068649a9714c88a7b901e (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.html41
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>