File size: 2,777 Bytes
5b4c023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c7a278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5b4c023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c7a278
5b4c023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def test_command_input_stays_enabled_while_execution_is_active():
    source = (ROOT / "frontend" / "app.js").read_text(encoding="utf-8")
    lock_body = source.split("function lockInput()", 1)[1].split(
        "document.getElementById('chat-form')",
        1,
    )[0]

    assert "chatInput.disabled = false" in lock_body
    assert "submitBtn.disabled = false" in lock_body
    assert "setSubmitButtonMode(true)" in lock_body


def test_click_stops_but_enter_submits_replacement_command():
    source = (ROOT / "frontend" / "app.js").read_text(encoding="utf-8")

    assert "enterSubmittedFromChatInput" in source
    assert "e.submitter === submitBtn && !submittedWithEnter" in source
    assert "JSON.stringify({ type: 'cancel' })" in source
    assert "type: 'run'" in source
    cancel_guard = source.index(
        "if (busy && e.submitter === submitBtn && !submittedWithEnter)"
    )
    prompt_guard = source.index("if (!prompt || !socket", cancel_guard)
    assert cancel_guard < prompt_guard


def test_empty_input_does_not_trigger_native_validation_before_stop():
    html = (ROOT / "frontend" / "index.html").read_text(encoding="utf-8")
    input_markup = html.split('id="chat-input"', 1)[1].split(">", 1)[0]

    assert "required" not in input_markup


def test_interrupt_requested_uses_stopping_button_state():
    source = (ROOT / "frontend" / "app.js").read_text(encoding="utf-8")

    handler = source.split("case 'interrupt_requested':", 1)[1].split(
        "case 'interrupted':",
        1,
    )[0]
    assert "setSubmitButtonMode(true, true)" in handler
    assert "Đang dừng lệnh..." in source


def test_execution_button_has_spinner_and_stop_square():
    script = (ROOT / "frontend" / "app.js").read_text(encoding="utf-8")
    styles = (ROOT / "frontend" / "index.css").read_text(encoding="utf-8")

    assert "stop-square" in script
    assert "is-executing" in script
    assert "#submit-btn.is-executing::before" in styles
    assert "@keyframes submitExecutionSpin" in styles


def test_html_cache_busts_live_command_assets():
    html = (ROOT / "frontend" / "index.html").read_text(encoding="utf-8")

    assert "/static/app.js?v=39" in html
    assert "/static/index.css?v=11" in html


def test_clarification_result_is_not_recorded_as_failed_execution():
    source = (ROOT / "frontend" / "app.js").read_text(encoding="utf-8")

    result_handler = source.split("case 'result':", 1)[1].split(
        "const badge =",
        1,
    )[0]
    clarification_guard = result_handler.index(
        "['clarify', 'reject'].includes(msg.response_type)"
    )
    history_write = result_handler.index("historyData.unshift")

    assert clarification_guard < history_write