|
| 1 | +import { mergeTests } from '@playwright/test' |
| 2 | + |
1 | 3 | import { |
2 | | - comfyPageFixture as test, |
3 | | - comfyExpect as expect |
| 4 | + comfyExpect as expect, |
| 5 | + comfyPageFixture |
4 | 6 | } from '@e2e/fixtures/ComfyPage' |
| 7 | +import { subgraphBreadcrumbFixture } from '@e2e/fixtures/helpers/SubgraphBreadcrumbHelper' |
5 | 8 | import { TestIds } from '@e2e/fixtures/selectors' |
6 | 9 |
|
| 10 | +const test = mergeTests(comfyPageFixture, subgraphBreadcrumbFixture) |
| 11 | + |
7 | 12 | test.describe('App mode usage', () => { |
8 | 13 | test('Drag and Drop @vue-nodes', async ({ comfyPage, comfyFiles }) => { |
9 | 14 | const { centerPanel } = comfyPage.appMode |
@@ -137,6 +142,117 @@ test.describe('App mode usage', () => { |
137 | 142 | await expect.poll(() => fileComboWidget.getValue()).toBe(targetImage) |
138 | 143 | }) |
139 | 144 |
|
| 145 | + test('Shows a single side toolbar per mode, filtered to assets + apps in app mode', async ({ |
| 146 | + comfyPage |
| 147 | + }) => { |
| 148 | + const { sideToolbar, nodeLibraryTab, assetsTab, appsTab } = comfyPage.menu |
| 149 | + |
| 150 | + await test.step('Graph mode shows the full toolbar', async () => { |
| 151 | + await expect(sideToolbar).toHaveCount(1) |
| 152 | + await expect(nodeLibraryTab.tabButton).toBeVisible() |
| 153 | + }) |
| 154 | + |
| 155 | + await test.step('App mode shows only assets + apps', async () => { |
| 156 | + await comfyPage.appMode.enterAppModeWithInputs([['3', 'seed']]) |
| 157 | + await expect(comfyPage.appMode.centerPanel).toBeVisible() |
| 158 | + |
| 159 | + await expect(sideToolbar).toHaveCount(1) |
| 160 | + await expect(assetsTab.tabButton).toBeVisible() |
| 161 | + await expect(appsTab.tabButton).toBeVisible() |
| 162 | + await expect(nodeLibraryTab.tabButton).toBeHidden() |
| 163 | + }) |
| 164 | + }) |
| 165 | + |
| 166 | + test('Workflow actions menu keeps the same position across graph/app mode', async ({ |
| 167 | + comfyPage, |
| 168 | + subgraphBreadcrumb |
| 169 | + }) => { |
| 170 | + const { workflowActions, centerPanel } = comfyPage.appMode |
| 171 | + |
| 172 | + // Toggling graph<->app mode happens from this control, so it must not move |
| 173 | + // out from under the cursor as the mode flips. |
| 174 | + const graphActions = workflowActions.triggerIn( |
| 175 | + subgraphBreadcrumb.panel.root |
| 176 | + ) |
| 177 | + await expect(graphActions).toBeVisible() |
| 178 | + const graphBox = await graphActions.boundingBox() |
| 179 | + |
| 180 | + expect(graphBox).not.toBeNull() |
| 181 | + |
| 182 | + await comfyPage.appMode.enterAppModeWithInputs([['3', 'seed']]) |
| 183 | + await expect(centerPanel).toBeVisible() |
| 184 | + |
| 185 | + const appActions = workflowActions.triggerIn(centerPanel) |
| 186 | + await expect(appActions).toBeVisible() |
| 187 | + |
| 188 | + // The toggle segments reorder (morph) as the mode flips, so poll until the |
| 189 | + // active control settles at the same x it occupied in graph mode. |
| 190 | + await expect |
| 191 | + .poll(async () => { |
| 192 | + const box = await appActions.boundingBox() |
| 193 | + return box ? Math.abs(box.x - graphBox!.x) : Infinity |
| 194 | + }) |
| 195 | + .toBeLessThanOrEqual(1) |
| 196 | + }) |
| 197 | + |
| 198 | + test('Toggle segment flips mode without opening the menu', async ({ |
| 199 | + comfyPage |
| 200 | + }) => { |
| 201 | + const { workflowActions } = comfyPage.appMode |
| 202 | + await expect(workflowActions.viewModeToggle).toBeVisible() |
| 203 | + |
| 204 | + await workflowActions.enterAppModeSegment.click() |
| 205 | + |
| 206 | + await expect(comfyPage.appMode.centerPanel).toBeVisible() |
| 207 | + // The inactive segment switches mode; it must not also open the actions menu. |
| 208 | + await expect(workflowActions.menu).toBeHidden() |
| 209 | + await expect(workflowActions.viewModeToggle).toBeVisible() |
| 210 | + }) |
| 211 | + |
| 212 | + test('Toggle segment flips mode via keyboard without opening the menu', async ({ |
| 213 | + comfyPage |
| 214 | + }) => { |
| 215 | + const { workflowActions } = comfyPage.appMode |
| 216 | + await workflowActions.enterAppModeSegment.focus() |
| 217 | + await workflowActions.enterAppModeSegment.press('Enter') |
| 218 | + |
| 219 | + await expect(comfyPage.appMode.centerPanel).toBeVisible() |
| 220 | + await expect(workflowActions.menu).toBeHidden() |
| 221 | + await expect(workflowActions.trigger).toBeFocused() |
| 222 | + }) |
| 223 | + |
| 224 | + test('Mode toggle re-appears after exiting the builder to graph mode', async ({ |
| 225 | + comfyPage |
| 226 | + }) => { |
| 227 | + const toggle = comfyPage.appMode.workflowActions.viewModeToggle |
| 228 | + await comfyPage.appMode.enableLinearMode() |
| 229 | + await expect(toggle).toBeVisible() |
| 230 | + |
| 231 | + await comfyPage.appMode.enterBuilder() |
| 232 | + await expect(toggle).toBeHidden() |
| 233 | + await expect(comfyPage.appMode.centerPanel).toBeHidden() |
| 234 | + |
| 235 | + await comfyPage.appMode.footer.exitButton.click() |
| 236 | + // Exiting the builder lands in graph mode: the app-mode-only center panel |
| 237 | + // stays hidden while the graph-mode toggle host re-mounts and the toggle |
| 238 | + // re-appears. |
| 239 | + await expect(toggle).toBeVisible() |
| 240 | + await expect(comfyPage.appMode.centerPanel).toBeHidden() |
| 241 | + }) |
| 242 | + |
| 243 | + test('Mode toggle survives a sidebar tab remounting the app panel', async ({ |
| 244 | + comfyPage |
| 245 | + }) => { |
| 246 | + const toggle = comfyPage.appMode.workflowActions.viewModeToggle |
| 247 | + await comfyPage.appMode.enterAppModeWithInputs([['3', 'seed']]) |
| 248 | + await expect(comfyPage.appMode.centerPanel).toBeVisible() |
| 249 | + await expect(toggle).toBeVisible() |
| 250 | + |
| 251 | + // Opening a sidebar tab remounts the app panel; the toggle re-renders with it. |
| 252 | + await comfyPage.menu.assetsTab.tabButton.click() |
| 253 | + await expect(toggle).toBeVisible() |
| 254 | + }) |
| 255 | + |
140 | 256 | test.describe('Mobile', { tag: ['@mobile'] }, () => { |
141 | 257 | test('panel navigation', async ({ comfyPage }) => { |
142 | 258 | const { mobile } = comfyPage.appMode |
|
0 commit comments