Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bb6ac37
style(vueNodes): update error node design
jaeone94 Mar 3, 2026
c225e8d
fix: remove unused isTransparent function from colorUtil
jaeone94 Mar 3, 2026
21e4923
style: refine node selection outline and footer rounding for error st…
jaeone94 Mar 4, 2026
5b357b5
test: use data-testid for LGraphNode outline tests
jaeone94 Mar 4, 2026
a9bd102
[automated] Update test expectations
invalid-email-address Mar 4, 2026
7ab6182
fix(tests): update browser tests to reflect new node DOM structure
jaeone94 Mar 4, 2026
a6bd6a8
fix(tests): use stable testid selectors for node state assertions
jaeone94 Mar 4, 2026
a8ade48
fix(tests): click visible area of footer tab button in enterSubgraph …
jaeone94 Mar 4, 2026
d1d84fc
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 4, 2026
c41c8a9
Merge branch 'style/subgraph-error-node-design' of https://github.com…
jaeone94 Mar 4, 2026
bba022e
[automated] Update test expectations
invalid-email-address Mar 4, 2026
1d21bdc
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 5, 2026
8284468
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 5, 2026
4b5024a
refactor(LGraphNode): extract inline handlers and consolidate footer …
jaeone94 Mar 5, 2026
07599ce
fix(LGraphNode): fix footer offset misalignment for border and resize…
jaeone94 Mar 5, 2026
bf638f5
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 5, 2026
76adef4
[automated] Apply ESLint and Oxfmt fixes
actions-user Mar 5, 2026
a2b4864
[automated] Update test expectations
invalid-email-address Mar 5, 2026
ae3af15
feat(LGraphNode): hide borders, badges, and lower outline z-index for…
jaeone94 Mar 6, 2026
a393f1b
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 6, 2026
6686158
[automated] Apply ESLint and Oxfmt fixes
actions-user Mar 6, 2026
f67f2d8
[automated] Update test expectations
invalid-email-address Mar 6, 2026
363637c
fix(LGraphNode): add transparent border to node-inner-wrapper to matc…
jaeone94 Mar 6, 2026
a988ea3
[automated] Update test expectations
invalid-email-address Mar 6, 2026
b53158e
Merge branch 'main' into style/subgraph-error-node-design
jaeone94 Mar 6, 2026
864e5a0
[automated] Update test expectations
invalid-email-address Mar 7, 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
15 changes: 14 additions & 1 deletion browser_tests/fixtures/VueNodeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@ export class VueNodeHelpers {
async enterSubgraph(nodeId?: string): Promise<void> {
const locator = nodeId ? this.getNodeLocator(nodeId) : this.page
const editButton = locator.getByTestId(TestIds.widgets.subgraphEnterButton)
await editButton.click()

// The footer tab button extends below the node body (visible area),
// but its bounding box center overlaps the node body div.
// Click at the bottom 25% of the button which is the genuinely visible
// and unobstructed area outside the node body boundary.
const box = await editButton.boundingBox()
if (!box) {
throw new Error(
'subgraph-enter-button has no bounding box: element may be hidden or not in DOM'
)
}
await editButton.click({
position: { x: box.width / 2, y: box.height * 0.75 }
})
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 12 additions & 4 deletions browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ test.describe('Vue Node Bypass', () => {
await comfyPage.page.getByText('Load Checkpoint').click()
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)

const checkpointNode =
comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
const checkpointNode = comfyPage.page
.locator('[data-node-id]')
.filter({ hasText: 'Load Checkpoint' })
.getByTestId('node-inner-wrapper')
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
Expand All @@ -41,8 +43,14 @@ test.describe('Vue Node Bypass', () => {
await comfyPage.page.getByText('Load Checkpoint').click()
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })

const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler')
const checkpointNode = comfyPage.page
.locator('[data-node-id]')
.filter({ hasText: 'Load Checkpoint' })
.getByTestId('node-inner-wrapper')
const ksamplerNode = comfyPage.page
.locator('[data-node-id]')
.filter({ hasText: 'KSampler' })
.getByTestId('node-inner-wrapper')

await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 9 additions & 5 deletions browser_tests/tests/vueNodes/nodeStates/error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
comfyPageFixture as test
} from '../../../fixtures/ComfyPage'

const ERROR_CLASS = /border-node-stroke-error/
const ERROR_CLASS = /ring-destructive-background/

test.describe('Vue Node Error', () => {
test.beforeEach(async ({ comfyPage }) => {
Expand All @@ -18,9 +18,10 @@ test.describe('Vue Node Error', () => {
await comfyPage.workflow.loadWorkflow('missing/missing_nodes')

// Expect error state on missing unknown node
const unknownNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'UNKNOWN NODE'
})
const unknownNode = comfyPage.page
.locator('[data-node-id]')
.filter({ hasText: 'UNKNOWN NODE' })
.getByTestId('node-inner-wrapper')
await expect(unknownNode).toHaveClass(ERROR_CLASS)
})

Expand All @@ -31,7 +32,10 @@ test.describe('Vue Node Error', () => {
await comfyPage.workflow.loadWorkflow('nodes/execution_error')
await comfyPage.runButton.click()

const raiseErrorNode = comfyPage.vueNodes.getNodeByTitle('Raise Error')
const raiseErrorNode = comfyPage.page
.locator('[data-node-id]')
.filter({ hasText: 'Raise Error' })
.getByTestId('node-inner-wrapper')
await expect(raiseErrorNode).toHaveClass(ERROR_CLASS)
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 29 additions & 1 deletion src/renderer/extensions/vueNodes/components/LGraphNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ vi.mock(
})
)

vi.mock('@/scripts/app', () => ({
app: {
rootGraph: { getNodeById: vi.fn() },
canvas: { setDirty: vi.fn() }
}
}))

vi.mock('@/utils/graphTraversalUtil', async (importOriginal) => {
const actual = (await importOriginal()) as Record<string, unknown>
return {
...actual,
getNodeByLocatorId: vi.fn(() => ({
isSubgraphNode: () => false
}))
}
})

vi.mock('@/composables/useErrorHandling', () => ({
useErrorHandling: () => ({
toastErrorHandler: vi.fn()
Expand Down Expand Up @@ -184,16 +201,27 @@ describe('LGraphNode', () => {

const wrapper = mountLGraphNode({ nodeData: mockNodeData })

expect(wrapper.classes()).toContain('outline-3')
// Root div should have the selection class
expect(wrapper.classes()).toContain('outline-node-component-outline')

// The layered outline overlay should be present
const overlay = wrapper.find('[data-testid="node-state-outline-overlay"]')
expect(overlay.exists()).toBe(true)
expect(overlay.classes()).toContain('border-node-component-outline')
})

it('should render progress indicator when executing prop is true', () => {
mockData.mockExecuting = true

const wrapper = mountLGraphNode({ nodeData: mockNodeData })

// Root div should have the executing class
expect(wrapper.classes()).toContain('outline-node-stroke-executing')

// The layered outline overlay should be present
const overlay = wrapper.find('[data-testid="node-state-outline-overlay"]')
expect(overlay.exists()).toBe(true)
expect(overlay.classes()).toContain('border-node-stroke-executing')
})

it('should initialize height CSS vars for collapsed nodes', () => {
Expand Down
Loading
Loading