Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
5 changes: 4 additions & 1 deletion browser_tests/fixtures/components/SidebarTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,14 @@ export class AssetsSidebarTab extends SidebarTab {
return this.page.locator('.p-contextmenu').getByText(label)
}

override async open() {
override async open({ waitForAssets = true } = {}) {
// Remove any toast notifications that may overlay the sidebar button
await this.dismissToasts()
await super.open()
await this.generatedTab.waitFor({ state: 'visible' })
if (waitForAssets) {
await this.waitForAssets()
}
}

/** Dismiss all visible toast notifications by clicking their close buttons. */
Expand Down
6 changes: 6 additions & 0 deletions browser_tests/fixtures/helpers/ToastHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import type { Locator, Page } from '@playwright/test'
export class ToastHelper {
public readonly visibleToasts: Locator
public readonly toastErrors: Locator
public readonly toastSuccesses: Locator
public readonly toastWarnings: Locator

constructor(private readonly page: Page) {
this.visibleToasts = page.locator('.p-toast-message:visible')
this.toastErrors = page.locator('.p-toast-message.p-toast-message-error')
this.toastSuccesses = page.locator(
'.p-toast-message.p-toast-message-success'
)
this.toastWarnings = page.locator('.p-toast-message.p-toast-message-warn')
}

async closeToasts(requireCount = 0): Promise<void> {
Expand Down
117 changes: 84 additions & 33 deletions browser_tests/tests/sidebar/assets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ const JOB_GAMMA_DETAIL: JobDetail = {
}
]
}
},
workflow: {
extra_data: {
extra_pnginfo: {
workflow: {
version: 0.4,
last_node_id: 0,
last_link_id: 0,
nodes: [],
links: []
}
}
}
}
}

Expand Down Expand Up @@ -112,15 +125,15 @@ test.describe('Assets sidebar - empty states', () => {

test('Shows empty-state copy for generated tab', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.open({ waitForAssets: false })

await expect(tab.emptyStateTitle('No generated files found')).toBeVisible()
await expect(tab.emptyStateMessage).toBeVisible()
})

test('Shows empty-state copy for imported tab', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.open({ waitForAssets: false })
await tab.switchToImported()

await expect(tab.emptyStateTitle('No imported files found')).toBeVisible()
Expand All @@ -129,7 +142,7 @@ test.describe('Assets sidebar - empty states', () => {

test('No asset cards are rendered when empty', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.open({ waitForAssets: false })

await expect(tab.assetCards).toHaveCount(0)
})
Expand Down Expand Up @@ -209,7 +222,6 @@ test.describe('Assets sidebar - grid view display', () => {
const tab = comfyPage.menu.assetsTab
await tab.open()

await tab.waitForAssets()
await expect.poll(() => tab.assetCards.count()).toBeGreaterThanOrEqual(1)
})

Expand Down Expand Up @@ -270,7 +282,6 @@ test.describe('Assets sidebar - view mode toggle', () => {
test('Can switch to list view via settings menu', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Open settings menu and select list view
await tab.openSettingsMenu()
Expand All @@ -283,7 +294,6 @@ test.describe('Assets sidebar - view mode toggle', () => {
test('Can switch back to grid view', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Switch to list view
await tab.openSettingsMenu()
Expand Down Expand Up @@ -326,7 +336,6 @@ test.describe('Assets sidebar - search', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = await tab.assetCards.count()

Expand All @@ -340,7 +349,6 @@ test.describe('Assets sidebar - search', () => {
test('Clearing search restores all assets', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = await tab.assetCards.count()

Expand All @@ -355,7 +363,6 @@ test.describe('Assets sidebar - search', () => {
test('Search with no matches shows empty state', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.searchInput.fill('nonexistent_file_xyz')
await expect(tab.assetCards).toHaveCount(0)
Expand All @@ -380,7 +387,6 @@ test.describe('Assets sidebar - selection', () => {
test('Clicking an asset card selects it', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Click first asset card
await tab.assetCards.first().click()
Expand All @@ -392,7 +398,6 @@ test.describe('Assets sidebar - selection', () => {
test('Ctrl+click adds to selection', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const cards = tab.assetCards
await expect.poll(() => cards.count()).toBeGreaterThanOrEqual(2)
Expand All @@ -411,7 +416,6 @@ test.describe('Assets sidebar - selection', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Select an asset
await tab.assetCards.first().click()
Expand All @@ -423,7 +427,6 @@ test.describe('Assets sidebar - selection', () => {
test('Deselect all clears selection', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Select an asset
await tab.assetCards.first().click()
Expand All @@ -441,7 +444,6 @@ test.describe('Assets sidebar - selection', () => {
test('Selection is cleared when switching tabs', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Select an asset
await tab.assetCards.first().click()
Expand Down Expand Up @@ -475,7 +477,6 @@ test.describe('Assets sidebar - context menu', () => {
test('Right-clicking an asset shows context menu', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Right-click first asset
await tab.assetCards.first().click({ button: 'right' })
Expand All @@ -490,7 +491,6 @@ test.describe('Assets sidebar - context menu', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })
await comfyPage.page
Expand All @@ -505,7 +505,6 @@ test.describe('Assets sidebar - context menu', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })
await comfyPage.page
Expand All @@ -520,7 +519,6 @@ test.describe('Assets sidebar - context menu', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })
await comfyPage.page
Expand All @@ -535,7 +533,6 @@ test.describe('Assets sidebar - context menu', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })
await comfyPage.page
Expand All @@ -550,7 +547,6 @@ test.describe('Assets sidebar - context menu', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })

Expand All @@ -563,12 +559,79 @@ test.describe('Assets sidebar - context menu', () => {
await expect(tab.contextMenuItem('Export workflow')).toBeVisible()
})

test('Cancelling export-workflow filename prompt does not show an error toast', async ({
comfyPage
}) => {
// job-gamma is the first card; its detail carries a valid workflow so
// extraction succeeds and the filename prompt opens.
await comfyPage.assets.mockJobDetail('job-gamma', JOB_GAMMA_DETAIL)

const tab = comfyPage.menu.assetsTab
await tab.open()

await tab.assetCards.first().click({ button: 'right' })
await tab.contextMenuItem('Export workflow').click()

const promptDialog = comfyPage.page.getByRole('dialog', {
name: 'Export Workflow'
})
await expect(promptDialog).toBeVisible()

await comfyPage.page.keyboard.press('Escape')
await expect(promptDialog).toBeHidden()

await expect(comfyPage.toast.toastErrors).toBeHidden({ timeout: 1500 })
})

test('Confirming export-workflow prompt downloads the file and shows a success toast', async ({
comfyPage
}) => {
await comfyPage.assets.mockJobDetail('job-gamma', JOB_GAMMA_DETAIL)

const tab = comfyPage.menu.assetsTab
await tab.open()

await tab.assetCards.first().click({ button: 'right' })
await tab.contextMenuItem('Export workflow').click()

const promptDialog = comfyPage.page.getByRole('dialog', {
name: 'Export Workflow'
})
await expect(promptDialog).toBeVisible()

const downloadPromise = comfyPage.page.waitForEvent('download')
await promptDialog.getByRole('button', { name: 'Confirm' }).click()

const download = await downloadPromise
expect(download.suggestedFilename()).toBe('abstract_art.json')

await expect(comfyPage.toast.toastSuccesses).toBeVisible()
})

test('Export-workflow shows a warning toast when the asset has no workflow', async ({
comfyPage
}) => {
// Strip the workflow field so extraction yields null and the export
// action returns { success: false, error: 'No workflow…' }.
const { workflow: _, ...detailWithoutWorkflow } = JOB_GAMMA_DETAIL
await comfyPage.assets.mockJobDetail('job-gamma', detailWithoutWorkflow)

const tab = comfyPage.menu.assetsTab
await tab.open()

await tab.assetCards.first().click({ button: 'right' })
await tab.contextMenuItem('Export workflow').click()

// Filename prompt should be skipped: extraction fails before the prompt.
await expect(comfyPage.toast.toastWarnings).toBeVisible()
await expect(comfyPage.toast.toastSuccesses).toBeHidden({ timeout: 1500 })
})

test('Bulk context menu shows when multiple assets selected', async ({
comfyPage
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const cards = tab.assetCards
await expect.poll(() => cards.count()).toBeGreaterThanOrEqual(2)
Expand Down Expand Up @@ -623,7 +686,6 @@ test.describe('Assets sidebar - bulk actions', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click()

Expand All @@ -636,7 +698,6 @@ test.describe('Assets sidebar - bulk actions', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click()

Expand All @@ -647,7 +708,6 @@ test.describe('Assets sidebar - bulk actions', () => {
test('Selection count displays correct number', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

// Select the two single-output assets (job-alpha, job-beta).
// The count reflects total outputs, not cards — job-gamma has
Expand Down Expand Up @@ -676,7 +736,6 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {

const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click()
await expect(tab.downloadSelectedButton).toBeVisible()
Expand All @@ -701,7 +760,6 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {

const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards
.first()
Expand Down Expand Up @@ -737,7 +795,6 @@ cloudTest.describe('Assets sidebar - cloud exports', { tag: '@cloud' }, () => {

const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.nth(1).click()
await comfyPage.page.keyboard.down('Control')
Expand Down Expand Up @@ -784,7 +841,6 @@ test.describe('Assets sidebar - pagination', () => {

const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const req = await firstRequest
const url = new URL(req.url())
Expand Down Expand Up @@ -840,7 +896,6 @@ test.describe('Assets sidebar - delete confirmation', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

await tab.assetCards.first().click({ button: 'right' })
await tab.contextMenuItem('Delete').click()
Expand All @@ -858,7 +913,6 @@ test.describe('Assets sidebar - delete confirmation', () => {
}) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = await tab.assetCards.count()

Expand All @@ -880,7 +934,6 @@ test.describe('Assets sidebar - delete confirmation', () => {
test('Cancelling delete preserves asset', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = await tab.assetCards.count()

Expand Down Expand Up @@ -977,7 +1030,6 @@ test.describe('Assets sidebar - media type filter', () => {
test('Unchecking image filter hides image assets', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = tab.assetCards
await expect(
Expand All @@ -998,7 +1050,6 @@ test.describe('Assets sidebar - media type filter', () => {
test('Re-enabling filter restores hidden assets', async ({ comfyPage }) => {
const tab = comfyPage.menu.assetsTab
await tab.open()
await tab.waitForAssets()

const initialCount = await tab.assetCards.count()

Expand Down
Loading
Loading