Merge main (Custom Colors Nodes 2.0 fix) into chore/release-1.3.1
This commit is contained in:
@@ -7,6 +7,13 @@
|
||||
- The console banner is one line, version plus tool count, instead of one
|
||||
`Loaded:` line per node.
|
||||
|
||||
### Custom Colors
|
||||
|
||||
- The `🫶 Custom Colors` entry opens its Full / Title / BG submenu again in
|
||||
Nodes 2.0. The Nodes 2.0 context menu converts litegraph items itself and
|
||||
only renders a submenu for entries flagged `has_submenu`, so the entry was an
|
||||
inert label there; the classic menu was unaffected.
|
||||
|
||||
### Model Resolution Picker
|
||||
|
||||
- New `Krea 2` family (Krea 2 Turbo, Raw and finetunes): 8x VAE, step 16,
|
||||
|
||||
@@ -1731,8 +1731,11 @@ test('custom colors handle absent settings, empty canvas menus, legacy groups an
|
||||
expect(await page.evaluate(() => {
|
||||
const extension = kikoHost.extensions.find(item => item.name === 'kikotools.customColors');
|
||||
kikoHost.settings.delete('kikotools.custom_colors.enabled');
|
||||
return [extension.getCanvasMenuItems({}), extension.getCanvasMenuItems({ graph_mouse: [0, 0], graph: { getGroupOnPos: () => null } }), extension.getNodeMenuItems(kikoHost.app.graph._nodes[0])[1].submenu.options.length];
|
||||
})).toEqual([[], [], 3]);
|
||||
const nodeMenu = extension.getNodeMenuItems(kikoHost.app.graph._nodes[0])[1];
|
||||
const groupMenu = extension.getCanvasMenuItems({ graph_mouse: [0, 0], graph: { getGroupOnPos: () => ({ color: '#000000' }) } })[1];
|
||||
// The Nodes 2.0 menu converter only renders submenu.options when has_submenu is set.
|
||||
return [extension.getCanvasMenuItems({}), extension.getCanvasMenuItems({ graph_mouse: [0, 0], graph: { getGroupOnPos: () => null } }), nodeMenu.submenu.options.length, nodeMenu.has_submenu, groupMenu.has_submenu];
|
||||
})).toEqual([[], [], 3, true, true]);
|
||||
await page.evaluate(() => {
|
||||
const extension = kikoHost.extensions.find(item => item.name === 'kikotools.customColors');
|
||||
window.testGroup = { color: '#000000' };
|
||||
|
||||
@@ -733,6 +733,45 @@ test('Custom Colors preserves node colors across renderers and workflow reload',
|
||||
await expect(page.locator('dialog.ca-color-dialog')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('Custom Colors opens from the node context menu in both renderers', async ({ page }) => {
|
||||
const errors = [];
|
||||
page.on('pageerror', error => errors.push(error.message));
|
||||
for (const renderer of [false, true]) {
|
||||
await page.evaluate(async renderer => {
|
||||
const { app } = await import('/scripts/app.js');
|
||||
await app.ui.settings.setSettingValue('Comfy.VueNodes.Enabled', renderer);
|
||||
}, renderer);
|
||||
await expect.poll(() => page.evaluate(() => LiteGraph.vueNodesMode)).toBe(renderer);
|
||||
const title = await page.evaluate(async () => {
|
||||
const { app } = await import('/scripts/app.js');
|
||||
app.graph.clear();
|
||||
const node = LiteGraph.createNode('EmptyLatentImage');
|
||||
app.graph.add(node);
|
||||
app.canvas.centerOnNode(node);
|
||||
app.canvas.setDirty(true, true);
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
const rect = app.canvas.canvas.getBoundingClientRect();
|
||||
const [x, y] = app.canvas.ds.convertOffsetToCanvas([node.pos[0] + node.size[0] / 2, node.pos[1] - 10]);
|
||||
return { x: rect.left + x, y: rect.top + y };
|
||||
});
|
||||
await page.mouse.click(title.x, title.y, { button: 'right' });
|
||||
// The Nodes 2.0 menu converts litegraph items itself and only renders a
|
||||
// submenu for entries flagged has_submenu; the classic menu opens
|
||||
// submenu.options either way. Both must reach the picker.
|
||||
const entry = page.getByText('🫶 Custom Colors', { exact: true }).first();
|
||||
const full = page.getByText('🫶 Custom Full', { exact: true }).first();
|
||||
await entry.hover();
|
||||
try { await full.waitFor({ state: 'visible', timeout: 2000 }); } // Nodes 2.0 opens on hover
|
||||
catch { await entry.click(); } // the classic litegraph menu opens on click
|
||||
await full.click();
|
||||
await expect(page.getByRole('dialog', { name: 'Custom full color', exact: true })).toBeVisible();
|
||||
await page.keyboard.press('Escape');
|
||||
await expect(page.locator('ca-color-picker')).toHaveCount(0);
|
||||
await page.keyboard.press('Escape');
|
||||
}
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
|
||||
test('Follow Execution honors live settings and host menus in both renderers', async ({ page }, testInfo) => {
|
||||
const errors = [];
|
||||
page.on('pageerror', error => errors.push(error.message));
|
||||
|
||||
@@ -86,10 +86,13 @@ const openPicker = (initialColor, apply, node, label) => {
|
||||
picker.dialog.showModal();
|
||||
};
|
||||
|
||||
// Wrap menu options in the "Custom Colors" submenu (or nothing if empty)
|
||||
// Wrap menu options in the "Custom Colors" submenu (or nothing if empty).
|
||||
// has_submenu is required as well as submenu: the Nodes 2.0 context menu
|
||||
// converts litegraph items itself and only renders submenu.options for
|
||||
// entries flagged has_submenu; without it the entry is an inert label.
|
||||
const customColorsMenu = (options) => options.length === 0 ? [] : [
|
||||
null, // separator
|
||||
{ content: "🫶 Custom Colors", submenu: { options } },
|
||||
{ content: "🫶 Custom Colors", has_submenu: true, submenu: { options } },
|
||||
];
|
||||
|
||||
app.registerExtension({
|
||||
|
||||
Reference in New Issue
Block a user