Refresh label-filter hook catalog after removing SEGS input

Recreate the hook through Chrome node search and native Export, preserving every expected widget name, order and value. Cover fresh and legacy hook execution with both native restoration modes.

Validation: all 16 catalog E2E tests passed on the identical source tree; native Export also normalizes MaskRectArea height from 356 to 358.
This commit is contained in:
Dr.Lt.Data
2026-10-31 23:15:51 +09:00
parent 4f339c0759
commit cf6eee3027
5 changed files with 356 additions and 197 deletions
+10
View File
@@ -183,6 +183,16 @@ Two direct-creation cases also check that label-filter presets start at `all`,
append a selected label to the text field, and retain both values after export
and reload.
The label-filter hook execution cases connect the hook to Preview as Text and
click Run before and after native export/reload, in both widget restoration
modes. They cover freshly created nodes without a `segs` input and the native
`label-filter-hook-legacy.json` fixture exported before PR #1218, which retains
the obsolete unconnected input. The selected preset, label text, widget order,
and positional saved values must survive loading while hook creation succeeds.
The all-node catalog replaces that legacy node through Chrome deletion, node
search, and native Export; its widget snapshot changes only the replacement
node's ID and record position, preserving every expected widget name and value.
Branching tests connect Inversed Switch through three distinct image operations
back into Switch, including both legacy names. Selection changes through the UI
must produce the expected pixels and final output, including after reimport.
+48
View File
@@ -207,6 +207,8 @@ def test_catalog_contains_every_registered_node():
for widget in node["widgets"]:
assert set(widget) == {"name", "value"}
assert isinstance(widget["name"], str)
label_hook = next(node for node in workflow["nodes"] if node["type"] == "SEGSLabelFilterDetailerHookProvider")
assert label_hook["inputs"] == [], "Recreate the label-filter hook to remove its obsolete SEGS input"
@pytest.fixture
@@ -253,6 +255,52 @@ def test_label_preset_initial_value_and_selection(ui, node_type):
assert_catalog(browser, [before])
@pytest.mark.parametrize("restore_by_name", [False, True], ids=["positional", "named"])
@pytest.mark.parametrize("legacy", [False, True], ids=["fresh", "legacy-segs-input"])
def test_label_filter_hook_executes_after_native_load(ui, restore_by_name, legacy):
browser, args = ui
node_type = "SEGSLabelFilterDetailerHookProvider"
expected_widgets = [{"name": "preset", "value": "person"},
{"name": "labels", "value": "person, dog"}]
setting(browser, "Restore widget values", "Comfy.Workflow.NamedValuesRestore", restore_by_name)
browser.new_workflow()
if legacy:
browser.load_workflow(ROOT / "tests/workflows/label-filter-hook-legacy.json", 2)
node_id = browser.app.evaluate("""(app, type) =>
String(app.graph._nodes.find(node => node.type === type).id)
""", node_type)
else:
full_zoom(browser)
definitions = node_definitions(browser)
node_id = browser.add_node(definitions[node_type]["display_name"], node_type, 250, 180)
browser.choose(node_type, "preset", "person")
browser.page.get_by_placeholder(
"List the types of segments to be allowed, separated by commas", exact=True
).fill("person, dog")
assert "segs" not in browser.app.evaluate("""(app, id) =>
app.graph.getNodeById(id).inputs.map(input => input.name)
""", node_id)
browser.add_node("Preview as Text", "PreviewAny", 850, 180)
browser.connect(node_type, "PreviewAny")
path = args.artifacts / "label-filter-hook.json"
for reloaded in (False, True):
if reloaded:
browser.new_workflow()
browser.load_workflow(path, 2)
full_zoom(browser)
show_node(browser, node_id)
assert widget_state(browser, node_id)["widgets"] == expected_widgets
entry = browser.run()
text = next(output["text"] for output in entry["outputs"].values() if "text" in output)
assert len(text) == 1 and "SEGSLabelFilterDetailerHook object" in text[0]
if not reloaded:
export_workflow(browser, path)
saved = next(node for node in json.loads(path.read_text())["nodes"] if node["type"] == node_type)
assert saved["widgets_values"] == ["person", "person, dog"]
assert saved["widgets_values_named"] == {"preset": "person", "labels": "person, dog"}
@pytest.mark.parametrize("mutation", [
"this.widgets[0].name = 'guide_size_broken';",
"[this.widgets[0], this.widgets[2]] = [this.widgets[2], this.widgets[0]];",
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -1710,20 +1710,6 @@
}
]
},
{
"id": "58",
"type": "SEGSLabelFilterDetailerHookProvider",
"widgets": [
{
"name": "preset",
"value": "all"
},
{
"name": "labels",
"value": ""
}
]
},
{
"id": "59",
"type": "VariationNoiseDetailerHookProvider",
@@ -3969,6 +3955,20 @@
"value": 1
}
]
},
{
"id": "198",
"type": "SEGSLabelFilterDetailerHookProvider",
"widgets": [
{
"name": "preset",
"value": "all"
},
{
"name": "labels",
"value": ""
}
]
}
]
}
@@ -0,0 +1,107 @@
{
"id": "16e4d8a1-d7cc-4dfa-a95e-bb8f5f5b21c9",
"revision": 0,
"last_node_id": 2,
"last_link_id": 1,
"nodes": [
{
"id": 1,
"type": "SEGSLabelFilterDetailerHookProvider",
"pos": [
-277.1111111111111,
135.55555555555554
],
"size": [
400,
200
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"name": "segs",
"type": "SEGS",
"link": null
}
],
"outputs": [
{
"name": "DETAILER_HOOK",
"type": "DETAILER_HOOK",
"links": [
1
]
}
],
"properties": {
"Node name for S&R": "SEGSLabelFilterDetailerHookProvider"
},
"widgets_values": [
"person",
"person, dog"
],
"widgets_values_named": {
"preset": "person",
"labels": "person, dog"
}
},
{
"id": 2,
"type": "PreviewAny",
"pos": [
417.8888888888889,
135.55555555555554
],
"size": [
210,
122
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 1
}
],
"outputs": [
{
"name": "STRING",
"type": "STRING",
"links": null
}
],
"properties": {
"Node name for S&R": "PreviewAny"
},
"widgets_values": [],
"widgets_values_named": {}
}
],
"links": [
[
1,
1,
0,
2,
0,
"DETAILER_HOOK"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1,
"offset": [
327.1111111111111,
54.44444444444446
]
},
"frontendVersion": "1.57.6"
},
"version": 0.4
}