fix(nodes): pin the Classic wildcard behaviour and match queued ids by type (#343)
- Classic PromptManager/PromptManagerText expose _pmTextSerializerReady, settled once their own text serializer is installed; the real-host specs wait on it and assert the Classic text is queued as written, as on main. - The Primitive fill only touches an output entry whose class_type matches the graph node at that id. - TESTING.md notes the host's harmless "Invalid widget" warning per Run.
This commit is contained in:
@@ -68,6 +68,8 @@ function build(page, { kind, positive, negative, prefix }) {
|
||||
const save = add('SaveImage', 2100, 0);
|
||||
save.widgets.find(widget => widget.name === 'filename_prefix').value = prefix;
|
||||
connect(images, 0, save, 'images');
|
||||
// The Classic nodes install their own text serializer shortly after creation; queue after it, as a user does.
|
||||
await prompt._pmTextSerializerReady;
|
||||
const { output, workflow } = await app.graphToPrompt();
|
||||
return { output, workflow, promptNode: String(prompt.id) };
|
||||
}, { kind, positive, negative, prefix });
|
||||
@@ -150,17 +152,17 @@ for (const kind of ['PromptManager', 'PromptManagerText', 'PromptManagerFocused'
|
||||
}
|
||||
}
|
||||
|
||||
// A legacy Primitive's wildcard is drawn once when the workflow is queued: the run saves and counts that one choice.
|
||||
// A legacy Primitive's wildcard is drawn once when the workflow is queued: the run saves and counts what was queued.
|
||||
for (const kind of ['PromptManager', 'PromptManagerFocused']) {
|
||||
test(`${kind} saves and counts the one choice a wildcard legacy Primitive queued (#343 re-review R1)`, async ({ execution, page }) => {
|
||||
test(`${kind} saves and counts the text a wildcard legacy Primitive queued (#343 re-review R1)`, async ({ execution, page }) => {
|
||||
test.setTimeout(90000);
|
||||
const stem = unique(`Wildcard ${kind}`);
|
||||
const evidence = await run(execution, page, { kind, positive: { typed: 'Typed under the link', text: `${stem} {alpha|beta}`, via: 'legacy' } });
|
||||
const queuedText = evidence.output[evidence.promptNode].inputs.text;
|
||||
// The Classic node keeps its widget binding: the host applies the Primitive, and its text widget queues the text
|
||||
// as written once its own serializer is installed (50 ms after creation), as on main.
|
||||
const choices = [`${stem} alpha`, `${stem} beta`, ...(kind === 'PromptManager' ? [`${stem} {alpha|beta}`] : [])];
|
||||
expect(choices).toContain(queuedText);
|
||||
// The Classic node keeps its widget binding: the host applies the Primitive, and its own text serializer
|
||||
// queues the text as written, as on main. The Focused editor queues one choice.
|
||||
if (kind === 'PromptManager') expect(queuedText).toBe(`${stem} {alpha|beta}`);
|
||||
else expect([`${stem} alpha`, `${stem} beta`]).toContain(queuedText);
|
||||
expect(evidence.context.positive.raw).toBe(queuedText);
|
||||
expect(evidence.usage).toEqual([{ role: 'positive', run_count: 1 }]);
|
||||
const saved = await (await execution.request.get(`/prompt_manager/library/${evidence.context.positive_prompt_id}`)).json();
|
||||
|
||||
@@ -223,6 +223,8 @@ test('a wildcard legacy Primitive queues one resolved choice, drawn once per run
|
||||
primitive.properties['Run widget replace on values'] = replace;
|
||||
ids[type] = [String(node.id), name];
|
||||
});
|
||||
// The Classic nodes install their own text serializer shortly after creation; run after it, as a user does.
|
||||
await Promise.all(app.graph.nodes.map(node => node._pmTextSerializerReady));
|
||||
// What another extension's graphToPrompt wrapper sees must be what the server gets.
|
||||
const inner = app.graphToPrompt;
|
||||
const seen = window.__pmSeen = [];
|
||||
@@ -240,12 +242,12 @@ test('a wildcard legacy Primitive queues one resolved choice, drawn once per run
|
||||
const year = String(new Date().getFullYear());
|
||||
const stems = { PromptManagerFocused: 'Focused', PromptManagerSplit: `Split ${year}`, PromptManagerPair: 'Pair', PromptManager: 'Classic', PromptManagerText: 'Text' };
|
||||
// The Classic nodes keep their widget binding, so the host applies the Primitive and #343 leaves the value alone.
|
||||
// As on main, their text widget's own serializer (installed 50 ms after creation) queues the text as written.
|
||||
// As on main, their text widget's own serializer queues the text as written, wildcard included.
|
||||
const classic = new Set(['PromptManager', 'PromptManagerText']);
|
||||
for (const [type, [id, name]] of Object.entries(ids)) {
|
||||
const value = prompt[id].inputs[name];
|
||||
const expected = classic.has(type) ? `(?:c\\d|${choices.replace(/[{}|]/g, '\\$&')})` : 'c\\d';
|
||||
expect(value, type).toMatch(new RegExp(`^${stems[type]} ${expected}$`));
|
||||
if (classic.has(type)) expect(value, type).toBe(`${stems[type]} ${choices}`);
|
||||
else expect(value, type).toMatch(new RegExp(`^${stems[type]} c\\d$`));
|
||||
expect(value, `${type}: one draw per run`).toBe(seen[0][id].inputs[name]);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user