Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
85aafed
style: Splitter style tailwind conversion part 1
DrJKL Dec 3, 2025
fe165fe
cleanup: Fix focus mode in splitter, more idiomatic store/ref use
DrJKL Dec 3, 2025
712bc86
cleanup: Simplify changes in TopMenuSection
DrJKL Dec 3, 2025
7645320
Consistency: Open the info in the properties panel too.
DrJKL Dec 3, 2025
941f22e
cleanup: unused action
DrJKL Dec 3, 2025
8214a92
i18n: Fix Panel title pluralization
DrJKL Dec 3, 2025
0a84c40
style: Buttons
DrJKL Dec 3, 2025
885dfe9
fix: Subgraph edit toggle logic
DrJKL Dec 3, 2025
eaca69b
cleanup: Node Info Tab
DrJKL Dec 3, 2025
de2f78c
cleanup: Parameters Accordions
DrJKL Dec 3, 2025
f9b56b3
cleanup: Search bar, not fully there
DrJKL Dec 3, 2025
21daf28
cleanup: Parameters and searchbox padding
DrJKL Dec 3, 2025
47749c5
cleanup: TabSettings part 1
DrJKL Dec 3, 2025
c19c29d
fix: Need a simpler way to detect when we can/should re-search
DrJKL Dec 3, 2025
515ade8
cleanup: TabSettings part 2
DrJKL Dec 3, 2025
95e39fd
Minimap in focus mode, but not in OG Comfy mode
DrJKL Dec 4, 2025
97864d8
Node state fix
DrJKL Dec 4, 2025
9fae437
YAGNI: Accordion item properties
DrJKL Dec 4, 2025
1c167d1
Suggested change
DrJKL Dec 4, 2025
51cbaaf
[automated] Update test expectations
invalid-email-address Dec 4, 2025
5708aea
cleanup: Button classes.
DrJKL Dec 4, 2025
d95359f
test: Update the help panel tests
DrJKL Dec 4, 2025
a0b6ce2
Consistently devolved model binding
DrJKL Dec 4, 2025
f62d17a
test: Remove old sidebar button expectation.
DrJKL Dec 4, 2025
cfcf67d
feat: make node title editable from Properties Panel
DrJKL Dec 4, 2025
b3bdfff
style: margin for searchbox to let the ring show
DrJKL Dec 4, 2025
5ccd48b
fix: Sticky header background
DrJKL Dec 4, 2025
55ae304
style: Add minimum height for some widgets
DrJKL Dec 4, 2025
c666df2
Re-add forced refresh. There are some re-render issues still.
DrJKL Dec 4, 2025
add7b98
test: Minimal properties panel Playwright test
DrJKL Dec 4, 2025
ce4f6ba
test: Test works! Update expectations
DrJKL Dec 5, 2025
10db9f5
Good rabbit suggestion
DrJKL Dec 5, 2025
8825d15
test: Add properties panel locator to fixture, scope assertions to it.
DrJKL Dec 5, 2025
cd6b2fc
test: Restructure actionbar locators
DrJKL Dec 5, 2025
20525a2
Fix: Focus mode on the right.
DrJKL Dec 5, 2025
d7857bf
fix: Hide bottom gutter in focus mode
DrJKL Dec 5, 2025
c7c1b16
[automated] Update test expectations
invalid-email-address Dec 5, 2025
199abdd
Title logic cleanup
DrJKL Dec 5, 2025
23c5512
feat: Handle empty Inputs sections
DrJKL Dec 5, 2025
6dfb1f0
Yeah, I like that better.
DrJKL Dec 5, 2025
fbab8a9
test: Also test searchbox filtering
DrJKL Dec 5, 2025
91fe4b6
Error handling while searching
DrJKL Dec 5, 2025
5b4aad6
[automated] Update test expectations
invalid-email-address Dec 6, 2025
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
14 changes: 14 additions & 0 deletions browser_tests/fixtures/ComfyPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,32 @@ dotenv.config()

type WorkspaceStore = ReturnType<typeof useWorkspaceStore>

class ComfyPropertiesPanel {
readonly root: Locator
readonly panelTitle: Locator
readonly searchBox: Locator

constructor(readonly page: Page) {
this.root = page.getByTestId('properties-panel')
this.panelTitle = this.root.locator('h3')
this.searchBox = this.root.getByPlaceholder('Search...')
}
}

class ComfyMenu {
private _nodeLibraryTab: NodeLibrarySidebarTab | null = null
private _workflowsTab: WorkflowsSidebarTab | null = null
private _topbar: Topbar | null = null

public readonly sideToolbar: Locator
public readonly propertiesPanel: ComfyPropertiesPanel
public readonly themeToggleButton: Locator
public readonly saveButton: Locator

constructor(public readonly page: Page) {
this.sideToolbar = page.locator('.side-tool-bar-container')
this.themeToggleButton = page.locator('.comfy-vue-theme-toggle')
this.propertiesPanel = new ComfyPropertiesPanel(page)
this.saveButton = page
.locator('button[title="Save the current workflow"]')
.nth(0)
Expand Down
8 changes: 6 additions & 2 deletions browser_tests/helpers/actionbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import type { AutoQueueMode } from '../../src/stores/queueStore'
export class ComfyActionbar {
public readonly root: Locator
public readonly queueButton: ComfyQueueButton
public readonly propertiesButton: Locator

constructor(public readonly page: Page) {
this.root = page.locator('.actionbar')
this.root = page.locator('.actionbar-container')
this.queueButton = new ComfyQueueButton(this)
this.propertiesButton = this.root.getByLabel('Toggle properties panel')
}

async isDocked() {
const className = await this.root.getAttribute('class')
const className = await this.root
.locator('.actionbar')
.getAttribute('class')
return className?.includes('static') ?? false
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 30 additions & 15 deletions browser_tests/tests/nodeHelp.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,10 @@ test.describe('Node Help', () => {
await expect(helpButton).toBeVisible()
await helpButton.click()

// Verify that the node library sidebar is opened
await expect(
comfyPage.menu.nodeLibraryTab.selectedTabButton
).toBeVisible()

// Verify that the help page is shown for the correct node
const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
Comment on lines +56 to +58
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Unify help panel selectors and consider a shared fixture helper

The switch to comfyPage.page.locator('[data-testid="properties-panel"]') for help content is a good move toward stable, specific selectors and matches the properties-panel refactor. However:

  • The node-library tests above still use .sidebar-content-container for help content (e.g., Lines 93–95 and 122–123). If node help is now intended to live in the properties panel for all entry points, those tests should likely assert against the same [data-testid="properties-panel"] locator for consistency and to avoid silently targeting a legacy container.
  • This locator is now repeated in many tests in this file. It would be cleaner and easier to maintain if the ComfyPage fixture exposed a propertiesPanel/helpPanel locator, and these tests reused that instead of inlining page.locator('[data-testid="properties-panel"]') everywhere.

I recommend (1) confirming whether node-library help is also rendered via the properties panel and aligning those tests accordingly, and (2) extracting a shared locator on comfyPage to deduplicate this pattern. Based on learnings, this also better follows the “prefer specific selectors in browser tests” guidance.

Also applies to: 170-172, 202-204, 237-239, 287-289, 362-364, 404-406, 473-475, 498-500, 544-546

await expect(helpPage).toContainText('KSampler')
await expect(helpPage.locator('.node-help-content')).toBeVisible()
})
Expand Down Expand Up @@ -170,7 +167,9 @@ test.describe('Node Help', () => {
await helpButton.click()

// Verify loading spinner is shown
const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage.locator('.p-progressspinner')).toBeVisible()

// Wait for content to load
Expand Down Expand Up @@ -200,7 +199,9 @@ test.describe('Node Help', () => {
await helpButton.click()

// Verify fallback content is shown (description, inputs, outputs)
const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage).toContainText('Description')
await expect(helpPage).toContainText('Inputs')
await expect(helpPage).toContainText('Outputs')
Expand Down Expand Up @@ -233,7 +234,9 @@ test.describe('Node Help', () => {
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage).toContainText('KSampler Documentation')

// Check that relative image paths are prefixed correctly
Expand Down Expand Up @@ -281,7 +284,9 @@ test.describe('Node Help', () => {
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)

// Check relative video paths are prefixed
const relativeVideo = helpPage.locator('video[src*="demo.mp4"]')
Expand Down Expand Up @@ -354,7 +359,9 @@ This is documentation for a custom node.
if (await helpButton.isVisible()) {
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage).toContainText('Custom Node Documentation')

// Check image path for custom nodes
Expand Down Expand Up @@ -394,7 +401,9 @@ This is documentation for a custom node.
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)

// Dangerous elements should be removed
await expect(helpPage.locator('script')).toHaveCount(0)
Expand Down Expand Up @@ -461,7 +470,9 @@ This is English documentation.
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage).toContainText('KSamplerノード')
await expect(helpPage).toContainText('これは日本語のドキュメントです')

Expand All @@ -484,7 +495,9 @@ This is English documentation.
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)

// Should show fallback content (node description)
await expect(helpPage).toBeVisible()
Expand Down Expand Up @@ -528,7 +541,9 @@ This is English documentation.
)
await helpButton.click()

const helpPage = comfyPage.page.locator('.sidebar-content-container')
const helpPage = comfyPage.page.locator(
'[data-testid="properties-panel"]'
)
await expect(helpPage).toContainText('KSampler Help')
await expect(helpPage).toContainText('This is KSampler documentation')

Expand Down
35 changes: 35 additions & 0 deletions browser_tests/tests/propertiesPanel/propertiesPanel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from '@playwright/test'

import { comfyPageFixture as test } from '../../fixtures/ComfyPage'

test.describe('Properties panel', () => {
test('opens and updates title based on selection', async ({ comfyPage }) => {
await comfyPage.actionbar.propertiesButton.click()

const { propertiesPanel } = comfyPage.menu

await expect(propertiesPanel.panelTitle).toContainText(
'No node(s) selected'
)

await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])

await expect(propertiesPanel.panelTitle).toContainText('3 nodes selected')
await expect(propertiesPanel.root.getByText('KSampler')).toHaveCount(1)
await expect(
propertiesPanel.root.getByText('CLIP Text Encode (Prompt)')
).toHaveCount(2)

await propertiesPanel.searchBox.fill('seed')
await expect(propertiesPanel.root.getByText('KSampler')).toHaveCount(1)
await expect(
propertiesPanel.root.getByText('CLIP Text Encode (Prompt)')
).toHaveCount(0)

await propertiesPanel.searchBox.fill('')
await expect(propertiesPanel.root.getByText('KSampler')).toHaveCount(1)
await expect(
propertiesPanel.root.getByText('CLIP Text Encode (Prompt)')
).toHaveCount(2)
})
})
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.
Loading