fix(curriculum):strengthen draw condition check test in tic-tac-toelab (#60960)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Ajay A
2025-07-04 18:46:01 +05:30
committed by GitHub
parent 637fb3765c
commit 573224fe04

View File

@@ -18,6 +18,31 @@ demoType: onClick
4. You should create a `button#reset` element that resets the game when clicked.
5. A message should be displayed indicating either `X` or `O` as the winner, or neither if the result is a draw.
# --before-all--
```js
let clock = __FakeTimers.install();
async function reset(assert) {
const reset = document.querySelector("#reset");
assert.exists(reset, "button#reset should exist");
reset.click();
clock.tick(50);
}
// Gets the text of the document excluding that of the matching selector.
function getInnerTextExcept(removingSelector) {
const body = document.body.cloneNode(true);
const squareElements = body.querySelectorAll(`${removingSelector},script`);
squareElements.forEach(element => {
element.parentNode.removeChild(element)
});
return body.innerText;
}
```
# --hints--
You should export a `Board` component.
@@ -99,7 +124,7 @@ async () => {
const el = document.querySelector("button.square");
el.click();
await delay(50);
clock.tick(50);
try {
assert.include(el.textContent, "X");
@@ -117,7 +142,7 @@ async () => {
// NOTE: This test is intentionally high-up, because the latter tests rely on the functionality.
const el = document.querySelector("button.square");
el.click();
await delay(50);
clock.tick(50);
try {
await reset(assert);
@@ -136,10 +161,10 @@ async () => {
await reset(assert);
const els = document.querySelectorAll("button.square");
els[0].click();
await delay(50);
clock.tick(50);
els[1].click();
await delay(50);
clock.tick(50);
try {
assert.include(els[1].textContent, "O");
@@ -160,7 +185,7 @@ async () => {
for (let i = 3; i < els.length + 3; i++) {
const wrappedI = i % els.length;
els[wrappedI].click();
await delay(50);
clock.tick(50);
assert.include(els[wrappedI].textContent, (i - 3) % 2 === 0 ? "X" : "O");
}
} catch(e) {
@@ -181,9 +206,9 @@ async () => {
const wrappedI = i % els.length;
// Click button twice to ensure it does not change
els[wrappedI].click();
await delay(50);
clock.tick(50);
els[wrappedI].click();
await delay(50);
clock.tick(50);
assert.include(els[wrappedI].textContent, (i - 3) % 2 === 0 ? "X" : "O");
}
} catch(e) {
@@ -204,12 +229,12 @@ async () => {
for (let i = 0; i < 3; i++) {
const x = els[i];
x.click();
await delay(50);
clock.tick(50);
assert.include(x.textContent, "X");
const o = els[i + 3];
o.click();
await delay(50);
clock.tick(50);
if (i === 2) {
assert.notInclude(o.textContent, "O");
} else {
@@ -237,16 +262,16 @@ async () => {
for (let i = 0; i < 2; i++) {
const x = els[i];
x.click();
await delay(50);
clock.tick(50);
const o = els[i + 3];
o.click();
await delay(50);
clock.tick(50);
}
const preXWin = getInnerTextExcept("button.square");
// Click winning button for X
els[2].click();
await delay(50);
clock.tick(50);
const postXWin = getInnerTextExcept("button.square");
assert.notEqual(preXWin, postXWin);
@@ -256,18 +281,18 @@ async () => {
for (let i = 0; i < 2; i++) {
const x = els[i];
x.click();
await delay(50);
clock.tick(50);
const o = els[i + 3];
o.click();
await delay(50);
clock.tick(50);
}
els[6].click();
await delay(50);
clock.tick(50);
const preOWin = getInnerTextExcept("button.square");
// Click winning button for O
els[5].click();
await delay(50);
clock.tick(50);
const postOWin = getInnerTextExcept("button.square");
assert.notEqual(preOWin, postOWin);
@@ -291,18 +316,28 @@ async () => {
await reset(assert);
const els = document.querySelectorAll("button.square");
try {
for (let i = 3; i < els.length + 2; i++) {
const wrappedI = i % els.length;
els[wrappedI].click();
await delay(50);
//use already known draw states
const drawMoves = [0, 1, 2, 4, 3, 5, 7, 6, 8];
const snapshot1 = getInnerTextExcept("button.square");
els[drawMoves[0]].click();
clock.tick(50);
const snapshot2 = getInnerTextExcept("button.square");
for (let i = 1; i < drawMoves.length - 1; i++) {
els[drawMoves[i]].click();
clock.tick(50);
}
const pre = getInnerTextExcept("button.square");
els[2].click();
await delay(50);
const snapshot3 = getInnerTextExcept("button.square");
els[drawMoves[drawMoves.length - 1]].click();
clock.tick(50);
const snapshot4 = getInnerTextExcept("button.square");
assert.notEqual(snapshot4, snapshot1);
assert.notEqual(snapshot4, snapshot2);
assert.notEqual(snapshot4, snapshot3);
const post = getInnerTextExcept("button.square");
assert.notEqual(pre, post);
} catch(e) {
console.error(e);
throw e;
@@ -310,30 +345,11 @@ async () => {
}
```
# --before-all--
Uninstall the clock, ignore this test
```js
async function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function reset(assert) {
const reset = document.querySelector("#reset");
assert.exists(reset, "button#reset should exist");
reset.click();
await delay(50);
}
// Gets the text of the document excluding that of the matching selector.
function getInnerTextExcept(removingSelector) {
const body = document.body.cloneNode(true);
const squareElements = body.querySelectorAll(`${removingSelector},script`);
squareElements.forEach(element => {
element.parentNode.removeChild(element)
});
return body.innerText;
async () => {
clock.uninstall()
}
```