Skipping a card is not a mistake
Scrolling through a deck without answering recorded a 0% attempt and listed every card under "Missed items" with its answer revealed. Only answered cards count now: the score is correct/answered, the attempt stores the answered count, an empty run records nothing, and the cards scrolled past wait under "Not answered (n)" - listed as prompts with "not counted as mistakes" - and "Answer the rest (n)" starts a catch-up run of just those cards (same restart path as retry-missed, so history and the SRS still see the answers). "Aced all" requires nothing left waiting too. phase2 pins the flow: all-skipped records no attempt and no mistake list; one-of-two reads "You got 1 of 1 right" + "Not answered (1)" with attempts:1, bestScore:100; the catch-up run records the remaining answer. Exam mode keeps its own rule: in a timed exam an unanswered question is a miss. Version 0.6.5, SW v87.
This commit is contained in:
parent
855ce82836
commit
98537cee64
7 changed files with 161 additions and 20 deletions
|
|
@ -96,6 +96,69 @@ const browser = await launchBrowser();
|
|||
await context.close();
|
||||
}
|
||||
|
||||
/* 1c. skipping a card is not a mistake ------------------------------- */
|
||||
{
|
||||
/* Swiping through a deck without answering used to record a 0% attempt and
|
||||
list every card under "Missed items" — "you can just scroll all the way
|
||||
down and it counts everything as incorrect". Skipped cards now wait under
|
||||
"Not answered", and the score counts the cards that were answered. */
|
||||
const skipped = await makePage(browser);
|
||||
await seed(skipped.page, { decks: [DECK] });
|
||||
await skipped.page.goto(`${BASE}/deck/seed_deck`, { waitUntil: "networkidle" });
|
||||
await skipped.page.waitForTimeout(900);
|
||||
await skipped.page.keyboard.press("End");
|
||||
await skipped.page.waitForTimeout(1000);
|
||||
check("skip: the all-skipped run offers the waiting cards", (await skipped.page.getByText("Not answered (2)").count()) === 1);
|
||||
check("skip: nothing is listed as a mistake", (await skipped.page.getByText(/Missed items/).count()) === 0);
|
||||
check(
|
||||
"skip: an empty run gets no score line",
|
||||
(await skipped.page.getByText("Nothing answered this time — pick up where you left off.").count()) === 1,
|
||||
);
|
||||
const skippedDeck = await skipped.page.evaluate(() => JSON.parse(localStorage.getItem("freezmo.decks.v1"))[0]);
|
||||
check(
|
||||
"skip: no attempt is recorded for an empty run",
|
||||
(skippedDeck.attempts ?? 0) === 0 && skippedDeck.bestScore === undefined,
|
||||
JSON.stringify({ attempts: skippedDeck.attempts, bestScore: skippedDeck.bestScore }),
|
||||
);
|
||||
await skipped.context.close();
|
||||
|
||||
/* Answer one of two: the score counts the answered card only, and the
|
||||
waiting one can be picked up from the results screen. */
|
||||
const partial = await makePage(browser);
|
||||
await seed(partial.page, { decks: [DECK] });
|
||||
await partial.page.goto(`${BASE}/deck/seed_deck`, { waitUntil: "networkidle" });
|
||||
await partial.page.waitForTimeout(900);
|
||||
await partial.page.getByRole("button", { name: "Blue" }).click();
|
||||
await partial.page.waitForTimeout(500);
|
||||
await partial.page.keyboard.press("End");
|
||||
await partial.page.waitForTimeout(1000);
|
||||
check("skip: the score counts answered cards only", (await partial.page.getByText("You got 1 of 1 right.").count()) === 1);
|
||||
check("skip: the unanswered card waits under its own heading", (await partial.page.getByText("Not answered (1)").count()) === 1);
|
||||
check("skip: it is not listed as missed", (await partial.page.getByText(/Missed items/).count()) === 0);
|
||||
const partialDeck = await partial.page.evaluate(() => JSON.parse(localStorage.getItem("freezmo.decks.v1"))[0]);
|
||||
check(
|
||||
"skip: the attempt records the answered card",
|
||||
partialDeck.attempts === 1 && partialDeck.bestScore === 100,
|
||||
JSON.stringify({ attempts: partialDeck.attempts, bestScore: partialDeck.bestScore }),
|
||||
);
|
||||
|
||||
await partial.page.getByRole("button", { name: "Answer the rest (1)" }).click();
|
||||
await partial.page.waitForTimeout(1000);
|
||||
check(
|
||||
"skip: catching up opens on the waiting card",
|
||||
await partial.page.getByRole("region", { name: /Activity 1 of/ }).getByText("What makes the sky blue?").isVisible(),
|
||||
);
|
||||
await partial.page.getByRole("button", { name: "Scattering" }).click();
|
||||
await partial.page.waitForTimeout(600);
|
||||
const caughtUp = await readLearning(partial.page);
|
||||
check(
|
||||
"skip: catching up records the second answer",
|
||||
caughtUp.answers.length === 2 && caughtUp.srs.length === 2,
|
||||
JSON.stringify({ answers: caughtUp.answers.length, srs: caughtUp.srs.length }),
|
||||
);
|
||||
await partial.context.close();
|
||||
}
|
||||
|
||||
/* 1b. AI grading feedback carries the disclaimer (stubbed model call) - */
|
||||
{
|
||||
const { context, page } = await makePage(browser);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue