CI / test (push) Successful in 50s
Fejl (fundet af QA, også i drift siden 7367b72): telefonen huskede
kladderne under nøglen kode:trin:fase, fx "KLMT:0:word". Nøglen går igen i
næste spil i samme rum, og kladderne blev aldrig glemt, så ved "Spil igen"
(og ved skift til Tegn og Gæt igen) stod det ord, man sendte sidst, allerede
i feltet. Nu glemmes kladderne uden for opgaverne (lobby, tema, afsløring,
slut); inden for et trin overlever de stadig en ny render.
Test: tegn.js's afterPlay kørt i node med en lille falsk DOM (springes over
uden node); den fejler på den gamle tegn.js.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
2.5 KiB
Python
48 lines
2.5 KiB
Python
"""Telefonens ordfelt i Tegn og Gæt (tegn.js afterPlay), kørt i node med en lille falsk DOM. Springes over uden node."""
|
|
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
TEGN_JS = Path(__file__).resolve().parents[1] / "static" / "party" / "tegn.js"
|
|
|
|
# Telefonen skriver et ord (input-hændelsen gemmer kladden), og så gennemløbes faserne. Hver render svarer til
|
|
# play.js: et nyt, tomt felt, når opgaven er ny, og afterPlay, der fylder kladden i.
|
|
SCRIPT = r"""
|
|
const fs = require('fs'), vm = require('vm');
|
|
const handlers = {};
|
|
const root = { _ui: {}, addEventListener: (t, f) => { handlers[t] = f; }, querySelectorAll: () => [], contains: () => true,
|
|
querySelector: (sel) => sel === '#tg-text' ? root.input : null };
|
|
const window = { WPP: { esc: (s) => String(s), now: () => 0, reducedMotion: () => true, cleanInput: (v) => v }, devicePixelRatio: 1,
|
|
addEventListener: () => {} };
|
|
vm.runInNewContext(fs.readFileSync(process.argv[1], 'utf8'), { window, document: { addEventListener() {} },
|
|
requestAnimationFrame: () => 0, setTimeout: () => 0, clearTimeout: () => {} });
|
|
const T = window.WPPTegn;
|
|
const state = (phase) => ({ code: 'KLMT', phase, step: { index: 0 }, me: { task: phase === 'word' ? { kind: 'word', done: false } : null } });
|
|
const render = (phase) => {
|
|
root.input = phase === 'word' ? { value: '', getAttribute: () => 'KLMT:0:word' } : null;
|
|
T.afterPlay(root, state(phase), root._ui);
|
|
return root.input && root.input.value;
|
|
};
|
|
const out = {};
|
|
render('word');
|
|
root.input.value = 'kat';
|
|
handlers.input && handlers.input({ target: Object.assign(root.input, { id: 'tg-text', matches: () => true, closest: () => root.input }) });
|
|
out.same_step = render('word'); // samme trin, ny render: kladden står der stadig
|
|
for (const p of ['draw', 'guess', 'reveal', 'final', 'theme']) render(p);
|
|
out.next_game = render('word'); // "Spil igen": samme nøgle KLMT:0:word i næste spil
|
|
console.log(JSON.stringify(out));
|
|
"""
|
|
|
|
|
|
@unittest.skipUnless(shutil.which("node"), "node findes ikke")
|
|
class WordDraftTests(unittest.TestCase):
|
|
def test_last_games_word_is_not_filled_in(self):
|
|
res = subprocess.run(["node", "-e", SCRIPT, str(TEGN_JS)], capture_output=True, text=True, timeout=30)
|
|
self.assertEqual(res.returncode, 0, res.stderr)
|
|
out = json.loads(res.stdout)
|
|
self.assertEqual(out["same_step"], "kat")
|
|
self.assertIn(out["next_game"], ("", None))
|