Files
ltdrdata-ComfyUI-Impact-Pack/tests/test_e2e_wildcard_tutorials.py
T

82 lines
4.2 KiB
Python

"""Import original tutorial PNGs, then use native Export and reload in Chrome.
Requires IMPACT_TUTORIALS_DIR. This checks the affected registered node even
when unrelated tutorial plugins are unavailable; it does not execute those
incomplete graphs. The full LBW inference check additionally needs a trusted
Main output in IMPACT_E2E_REFERENCE_IMAGE and the original models/Inspire Pack.
"""
import json
import os
from pathlib import Path
from PIL import Image
import pytest
from test_e2e_wildcard_cache import ui as ui # shared browser fixture
from test_e2e_widget_catalog import ROOT, export_workflow, setting, show_node, widget_state
from wildcard_tutorial_cases import CASES, tutorial
@pytest.mark.parametrize("restore_by_name", [False, True], ids=["positional", "named"])
@pytest.mark.parametrize("case", CASES)
def test_native_tutorial_widgets(ui, case, restore_by_name):
path, original, target = tutorial(os.environ["IMPACT_TUTORIALS_DIR"], case)
node_id = str(target["id"])
setting(ui, "Restore widget values", "Comfy.Workflow.NamedValuesRestore", restore_by_name)
ui.load_workflow(path, len(original["nodes"]), check_node_errors=False)
show_node(ui, node_id)
before = widget_state(ui, node_id)
catalog = json.loads((ROOT / "tests/workflows/all-impact-nodes.widgets.json").read_text())
reference = next(node for node in catalog["nodes"] if node["type"] == target["type"])
assert [w["name"] for w in before["widgets"]] == [w["name"] for w in reference["widgets"]]
saved = target["widgets_values"]
# Explicit legacy behavior, checked against Main. "Fixed" remains invalid
# for execution in the oldest tutorial; do not silently bless a migration.
mode = ("populate" if saved[2] else "fixed") if isinstance(saved[2], bool) else saved[2]
expected = [widget["value"] for widget in reference["widgets"]]
expected[:3] = [*saved[:2], mode]
if target["type"] == "ImpactWildcardEncode":
expected[5:] = saved[5:]
# JSON equality distinguishes false from zero, unlike Python list equality.
expected_values = json.dumps(expected)
assert json.dumps([w["value"] for w in before["widgets"]]) == expected_values
first = ui.artifacts / "export.json"
export_workflow(ui, first)
exported = json.loads(first.read_text())
exported_target = next(n for n in exported["nodes"] if str(n["id"]) == node_id)
assert json.dumps(exported_target["widgets_values"]) == expected_values
ui.new_workflow()
ui.load_workflow(first, len(original["nodes"]), check_node_errors=False)
show_node(ui, node_id)
assert json.dumps(widget_state(ui, node_id), sort_keys=True) == json.dumps(before, sort_keys=True)
second = ui.artifacts / "roundtrip.json"
export_workflow(ui, second)
restored = json.loads(second.read_text())
restored_target = next(n for n in restored["nodes"] if str(n["id"]) == node_id)
assert json.dumps(restored_target["widgets_values"]) == expected_values
assert sorted(restored["links"]) == sorted(exported["links"])
original_links = sorted(link for link in original["links"] if node_id in (str(link[1]), str(link[3])))
for graph in (exported, restored):
assert sorted(link for link in graph["links"] if node_id in (str(link[1]), str(link[3]))) == original_links
(ui.artifacts / "widget-state.json").write_text(json.dumps(before, indent=2) + "\n")
def test_lbw_tutorial_inference(ui):
reference = Path(os.environ["IMPACT_E2E_REFERENCE_IMAGE"])
assert reference.is_file(), "Capture the original PNG's output with trusted Main first"
path, workflow, target = tutorial(os.environ["IMPACT_TUTORIALS_DIR"], "lbw")
ui.load_workflow(path, len(workflow["nodes"]))
ui.timeout = 900
entry = ui.run()
(ui.artifacts / "history.json").write_text(json.dumps(entry, indent=2) + "\n")
actual = ui.images(entry)["9"][0]
actual.save(ui.artifacts / "output.png")
with Image.open(reference) as image:
assert actual.size == image.size
assert actual.tobytes() == image.convert("RGB").tobytes()
saved = next(n for n in entry["prompt"][3]["extra_pnginfo"]["workflow"]["nodes"]
if str(n["id"]) == str(target["id"]))
assert saved["widgets_values"][5] == target["widgets_values"][5]