Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
9058d3e
feat: implement NodeLibrarySidebarTabV2 with Reka UI components
Yourz Feb 2, 2026
f5b0b70
feat: add main_category field and group nodes by category
Yourz Feb 3, 2026
2ed895c
feat: previewCard and BadgPill and api node logo
Yourz Feb 5, 2026
3f07dd2
fix: preview card, icon
Yourz Feb 6, 2026
37477b2
fix: ci
Yourz Feb 7, 2026
bde6678
fix: reviews
Yourz Feb 7, 2026
f80b87b
fix: reviews for coderabbit
Yourz Feb 7, 2026
70b514a
feat: drop nodes when click the canvas
Yourz Feb 7, 2026
98532a8
feat: api nodes icon
Yourz Feb 8, 2026
e637471
fix: ci and badge
Yourz Feb 8, 2026
91ad183
feat: new drag preview
Yourz Feb 8, 2026
1aa10e7
fix: coderabbit reviews
Yourz Feb 8, 2026
1a94e34
fix: coderabbit reviews
Yourz Feb 8, 2026
594c249
fix: coderabbit reviews
Yourz Feb 8, 2026
193d482
fix: coderabbit reviews
Yourz Feb 9, 2026
99d31a7
fix: update for reviews
Yourz Feb 9, 2026
41d4ada
fix: update icons
Yourz Feb 10, 2026
d78e4b9
feat: support drag and drop creation
Yourz Feb 10, 2026
34dd961
feat: essentials tab
Yourz Feb 12, 2026
9a4aff5
fix: ci
Yourz Feb 13, 2026
a4975a0
[automated] Update test expectations
invalid-email-address Feb 13, 2026
824f8bb
fix: improve NodePreviewCard styling and drag-drop reliability
Yourz Feb 13, 2026
7a4f7dc
fix: update for design reviews
Yourz Feb 13, 2026
726ae23
fix: add missing DEFAULT_SORTING_ID to test mock
Yourz Feb 13, 2026
fedce61
fix: update for design reviews, and add setting toggle to switch node…
Yourz Feb 15, 2026
1b16b0f
fix: unit tests
Yourz Feb 16, 2026
b52785a
fix: update for design reviews
Yourz Feb 18, 2026
4754be7
fix: unit tests
Yourz Feb 18, 2026
def0def
fix: design reviews
Yourz Feb 19, 2026
cc85df9
fix: design reviews
Yourz Feb 19, 2026
7d00323
fix: unit tests
Yourz Feb 19, 2026
c8f1e03
[automated] Apply ESLint and Oxfmt fixes
actions-user Feb 19, 2026
d85db63
new v2 node search box with categories - input/output/source filters …
pythongosssss Feb 13, 2026
2e3a775
review feedback
pythongosssss Feb 9, 2026
ca86212
design feedback
pythongosssss Feb 13, 2026
f88a426
add essentials
pythongosssss Feb 13, 2026
663efef
Add text ticker overflow description
pythongosssss Feb 13, 2026
7d73f01
Add text ticker
pythongosssss Feb 13, 2026
c545c9d
tweaks
pythongosssss Feb 17, 2026
99d6f87
set v2 search as default
pythongosssss Feb 19, 2026
c44155b
hide node library setting
pythongosssss Feb 19, 2026
a597050
update tests to use v1 search
pythongosssss Feb 19, 2026
3d2699c
fix tests & rabbit
pythongosssss Feb 19, 2026
67af441
fix tests
pythongosssss Feb 19, 2026
615f572
fix test
pythongosssss Feb 19, 2026
ab1b72a
[automated] Apply ESLint and Oxfmt fixes
actions-user Feb 19, 2026
bad9642
Review fixes for V2 Node Search (#8987) (#9001)
christian-byrne Feb 20, 2026
1d6b743
fix: resolve merge conflict with main (draftTypes.ts deleted on both …
christian-byrne Feb 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"reference",
"plugin",
"custom-variant",
"utility"
"utility",
"source"
]
}
],
Expand Down
3 changes: 3 additions & 0 deletions browser_tests/fixtures/ComfyPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ComfyTemplates } from '../helpers/templates'
import { ComfyMouse } from './ComfyMouse'
import { VueNodeHelpers } from './VueNodeHelpers'
import { ComfyNodeSearchBox } from './components/ComfyNodeSearchBox'
import { ComfyNodeSearchBoxV2 } from './components/ComfyNodeSearchBoxV2'
import { ContextMenu } from './components/ContextMenu'
import { SettingDialog } from './components/SettingDialog'
import { BottomPanel } from './components/BottomPanel'
Expand Down Expand Up @@ -166,6 +167,7 @@ export class ComfyPage {

// Components
public readonly searchBox: ComfyNodeSearchBox
public readonly searchBoxV2: ComfyNodeSearchBoxV2
public readonly menu: ComfyMenu
public readonly actionbar: ComfyActionbar
public readonly templates: ComfyTemplates
Expand Down Expand Up @@ -210,6 +212,7 @@ export class ComfyPage {
this.workflowUploadInput = page.locator('#comfy-file-input')

this.searchBox = new ComfyNodeSearchBox(page)
this.searchBoxV2 = new ComfyNodeSearchBoxV2(page)
this.menu = new ComfyMenu(page)
this.actionbar = new ComfyActionbar(page)
this.templates = new ComfyTemplates(page)
Expand Down
29 changes: 29 additions & 0 deletions browser_tests/fixtures/components/ComfyNodeSearchBoxV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Locator, Page } from '@playwright/test'

import type { ComfyPage } from '../ComfyPage'

export class ComfyNodeSearchBoxV2 {
readonly dialog: Locator
readonly input: Locator
readonly results: Locator
readonly filterOptions: Locator

constructor(readonly page: Page) {
this.dialog = page.getByRole('search')
this.input = this.dialog.locator('input[type="text"]')
this.results = this.dialog.getByTestId('result-item')
this.filterOptions = this.dialog.getByTestId('filter-option')
}

categoryButton(categoryId: string): Locator {
return this.dialog.getByTestId(`category-${categoryId}`)
}

filterBarButton(name: string): Locator {
return this.dialog.getByRole('button', { name })
}

async reload(comfyPage: ComfyPage) {
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
}
}
2 changes: 1 addition & 1 deletion browser_tests/tests/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ test.describe('Load workflow warning', { tag: '@ui' }, () => {
})

test('Does not report warning on undo/redo', async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v1 (legacy)')

await comfyPage.workflow.loadWorkflow('missing/missing_nodes')
await comfyPage.page
Expand Down
1 change: 1 addition & 0 deletions browser_tests/tests/groupNode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { NodeReference } from '../fixtures/utils/litegraphUtils'

test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v1 (legacy)')
})

test.describe('Group Node', { tag: '@node' }, () => {
Expand Down
25 changes: 20 additions & 5 deletions browser_tests/tests/nodeSearchBox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ test.describe('Node search box', { tag: '@node' }, () => {
'Comfy.LinkRelease.ActionShift',
'search box'
)
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
})

test(`Can trigger on empty canvas double click`, async ({ comfyPage }) => {
Expand All @@ -45,7 +48,10 @@ test.describe('Node search box', { tag: '@node' }, () => {
await comfyPage.setup({ clearStorage: true })
// Simulate new user with 1.24.1+ installed version
await comfyPage.settings.setSetting('Comfy.InstalledVersion', '1.24.1')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
// Don't set LinkRelease settings explicitly to test versioned defaults

await comfyPage.canvasOps.disconnectEdge()
Expand Down Expand Up @@ -285,7 +291,10 @@ test.describe('Release context menu', { tag: '@node' }, () => {
'Comfy.LinkRelease.ActionShift',
'search box'
)
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
})

test(
Expand Down Expand Up @@ -329,7 +338,10 @@ test.describe('Release context menu', { tag: '@node' }, () => {
await comfyPage.setup({ clearStorage: true })
// Simulate existing user with pre-1.24.1 version
await comfyPage.settings.setSetting('Comfy.InstalledVersion', '1.23.0')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
// Don't set LinkRelease settings explicitly to test versioned defaults

await comfyPage.canvasOps.disconnectEdge()
Expand All @@ -350,7 +362,10 @@ test.describe('Release context menu', { tag: '@node' }, () => {
'Comfy.LinkRelease.Action',
'context menu'
)
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)

await comfyPage.canvasOps.disconnectEdge()
// Context menu should appear due to explicit setting, not search box
Expand Down
149 changes: 149 additions & 0 deletions browser_tests/tests/nodeSearchBoxV2.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import {
comfyExpect as expect,
comfyPageFixture as test
} from '../fixtures/ComfyPage'

test.describe('Node search box V2', { tag: '@node' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.LinkRelease.Action',
'search box'
)
await comfyPage.settings.setSetting(
'Comfy.LinkRelease.ActionShift',
'search box'
)
await comfyPage.searchBoxV2.reload(comfyPage)
})

test('Can open search and add node', async ({ comfyPage }) => {
const { searchBoxV2 } = comfyPage
const initialCount = await comfyPage.nodeOps.getGraphNodesCount()

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

await searchBoxV2.input.fill('KSampler')
await expect(searchBoxV2.results.first()).toBeVisible()

await comfyPage.page.keyboard.press('Enter')
await expect(searchBoxV2.input).not.toBeVisible()

const newCount = await comfyPage.nodeOps.getGraphNodesCount()
expect(newCount).toBe(initialCount + 1)
})

test('Can add first default result with Enter', async ({ comfyPage }) => {
const { searchBoxV2 } = comfyPage
const initialCount = await comfyPage.nodeOps.getGraphNodesCount()

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

// Default results should be visible without typing
await expect(searchBoxV2.results.first()).toBeVisible()

// Enter should add the first (selected) result
await comfyPage.page.keyboard.press('Enter')
await expect(searchBoxV2.input).not.toBeVisible()

const newCount = await comfyPage.nodeOps.getGraphNodesCount()
expect(newCount).toBe(initialCount + 1)
})

test.describe('Category navigation', () => {
test('Favorites shows only bookmarked nodes', async ({ comfyPage }) => {
const { searchBoxV2 } = comfyPage
await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [
'KSampler'
])
await searchBoxV2.reload(comfyPage)

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

await searchBoxV2.categoryButton('favorites').click()

await expect(searchBoxV2.results).toHaveCount(1)
await expect(searchBoxV2.results.first()).toContainText('KSampler')
})

test('Category filters results to matching nodes', async ({
comfyPage
}) => {
const { searchBoxV2 } = comfyPage

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

await searchBoxV2.categoryButton('sampling').click()

await expect(searchBoxV2.results.first()).toBeVisible()
const count = await searchBoxV2.results.count()
expect(count).toBeGreaterThan(0)
})
})

test.describe('Filter workflow', () => {
test('Can filter by input type via filter bar', async ({ comfyPage }) => {
const { searchBoxV2 } = comfyPage

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

// Click "Input" filter chip in the filter bar
await searchBoxV2.filterBarButton('Input').click()

// Filter options should appear
await expect(searchBoxV2.filterOptions.first()).toBeVisible()

// Type to narrow and select MODEL
await searchBoxV2.input.fill('MODEL')
await searchBoxV2.filterOptions
.filter({ hasText: 'MODEL' })
.first()
.click()

// Filter chip should appear and results should be filtered
await expect(
searchBoxV2.dialog.getByText('Input:', { exact: false }).locator('..')
).toContainText('MODEL')
await expect(searchBoxV2.results.first()).toBeVisible()
})
})

test.describe('Keyboard navigation', () => {
test('Can navigate and select with keyboard', async ({ comfyPage }) => {
const { searchBoxV2 } = comfyPage
const initialCount = await comfyPage.nodeOps.getGraphNodesCount()

await comfyPage.canvasOps.doubleClick()
await expect(searchBoxV2.input).toBeVisible()

await searchBoxV2.input.fill('KSampler')
const results = searchBoxV2.results
await expect(results.first()).toBeVisible()

// First result selected by default
await expect(results.first()).toHaveAttribute('aria-selected', 'true')

// ArrowDown moves selection
await comfyPage.page.keyboard.press('ArrowDown')
await expect(results.nth(1)).toHaveAttribute('aria-selected', 'true')
await expect(results.first()).toHaveAttribute('aria-selected', 'false')

// ArrowUp moves back
await comfyPage.page.keyboard.press('ArrowUp')
await expect(results.first()).toHaveAttribute('aria-selected', 'true')

// Enter selects and adds node
await comfyPage.page.keyboard.press('Enter')
await expect(searchBoxV2.input).not.toBeVisible()

const newCount = await comfyPage.nodeOps.getGraphNodesCount()
expect(newCount).toBe(initialCount + 1)
})
})
})
1 change: 1 addition & 0 deletions browser_tests/tests/recordAudio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage'

test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v1 (legacy)')
})

test.describe('Record Audio Node', { tag: '@screenshot' }, () => {
Expand Down
4 changes: 4 additions & 0 deletions browser_tests/tests/remoteWidgets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {

test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
})

test.describe('Loading options', () => {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions browser_tests/tests/subgraph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const SELECTORS = {
test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
})

// Helper to get subgraph slot count
Expand Down
5 changes: 4 additions & 1 deletion browser_tests/tests/subgraphSearchAliases.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ async function searchAndExpectResult(
test.describe('Subgraph Search Aliases', { tag: ['@subgraph'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)
})

test('Can set search aliases on subgraph and find via search', async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
// await comfyPage.setup()
await comfyPage.workflow.loadWorkflow('vueNodes/simple-triple')
await comfyPage.vueNodes.waitForNodes()
Expand Down Expand Up @@ -928,7 +929,10 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
'Comfy.LinkRelease.ActionShift',
'context menu'
)
await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)

const samplerNode = (
await comfyPage.nodeOps.getNodeRefsByType('KSampler')
Expand Down Expand Up @@ -994,6 +998,10 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
'Comfy.LinkRelease.ActionShift',
'search box'
)
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)

const samplerNode = (
await comfyPage.nodeOps.getNodeRefsByType('KSampler')
Expand Down Expand Up @@ -1048,6 +1056,11 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
comfyPage,
comfyMouse
}) => {
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'
)

Comment on lines +1059 to +1063
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 1. Check loadWorkflow implementation
echo "=== loadWorkflow implementation ==="
rg -n "loadWorkflow" browser_tests/fixtures/ComfyPage.ts -A 20

# 2. Check the test file structure around lines 102-109 and 1058-1062
echo -e "\n=== Test file structure (beforeEach and relevant test) ==="
sed -n '100,115p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Settings setter call at line 1058 ==="
sed -n '1055,1065p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

# 3. Search for other setSetting calls in the test file to understand patterns
echo -e "\n=== All setSetting calls in test file ==="
rg -n "setSetting" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

# 4. Check ComfyPage setup method to understand what it does
echo -e "\n=== ComfyPage setup method ==="
rg -n "setup()" browser_tests/fixtures/ComfyPage.ts -A 15 | head -40

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2835


🏁 Script executed:

#!/bin/bash
# The first search didn't find loadWorkflow with -A 20. Let me search more broadly
echo "=== Searching for loadWorkflow definition ==="
rg -n "loadWorkflow\(" browser_tests/fixtures/ -A 20 | head -60

echo -e "\n=== Check if loadWorkflow is in WorkflowFixture ==="
fd "Workflow" browser_tests/fixtures/ --type f

echo -e "\n=== Check what workflow object contains ==="
rg -n "workflow\." browser_tests/fixtures/ComfyPage.ts | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2099


🏁 Script executed:

#!/bin/bash
# Now let me check what happens during workflow upload and if settings persist
echo "=== Check if workflowUploadInput triggers page reload ==="
rg -n "workflowUploadInput" browser_tests/fixtures/ComfyPage.ts -A 5 -B 2

echo -e "\n=== Check the setup method implementation (continued) ==="
rg -n "async setup" browser_tests/fixtures/ComfyPage.ts -A 50 | head -80

echo -e "\n=== Check if clearStorage clears settings ==="
rg -n "clearStorage" browser_tests/fixtures/ComfyPage.ts -B 2 -A 10

echo -e "\n=== Check localStorage/settings handling ==="
rg -n "localStorage" browser_tests/fixtures/ -l

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4247


🏁 Script executed:

#!/bin/bash
# Check the structure of tests after line 1058 to see if any rely on v2 default
echo "=== Tests after the 'Dragging from subgraph input' test (line 1058) ==="
rg -n "test\(" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts | tail -20

echo -e "\n=== Check the full test name and location ==="
sed -n '1050,1080p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Check if any tests after line 1058 are still in the same describe block ==="
tail -50 browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4504


🏁 Script executed:

#!/bin/bash
# Check what's after the closing braces at the end of the file
echo "=== Check end of file structure ==="
wc -l browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Last 20 lines of file ==="
tail -20 browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Check if there are more test() calls after line 1054 ==="
rg -n "^  test\(" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts | tail -5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1268


🏁 Script executed:

#!/bin/bash
# Check if there are other describe blocks after this one
echo "=== Check for other describe blocks ==="
rg -n "test\.describe\|describe\(" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Verify the closing structure around line 1108-1109 ==="
sed -n '1100,1109p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Check if NewBlankWorkflow command resets settings/page state ==="
rg -n "NewBlankWorkflow" browser_tests/ -l

echo -e "\n=== Check if page reload happens in other tests ==="
rg -n "goto\(\)" browser_tests/fixtures/ComfyPage.ts | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 964


🏁 Script executed:

#!/bin/bash
# Check if tests share the same page context across describe blocks
echo "=== Check test file structure and page fixture scope ==="
head -20 browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Check how comfyPage fixture is created ==="
rg -n "comfyPage" browser_tests/fixtures/index.ts -A 5 | head -30

echo -e "\n=== Confirm: Is this the last test in the describe block? ==="
sed -n '1054,1109p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts | grep -n "^})"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1083


🏁 Script executed:

#!/bin/bash
# Check fixture setup
echo "=== Check ComfyPage fixture setup ==="
ls -la browser_tests/fixtures/*.ts | head -10

echo -e "\n=== Check how the page is managed in tests ==="
rg -n "comfyPageFixture\|test\(" browser_tests/fixtures/ComfyPage.ts | head -20

echo -e "\n=== Key question: Does NewBlankWorkflow clear settings or localStorage? ==="
rg -n "NewBlankWorkflow\|Comfy\.NewBlankWorkflow" browser_tests -l

echo -e "\n=== Check if each test gets a fresh page or shares state ==="
rg -n "use\(" browser_tests/fixtures/ComfyPage.ts | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1008


🏁 Script executed:

#!/bin/bash
# Verify this is truly the last test in the file and the last in the describe block
echo "=== Verify test count and structure ==="
rg -c "^  test\(" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Show all top-level test() calls with line numbers ==="
rg -n "^  test\(" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

echo -e "\n=== Confirm structure: last test ends before final closing braces ==="
sed -n '1054,1109p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts | tail -10

echo -e "\n=== Verify the describe block boundaries ==="
rg -n "test\.describe\|^}\)" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts | tail -3

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1852


🏁 Script executed:

#!/bin/bash
# Final verification: confirm that settings use localStorage and persist across navigations
echo "=== Check how Comfy.NodeSearchBoxImpl setting is stored/retrieved ==="
rg -n "Comfy\.NodeSearchBoxImpl" browser_tests -l

echo -e "\n=== Verify setSetting method stores in localStorage ==="
rg -n "setSetting" browser_tests/fixtures/ -l

echo -e "\n=== Quick check: Does any test file have cleanup/teardown after tests? ==="
rg -n "afterEach\|teardown" browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 795


🏁 Script executed:

#!/bin/bash
# Check how setSetting is implemented - does it use localStorage?
echo "=== SettingsHelper implementation ==="
cat browser_tests/fixtures/helpers/SettingsHelper.ts

echo -e "\n=== Check what the default value of NodeSearchBoxImpl should be ==="
rg -n "NodeSearchBoxImpl" browser_tests/tests/nodeSearchBox.spec.ts | head -5

echo -e "\n=== Check if there are nested describe blocks within the main one ==="
sed -n '100,120p' browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1815


Settings leak: test sets NodeSearchBoxImpl to 'v1 (legacy)' without resetting in beforeEach.

This test is currently the last one in the describe block, so there's no immediate impact. However, since loadWorkflow() doesn't reload the page (it only uploads JSON and calls nextFrame()), the setting persists in app state. If tests are added after this one, they will silently inherit 'v1 (legacy)' instead of the default 'v2'.

Add an explicit reset to the outer beforeEach to prevent accidental test-order dependency:

Proposed safeguard
  test.beforeEach(async ({ comfyPage }) => {
    await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
    await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
+   await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v2')
    await comfyPage.workflow.loadWorkflow('vueNodes/simple-triple')
    await comfyPage.vueNodes.waitForNodes()
    await fitToViewInstant(comfyPage)
  })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts`
around lines 1058 - 1062, The test mutates app state by calling
comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v1 (legacy)') and
never resets it, risking test-order dependency; update the outer beforeEach to
explicitly reset this setting back to the default (e.g., call
comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'v2') or the app's
default) so that loadWorkflow() and subsequent tests see the expected setting,
ensuring the reset runs before each test that uses loadWorkflow() or comfyPage.

// Setup workflow with a KSampler node
await comfyPage.command.executeCommand('Comfy.NewBlankWorkflow')
await comfyPage.nodeOps.waitForGraphNodes(0)
Expand Down
6 changes: 6 additions & 0 deletions packages/design-system/src/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
icon-sets: from-folder(comfy, './packages/design-system/src/icons');
}

/* Safelist dynamic comfy icons for node library folders */
@source inline("icon-[comfy--{ai-model,bfl,bria,bytedance,credits,extensions-blocks,file-output,gemini,grok,hitpaw,ideogram,image-ai-edit,kling,ltxv,luma,magnific,mask,meshy,minimax,moonvalley-marey,node,openai,pin,pixverse,play,recraft,rodin,runway,sora,stability-ai,template,tencent,topaz,tripo,veo,vidu,wan,wavespeed,workflow}]");

/* Safelist dynamic comfy icons for essential nodes (kebab-case of node names) */
@source inline("icon-[comfy--{load-image,save-image,load-video,save-video,load-3-d,save-glb,image-batch,image-crop,image-scale,image-rotate,image-blur,image-invert,canny,recraft-remove-background-node,kling-lip-sync-audio-to-video-node,load-audio,save-audio,stability-text-to-audio,lora-loader,clip-text-encode,get-video-components,tencent-text-to-model-node,tencent-image-to-model-node,open-ai-chat-node,subgraph-blueprint-canny-to-video-ltx-2-0,subgraph-blueprint-pose-to-video-ltx-2-0}]");

@custom-variant touch (@media (hover: none));

@theme {
Expand Down
10 changes: 10 additions & 0 deletions packages/design-system/src/icons/bfl.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading