Compare commits

...

3 Commits

Author SHA1 Message Date
bymyself
3e35b8fbb9 fix: address CodeRabbit review — remove .or(body) fallback, use TestIds, stricter assertions 2026-03-25 19:11:20 -07:00
GitHub Action
d9c53b216b [automated] Apply ESLint and Oxfmt fixes 2026-03-26 01:36:13 +00:00
bymyself
a0b4c8ee5d test(infra): add cloud Playwright project with @cloud/@oss tagging
- Add 'cloud' Playwright project for testing DISTRIBUTION=cloud builds
- Add build:cloud npm script (DISTRIBUTION=cloud vite build)
- Cloud project uses grep: /@cloud/ to run cloud-only tests
- Default chromium project uses grepInvert to exclude @cloud tests
- Add 2 example cloud-only tests (subscribe button, bottom panel toggle)
- Runtime toggle investigation: NOT feasible (breaks tree-shaking)
  → separate build approach chosen

Convention:
  test('feature works @cloud', ...) — cloud-only
  test('feature works @oss', ...) — OSS-only
  test('feature works', ...) — runs in both

Part of: Test Coverage Q2 Overhaul (UTIL-07)
2026-03-25 18:32:06 -07:00
4 changed files with 80 additions and 42 deletions

View File

@@ -5,70 +5,71 @@
export const TestIds = {
sidebar: {
toolbar: 'side-toolbar',
nodeLibrary: 'node-library-tree',
nodeLibrarySearch: 'node-library-search',
workflows: 'workflows-sidebar',
modeToggle: 'mode-toggle'
toolbar: "side-toolbar",
nodeLibrary: "node-library-tree",
nodeLibrarySearch: "node-library-search",
workflows: "workflows-sidebar",
modeToggle: "mode-toggle",
},
tree: {
folder: 'tree-folder',
leaf: 'tree-leaf',
node: 'tree-node'
folder: "tree-folder",
leaf: "tree-leaf",
node: "tree-node",
},
canvas: {
main: 'graph-canvas',
contextMenu: 'canvas-context-menu',
toggleMinimapButton: 'toggle-minimap-button',
toggleLinkVisibilityButton: 'toggle-link-visibility-button'
main: "graph-canvas",
contextMenu: "canvas-context-menu",
toggleMinimapButton: "toggle-minimap-button",
toggleLinkVisibilityButton: "toggle-link-visibility-button",
},
dialogs: {
settings: 'settings-dialog',
settingsContainer: 'settings-container',
settingsTabAbout: 'settings-tab-about',
confirm: 'confirm-dialog',
errorOverlay: 'error-overlay',
missingNodeCard: 'missing-node-card',
about: 'about-panel',
whatsNewSection: 'whats-new-section'
settings: "settings-dialog",
settingsContainer: "settings-container",
settingsTabAbout: "settings-tab-about",
confirm: "confirm-dialog",
errorOverlay: "error-overlay",
missingNodeCard: "missing-node-card",
about: "about-panel",
whatsNewSection: "whats-new-section",
},
topbar: {
queueButton: 'queue-button',
queueModeMenuTrigger: 'queue-mode-menu-trigger',
saveButton: 'save-workflow-button'
queueButton: "queue-button",
queueModeMenuTrigger: "queue-mode-menu-trigger",
saveButton: "save-workflow-button",
subscribeButton: "topbar-subscribe-button",
},
nodeLibrary: {
bookmarksSection: 'node-library-bookmarks-section'
bookmarksSection: "node-library-bookmarks-section",
},
propertiesPanel: {
root: 'properties-panel'
root: "properties-panel",
},
node: {
titleInput: 'node-title-input'
titleInput: "node-title-input",
},
selectionToolbox: {
colorPickerButton: 'color-picker-button',
colorPickerCurrentColor: 'color-picker-current-color',
colorBlue: 'blue',
colorRed: 'red'
colorPickerButton: "color-picker-button",
colorPickerCurrentColor: "color-picker-current-color",
colorBlue: "blue",
colorRed: "red",
},
widgets: {
decrement: 'decrement',
increment: 'increment',
domWidgetTextarea: 'dom-widget-textarea',
subgraphEnterButton: 'subgraph-enter-button'
decrement: "decrement",
increment: "increment",
domWidgetTextarea: "dom-widget-textarea",
subgraphEnterButton: "subgraph-enter-button",
},
breadcrumb: {
subgraph: 'subgraph-breadcrumb'
subgraph: "subgraph-breadcrumb",
},
templates: {
content: 'template-workflows-content',
workflowCard: (id: string) => `template-workflow-${id}`
content: "template-workflows-content",
workflowCard: (id: string) => `template-workflow-${id}`,
},
user: {
currentUserIndicator: 'current-user-indicator'
}
} as const
currentUserIndicator: "current-user-indicator",
},
} as const;
/**
* Helper type for accessing nested TestIds (excludes function values)
@@ -89,4 +90,4 @@ export type TestIdValue =
(typeof TestIds.templates)[keyof typeof TestIds.templates],
(id: string) => string
>
| (typeof TestIds.user)[keyof typeof TestIds.user]
| (typeof TestIds.user)[keyof typeof TestIds.user];

View File

@@ -0,0 +1,28 @@
import { expect } from "@playwright/test";
import { comfyPageFixture as test } from "../fixtures/ComfyPage";
import { TestIds } from "../fixtures/selectors";
test.describe("Cloud distribution UI @cloud", () => {
test("subscribe button is visible for free-tier users @cloud", async ({
comfyPage,
}) => {
const subscribeButton = comfyPage.page.getByTestId(
TestIds.topbar.subscribeButton,
);
await expect(subscribeButton).toBeAttached();
});
test("bottom panel toggle is hidden in cloud mode @cloud", async ({
comfyPage,
}) => {
const sideToolbar = comfyPage.page.getByTestId(TestIds.sidebar.toolbar);
await expect(sideToolbar).toBeVisible();
// In cloud mode, the bottom panel toggle button should not be rendered
const bottomPanelToggle = sideToolbar.getByRole("button", {
name: /bottom panel|terminal/i,
});
await expect(bottomPanelToggle).toHaveCount(0);
});
});

View File

@@ -8,6 +8,7 @@
"repository": "https://github.com/Comfy-Org/ComfyUI_frontend",
"type": "module",
"scripts": {
"build:cloud": "cross-env DISTRIBUTION=cloud NODE_OPTIONS='--max-old-space-size=8192' nx build",
"build:desktop": "nx build @comfyorg/desktop-ui",
"build-storybook": "storybook build",
"build:types": "nx build --config vite.types.config.mts && node scripts/prepare-types.js",

View File

@@ -36,7 +36,7 @@ export default defineConfig({
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
timeout: 15000,
grepInvert: /@mobile|@perf/ // Run all tests except those tagged with @mobile or @perf
grepInvert: /@mobile|@perf|@cloud/ // Run all tests except those tagged with @mobile, @perf, or @cloud
},
{
@@ -74,6 +74,14 @@ export default defineConfig({
// use: { ...devices['Desktop Safari'] },
// },
{
name: 'cloud',
use: { ...devices['Desktop Chrome'] },
timeout: 15000,
grep: /@cloud/, // Run only tests tagged with @cloud
grepInvert: /@oss/ // Exclude tests tagged with @oss
},
/* Test against mobile viewports. */
{
name: 'mobile-chrome',