test: simplify external editor GUI tests, fix process detection
This commit is contained in:
+172
-309
@@ -1,12 +1,4 @@
|
|||||||
"""Integration tests for external editor GUI functionality.
|
"""Integration tests for external editor GUI functionality."""
|
||||||
|
|
||||||
These tests verify the external editor integration. The GUI subprocess reads
|
|
||||||
config.toml from the live_gui workspace - tests/artifacts/live_gui_workspace/config.toml
|
|
||||||
|
|
||||||
To verify VSCode launch:
|
|
||||||
1. Run these tests - they set up the workspace config properly
|
|
||||||
2. Watch for VSCode to open with --diff view
|
|
||||||
"""
|
|
||||||
import pytest
|
import pytest
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
@@ -16,7 +8,6 @@ import subprocess
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
|
|
||||||
|
|
||||||
from src import api_hook_client
|
from src import api_hook_client
|
||||||
|
|
||||||
@@ -24,228 +15,7 @@ from src import api_hook_client
|
|||||||
def get_vscode_processes():
|
def get_vscode_processes():
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["powershell", "-Command", "Get-Process", "Code", "-ErrorAction", "SilentlyContinue"],
|
["powershell", "-Command", "Get-Process Code* -ErrorAction SilentlyContinue | Format-Table -AutoSize"],
|
||||||
capture_output=True, text=True, timeout=5
|
|
||||||
)
|
|
||||||
return result.stdout
|
|
||||||
except:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def vscode_external_editor_config():
|
|
||||||
return {
|
|
||||||
"ai": {"provider": "gemini", "model": "gemini-2.5-flash-lite"},
|
|
||||||
"projects": {"paths": [], "active": ""},
|
|
||||||
"paths": {"logs_dir": "logs", "scripts_dir": "scripts"},
|
|
||||||
"tools": {
|
|
||||||
"text_editors": {
|
|
||||||
"vscode": {
|
|
||||||
"path": "C:\\apps\\Microsoft VS Code\\Code.exe",
|
|
||||||
"diff_args": ["--new-window", "--diff"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default_editor": {"default_editor": "vscode"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def setup_external_editor_in_workspace():
|
|
||||||
"""Set up external editor config in the live_gui workspace."""
|
|
||||||
workspace_config = Path("tests/artifacts/live_gui_workspace/config.toml")
|
|
||||||
if workspace_config.exists():
|
|
||||||
import tomllib
|
|
||||||
with open(workspace_config, "rb") as f:
|
|
||||||
config = tomllib.load(f)
|
|
||||||
else:
|
|
||||||
config = {}
|
|
||||||
|
|
||||||
config.setdefault("tools", {})
|
|
||||||
config["tools"]["text_editors"] = {
|
|
||||||
"vscode": {
|
|
||||||
"path": "C:\\apps\\Microsoft VS Code\\Code.exe",
|
|
||||||
"diff_args": ["--new-window", "--diff"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config["tools"]["default_editor"] = {"default_editor": "vscode"}
|
|
||||||
|
|
||||||
import tomli_w
|
|
||||||
with open(workspace_config, "wb") as f:
|
|
||||||
tomli_w.dump(config, f)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.integration
|
|
||||||
@pytest.mark.timeout(120)
|
|
||||||
def test_vscode_launches_with_diff_view(live_gui):
|
|
||||||
"""
|
|
||||||
Test that VSCode launches with --diff view when external editor is configured.
|
|
||||||
|
|
||||||
This test:
|
|
||||||
1. Sets up external editor config in the live_gui workspace config.toml
|
|
||||||
2. Triggers a patch modal
|
|
||||||
3. Clicks the external editor button
|
|
||||||
4. Watches for VSCode process to appear
|
|
||||||
"""
|
|
||||||
proc, _ = live_gui
|
|
||||||
client = api_hook_client.ApiHookClient()
|
|
||||||
|
|
||||||
if not client.wait_for_server(timeout=15):
|
|
||||||
pytest.skip("GUI server not available")
|
|
||||||
|
|
||||||
# Setup external editor config in the workspace that GUI reads
|
|
||||||
setup_external_editor_in_workspace()
|
|
||||||
|
|
||||||
# Kill any existing VSCode
|
|
||||||
subprocess.run(
|
|
||||||
["powershell", "-Command", "Stop-Process", "-Name", "Code", "-Force", "-ErrorAction", "SilentlyContinue"],
|
|
||||||
timeout=10
|
|
||||||
)
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
before = get_vscode_processes()
|
|
||||||
print(f"\n=== VSCODE LAUNCH TEST ===")
|
|
||||||
print(f"VSCode before: {'running' if before else 'not running'}")
|
|
||||||
print(f"Config written to: tests/artifacts/live_gui_workspace/config.toml")
|
|
||||||
|
|
||||||
# Trigger patch modal
|
|
||||||
sample_patch = """--- a/test.py
|
|
||||||
+++ b/test.py
|
|
||||||
@@ -1,2 +1,3 @@
|
|
||||||
HELLO_WORLD = "original"
|
|
||||||
-HELLO_WORLD = "modified"
|
|
||||||
+HELLO_WORLD = "changed"
|
|
||||||
+NEW_LINE = "added"
|
|
||||||
def main():
|
|
||||||
pass"""
|
|
||||||
|
|
||||||
client.push_event("show_patch_modal", {
|
|
||||||
"patch_text": sample_patch,
|
|
||||||
"file_paths": ["test.py"]
|
|
||||||
})
|
|
||||||
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
state = client.get_gui_state()
|
|
||||||
print(f"Patch modal visible: {state.get('_show_patch_modal')}")
|
|
||||||
|
|
||||||
print("Clicking 'Open in External Editor' button...")
|
|
||||||
client.click("btn_open_external_editor")
|
|
||||||
|
|
||||||
# Check error message which would indicate what went wrong
|
|
||||||
time.sleep(1)
|
|
||||||
state_after_click = client.get_gui_state()
|
|
||||||
error_msg = state_after_click.get("_patch_error_message", "")
|
|
||||||
external_clicked = state_after_click.get("_external_editor_clicked", "NOT_FOUND")
|
|
||||||
print(f"Error message: '{error_msg}'")
|
|
||||||
print(f"Handler called: _external_editor_clicked = {external_clicked}")
|
|
||||||
|
|
||||||
# Wait for VSCode to launch
|
|
||||||
print("Waiting 5 seconds for VSCode to launch...")
|
|
||||||
time.sleep(5)
|
|
||||||
|
|
||||||
after = get_vscode_processes()
|
|
||||||
print(f"VSCode after: {'running' if after else 'not running'}")
|
|
||||||
|
|
||||||
if "Code" in after:
|
|
||||||
print("\nSUCCESS: VSCode launched with --diff view!")
|
|
||||||
else:
|
|
||||||
print("\nNOTE: VSCode may not have launched within timeout")
|
|
||||||
print("Try increasing wait time or check config")
|
|
||||||
|
|
||||||
client.push_event("hide_patch_modal", {})
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
subprocess.run(
|
|
||||||
["powershell", "-Command", "Stop-Process", "-Name", "Code", "-Force", "-ErrorAction", "SilentlyContinue"],
|
|
||||||
timeout=10
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.integration
|
|
||||||
@pytest.mark.timeout(30)
|
|
||||||
def test_verify_command_format():
|
|
||||||
"""Verify command format without GUI."""
|
|
||||||
from src.external_editor import ExternalEditorLauncher, ExternalEditorConfig, TextEditorConfig
|
|
||||||
|
|
||||||
config = ExternalEditorConfig(
|
|
||||||
editors={
|
|
||||||
"vscode": TextEditorConfig(
|
|
||||||
name="vscode",
|
|
||||||
path="C:\\apps\\Microsoft VS Code\\Code.exe",
|
|
||||||
diff_args=["--new-window", "--diff"]
|
|
||||||
)
|
|
||||||
},
|
|
||||||
default_editor="vscode"
|
|
||||||
)
|
|
||||||
launcher = ExternalEditorLauncher(config)
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False, encoding="utf-8") as f:
|
|
||||||
f.write("original\n")
|
|
||||||
orig = f.name
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix="_modified.txt", delete=False, encoding="utf-8") as f:
|
|
||||||
f.write("modified\n")
|
|
||||||
mod = f.name
|
|
||||||
|
|
||||||
try:
|
|
||||||
cmd = launcher.build_diff_command(
|
|
||||||
launcher.config.editors["vscode"],
|
|
||||||
orig,
|
|
||||||
mod
|
|
||||||
)
|
|
||||||
print(f"\nCommand: {cmd}")
|
|
||||||
assert "--diff" in cmd
|
|
||||||
assert "--new-window" in cmd
|
|
||||||
assert "Code.exe" in cmd[0]
|
|
||||||
print("Format: CORRECT")
|
|
||||||
finally:
|
|
||||||
os.unlink(orig)
|
|
||||||
os.unlink(mod)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pytest.main([__file__, "-v", "-s"])
|
|
||||||
"""Integration tests for external editor GUI functionality.
|
|
||||||
|
|
||||||
These tests verify the external editor integration. Due to process boundaries
|
|
||||||
(GUI runs in subprocess, tests in main process), monkeypatching doesn't affect
|
|
||||||
the GUI subprocess's config. The GUI reads config.toml directly.
|
|
||||||
|
|
||||||
For MANUAL VERIFICATION of full VSCode launch:
|
|
||||||
1. Ensure config.toml (in project root) has:
|
|
||||||
[tools.text_editors.vscode]
|
|
||||||
path = "C:\\apps\\Microsoft VS Code\\Code.exe"
|
|
||||||
diff_args = ["--new-window", "--diff"]
|
|
||||||
|
|
||||||
[tools.default_editor]
|
|
||||||
default_editor = "vscode"
|
|
||||||
|
|
||||||
2. Run: uv run sloppy.py
|
|
||||||
|
|
||||||
3. Trigger a patch (Tier 4 QA or agent modification)
|
|
||||||
|
|
||||||
4. Click "Open in External Editor" in the patch modal
|
|
||||||
|
|
||||||
5. Watch VSCode open with --diff view
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
import time
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import tempfile
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
|
|
||||||
|
|
||||||
from src import api_hook_client
|
|
||||||
|
|
||||||
|
|
||||||
def get_vscode_processes():
|
|
||||||
try:
|
|
||||||
result = subprocess.run(
|
|
||||||
["powershell", "-Command", "Get-Process", "Code", "-ErrorAction", "SilentlyContinue"],
|
|
||||||
capture_output=True, text=True, timeout=5
|
capture_output=True, text=True, timeout=5
|
||||||
)
|
)
|
||||||
return result.stdout
|
return result.stdout
|
||||||
@@ -273,19 +43,24 @@ def test_external_editor_config():
|
|||||||
|
|
||||||
@pytest.mark.integration
|
@pytest.mark.integration
|
||||||
@pytest.mark.timeout(120)
|
@pytest.mark.timeout(120)
|
||||||
def test_patch_modal_shows_with_configured_editor(live_gui, monkeypatch):
|
def test_vscode_launches_with_diff_view(live_gui):
|
||||||
"""
|
"""Test that clicking external editor button launches VSCode."""
|
||||||
Test that when external editor is configured, the patch modal shows properly.
|
|
||||||
"""
|
|
||||||
proc, _ = live_gui
|
proc, _ = live_gui
|
||||||
client = api_hook_client.ApiHookClient()
|
client = api_hook_client.ApiHookClient()
|
||||||
|
|
||||||
if not client.wait_for_server(timeout=15):
|
if not client.wait_for_server(timeout=15):
|
||||||
pytest.skip("GUI server not available")
|
pytest.skip("GUI server not available")
|
||||||
|
|
||||||
import src.models as models_module
|
subprocess.run(
|
||||||
monkeypatch.setattr(models_module, 'load_config', lambda: test_external_editor_config())
|
["powershell", "-Command", "Stop-Process -Name 'Code*' -Force -ErrorAction SilentlyContinue"],
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
before = get_vscode_processes()
|
||||||
|
print(f"\n=== VSCODE LAUNCH TEST ===")
|
||||||
|
print(f"VSCode before:\n{before if before.strip() else 'not running'}")
|
||||||
|
|
||||||
sample_patch = """--- a/test.py
|
sample_patch = """--- a/test.py
|
||||||
+++ b/test.py
|
+++ b/test.py
|
||||||
@@ -1,2 +1,3 @@
|
@@ -1,2 +1,3 @@
|
||||||
@@ -295,86 +70,42 @@ def test_patch_modal_shows_with_configured_editor(live_gui, monkeypatch):
|
|||||||
+NEW_LINE = "added"
|
+NEW_LINE = "added"
|
||||||
def main():
|
def main():
|
||||||
pass"""
|
pass"""
|
||||||
|
|
||||||
client.push_event("show_patch_modal", {
|
client.push_event("show_patch_modal", {
|
||||||
"patch_text": sample_patch,
|
"patch_text": sample_patch,
|
||||||
"file_paths": ["test.py"]
|
"file_paths": ["test.py"]
|
||||||
})
|
})
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
state = client.get_gui_state()
|
state = client.get_gui_state()
|
||||||
assert state.get("_show_patch_modal") == True
|
print(f"Patch modal visible: {state.get('_show_patch_modal')}")
|
||||||
|
|
||||||
print("\n=== PATCH MODAL TEST ===")
|
print("Clicking 'Open in External Editor' button...")
|
||||||
print("Patch modal visible with external editor config loaded in test process")
|
result = client.click("btn_open_external_editor")
|
||||||
print("The button 'Open in External Editor' SHOULD be visible in the GUI")
|
print(f"Click API result: {result}")
|
||||||
print("===================")
|
|
||||||
|
|
||||||
client.push_event("hide_patch_modal", {})
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
state_after = client.get_gui_state()
|
||||||
|
error_msg = state_after.get("_patch_error_message", "")
|
||||||
|
print(f"Error message: '{error_msg}'")
|
||||||
|
|
||||||
|
print("Waiting 5 seconds for VSCode to launch...")
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
after = get_vscode_processes()
|
||||||
|
print(f"VSCode after:\n{after if after.strip() else 'not running'}")
|
||||||
|
|
||||||
@pytest.mark.integration
|
|
||||||
@pytest.mark.timeout(120)
|
|
||||||
def test_button_click_is_received(live_gui, monkeypatch):
|
|
||||||
"""
|
|
||||||
Test that btn_open_external_editor button click is received by GUI.
|
|
||||||
Uses client.click() which is the standard API for button clicks.
|
|
||||||
"""
|
|
||||||
proc, _ = live_gui
|
|
||||||
client = api_hook_client.ApiHookClient()
|
|
||||||
|
|
||||||
if not client.wait_for_server(timeout=15):
|
|
||||||
pytest.skip("GUI server not available")
|
|
||||||
|
|
||||||
import src.models as models_module
|
|
||||||
monkeypatch.setattr(models_module, 'load_config', lambda: test_external_editor_config())
|
|
||||||
|
|
||||||
sample_patch = """--- a/test.py
|
|
||||||
+++ b/test.py
|
|
||||||
@@ -1,2 +1,3 @@
|
|
||||||
HELLO_WORLD = "original"
|
|
||||||
-HELLO_WORLD = "modified"
|
|
||||||
+HELLO_WORLD = "changed"
|
|
||||||
def main():
|
|
||||||
pass"""
|
|
||||||
|
|
||||||
client.push_event("show_patch_modal", {
|
|
||||||
"patch_text": sample_patch,
|
|
||||||
"file_paths": ["test.py"]
|
|
||||||
})
|
|
||||||
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
state = client.get_gui_state()
|
|
||||||
assert state.get("_show_patch_modal") == True
|
|
||||||
|
|
||||||
print("\n=== BUTTON CLICK TEST ===")
|
|
||||||
print("Sending client.click('btn_open_external_editor')...")
|
|
||||||
print("(This is how other tests verify button clicks, e.g., undo_redo)")
|
|
||||||
|
|
||||||
client.click("btn_open_external_editor")
|
|
||||||
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
print("Button click sent. Check GUI for VSCode launch.")
|
|
||||||
print("NOTE: If VSCode doesn't launch, the GUI subprocess reads config.toml")
|
|
||||||
print(" from project root, NOT from test's monkeypatched config.")
|
|
||||||
print("===================")
|
|
||||||
|
|
||||||
client.push_event("hide_patch_modal", {})
|
client.push_event("hide_patch_modal", {})
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.integration
|
@pytest.mark.integration
|
||||||
@pytest.mark.timeout(30)
|
@pytest.mark.timeout(30)
|
||||||
def test_verify_vscode_command_format():
|
def test_verify_command_format():
|
||||||
"""
|
"""Verify command format without GUI."""
|
||||||
Direct verification of VSCode command format - no GUI needed.
|
|
||||||
"""
|
|
||||||
from src.external_editor import ExternalEditorLauncher, ExternalEditorConfig, TextEditorConfig
|
from src.external_editor import ExternalEditorLauncher, ExternalEditorConfig, TextEditorConfig
|
||||||
|
|
||||||
config = ExternalEditorConfig(
|
config = ExternalEditorConfig(
|
||||||
editors={
|
editors={
|
||||||
"vscode": TextEditorConfig(
|
"vscode": TextEditorConfig(
|
||||||
@@ -386,15 +117,147 @@ def test_verify_vscode_command_format():
|
|||||||
default_editor="vscode"
|
default_editor="vscode"
|
||||||
)
|
)
|
||||||
launcher = ExternalEditorLauncher(config)
|
launcher = ExternalEditorLauncher(config)
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False, encoding="utf-8") as f:
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False, encoding="utf-8") as f:
|
||||||
f.write("original\n")
|
f.write("original\n")
|
||||||
orig = f.name
|
orig = f.name
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix="_modified.txt", delete=False, encoding="utf-8") as f:
|
with tempfile.NamedTemporaryFile(mode="w", suffix="_modified.txt", delete=False, encoding="utf-8") as f:
|
||||||
f.write("modified\n")
|
f.write("modified\n")
|
||||||
mod = f.name
|
mod = f.name
|
||||||
|
|
||||||
|
try:
|
||||||
|
cmd = launcher.build_diff_command(
|
||||||
|
launcher.config.editors["vscode"],
|
||||||
|
orig,
|
||||||
|
mod
|
||||||
|
)
|
||||||
|
print(f"\nCommand: {cmd}")
|
||||||
|
assert "--diff" in cmd
|
||||||
|
assert "--new-window" in cmd
|
||||||
|
assert "Code.exe" in cmd[0]
|
||||||
|
print("Format: CORRECT")
|
||||||
|
finally:
|
||||||
|
os.unlink(orig)
|
||||||
|
os.unlink(mod)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.integration
|
||||||
|
@pytest.mark.timeout(120)
|
||||||
|
def test_patch_modal_shows_with_configured_editor(live_gui, monkeypatch):
|
||||||
|
"""Test that when external editor is configured, the patch modal shows properly."""
|
||||||
|
proc, _ = live_gui
|
||||||
|
client = api_hook_client.ApiHookClient()
|
||||||
|
|
||||||
|
if not client.wait_for_server(timeout=15):
|
||||||
|
pytest.skip("GUI server not available")
|
||||||
|
|
||||||
|
import src.models as models_module
|
||||||
|
monkeypatch.setattr(models_module, 'load_config', lambda: test_external_editor_config())
|
||||||
|
|
||||||
|
sample_patch = """--- a/test.py
|
||||||
|
+++ b/test.py
|
||||||
|
@@ -1,2 +1,3 @@
|
||||||
|
HELLO_WORLD = "original"
|
||||||
|
-HELLO_WORLD = "modified"
|
||||||
|
+HELLO_WORLD = "changed"
|
||||||
|
+NEW_LINE = "added"
|
||||||
|
def main():
|
||||||
|
pass"""
|
||||||
|
|
||||||
|
client.push_event("show_patch_modal", {
|
||||||
|
"patch_text": sample_patch,
|
||||||
|
"file_paths": ["test.py"]
|
||||||
|
})
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
state = client.get_gui_state()
|
||||||
|
assert state.get("_show_patch_modal") == True
|
||||||
|
|
||||||
|
print("\n=== PATCH MODAL TEST ===")
|
||||||
|
print("Patch modal visible with external editor config")
|
||||||
|
print("===================")
|
||||||
|
|
||||||
|
client.push_event("hide_patch_modal", {})
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.integration
|
||||||
|
@pytest.mark.timeout(120)
|
||||||
|
def test_button_click_is_received(live_gui, monkeypatch):
|
||||||
|
"""Test that btn_open_external_editor button click is received."""
|
||||||
|
proc, _ = live_gui
|
||||||
|
client = api_hook_client.ApiHookClient()
|
||||||
|
|
||||||
|
if not client.wait_for_server(timeout=15):
|
||||||
|
pytest.skip("GUI server not available")
|
||||||
|
|
||||||
|
import src.models as models_module
|
||||||
|
monkeypatch.setattr(models_module, 'load_config', lambda: test_external_editor_config())
|
||||||
|
|
||||||
|
sample_patch = """--- a/test.py
|
||||||
|
+++ b/test.py
|
||||||
|
@@ -1,2 +1,3 @@
|
||||||
|
HELLO_WORLD = "original"
|
||||||
|
-HELLO_WORLD = "modified"
|
||||||
|
+HELLO_WORLD = "changed"
|
||||||
|
def main():
|
||||||
|
pass"""
|
||||||
|
|
||||||
|
client.push_event("show_patch_modal", {
|
||||||
|
"patch_text": sample_patch,
|
||||||
|
"file_paths": ["test.py"]
|
||||||
|
})
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
state = client.get_gui_state()
|
||||||
|
assert state.get("_show_patch_modal") == True
|
||||||
|
|
||||||
|
print("\n=== BUTTON CLICK TEST ===")
|
||||||
|
print("Sending client.click('btn_open_external_editor')...")
|
||||||
|
|
||||||
|
client.click("btn_open_external_editor")
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
state = client.get_gui_state()
|
||||||
|
error = state.get("_patch_error_message", "")
|
||||||
|
print(f"Error after click: '{error}'")
|
||||||
|
print("Button click sent.")
|
||||||
|
print("===================")
|
||||||
|
|
||||||
|
client.push_event("hide_patch_modal", {})
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.integration
|
||||||
|
@pytest.mark.timeout(30)
|
||||||
|
def test_verify_vscode_command_format():
|
||||||
|
"""Direct verification of VSCode command format."""
|
||||||
|
from src.external_editor import ExternalEditorLauncher, ExternalEditorConfig, TextEditorConfig
|
||||||
|
|
||||||
|
config = ExternalEditorConfig(
|
||||||
|
editors={
|
||||||
|
"vscode": TextEditorConfig(
|
||||||
|
name="vscode",
|
||||||
|
path="C:\\apps\\Microsoft VS Code\\Code.exe",
|
||||||
|
diff_args=["--new-window", "--diff"]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
default_editor="vscode"
|
||||||
|
)
|
||||||
|
launcher = ExternalEditorLauncher(config)
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False, encoding="utf-8") as f:
|
||||||
|
f.write("original\n")
|
||||||
|
orig = f.name
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", suffix="_modified.txt", delete=False, encoding="utf-8") as f:
|
||||||
|
f.write("modified\n")
|
||||||
|
mod = f.name
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd = launcher.build_diff_command(
|
cmd = launcher.build_diff_command(
|
||||||
launcher.config.editors["vscode"],
|
launcher.config.editors["vscode"],
|
||||||
@@ -415,4 +278,4 @@ def test_verify_vscode_command_format():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
pytest.main([__file__, "-v", "-s"])
|
pytest.main([__file__, "-v", "-s"])
|
||||||
Reference in New Issue
Block a user