Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
ac8b108
feat: Enhance template filtering with Fuse.js and add model selection
Myestery Aug 20, 2025
d36c868
feat: Implement workflow template selector dialog and enhance templat…
Myestery Aug 20, 2025
248a4c8
Merge branch 'main' into feat/new-workflow-templates
Myestery Aug 20, 2025
8e36c34
feat: use old template workflow view in workflow selector
Myestery Aug 20, 2025
ce30ea3
feat: enhance MultiSelect and SearchBox components with improved filt…
Myestery Aug 20, 2025
989e4e5
feat: remove TemplateSearchBar component and enhance template filteri…
Myestery Aug 20, 2025
18482ac
feat: enhance navigation and template filtering with icon support and…
Myestery Aug 20, 2025
9ec2f69
feat: add category icon mapping functions for IDs and titles
Myestery Aug 20, 2025
8fb225f
feat: add new sorting options for template filtering by VRAM utilizat…
Myestery Aug 20, 2025
c6d6de7
[skip ci]
Myestery Aug 21, 2025
d273c1f
Merge branch 'main' into feat/new-workflow-templates
Myestery Aug 27, 2025
f6dc62a
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Aug 27, 2025
5d88200
fix layout overflow issues on bigger screens
Myestery Aug 28, 2025
fa317d7
fix: adjust dialog content styling for improved layout management
Myestery Aug 28, 2025
b243b46
feat: implement model size sorting and enhance performance filtering …
Myestery Aug 28, 2025
4471c06
fix: update icon in WorkflowTemplateSelector and improve tag display …
Myestery Aug 28, 2025
a3f0265
feat: add LLM category support and corresponding icon in workflow tem…
Myestery Aug 28, 2025
fde58ab
feat: add tutorial button and corresponding tooltip in TemplateWorkfl…
Myestery Aug 28, 2025
1705760
fix: remove performance filters and counts from workflow templates
Myestery Aug 28, 2025
01827df
Implement falback default template Image
Myestery Aug 28, 2025
24af976
fix: remove LoRA training filter and counts from workflow templates
Myestery Aug 30, 2025
eb72d04
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 5, 2025
c6933a4
style: enhance MultiSelect component's overlay and list for better sc…
Myestery Sep 5, 2025
142179d
feat: enable search box in MultiSelect and replace tag spans with Squ…
Myestery Sep 5, 2025
956692b
WIP use new workflowtemplate selector to match design
Myestery Sep 5, 2025
deb3f27
wip: reposition workflow title text
Myestery Sep 5, 2025
387c088
refactor: move tutorial button to card bottom
Myestery Sep 7, 2025
f896686
refactor: simplify thumbnail source retrieval and enhance onLoadWorkf…
Myestery Sep 8, 2025
4d70fed
Add props to CatdBottom and CardContainer
Myestery Sep 8, 2025
0e3da72
refactor: adjust MultiSelect overlay height
Myestery Sep 8, 2025
c0eacb7
refactor: update SingleSelect label class and adjust NavItem icon size
Myestery Sep 8, 2025
967e506
refactor: update button label and visibility, adjust CardBottom prope…
Myestery Sep 8, 2025
e465d1f
refactor: update NavItem font size from text-xs to text-sm
Myestery Sep 8, 2025
521842f
refactor: update default sort option to 'newest'
Myestery Sep 8, 2025
a883288
refactor: adjust sort options container position and update SingleSel…
Myestery Sep 8, 2025
88aa77a
refactor: add page title display and improve template card structure
Myestery Sep 8, 2025
73af4d5
refactor: enhance MultiSelect component with search functionality and…
Myestery Sep 8, 2025
180a8ea
refactor: update title styling and enhance hover transition effects
Myestery Sep 9, 2025
deb3d94
refactor: replace dialogService method call with useWorkflowTemplateS…
Myestery Sep 9, 2025
cb3a296
refactor: remove unused getCategoryIconByTitle function and clean up …
Myestery Sep 9, 2025
06f6b67
refactor: remove old WorkflowTemplateSelector component
Myestery Sep 9, 2025
a96a8f5
refactor: rename NewWorkflowTemplateSelectorDialog
Myestery Sep 9, 2025
54c7851
refactor: delete unused components
Myestery Sep 9, 2025
2a50793
refactor: update BaseThumbnail tests and improve template description…
Myestery Sep 9, 2025
619728c
Merge branch 'main' into feat/new-workflow-templates
Myestery Sep 9, 2025
406a53a
Merge branch 'main' into feat/new-workflow-templates
Myestery Sep 12, 2025
1864b1c
fix: Replace BaseWidgetLayout with BaseModalLayout and ensure hovered…
Myestery Sep 12, 2025
482dfcc
fix: reset base components to use default props
Myestery Sep 12, 2025
1bd6fdd
fix: update category icon mappings to use Lucide icon classes
Myestery Sep 12, 2025
b1b1312
Merge branch 'main' into feat/new-workflow-templates
Myestery Sep 12, 2025
f0c8a6d
fix: add data-testid attributes for template workflows in WorkflowTem…
Myestery Sep 12, 2025
6844b77
fix: update fallback behavior for loading core workflow templates to …
Myestery Sep 12, 2025
578bb54
fix: enhance CardContainer and MultiSelect components with improved p…
Myestery Sep 13, 2025
8cb10b0
fix(links): remove drag-end offset in straight/linear modes by honori…
benceruleanlu Sep 12, 2025
64058e8
Feat: Change the Run button / ActionBar to dock by default (#5519)
DrJKL Sep 12, 2025
a28a52c
Component: Vue Widget Slider (new) (#5516)
DrJKL Sep 13, 2025
066d292
ADR: PrimeVue Fork Decision (#5230)
christian-byrne Sep 13, 2025
3d5bbbe
a11y: Bigger click/touch target for Slider track (#5524)
DrJKL Sep 13, 2025
c673ce9
[test] Add Vue Node header component test (#5457)
christian-byrne Sep 13, 2025
8cee668
feat: add test count display to Playwright PR comments (#5458)
snomiao Sep 13, 2025
cca69a8
Fix update Action version extraction (#5527)
webfiltered Sep 13, 2025
5c64fcd
[chore] Update electron-types to 0.4.72 (#5526)
comfy-pr-bot Sep 13, 2025
c984993
[test] Add component test for Vue button widget (#5468)
christian-byrne Sep 13, 2025
ccf2c57
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 17, 2025
a3ca397
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 17, 2025
9fae98e
refactor: Update import paths for template workflows and workflow tem…
Myestery Sep 17, 2025
d48ed60
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 17, 2025
632f53a
feat: Enhance navigation with collapsible groups and improved NavTitl…
Myestery Sep 17, 2025
b48f91f
feat: Add extension-specific filtering to template filters
Myestery Sep 17, 2025
76308e7
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 19, 2025
b9cc103
Merge remote-tracking branch 'origin/main' into feat/new-workflow-tem…
Myestery Sep 22, 2025
6f13519
refactor: update template parameter types in WorkflowTemplateSelector…
Myestery Sep 22, 2025
699d4b4
fix: add backgroundRepeat style to AudioThumbnail component
Myestery Sep 22, 2025
e72efad
refactor: let categories on leftsidepanel be one to one with JSON
Myestery Sep 22, 2025
7291255
refactor: remove unused SMALL_MODEL_SIZE_LIMIT constant from template…
Myestery Sep 22, 2025
c7b4ec8
fix: add overflow-y-scroll to LeftSidePanel for improved scrolling be…
Myestery Sep 22, 2025
4305497
refactor: simplify hover state management in WorkflowTemplateSelector…
Myestery Sep 22, 2025
4a784df
fix: optimize template hover state with v-memo and release DOM refs o…
Myestery Sep 23, 2025
d1e8ec3
fix: update placeholder text in SearchBox to use translation function
Myestery Sep 23, 2025
e06f967
fix: implement debounced search query in useTemplateFiltering for imp…
Myestery Sep 23, 2025
91eb417
fix: enhance loading states with skeletons and async state
Myestery Sep 23, 2025
27e4ee5
fix: update MultiSelect component to use VueUse's useFuse for improve…
Myestery Sep 23, 2025
b6b4a56
fix: refactor containerClasses and containerStyle to use cn() and pre…
Myestery Sep 23, 2025
920f6cf
fix: update template filtering and workflow templates to include 'Get…
Myestery Sep 23, 2025
2cf3421
fix: improve template loading feedback with better placement for titl…
Myestery Sep 23, 2025
e43a2fc
fix: add flex-wrap to bottom-right slot for stacking square chips
Myestery Sep 23, 2025
7676ebf
fix e2e tests
Myestery Sep 24, 2025
77bb1e4
Update test expectations [skip ci]
invalid-email-address Sep 24, 2025
a3adaf2
fix: remove unused SquareChip templates from WorkflowTemplateSelector…
Myestery Sep 24, 2025
65bb4c6
fix: update 'Getting Started' label to reflect essential category title
Myestery Sep 24, 2025
939254b
Merge branch 'main' into feat/new-workflow-templates
Myestery Sep 24, 2025
7d34490
feat: improve workflow template cards UI
felixturner Sep 24, 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
180 changes: 126 additions & 54 deletions browser_tests/tests/templates.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ test.describe('Templates', () => {
// Load a template
await comfyPage.executeCommand('Comfy.BrowseTemplates')
await expect(comfyPage.templates.content).toBeVisible()

await comfyPage.page
.locator(
'nav > div:nth-child(2) > div > span:has-text("Getting Started")'
)
.click()
await comfyPage.templates.loadTemplate('default')
await expect(comfyPage.templates.content).toBeHidden()

Expand All @@ -102,48 +108,72 @@ test.describe('Templates', () => {
expect(await comfyPage.templates.content.isVisible()).toBe(true)
})

test('Uses title field as fallback when the key is not found in locales', async ({
test('Uses proper locale files for templates', async ({ comfyPage }) => {
// Set locale to French before opening templates
await comfyPage.setSetting('Comfy.Locale', 'fr')

// Load the templates dialog and wait for the French index file request
const requestPromise = comfyPage.page.waitForRequest(
'**/templates/index.fr.json'
)

await comfyPage.executeCommand('Comfy.BrowseTemplates')

const request = await requestPromise

// Verify French index was requested
expect(request.url()).toContain('templates/index.fr.json')

await expect(comfyPage.templates.content).toBeVisible()
})

test('Falls back to English templates when locale file not found', async ({
comfyPage
}) => {
// Capture request for the index.json
await comfyPage.page.route('**/templates/index.json', async (route, _) => {
// Add a new template that won't have a translation pre-generated
const response = [
{
moduleName: 'default',
title: 'FALLBACK CATEGORY',
type: 'image',
templates: [
{
name: 'unknown_key_has_no_translation_available',
title: 'FALLBACK TEMPLATE NAME',
mediaType: 'image',
mediaSubtype: 'webp',
description: 'No translations found'
}
]
}
]
// Set locale to a language that doesn't have a template file
await comfyPage.setSetting('Comfy.Locale', 'de') // German - no index.de.json exists

// Wait for the German request (expected to 404)
const germanRequestPromise = comfyPage.page.waitForRequest(
'**/templates/index.de.json'
)

// Wait for the fallback English request
const englishRequestPromise = comfyPage.page.waitForRequest(
'**/templates/index.json'
)

// Intercept the German file to simulate a 404
await comfyPage.page.route('**/templates/index.de.json', async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify(response),
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-store'
}
status: 404,
headers: { 'Content-Type': 'text/plain' },
body: 'Not Found'
})
})

// Allow the English index to load normally
await comfyPage.page.route('**/templates/index.json', (route) =>
route.continue()
)

// Load the templates dialog
await comfyPage.executeCommand('Comfy.BrowseTemplates')
await expect(comfyPage.templates.content).toBeVisible()

// Verify German was requested first, then English as fallback
const germanRequest = await germanRequestPromise
const englishRequest = await englishRequestPromise

expect(germanRequest.url()).toContain('templates/index.de.json')
expect(englishRequest.url()).toContain('templates/index.json')

// Expect the title to be used as fallback for template cards
// Verify English titles are shown as fallback
await expect(
comfyPage.templates.content.getByText('FALLBACK TEMPLATE NAME')
comfyPage.templates.content.getByRole('heading', {
name: 'Image Generation'
})
).toBeVisible()

// Expect the title to be used as fallback for the template categories
await expect(comfyPage.page.getByLabel('FALLBACK CATEGORY')).toBeVisible()
})

test('template cards are dynamically sized and responsive', async ({
Expand All @@ -153,36 +183,57 @@ test.describe('Templates', () => {
await comfyPage.executeCommand('Comfy.BrowseTemplates')
await expect(comfyPage.templates.content).toBeVisible()

// Wait for at least one template card to appear
await expect(comfyPage.page.locator('.template-card').first()).toBeVisible({
timeout: 5000
})
const firstCard = comfyPage.page
.locator('[data-testid^="template-workflow-"]')
.first()
await expect(firstCard).toBeVisible({ timeout: 5000 })

// Take snapshot of the template grid
const templateGrid = comfyPage.templates.content.locator('.grid').first()
// Get the template grid
const templateGrid = comfyPage.page.locator(
'[data-testid="template-workflows-content"]'
)
await expect(templateGrid).toBeVisible()
await expect(templateGrid).toHaveScreenshot('template-grid-desktop.png')

// Check grid layout at desktop size (default)
const desktopGridClass = await templateGrid.getAttribute('class')
expect(desktopGridClass).toContain('grid')
expect(desktopGridClass).toContain(
'grid-cols-[repeat(auto-fill,minmax(16rem,1fr))]'
)

// Count visible cards at desktop size
const desktopCardCount = await comfyPage.page
.locator('[data-testid^="template-workflow-"]')
.count()
expect(desktopCardCount).toBeGreaterThan(0)

// Check cards at mobile viewport size
await comfyPage.page.setViewportSize({ width: 640, height: 800 })
await expect(templateGrid).toBeVisible()
await expect(templateGrid).toHaveScreenshot('template-grid-mobile.png')
// Grid should still be responsive at mobile size
const mobileGridClass = await templateGrid.getAttribute('class')
expect(mobileGridClass).toContain('grid')

// Check cards at tablet size
await comfyPage.page.setViewportSize({ width: 1024, height: 800 })
await expect(templateGrid).toBeVisible()
await expect(templateGrid).toHaveScreenshot('template-grid-tablet.png')
// Grid should still be responsive at tablet size
const tabletGridClass = await templateGrid.getAttribute('class')
expect(tabletGridClass).toContain('grid')
})

test('hover effects work on template cards', async ({ comfyPage }) => {
// Open templates dialog
await comfyPage.executeCommand('Comfy.BrowseTemplates')
await expect(comfyPage.templates.content).toBeVisible()

// Get a template card
const firstCard = comfyPage.page.locator('.template-card').first()
// Get a template card using data-testid
const firstCard = comfyPage.page
.locator('[data-testid^="template-workflow-"]')
.first()
await expect(firstCard).toBeVisible({ timeout: 5000 })

// Check initial state - card should have transition classes
// Take snapshot before hover
await expect(firstCard).toHaveScreenshot('template-card-before-hover.png')

Expand Down Expand Up @@ -257,21 +308,42 @@ test.describe('Templates', () => {
await comfyPage.executeCommand('Comfy.BrowseTemplates')
await expect(comfyPage.templates.content).toBeVisible()

// Verify cards are visible with varying content lengths
await expect(
comfyPage.page.getByText('This is a short description.')
).toBeVisible({ timeout: 5000 })
// Wait for cards to load
await expect(
comfyPage.page.getByText('This is a medium length description')
).toBeVisible({ timeout: 5000 })
await expect(
comfyPage.page.getByText('This is a much longer description')
comfyPage.page.locator(
'[data-testid="template-workflow-short-description"]'
)
).toBeVisible({ timeout: 5000 })

// Take snapshot of a grid with specific cards
const templateGrid = comfyPage.templates.content
.locator('.grid:has-text("Short Description")')
.first()
// Verify all three cards with different descriptions are visible
const shortDescCard = comfyPage.page.locator(
'[data-testid="template-workflow-short-description"]'
)
const mediumDescCard = comfyPage.page.locator(
'[data-testid="template-workflow-medium-description"]'
)
const longDescCard = comfyPage.page.locator(
'[data-testid="template-workflow-long-description"]'
)

await expect(shortDescCard).toBeVisible()
await expect(mediumDescCard).toBeVisible()
await expect(longDescCard).toBeVisible()

// Verify descriptions are visible and have line-clamp class
// The description is in a p tag with text-muted class
const shortDesc = shortDescCard.locator('p.text-muted.line-clamp-2')
const mediumDesc = mediumDescCard.locator('p.text-muted.line-clamp-2')
const longDesc = longDescCard.locator('p.text-muted.line-clamp-2')

await expect(shortDesc).toContainText('short description')
await expect(mediumDesc).toContainText('medium length description')
await expect(longDesc).toContainText('much longer description')

// Verify grid layout maintains consistency
const templateGrid = comfyPage.page.locator(
'[data-testid="template-workflows-content"]'
)
await expect(templateGrid).toBeVisible()
await expect(templateGrid).toHaveScreenshot(
'template-grid-varying-content.png'
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.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
"@tiptap/extension-table-row": "^2.10.4",
"@tiptap/starter-kit": "^2.10.4",
"@vueuse/core": "^11.0.0",
"@vueuse/integrations": "^13.9.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-serialize": "^0.13.0",
"@xterm/xterm": "^5.5.0",
Expand Down
Loading