テスト時に指定された複数のComfyUIバージョンを自動ダウンロードし、最適な仮想環境を構築した上でテストを実行する仕組みを導入。また、Playwright同期APIに起因するデッドロックやキャッシュ汚染によるテストのハングアップ問題を解消。 - 設定ファイルで複数バージョンの定義をサポート - 該当するComfyUIおよびEmbeddable Pythonを自動取得するdownloaderモジュールを追加 - pytest_generate_testsによりバージョン別のテストを動的にパラメータ化 - min_comfy_versionマーカーによるバージョン制限テストの条件付きスキップをサポート - Windows環境でのゾンビプロセス防止のためtaskkillによる強制終了処理を追加 - バージョン切り替え時のブラウザキャッシュ汚染を防ぐためキャッシュを無効化 - Playwright同期APIのダイアログ処理をJavaScript側でのモック化へ移行しデッドロックを回避 - 設定画面でのCSVトグル描画有無によるテストアプローチの動的切り替えを実装 - リサイズ操作のsteps指定など各種タイミング競合とタイムアウト処理を強化
153 lines
6.6 KiB
Python
153 lines
6.6 KiB
Python
import pytest
|
|
import time
|
|
import os
|
|
from pathlib import Path
|
|
from playwright.sync_api import Page, expect
|
|
|
|
def test_settings_sync_between_editors(page: Page, comfyui_server, wait_for_comfyui, wmp_helpers):
|
|
page.on("console", lambda msg: print(f"BROWSER CONSOLE: {msg.type}: {msg.text}"))
|
|
page.set_viewport_size({"width": 1920, "height": 1080})
|
|
wmp_helpers.load_comfyui(page, comfyui_server, wait_for_comfyui)
|
|
|
|
wmp_helpers.wait_for_graph_clear(page)
|
|
|
|
page.evaluate(f"""() => {{
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const types = Object.keys(window.LiteGraph.registered_node_types);
|
|
const nodeType = types.find(t => t.includes('WebuiMonacoPromptMultiText') || t.includes('MultiText'));
|
|
|
|
const node1 = window.LiteGraph.createNode(nodeType);
|
|
node1.pos = [100, 300];
|
|
app.graph.add(node1);
|
|
|
|
const node2 = window.LiteGraph.createNode(nodeType);
|
|
node2.pos = [700, 300];
|
|
app.graph.add(node2);
|
|
|
|
app.canvas.centerOnNode(node1);
|
|
}}""")
|
|
|
|
page.wait_for_function("() => app.graph && app.graph._nodes.length >= 2")
|
|
wmp_helpers.wait_for_editor(page)
|
|
|
|
font_sizes = page.evaluate("""() => {
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const nodes = app.graph._nodes.filter(n => n.type && n.type.includes('MultiText'));
|
|
return nodes.map((n, i) => {
|
|
if (n.multitext_widget && n.multitext_widget.editorInstance) {
|
|
return n.multitext_widget.editorInstance.getSettings().fontSize;
|
|
}
|
|
return null;
|
|
});
|
|
}""")
|
|
|
|
assert font_sizes[0] == font_sizes[1], "Both editors should start with the same font size."
|
|
|
|
wmp_helpers.open_settings(page)
|
|
wmp_helpers.switch_settings_category(page, "WebuiMonacoPrompt")
|
|
|
|
wmp_helpers.set_comfy_setting(page, 'WebuiMonacoPrompt.FontSize', 18)
|
|
|
|
page.wait_for_function("""() => {
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const nodes = app.graph._nodes.filter(n => n.type && n.type.includes('MultiText'));
|
|
return nodes.every(n => n.multitext_widget && n.multitext_widget.editorInstance && n.multitext_widget.editorInstance.getSettings().fontSize === 18);
|
|
}""")
|
|
|
|
new_font_sizes = page.evaluate("""() => {
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const nodes = app.graph._nodes.filter(n => n.type && n.type.includes('MultiText'));
|
|
return nodes.map(n => n.multitext_widget.editorInstance.getSettings().fontSize);
|
|
}""")
|
|
assert new_font_sizes[0] == 18 and new_font_sizes[1] == 18, "Both editors should reflect the new font size."
|
|
|
|
def test_dynamic_csv_toggle_sync(page: Page, comfyui_server, wait_for_comfyui, wmp_helpers):
|
|
page.set_viewport_size({"width": 1920, "height": 1080})
|
|
wmp_helpers.load_comfyui(page, comfyui_server, wait_for_comfyui)
|
|
|
|
wmp_helpers.wait_for_graph_clear(page)
|
|
|
|
page.evaluate(f"""() => {{
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const types = Object.keys(window.LiteGraph.registered_node_types);
|
|
const nodeType = types.find(t => t.includes('WebuiMonacoPromptMultiText') || t.includes('MultiText'));
|
|
const node1 = window.LiteGraph.createNode(nodeType);
|
|
node1.pos = [100, 300];
|
|
app.graph.add(node1);
|
|
app.canvas.centerOnNode(node1);
|
|
}}""")
|
|
|
|
wmp_helpers.wait_for_editor(page)
|
|
|
|
extension_path = os.environ.get("COMFYUI_EXTENSION_PATH", os.getcwd())
|
|
csv_dir = Path(extension_path) / "csv"
|
|
csv_dir.mkdir(exist_ok=True)
|
|
test_csv_path = csv_dir / "test_dynamic.csv"
|
|
|
|
try:
|
|
if test_csv_path.exists():
|
|
test_csv_path.unlink()
|
|
|
|
wmp_helpers.load_comfyui(page, comfyui_server, wait_for_comfyui)
|
|
|
|
wmp_helpers.wait_for_graph_clear(page)
|
|
|
|
page.evaluate(f"""() => {{
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const types = Object.keys(window.LiteGraph.registered_node_types);
|
|
const nodeType = types.find(t => t.includes('WebuiMonacoPromptMultiText') || t.includes('MultiText'));
|
|
const node1 = window.LiteGraph.createNode(nodeType);
|
|
node1.pos = [100, 300];
|
|
app.graph.add(node1);
|
|
app.canvas.centerOnNode(node1);
|
|
}}""")
|
|
|
|
wmp_helpers.wait_for_editor(page)
|
|
|
|
content = "test_tag_1,100\\ntest_tag_2,50\\n"
|
|
with open(test_csv_path, "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
|
|
refresh_btn = page.locator("button:has-text('Refresh')")
|
|
if refresh_btn.is_visible():
|
|
refresh_btn.click()
|
|
else:
|
|
page.evaluate("""() => {
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
if (app.refreshComboInNodes) {
|
|
app.refreshComboInNodes();
|
|
} else if (app.extensionManager && app.extensionManager.refreshComboInNodes) {
|
|
app.extensionManager.refreshComboInNodes();
|
|
}
|
|
}""")
|
|
|
|
# Wait dynamically instead of fixed timeout to avoid flakiness
|
|
try:
|
|
page.wait_for_function("""() => {
|
|
const findApp = () => window.app || (window.comfyAPI && window.comfyAPI.app) || window.ComfyApp;
|
|
const app = findApp();
|
|
const nodes = app.graph._nodes.filter(n => n.type && n.type.includes('MultiText'));
|
|
if (nodes.length === 0) return false;
|
|
const editor = nodes[0].multitext_widget.editorInstance;
|
|
if (!editor) return false;
|
|
|
|
const val = editor.getContext(editor.createContextKey("csv.test_dynamic"));
|
|
return val !== undefined && val !== null;
|
|
}""")
|
|
except Exception:
|
|
pytest.fail("Dynamic CSV was not detected or added to the local context by refresh within timeout")
|
|
|
|
finally:
|
|
if test_csv_path.exists():
|
|
try:
|
|
test_csv_path.unlink()
|
|
except Exception as e:
|
|
print(f"Failed to cleanup {test_csv_path}: {e}")
|