EU-Utility/plugins/test_suite/api_comprehensive_test/plugin.py

812 lines
31 KiB
Python

"""
API Comprehensive Test Plugin
Tests every method in the three-tier API:
- PluginAPI: All 12 services
- WidgetAPI: All widget operations
- ExternalAPI: REST, webhooks, auth, IPC
Usage:
This plugin runs automatically on initialization and generates
a comprehensive test report visible in its widget.
"""
import time
import json
from datetime import datetime
from typing import Dict, List, Any, Callable
from dataclasses import dataclass, asdict
from core.base_plugin import BasePlugin
from core.api.plugin_api import get_api, PluginAPIError, ServiceNotAvailableError
from core.api.widget_api import get_widget_api, WidgetType, WidgetAnchor, WidgetConfig
from core.api.external_api import get_external_api, ExternalAPIError
@dataclass
class TestResult:
"""Single test result record."""
name: str
api: str
passed: bool
duration_ms: float
error: str = None
details: Dict = None
class APIComprehensiveTestPlugin(BasePlugin):
"""
Comprehensive test suite for EU-Utility APIs.
Tests every public method across all three API tiers:
- PluginAPI: 12 services
- WidgetAPI: Widget lifecycle and operations
- ExternalAPI: Server, webhooks, IPC
"""
def __init__(self):
super().__init__()
self.api = None
self.widget_api = None
self.external_api = None
self.results: List[TestResult] = []
self.widget = None
self.test_widget = None
def initialize(self):
"""Initialize plugin and run all tests."""
self.api = get_api()
self.widget_api = get_widget_api()
self.external_api = get_external_api()
self._create_results_widget()
self._run_all_tests()
self._update_widget_display()
def _create_results_widget(self):
"""Create widget to display test results."""
self.widget = self.widget_api.create_widget(
name="api_comprehensive_test",
title="🔬 API Comprehensive Test Results",
size=(800, 600),
position=(50, 50),
widget_type=WidgetType.CUSTOM
)
# Create simple HTML content for results
content = self._create_results_html()
self.widget.set_content(content)
self.widget.show()
def _create_results_html(self):
"""Create HTML content for results display."""
try:
from PyQt6.QtWidgets import QTextBrowser, QVBoxLayout, QWidget
container = QWidget()
layout = QVBoxLayout(container)
self.results_browser = QTextBrowser()
self.results_browser.setHtml(self._get_initial_html())
layout.addWidget(self.results_browser)
return container
except ImportError:
return None
def _get_initial_html(self) -> str:
"""Generate initial HTML template."""
return """
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: monospace; background: #1a1a2e; color: #eee; padding: 20px; }
h1 { color: #ff8c42; }
.pass { color: #4ecca3; }
.fail { color: #ff6b6b; }
.running { color: #ffd93d; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th { background: #2d3748; padding: 10px; text-align: left; }
td { padding: 8px; border-bottom: 1px solid #444; }
.summary { background: #2d3748; padding: 15px; border-radius: 8px; margin: 20px 0; }
</style>
</head>
<body>
<h1>🔬 API Comprehensive Test Suite</h1>
<div class="running">⏳ Running tests...</div>
</body>
</html>
"""
def _update_widget_display(self):
"""Update widget with test results."""
if hasattr(self, 'results_browser'):
self.results_browser.setHtml(self._generate_results_html())
def _generate_results_html(self) -> str:
"""Generate full results HTML."""
passed = sum(1 for r in self.results if r.passed)
failed = sum(1 for r in self.results if not r.passed)
total = len(self.results)
html = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: 'Segoe UI', monospace; background: #1a1a2e; color: #eee; padding: 20px; }}
h1 {{ color: #ff8c42; margin-bottom: 10px; }}
.summary {{ background: #2d3748; padding: 20px; border-radius: 8px; margin: 20px 0; }}
.pass {{ color: #4ecca3; }}
.fail {{ color: #ff6b6b; }}
.stat {{ display: inline-block; margin-right: 30px; }}
.stat-value {{ font-size: 2em; font-weight: bold; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 13px; }}
th {{ background: #2d3748; padding: 12px; text-align: left; color: #ff8c42; }}
td {{ padding: 10px; border-bottom: 1px solid #444; }}
tr:hover {{ background: #252540; }}
.api-section {{ background: #2d3748; padding: 5px 10px; border-radius: 4px; font-weight: bold; }}
.duration {{ color: #888; font-size: 0.9em; }}
</style>
</head>
<body>
<h1>🔬 API Comprehensive Test Results</h1>
<div class="summary">
<div class="stat">
<div class="stat-value">{total}</div>
<div>Total Tests</div>
</div>
<div class="stat">
<div class="stat-value pass">{passed} ✅</div>
<div>Passed</div>
</div>
<div class="stat">
<div class="stat-value fail">{failed} ❌</div>
<div>Failed</div>
</div>
<div class="stat">
<div class="stat-value">{(passed/total*100 if total else 0):.1f}%</div>
<div>Success Rate</div>
</div>
</div>
<table>
<tr>
<th>API</th>
<th>Test Name</th>
<th>Result</th>
<th>Duration</th>
<th>Error</th>
</tr>
"""
for result in self.results:
status_class = "pass" if result.passed else "fail"
status_icon = "" if result.passed else ""
error_text = result.error if result.error else ""
html += f"""
<tr>
<td><span class="api-section">{result.api}</span></td>
<td>{result.name}</td>
<td class="{status_class}">{status_icon} {'PASS' if result.passed else 'FAIL'}</td>
<td class="duration">{result.duration_ms:.2f}ms</td>
<td class="fail">{error_text}</td>
</tr>
"""
html += """
</table>
</body>
</html>
"""
return html
def _run_test(self, name: str, api: str, test_func: Callable) -> TestResult:
"""Run a single test and record result."""
start = time.time()
try:
test_func()
duration = (time.time() - start) * 1000
result = TestResult(name=name, api=api, passed=True, duration_ms=duration)
except Exception as e:
duration = (time.time() - start) * 1000
result = TestResult(name=name, api=api, passed=False, duration_ms=duration, error=str(e))
self.results.append(result)
return result
def _run_all_tests(self):
"""Execute all API tests."""
self._test_plugin_api()
self._test_widget_api()
self._test_external_api()
# =====================================================================
# PluginAPI Tests
# =====================================================================
def _test_plugin_api(self):
"""Test all PluginAPI services."""
# Log Reader API
self._run_test("read_log_lines", "PluginAPI", self._test_read_log_lines)
self._run_test("read_log_since", "PluginAPI", self._test_read_log_since)
# Window Manager API
self._run_test("get_eu_window", "PluginAPI", self._test_get_eu_window)
self._run_test("is_eu_focused", "PluginAPI", self._test_is_eu_focused)
self._run_test("is_eu_visible", "PluginAPI", self._test_is_eu_visible)
self._run_test("bring_eu_to_front", "PluginAPI", self._test_bring_eu_to_front)
# OCR API
self._run_test("ocr_available", "PluginAPI", self._test_ocr_available)
self._run_test("recognize_text", "PluginAPI", self._test_recognize_text)
# Screenshot API
self._run_test("screenshot_available", "PluginAPI", self._test_screenshot_available)
self._run_test("capture_screen", "PluginAPI", self._test_capture_screen)
# Nexus API
self._run_test("search_items", "PluginAPI", self._test_search_items)
self._run_test("get_item_details", "PluginAPI", self._test_get_item_details)
# HTTP Client API
self._run_test("http_get", "PluginAPI", self._test_http_get)
self._run_test("http_post", "PluginAPI", self._test_http_post)
# Audio API
self._run_test("play_sound", "PluginAPI", self._test_play_sound)
self._run_test("beep", "PluginAPI", self._test_beep)
# Notification API
self._run_test("show_notification", "PluginAPI", self._test_show_notification)
# Clipboard API
self._run_test("copy_to_clipboard", "PluginAPI", self._test_copy_to_clipboard)
self._run_test("paste_from_clipboard", "PluginAPI", self._test_paste_from_clipboard)
# Event Bus API
self._run_test("subscribe", "PluginAPI", self._test_subscribe)
self._run_test("unsubscribe", "PluginAPI", self._test_unsubscribe)
self._run_test("publish", "PluginAPI", self._test_publish)
# Data Store API
self._run_test("set_data", "PluginAPI", self._test_set_data)
self._run_test("get_data", "PluginAPI", self._test_get_data)
self._run_test("delete_data", "PluginAPI", self._test_delete_data)
# Task API
self._run_test("run_task", "PluginAPI", self._test_run_task)
self._run_test("cancel_task", "PluginAPI", self._test_cancel_task)
def _test_read_log_lines(self):
"""Test read_log_lines method."""
lines = self.api.read_log_lines(10)
assert isinstance(lines, list)
def _test_read_log_since(self):
"""Test read_log_since method."""
lines = self.api.read_log_since(datetime.now())
assert isinstance(lines, list)
def _test_get_eu_window(self):
"""Test get_eu_window method."""
window = self.api.get_eu_window()
# May be None if EU not running
if window is not None:
assert isinstance(window, dict)
assert 'title' in window
def _test_is_eu_focused(self):
"""Test is_eu_focused method."""
result = self.api.is_eu_focused()
assert isinstance(result, bool)
def _test_is_eu_visible(self):
"""Test is_eu_visible method."""
result = self.api.is_eu_visible()
assert isinstance(result, bool)
def _test_bring_eu_to_front(self):
"""Test bring_eu_to_front method."""
result = self.api.bring_eu_to_front()
assert isinstance(result, bool)
def _test_ocr_available(self):
"""Test ocr_available method."""
result = self.api.ocr_available()
assert isinstance(result, bool)
def _test_recognize_text(self):
"""Test recognize_text method."""
if not self.api.ocr_available():
return # Skip if OCR not available
try:
text = self.api.recognize_text((0, 0, 100, 100))
assert isinstance(text, str)
except ServiceNotAvailableError:
pass # Expected if service not available
def _test_screenshot_available(self):
"""Test screenshot_available method."""
result = self.api.screenshot_available()
assert isinstance(result, bool)
def _test_capture_screen(self):
"""Test capture_screen method."""
result = self.api.capture_screen((0, 0, 100, 100))
# May be None if screenshot service unavailable
assert result is None or hasattr(result, 'size')
def _test_search_items(self):
"""Test search_items method."""
items = self.api.search_items("test", limit=5)
assert isinstance(items, list)
def _test_get_item_details(self):
"""Test get_item_details method."""
details = self.api.get_item_details(12345)
# May be None if item not found
assert details is None or isinstance(details, dict)
def _test_http_get(self):
"""Test http_get method."""
result = self.api.http_get("https://httpbin.org/get", cache=False)
assert isinstance(result, dict)
assert 'success' in result
def _test_http_post(self):
"""Test http_post method."""
result = self.api.http_post("https://httpbin.org/post", {"test": "data"})
assert isinstance(result, dict)
assert 'success' in result
def _test_play_sound(self):
"""Test play_sound method."""
result = self.api.play_sound("nonexistent.wav")
# Returns False for non-existent file, but shouldn't crash
assert isinstance(result, bool)
def _test_beep(self):
"""Test beep method."""
result = self.api.beep()
assert isinstance(result, bool)
def _test_show_notification(self):
"""Test show_notification method."""
result = self.api.show_notification("Test", "Test message", duration=100)
assert isinstance(result, bool)
def _test_copy_to_clipboard(self):
"""Test copy_to_clipboard method."""
result = self.api.copy_to_clipboard("test text")
assert isinstance(result, bool)
def _test_paste_from_clipboard(self):
"""Test paste_from_clipboard method."""
result = self.api.paste_from_clipboard()
assert isinstance(result, str)
def _test_subscribe(self):
"""Test subscribe method."""
def handler(data):
pass
sub_id = self.api.subscribe("test_event", handler)
assert isinstance(sub_id, str)
self._test_sub_id = sub_id
def _test_unsubscribe(self):
"""Test unsubscribe method."""
result = self.api.unsubscribe("invalid_id")
assert isinstance(result, bool)
def _test_publish(self):
"""Test publish method."""
result = self.api.publish("test_event", {"key": "value"})
assert isinstance(result, bool)
def _test_set_data(self):
"""Test set_data method."""
result = self.api.set_data("test_key", "test_value")
assert isinstance(result, bool)
def _test_get_data(self):
"""Test get_data method."""
result = self.api.get_data("test_key", default="default")
assert result is not None
def _test_delete_data(self):
"""Test delete_data method."""
result = self.api.delete_data("test_key")
assert isinstance(result, bool)
def _test_run_task(self):
"""Test run_task method."""
def task():
return "done"
def callback(result):
pass
task_id = self.api.run_task(task, callback=callback)
assert isinstance(task_id, str)
self._test_task_id = task_id
def _test_cancel_task(self):
"""Test cancel_task method."""
result = self.api.cancel_task("invalid_task_id")
assert isinstance(result, bool)
# =====================================================================
# WidgetAPI Tests
# =====================================================================
def _test_widget_api(self):
"""Test all WidgetAPI methods."""
self._run_test("create_widget", "WidgetAPI", self._test_create_widget)
self._run_test("get_widget", "WidgetAPI", self._test_get_widget)
self._run_test("widget_exists", "WidgetAPI", self._test_widget_exists)
self._run_test("get_all_widgets", "WidgetAPI", self._test_get_all_widgets)
self._run_test("get_visible_widgets", "WidgetAPI", self._test_get_visible_widgets)
self._run_test("show_widget", "WidgetAPI", self._test_show_widget)
self._run_test("hide_widget", "WidgetAPI", self._test_hide_widget)
self._run_test("close_widget", "WidgetAPI", self._test_close_widget)
self._run_test("show_all_widgets", "WidgetAPI", self._test_show_all_widgets)
self._run_test("hide_all_widgets", "WidgetAPI", self._test_hide_all_widgets)
self._run_test("set_all_opacity", "WidgetAPI", self._test_set_all_opacity)
self._run_test("lock_all", "WidgetAPI", self._test_lock_all)
self._run_test("unlock_all", "WidgetAPI", self._test_unlock_all)
self._run_test("arrange_widgets", "WidgetAPI", self._test_arrange_widgets)
self._run_test("snap_to_grid", "WidgetAPI", self._test_snap_to_grid)
self._run_test("register_preset", "WidgetAPI", self._test_register_preset)
self._run_test("create_from_preset", "WidgetAPI", self._test_create_from_preset)
self._run_test("save_all_states", "WidgetAPI", self._test_save_all_states)
self._run_test("load_all_states", "WidgetAPI", self._test_load_all_states)
# Widget instance methods
self._run_test("widget.show", "WidgetAPI", self._test_widget_show)
self._run_test("widget.hide", "WidgetAPI", self._test_widget_hide)
self._run_test("widget.move", "WidgetAPI", self._test_widget_move)
self._run_test("widget.resize", "WidgetAPI", self._test_widget_resize)
self._run_test("widget.set_opacity", "WidgetAPI", self._test_widget_set_opacity)
self._run_test("widget.set_title", "WidgetAPI", self._test_widget_set_title)
self._run_test("widget.set_locked", "WidgetAPI", self._test_widget_set_locked)
self._run_test("widget.minimize", "WidgetAPI", self._test_widget_minimize)
self._run_test("widget.restore", "WidgetAPI", self._test_widget_restore)
self._run_test("widget.raise_widget", "WidgetAPI", self._test_widget_raise)
self._run_test("widget.lower_widget", "WidgetAPI", self._test_widget_lower)
self._run_test("widget.save_state", "WidgetAPI", self._test_widget_save_state)
self._run_test("widget.load_state", "WidgetAPI", self._test_widget_load_state)
def _test_create_widget(self):
"""Test create_widget method."""
self.test_widget = self.widget_api.create_widget(
name="test_widget_123",
title="Test Widget",
size=(300, 200)
)
assert self.test_widget is not None
assert self.test_widget.name == "test_widget_123"
def _test_get_widget(self):
"""Test get_widget method."""
widget = self.widget_api.get_widget("test_widget_123")
assert widget is not None
def _test_widget_exists(self):
"""Test widget_exists method."""
exists = self.widget_api.widget_exists("test_widget_123")
assert exists is True
def _test_get_all_widgets(self):
"""Test get_all_widgets method."""
widgets = self.widget_api.get_all_widgets()
assert isinstance(widgets, list)
def _test_get_visible_widgets(self):
"""Test get_visible_widgets method."""
widgets = self.widget_api.get_visible_widgets()
assert isinstance(widgets, list)
def _test_show_widget(self):
"""Test show_widget method."""
result = self.widget_api.show_widget("test_widget_123")
assert isinstance(result, bool)
def _test_hide_widget(self):
"""Test hide_widget method."""
result = self.widget_api.hide_widget("test_widget_123")
assert isinstance(result, bool)
def _test_close_widget(self):
"""Test close_widget method."""
# Create a temp widget to close
temp = self.widget_api.create_widget(
name="temp_to_close",
title="Temp",
size=(100, 100)
)
result = self.widget_api.close_widget("temp_to_close")
assert isinstance(result, bool)
def _test_show_all_widgets(self):
"""Test show_all_widgets method."""
self.widget_api.show_all_widgets()
# No return value, just ensure no exception
def _test_hide_all_widgets(self):
"""Test hide_all_widgets method."""
self.widget_api.hide_all_widgets()
# No return value
self.widget_api.show_all_widgets() # Restore
def _test_set_all_opacity(self):
"""Test set_all_opacity method."""
self.widget_api.set_all_opacity(0.8)
# Verify
self.widget_api.set_all_opacity(0.95)
def _test_lock_all(self):
"""Test lock_all method."""
self.widget_api.lock_all()
def _test_unlock_all(self):
"""Test unlock_all method."""
self.widget_api.unlock_all()
def _test_arrange_widgets(self):
"""Test arrange_widgets method."""
self.widget_api.arrange_widgets(layout="grid", spacing=10)
self.widget_api.arrange_widgets(layout="horizontal")
self.widget_api.arrange_widgets(layout="vertical")
self.widget_api.arrange_widgets(layout="cascade")
def _test_snap_to_grid(self):
"""Test snap_to_grid method."""
self.widget_api.snap_to_grid(grid_size=10)
def _test_register_preset(self):
"""Test register_preset method."""
preset = WidgetConfig(
name="preset_test",
title="Preset Test",
widget_type=WidgetType.MINI,
size=(200, 150)
)
self.widget_api.register_preset("test_preset", preset)
def _test_create_from_preset(self):
"""Test create_from_preset method."""
widget = self.widget_api.create_from_preset("test_preset", name="from_preset")
assert widget is not None or widget is None # May fail if preset not registered properly
if widget:
self.widget_api.close_widget("from_preset")
def _test_save_all_states(self):
"""Test save_all_states method."""
states = self.widget_api.save_all_states()
assert isinstance(states, dict)
def _test_load_all_states(self):
"""Test load_all_states method."""
states = self.widget_api.save_all_states()
self.widget_api.load_all_states(states)
# Widget instance methods
def _test_widget_show(self):
"""Test widget.show() method."""
if self.test_widget:
self.test_widget.show()
def _test_widget_hide(self):
"""Test widget.hide() method."""
if self.test_widget:
self.test_widget.hide()
self.test_widget.show() # Restore
def _test_widget_move(self):
"""Test widget.move() method."""
if self.test_widget:
self.test_widget.move(200, 200)
x, y = self.test_widget.position
assert x == 200 and y == 200
def _test_widget_resize(self):
"""Test widget.resize() method."""
if self.test_widget:
self.test_widget.resize(400, 300)
w, h = self.test_widget.size
assert w == 400 and h == 300
def _test_widget_set_opacity(self):
"""Test widget.set_opacity() method."""
if self.test_widget:
self.test_widget.set_opacity(0.5)
assert self.test_widget.config.opacity == 0.5
def _test_widget_set_title(self):
"""Test widget.set_title() method."""
if self.test_widget:
self.test_widget.set_title("New Title")
assert self.test_widget.config.title == "New Title"
def _test_widget_set_locked(self):
"""Test widget.set_locked() method."""
if self.test_widget:
self.test_widget.set_locked(True)
assert self.test_widget.config.locked == True
self.test_widget.set_locked(False)
def _test_widget_minimize(self):
"""Test widget.minimize() method."""
if self.test_widget:
self.test_widget.minimize()
def _test_widget_restore(self):
"""Test widget.restore() method."""
if self.test_widget:
self.test_widget.restore()
def _test_widget_raise(self):
"""Test widget.raise_widget() method."""
if self.test_widget:
self.test_widget.raise_widget()
def _test_widget_lower(self):
"""Test widget.lower_widget() method."""
if self.test_widget:
self.test_widget.lower_widget()
def _test_widget_save_state(self):
"""Test widget.save_state() method."""
if self.test_widget:
state = self.test_widget.save_state()
assert isinstance(state, dict)
assert 'config' in state
def _test_widget_load_state(self):
"""Test widget.load_state() method."""
if self.test_widget:
state = self.test_widget.save_state()
self.test_widget.load_state(state)
# =====================================================================
# ExternalAPI Tests
# =====================================================================
def _test_external_api(self):
"""Test all ExternalAPI methods."""
self._run_test("start_server", "ExternalAPI", self._test_start_server)
self._run_test("get_status", "ExternalAPI", self._test_get_status)
self._run_test("get_url", "ExternalAPI", self._test_get_url)
self._run_test("register_endpoint", "ExternalAPI", self._test_register_endpoint)
self._run_test("unregister_endpoint", "ExternalAPI", self._test_unregister_endpoint)
self._run_test("get_endpoints", "ExternalAPI", self._test_get_endpoints)
self._run_test("register_webhook", "ExternalAPI", self._test_register_webhook)
self._run_test("unregister_webhook", "ExternalAPI", self._test_unregister_webhook)
self._run_test("get_webhooks", "ExternalAPI", self._test_get_webhooks)
self._run_test("get_webhook_history", "ExternalAPI", self._test_get_webhook_history)
self._run_test("post_webhook", "ExternalAPI", self._test_post_webhook)
self._run_test("create_api_key", "ExternalAPI", self._test_create_api_key)
self._run_test("revoke_api_key", "ExternalAPI", self._test_revoke_api_key)
self._run_test("register_ipc_handler", "ExternalAPI", self._test_register_ipc_handler)
self._run_test("send_ipc", "ExternalAPI", self._test_send_ipc)
self._run_test("stop_server", "ExternalAPI", self._test_stop_server)
def _test_start_server(self):
"""Test start_server method."""
result = self.external_api.start_server(port=8765)
assert isinstance(result, bool)
def _test_get_status(self):
"""Test get_status method."""
status = self.external_api.get_status()
assert isinstance(status, dict)
assert 'server_running' in status
def _test_get_url(self):
"""Test get_url method."""
url = self.external_api.get_url("api/test")
assert isinstance(url, str)
def _test_register_endpoint(self):
"""Test register_endpoint method."""
def handler(params):
return {"test": "data"}
self.external_api.register_endpoint("test_endpoint", handler, methods=["GET"])
def _test_unregister_endpoint(self):
"""Test unregister_endpoint method."""
result = self.external_api.unregister_endpoint("test_endpoint")
assert isinstance(result, bool)
def _test_get_endpoints(self):
"""Test get_endpoints method."""
endpoints = self.external_api.get_endpoints()
assert isinstance(endpoints, list)
def _test_register_webhook(self):
"""Test register_webhook method."""
def handler(payload):
return {"received": True}
self.external_api.register_webhook("test_webhook", handler)
def _test_unregister_webhook(self):
"""Test unregister_webhook method."""
result = self.external_api.unregister_webhook("test_webhook")
assert isinstance(result, bool)
def _test_get_webhooks(self):
"""Test get_webhooks method."""
webhooks = self.external_api.get_webhooks()
assert isinstance(webhooks, list)
def _test_get_webhook_history(self):
"""Test get_webhook_history method."""
history = self.external_api.get_webhook_history(limit=10)
assert isinstance(history, list)
def _test_post_webhook(self):
"""Test post_webhook method."""
result = self.external_api.post_webhook(
"https://httpbin.org/post",
{"test": "data"},
timeout=5
)
assert isinstance(result, dict)
assert 'success' in result
def _test_create_api_key(self):
"""Test create_api_key method."""
key = self.external_api.create_api_key("test_key", permissions=["read"])
assert isinstance(key, str)
assert len(key) > 0
self._test_api_key = key
def _test_revoke_api_key(self):
"""Test revoke_api_key method."""
# Create then revoke
key = self.external_api.create_api_key("temp_key")
result = self.external_api.revoke_api_key(key)
assert isinstance(result, bool)
def _test_register_ipc_handler(self):
"""Test register_ipc_handler method."""
def handler(data):
pass
self.external_api.register_ipc_handler("test_channel", handler)
def _test_send_ipc(self):
"""Test send_ipc method."""
result = self.external_api.send_ipc("test_channel", {"message": "test"})
assert isinstance(result, bool)
def _test_stop_server(self):
"""Test stop_server method."""
result = self.external_api.stop_server()
assert isinstance(result, bool)
def shutdown(self):
"""Clean up test resources."""
# Close test widget
if self.test_widget:
self.test_widget.close()
# Save test results
results_data = {
"timestamp": datetime.now().isoformat(),
"results": [asdict(r) for r in self.results],
"summary": {
"total": len(self.results),
"passed": sum(1 for r in self.results if r.passed),
"failed": sum(1 for r in self.results if not r.passed)
}
}
try:
import json
with open("api_comprehensive_test_results.json", "w") as f:
json.dump(results_data, f, indent=2)
except:
pass
# Plugin entry point
plugin_class = APIComprehensiveTestPlugin