Compare commits
225 Commits
v1.11.8
...
create_fol
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e6e34cfd3 | ||
|
|
2a445f3f94 | ||
|
|
f8dcb915aa | ||
|
|
11925ce345 | ||
|
|
90053058ba | ||
|
|
b36f748a78 | ||
|
|
d57d12b426 | ||
|
|
bd1be28478 | ||
|
|
891e18af8e | ||
|
|
1610d06cd1 | ||
|
|
e3c7bbf966 | ||
|
|
0bfbbe838f | ||
|
|
c82fe80716 | ||
|
|
ad98bcb87c | ||
|
|
652ea15e8b | ||
|
|
a7a8cc633b | ||
|
|
d23aec4ceb | ||
|
|
8db088b27a | ||
|
|
7ef6e52f38 | ||
|
|
edeefe0883 | ||
|
|
c6046e47d2 | ||
|
|
e8bcccc276 | ||
|
|
7705a09760 | ||
|
|
2a860d72b2 | ||
|
|
f583015a14 | ||
|
|
07f285b05a | ||
|
|
64a0a120b6 | ||
|
|
3956e31810 | ||
|
|
679f2daa8d | ||
|
|
48ae6f7bf2 | ||
|
|
cf732974a9 | ||
|
|
e1179aace0 | ||
|
|
866d03b9c4 | ||
|
|
aab1dd8698 | ||
|
|
eff68ae7a8 | ||
|
|
8be25883cd | ||
|
|
c6b3e2a0ed | ||
|
|
bde518fa13 | ||
|
|
c34be53f4d | ||
|
|
412500ea48 | ||
|
|
d1c53a2eb5 | ||
|
|
af0d0c6e39 | ||
|
|
9f0abac57b | ||
|
|
24c2f2b712 | ||
|
|
7450e61b10 | ||
|
|
05dd587928 | ||
|
|
20d2eca51e | ||
|
|
3b5634623a | ||
|
|
8f8b5bdcf4 | ||
|
|
0cfd6a487a | ||
|
|
744b5fab68 | ||
|
|
56cea8047d | ||
|
|
27fe7f89be | ||
|
|
116a11bd58 | ||
|
|
58be9ad4c3 | ||
|
|
1605a37679 | ||
|
|
c1d17b64b0 | ||
|
|
46fa50f232 | ||
|
|
a7d3a74daa | ||
|
|
8b69b280fa | ||
|
|
fe5e4e0d8a | ||
|
|
067a0ea376 | ||
|
|
661934156c | ||
|
|
e6ccdccce3 | ||
|
|
e1e8fcf62c | ||
|
|
d133aeb614 | ||
|
|
e371880a4e | ||
|
|
bcd76ba49b | ||
|
|
aad7ded636 | ||
|
|
3e8ef33cbc | ||
|
|
0facb0458b | ||
|
|
fd6aae141a | ||
|
|
9be090f929 | ||
|
|
313f32b094 | ||
|
|
d76391b682 | ||
|
|
3c68a1da2c | ||
|
|
3de1ef993e | ||
|
|
29df14f477 | ||
|
|
e4e7d53fcc | ||
|
|
8fa970ffba | ||
|
|
d4c3685326 | ||
|
|
ebb030c401 | ||
|
|
db6a25a092 | ||
|
|
a90b6519b5 | ||
|
|
c2006412de | ||
|
|
a046e00bc3 | ||
|
|
b347693f4d | ||
|
|
c4ca694d1d | ||
|
|
cd7e2d7b91 | ||
|
|
46029a5ce3 | ||
|
|
4123cb611c | ||
|
|
03bf81cc1b | ||
|
|
710bc2bb2e | ||
|
|
e6ef4c8e6d | ||
|
|
62528fde2e | ||
|
|
abe4754904 | ||
|
|
3eb036b5e3 | ||
|
|
e29a5d3047 | ||
|
|
9cea1fe0d3 | ||
|
|
61cf07be88 | ||
|
|
ec013cc511 | ||
|
|
60022134ed | ||
|
|
1558a5bb19 | ||
|
|
445be93d50 | ||
|
|
4b05d5a8fa | ||
|
|
131229f02f | ||
|
|
3a0b337d0c | ||
|
|
97d9f90374 | ||
|
|
496abfde53 | ||
|
|
72994621a6 | ||
|
|
83f9240587 | ||
|
|
ba8c1ee823 | ||
|
|
3d6fe41ee9 | ||
|
|
96b84761f3 | ||
|
|
d32ff0b018 | ||
|
|
6e378c68f9 | ||
|
|
65573f106b | ||
|
|
d8721760f1 | ||
|
|
f53c04834f | ||
|
|
50ecefadc1 | ||
|
|
fdc899a7d9 | ||
|
|
fb0a134278 | ||
|
|
082f0061f6 | ||
|
|
d10dad85c6 | ||
|
|
e4659a3930 | ||
|
|
91388e8b16 | ||
|
|
d24bbe2d7f | ||
|
|
87c21b45d7 | ||
|
|
8718e20693 | ||
|
|
37ae12eb41 | ||
|
|
b546131efb | ||
|
|
48fe30a977 | ||
|
|
278555f984 | ||
|
|
e51dcb9860 | ||
|
|
5f149ceb30 | ||
|
|
af31937e54 | ||
|
|
d74f47db0b | ||
|
|
f7be9157e0 | ||
|
|
caaf050728 | ||
|
|
367a1c63a5 | ||
|
|
f0ba48ea22 | ||
|
|
49964b1c2f | ||
|
|
aca419e1fb | ||
|
|
e7863676dd | ||
|
|
a6d54de2a7 | ||
|
|
15e396b4cc | ||
|
|
ba4e4ed0b8 | ||
|
|
35e6cabfe7 | ||
|
|
8a479979b1 | ||
|
|
1882a9af6f | ||
|
|
c3a984a293 | ||
|
|
4c31d04573 | ||
|
|
621568f99e | ||
|
|
b80c991299 | ||
|
|
b71952c141 | ||
|
|
680268bb29 | ||
|
|
d0ce2d2597 | ||
|
|
6255cea181 | ||
|
|
89b73429b7 | ||
|
|
a415da616c | ||
|
|
05b6f6d8a2 | ||
|
|
2d179ad632 | ||
|
|
fe5964ceb6 | ||
|
|
f434610979 | ||
|
|
eceea51800 | ||
|
|
ed4d2aa40c | ||
|
|
f593f3caa4 | ||
|
|
252e07ad17 | ||
|
|
51aafaec08 | ||
|
|
85aee9838f | ||
|
|
e8efd0d801 | ||
|
|
22f0dcc0a0 | ||
|
|
b2f3d85e24 | ||
|
|
e1f23bf02e | ||
|
|
8affd7eec7 | ||
|
|
47604e6c2d | ||
|
|
30c750f787 | ||
|
|
b24bc48102 | ||
|
|
603825b2a0 | ||
|
|
f76995a3b9 | ||
|
|
21f115c077 | ||
|
|
ca1607024f | ||
|
|
1b14e4086e | ||
|
|
82a8aba704 | ||
|
|
a38a11f397 | ||
|
|
132a0ded09 | ||
|
|
c997bcdba1 | ||
|
|
9f36b9daf3 | ||
|
|
bd8672a04a | ||
|
|
f16ef00055 | ||
|
|
8584f982a0 | ||
|
|
d37ac3aa16 | ||
|
|
a8bb6c4daa | ||
|
|
5543c969b2 | ||
|
|
b30aac6f98 | ||
|
|
fd4263065b | ||
|
|
fee833ddb6 | ||
|
|
5b2b3cdacf | ||
|
|
0386fd7c7d | ||
|
|
8d515dc309 | ||
|
|
e6a583e11b | ||
|
|
9431c955a6 | ||
|
|
6303992f4e | ||
|
|
3493a827ee | ||
|
|
790b284a23 | ||
|
|
224a236896 | ||
|
|
0aef39ceee | ||
|
|
b1713b4c80 | ||
|
|
699ebe2f93 | ||
|
|
f5c21814f9 | ||
|
|
ba2797c332 | ||
|
|
0175db58bb | ||
|
|
503341b966 | ||
|
|
e58fab92d1 | ||
|
|
09ab14ac81 | ||
|
|
bca0af82a3 | ||
|
|
9b8f9bd597 | ||
|
|
9b5fa95ae2 | ||
|
|
1e36b6ef22 | ||
|
|
2b212f9701 | ||
|
|
ba4bb5774e | ||
|
|
b71a851a35 | ||
|
|
8bcf9e8640 | ||
|
|
a814f9f902 | ||
|
|
7d92e453ef |
@@ -11,12 +11,6 @@ DEV_SERVER_COMFYUI_URL=http://127.0.0.1:8188
|
|||||||
# and public addresses.
|
# and public addresses.
|
||||||
VITE_REMOTE_DEV=false
|
VITE_REMOTE_DEV=false
|
||||||
|
|
||||||
# The target ComfyUI checkout directory to deploy the frontend code to.
|
|
||||||
# The dist directory will be copied to {DEPLOY_COMFYUI_DIR}/custom_web_versions/main/dev
|
|
||||||
# Add `--front-end-root {DEPLOY_COMFYUI_DIR}/custom_web_versions/main/dev`
|
|
||||||
# to ComfyUI launch script to serve the custom web version.
|
|
||||||
DEPLOY_COMFYUI_DIR=/home/ComfyUI/web
|
|
||||||
|
|
||||||
# The directory containing the ComfyUI installation used to run Playwright tests.
|
# The directory containing the ComfyUI installation used to run Playwright tests.
|
||||||
# If you aren't using a separate install for testing, point this to your regular install.
|
# If you aren't using a separate install for testing, point this to your regular install.
|
||||||
TEST_COMFYUI_DIR=/home/ComfyUI
|
TEST_COMFYUI_DIR=/home/ComfyUI
|
||||||
|
|||||||
2
.github/workflows/i18n-node-defs.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
update-locales:
|
update-locales:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
|
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: npx playwright install chromium --with-deps
|
run: npx playwright install chromium --with-deps
|
||||||
working-directory: ComfyUI_frontend
|
working-directory: ComfyUI_frontend
|
||||||
|
|||||||
6
.github/workflows/i18n.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
|
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: npx playwright install chromium --with-deps
|
run: npx playwright install chromium --with-deps
|
||||||
working-directory: ComfyUI_frontend
|
working-directory: ComfyUI_frontend
|
||||||
@@ -34,7 +34,11 @@ jobs:
|
|||||||
git config --global user.name 'github-actions'
|
git config --global user.name 'github-actions'
|
||||||
git config --global user.email 'github-actions@github.com'
|
git config --global user.email 'github-actions@github.com'
|
||||||
git fetch origin ${{ github.head_ref }}
|
git fetch origin ${{ github.head_ref }}
|
||||||
|
# Stash any local changes before checkout
|
||||||
|
git stash -u
|
||||||
git checkout -B ${{ github.head_ref }} origin/${{ github.head_ref }}
|
git checkout -B ${{ github.head_ref }} origin/${{ github.head_ref }}
|
||||||
|
# Apply the stashed changes if any
|
||||||
|
git stash pop || true
|
||||||
git add src/locales/
|
git add src/locales/
|
||||||
git diff --staged --quiet || git commit -m "Update locales [skip ci]"
|
git diff --staged --quiet || git commit -m "Update locales [skip ci]"
|
||||||
git push origin HEAD:${{ github.head_ref }}
|
git push origin HEAD:${{ github.head_ref }}
|
||||||
|
|||||||
5
.github/workflows/release.yaml
vendored
@@ -27,8 +27,11 @@ jobs:
|
|||||||
- name: Build project
|
- name: Build project
|
||||||
env:
|
env:
|
||||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||||
|
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
|
||||||
|
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
|
npm run fetch-templates
|
||||||
npm run build
|
npm run build
|
||||||
npm run zipdist
|
npm run zipdist
|
||||||
- name: Upload dist artifact
|
- name: Upload dist artifact
|
||||||
@@ -60,7 +63,7 @@ jobs:
|
|||||||
tag_name: v${{ needs.build.outputs.version }}
|
tag_name: v${{ needs.build.outputs.version }}
|
||||||
target_commitish: ${{ github.event.pull_request.base.ref }}
|
target_commitish: ${{ github.event.pull_request.base.ref }}
|
||||||
make_latest: ${{ github.event.pull_request.base.ref == 'main' }}
|
make_latest: ${{ github.event.pull_request.base.ref == 'main' }}
|
||||||
draft: true
|
draft: ${{ github.event.pull_request.base.ref != 'main' }}
|
||||||
prerelease: false
|
prerelease: false
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/test-browser-exp.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.label.name == 'New Browser Test Expectations'
|
if: github.event.label.name == 'New Browser Test Expectations'
|
||||||
steps:
|
steps:
|
||||||
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.2
|
- uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: npx playwright install chromium --with-deps
|
run: npx playwright install chromium --with-deps
|
||||||
working-directory: ComfyUI_frontend
|
working-directory: ComfyUI_frontend
|
||||||
|
|||||||
26
.github/workflows/test-ui.yaml
vendored
@@ -32,16 +32,15 @@ jobs:
|
|||||||
path: 'ComfyUI/custom_nodes/ComfyUI_devtools'
|
path: 'ComfyUI/custom_nodes/ComfyUI_devtools'
|
||||||
ref: '080e6d4af809a46852d1c4b7ed85f06e8a3a72be'
|
ref: '080e6d4af809a46852d1c4b7ed85f06e8a3a72be'
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
|
|
||||||
- name: Build & Install ComfyUI_frontend
|
- name: Build ComfyUI_frontend
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
|
npm run fetch-templates
|
||||||
npm run build
|
npm run build
|
||||||
rm -rf ../ComfyUI/web/*
|
|
||||||
mv dist/* ../ComfyUI/web/
|
|
||||||
working-directory: ComfyUI_frontend
|
working-directory: ComfyUI_frontend
|
||||||
|
|
||||||
- name: Generate cache key
|
- name: Generate cache key
|
||||||
@@ -56,23 +55,6 @@ jobs:
|
|||||||
ComfyUI_frontend
|
ComfyUI_frontend
|
||||||
key: comfyui-setup-${{ steps.cache-key.outputs.key }}
|
key: comfyui-setup-${{ steps.cache-key.outputs.key }}
|
||||||
|
|
||||||
jest-tests:
|
|
||||||
needs: setup
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Restore cached setup
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
ComfyUI
|
|
||||||
ComfyUI_frontend
|
|
||||||
key: comfyui-setup-${{ needs.setup.outputs.cache-key }}
|
|
||||||
|
|
||||||
- name: Run Jest tests
|
|
||||||
run: |
|
|
||||||
npm run test:jest -- --verbose
|
|
||||||
working-directory: ComfyUI_frontend
|
|
||||||
|
|
||||||
playwright-tests:
|
playwright-tests:
|
||||||
needs: setup
|
needs: setup
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -103,7 +85,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Start ComfyUI server
|
- name: Start ComfyUI server
|
||||||
run: |
|
run: |
|
||||||
python main.py --cpu --multi-user &
|
python main.py --cpu --multi-user --front-end-root ../ComfyUI_frontend/dist &
|
||||||
wait-for-it --service 127.0.0.1:8188 -t 600
|
wait-for-it --service 127.0.0.1:8188 -t 600
|
||||||
working-directory: ComfyUI
|
working-directory: ComfyUI
|
||||||
|
|
||||||
|
|||||||
44
.github/workflows/update-electron-types.yaml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Update Electron Types
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-electron-types:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Update electron types
|
||||||
|
run: npm install @comfyorg/comfyui-electron-types@latest
|
||||||
|
|
||||||
|
- name: Get new version
|
||||||
|
id: get-version
|
||||||
|
run: |
|
||||||
|
NEW_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('./package-lock.json')).packages['node_modules/@comfyorg/comfyui-electron-types'].version)")
|
||||||
|
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
commit-message: '[chore] Update electron-types to ${{ steps.get-version.outputs.NEW_VERSION }}'
|
||||||
|
title: '[chore] Update electron-types to ${{ steps.get-version.outputs.NEW_VERSION }}'
|
||||||
|
body: |
|
||||||
|
Automated update of desktop API types to version ${{ steps.get-version.outputs.NEW_VERSION }}.
|
||||||
|
branch: update-electron-types-${{ steps.get-version.outputs.NEW_VERSION }}
|
||||||
|
base: main
|
||||||
|
labels: |
|
||||||
|
dependencies
|
||||||
|
Electron
|
||||||
43
.github/workflows/update-litegraph.yaml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Update Litegraph Dependency
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-litegraph:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
|
||||||
|
- name: Update litegraph
|
||||||
|
run: npm install @comfyorg/litegraph@latest
|
||||||
|
|
||||||
|
- name: Get new version
|
||||||
|
id: get-version
|
||||||
|
run: |
|
||||||
|
NEW_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('./package-lock.json')).packages['node_modules/@comfyorg/litegraph'].version)")
|
||||||
|
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.PR_GH_TOKEN }}
|
||||||
|
commit-message: '[chore] Update litegraph to ${{ steps.get-version.outputs.NEW_VERSION }}'
|
||||||
|
title: '[chore] Update litegraph to ${{ steps.get-version.outputs.NEW_VERSION }}'
|
||||||
|
body: |
|
||||||
|
Automated update of litegraph to version ${{ steps.get-version.outputs.NEW_VERSION }}.
|
||||||
|
Ref: https://github.com/Comfy-Org/litegraph.js/releases/tag/v${{ steps.get-version.outputs.NEW_VERSION }}
|
||||||
|
branch: update-litegraph-${{ steps.get-version.outputs.NEW_VERSION }}
|
||||||
|
base: main
|
||||||
|
labels: |
|
||||||
|
dependencies
|
||||||
97
.github/workflows/update-registry-types.yaml
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
name: Update Comfy Registry API Types
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Manual trigger
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Triggered from comfy-api repo
|
||||||
|
repository_dispatch:
|
||||||
|
types: [comfy-api-updated]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-registry-types:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Checkout comfy-api repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: Comfy-Org/comfy-api
|
||||||
|
path: comfy-api
|
||||||
|
token: ${{ secrets.COMFY_API_PAT }}
|
||||||
|
clean: true
|
||||||
|
|
||||||
|
- name: Get API commit information
|
||||||
|
id: api-info
|
||||||
|
run: |
|
||||||
|
cd comfy-api
|
||||||
|
API_COMMIT=$(git rev-parse --short HEAD)
|
||||||
|
echo "commit=${API_COMMIT}" >> $GITHUB_OUTPUT
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- name: Generate API types
|
||||||
|
run: |
|
||||||
|
echo "Generating TypeScript types from comfy-api@${{ steps.api-info.outputs.commit }}..."
|
||||||
|
npx openapi-typescript ./comfy-api/openapi.yml --output ./src/types/comfyRegistryTypes.ts
|
||||||
|
|
||||||
|
- name: Validate generated types
|
||||||
|
run: |
|
||||||
|
if [ ! -f ./src/types/comfyRegistryTypes.ts ]; then
|
||||||
|
echo "Error: Types file was not generated."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if file is not empty
|
||||||
|
if [ ! -s ./src/types/comfyRegistryTypes.ts ]; then
|
||||||
|
echo "Error: Generated types file is empty."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check-changes
|
||||||
|
run: |
|
||||||
|
if [[ -z $(git status --porcelain ./src/types/comfyRegistryTypes.ts) ]]; then
|
||||||
|
echo "No changes to Comfy Registry API types detected."
|
||||||
|
echo "changed=false" >> $GITHUB_OUTPUT
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Changes detected in Comfy Registry API types."
|
||||||
|
echo "changed=true" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.check-changes.outputs.changed == 'true'
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.PR_GH_TOKEN }}
|
||||||
|
commit-message: '[chore] Update Comfy Registry API types from comfy-api@${{ steps.api-info.outputs.commit }}'
|
||||||
|
title: '[chore] Update Comfy Registry API types from comfy-api@${{ steps.api-info.outputs.commit }}'
|
||||||
|
body: |
|
||||||
|
## Automated API Type Update
|
||||||
|
|
||||||
|
This PR updates the Comfy Registry API types from the latest comfy-api OpenAPI specification.
|
||||||
|
|
||||||
|
- API commit: ${{ steps.api-info.outputs.commit }}
|
||||||
|
- Generated on: ${{ github.event.repository.updated_at }}
|
||||||
|
|
||||||
|
These types are automatically generated using openapi-typescript.
|
||||||
|
branch: update-registry-types-${{ steps.api-info.outputs.commit }}
|
||||||
|
base: main
|
||||||
|
labels: CNR
|
||||||
|
delete-branch: true
|
||||||
|
add-paths: |
|
||||||
|
src/types/comfyRegistryTypes.ts
|
||||||
51
.github/workflows/version-bump.yaml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: Version Bump
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version_type:
|
||||||
|
description: 'Version increment type'
|
||||||
|
required: true
|
||||||
|
default: 'patch'
|
||||||
|
type: 'choice'
|
||||||
|
options:
|
||||||
|
- patch
|
||||||
|
- minor
|
||||||
|
- major
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bump-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Bump version
|
||||||
|
id: bump-version
|
||||||
|
run: |
|
||||||
|
npm version ${{ github.event.inputs.version_type }} --no-git-tag-version
|
||||||
|
NEW_VERSION=$(node -p "require('./package.json').version")
|
||||||
|
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.PR_GH_TOKEN }}
|
||||||
|
commit-message: '[release] Bump version to ${{ steps.bump-version.outputs.NEW_VERSION }}'
|
||||||
|
title: '${{ steps.bump-version.outputs.NEW_VERSION }}'
|
||||||
|
body: |
|
||||||
|
Automated version bump to ${{ steps.bump-version.outputs.NEW_VERSION }}
|
||||||
|
branch: version-bump-${{ steps.bump-version.outputs.NEW_VERSION }}
|
||||||
|
base: main
|
||||||
|
labels: |
|
||||||
|
Release
|
||||||
4
.github/workflows/vitest.yaml
vendored
@@ -22,4 +22,6 @@ jobs:
|
|||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
- name: Run Vitest tests
|
- name: Run Vitest tests
|
||||||
run: npm run test:component
|
run: |
|
||||||
|
npm run test:component
|
||||||
|
npm run test:unit
|
||||||
|
|||||||
7
.gitignore
vendored
@@ -48,3 +48,10 @@ dist.zip
|
|||||||
|
|
||||||
# Generated JSON Schemas
|
# Generated JSON Schemas
|
||||||
/schemas/
|
/schemas/
|
||||||
|
|
||||||
|
# Workflow templates assets
|
||||||
|
# Hosted on https://github.com/Comfy-Org/workflow_templates
|
||||||
|
/public/templates/
|
||||||
|
|
||||||
|
# Temporary repository directory
|
||||||
|
templates_repo/
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ module.exports = defineConfig({
|
|||||||
entryLocale: 'en',
|
entryLocale: 'en',
|
||||||
output: 'src/locales',
|
output: 'src/locales',
|
||||||
outputLocales: ['zh', 'ru', 'ja', 'ko', 'fr'],
|
outputLocales: ['zh', 'ru', 'ja', 'ko', 'fr'],
|
||||||
reference: `Special names to keep untranslated: flux, photomaker, clip, vae, cfg, stable audio, stable cascade.
|
reference: `Special names to keep untranslated: flux, photomaker, clip, vae, cfg, stable audio, stable cascade, controlnet, lora.
|
||||||
'latent' is the short form of 'latent space'.
|
'latent' is the short form of 'latent space'.
|
||||||
'mask' is in the context of image processing.
|
'mask' is in the context of image processing.
|
||||||
`
|
`
|
||||||
|
|||||||
127
README.md
@@ -31,8 +31,22 @@
|
|||||||
|
|
||||||
## Release Schedule
|
## Release Schedule
|
||||||
|
|
||||||
### Nightly Release
|
The project follows a structured release process for each minor version, consisting of three distinct phases:
|
||||||
|
|
||||||
|
1. **Development Phase** - 1 week
|
||||||
|
- Active development of new features
|
||||||
|
- Code changes merged to the development branch
|
||||||
|
|
||||||
|
2. **Feature Freeze** - 1 week
|
||||||
|
- No new features accepted
|
||||||
|
- Only bug fixes are cherry-picked to the release branch
|
||||||
|
- Testing and stabilization of the codebase
|
||||||
|
|
||||||
|
3. **Publication**
|
||||||
|
- Release is published at the end of the freeze period
|
||||||
|
- Version is finalized and made available to all users
|
||||||
|
|
||||||
|
### Nightly Releases
|
||||||
Nightly releases are published daily at [https://github.com/Comfy-Org/ComfyUI_frontend/releases](https://github.com/Comfy-Org/ComfyUI_frontend/releases).
|
Nightly releases are published daily at [https://github.com/Comfy-Org/ComfyUI_frontend/releases](https://github.com/Comfy-Org/ComfyUI_frontend/releases).
|
||||||
|
|
||||||
To use the latest nightly release, add the following command line argument to your ComfyUI launch script:
|
To use the latest nightly release, add the following command line argument to your ComfyUI launch script:
|
||||||
@@ -41,18 +55,17 @@ To use the latest nightly release, add the following command line argument to yo
|
|||||||
--front-end-version Comfy-Org/ComfyUI_frontend@latest
|
--front-end-version Comfy-Org/ComfyUI_frontend@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
#### For Windows Stand-alone Build Users
|
## Overlapping Release Cycles
|
||||||
|
The development of successive minor versions overlaps. For example, while version 1.1 is in feature freeze, development for version 1.2 begins simultaneously.
|
||||||
|
|
||||||
Edit your `run_cpu.bat` or `run_nvidia_gpu.bat` file as follows:
|
### Example Release Cycle
|
||||||
|
|
||||||
```bat
|
| Week | Date Range | Version 1.1 | Version 1.2 | Version 1.3 | Patch Releases |
|
||||||
.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --front-end-version Comfy-Org/ComfyUI_frontend@latest
|
|------|------------|-------------|-------------|-------------|----------------|
|
||||||
pause
|
| 1 | Mar 1-7 | Development | - | - | - |
|
||||||
```
|
| 2 | Mar 8-14 | Feature Freeze | Development | - | 1.1.0 through 1.1.6 (daily) |
|
||||||
|
| 3 | Mar 15-21 | Released | Feature Freeze | Development | 1.1.7 through 1.1.13 (daily)<br>1.2.0 through 1.2.6 (daily) |
|
||||||
### Stable Release
|
| 4 | Mar 22-28 | - | Released | Feature Freeze | 1.2.7 through 1.2.13 (daily)<br>1.3.0 through 1.3.6 (daily) |
|
||||||
|
|
||||||
Stable releases are published bi-weekly in the ComfyUI main repository.
|
|
||||||
|
|
||||||
## Release Summary
|
## Release Summary
|
||||||
|
|
||||||
@@ -504,7 +517,7 @@ The selection toolbox will display the command button when items are selected:
|
|||||||
- [Vue 3](https://vuejs.org/) with [TypeScript](https://www.typescriptlang.org/)
|
- [Vue 3](https://vuejs.org/) with [TypeScript](https://www.typescriptlang.org/)
|
||||||
- [Pinia](https://pinia.vuejs.org/) for state management
|
- [Pinia](https://pinia.vuejs.org/) for state management
|
||||||
- [PrimeVue](https://primevue.org/) with [TailwindCSS](https://tailwindcss.com/) for UI
|
- [PrimeVue](https://primevue.org/) with [TailwindCSS](https://tailwindcss.com/) for UI
|
||||||
- [Litegraph](https://github.com/Comfy-Org/litegraph.js) for node editor
|
- [litegraph.js](https://github.com/Comfy-Org/litegraph.js) for node editor
|
||||||
- [zod](https://zod.dev/) for schema validation
|
- [zod](https://zod.dev/) for schema validation
|
||||||
- [vue-i18n](https://github.com/intlify/vue-i18n) for internationalization
|
- [vue-i18n](https://github.com/intlify/vue-i18n) for internationalization
|
||||||
|
|
||||||
@@ -547,7 +560,7 @@ navigate to `http://<server_ip>:5173` (e.g. `http://192.168.2.20:5173` here), to
|
|||||||
### Unit Test
|
### Unit Test
|
||||||
|
|
||||||
- `npm i` to install all dependencies
|
- `npm i` to install all dependencies
|
||||||
- `npm run test:jest` to execute all unit tests.
|
- `npm run test:unit` to execute all unit tests.
|
||||||
|
|
||||||
### Component Test
|
### Component Test
|
||||||
|
|
||||||
@@ -559,97 +572,17 @@ Component test verifies Vue components in `src/components/`.
|
|||||||
|
|
||||||
Playwright test verifies the whole app. See <https://github.com/Comfy-Org/ComfyUI_frontend/blob/main/browser_tests/README.md> for details.
|
Playwright test verifies the whole app. See <https://github.com/Comfy-Org/ComfyUI_frontend/blob/main/browser_tests/README.md> for details.
|
||||||
|
|
||||||
### LiteGraph
|
### litegraph.js
|
||||||
|
|
||||||
This repo is using litegraph package hosted on <https://github.com/Comfy-Org/litegraph.js>. Any changes to litegraph should be submitted in that repo instead.
|
This repo is using litegraph package hosted on <https://github.com/Comfy-Org/litegraph.js>. Any changes to litegraph should be submitted in that repo instead.
|
||||||
|
|
||||||
### Test litegraph changes
|
#### Test litegraph.js changes
|
||||||
|
|
||||||
- Run `npm link` in the local litegraph repo.
|
- Run `npm link` in the local litegraph repo.
|
||||||
- Run `npm link @comfyorg/litegraph` in this repo.
|
- Run `npm link @comfyorg/litegraph` in this repo.
|
||||||
|
|
||||||
This will replace the litegraph package in this repo with the local litegraph repo.
|
This will replace the litegraph package in this repo with the local litegraph repo.
|
||||||
|
|
||||||
## Internationalization (i18n)
|
### i18n
|
||||||
|
|
||||||
Our project supports multiple languages using `vue-i18n`. This allows users around the world to use the application in their preferred language.
|
See [locales/README.md](src/locales/README.md) for details.
|
||||||
|
|
||||||
### Supported Languages
|
|
||||||
|
|
||||||
- en (English)
|
|
||||||
- zh (中文)
|
|
||||||
- ru (Русский)
|
|
||||||
- ja (日本語)
|
|
||||||
- ko (한국어)
|
|
||||||
- fr (Français)
|
|
||||||
|
|
||||||
### How to Add a New Language
|
|
||||||
|
|
||||||
We welcome the addition of new languages. You can add a new language by following these steps:
|
|
||||||
|
|
||||||
#### 1. Generate language files
|
|
||||||
We use [lobe-i18n](https://github.com/lobehub/lobe-cli-toolbox/blob/master/packages/lobe-i18n/README.md) as our translation tool, which integrates with LLM for efficient localization.
|
|
||||||
|
|
||||||
Update the configuration file to include the new language(s) you wish to add:
|
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const { defineConfig } = require('@lobehub/i18n-cli');
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
|
||||||
entry: 'src/locales/en.json', // Base language file
|
|
||||||
entryLocale: 'en',
|
|
||||||
output: 'src/locales',
|
|
||||||
outputLocales: ['zh', 'ru', 'ja'], // Add the new language(s) here
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Set your OpenAI API Key by running the following command:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npx lobe-i18n --option
|
|
||||||
```
|
|
||||||
|
|
||||||
Once configured, generate the translation files with:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npx lobe-i18n locale
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create the language files for the specified languages in the configuration.
|
|
||||||
|
|
||||||
#### 2. Update i18n Configuration
|
|
||||||
|
|
||||||
Import the newly generated locale file(s) in the `src/i18n.ts` file to include them in the application's i18n setup.
|
|
||||||
|
|
||||||
#### 3. Enable Selection of the New Language
|
|
||||||
|
|
||||||
Add the newly added language to the following item in `src/constants/coreSettings.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
{
|
|
||||||
id: 'Comfy.Locale',
|
|
||||||
name: 'Locale',
|
|
||||||
type: 'combo',
|
|
||||||
// Add the new language(s) here
|
|
||||||
options: [
|
|
||||||
{ value: 'en', text: 'English' },
|
|
||||||
{ value: 'zh', text: '中文' },
|
|
||||||
{ value: 'ru', text: 'Русский' },
|
|
||||||
{ value: 'ja', text: '日本語' }
|
|
||||||
],
|
|
||||||
defaultValue: navigator.language.split('-')[0] || 'en'
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
This will make the new language selectable in the application's settings.
|
|
||||||
|
|
||||||
#### 4. Test the Translations
|
|
||||||
|
|
||||||
Start the development server, switch to the new language, and verify the translations.
|
|
||||||
You can switch languages by opening the ComfyUI Settings and selecting from the `ComfyUI > Locale` dropdown box.
|
|
||||||
|
|
||||||
## Deploy
|
|
||||||
|
|
||||||
- Option 1: Set `DEPLOY_COMFYUI_DIR` in `.env` and run `npm run deploy`.
|
|
||||||
- Option 2: Copy everything under `dist/` to `ComfyUI/web/` in your ComfyUI checkout manually.
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
"@babel/preset-env"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"babel-plugin-transform-import-meta"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
55
browser_tests/assets/note_nodes.json
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 2,
|
||||||
|
"last_link_id": 0,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "Note",
|
||||||
|
"pos": [
|
||||||
|
50, 50
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
322.3645935058594,
|
||||||
|
167.91612243652344
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"properties": {},
|
||||||
|
"widgets_values": [
|
||||||
|
"Foo\n123"
|
||||||
|
],
|
||||||
|
"color": "#432",
|
||||||
|
"bgcolor": "#653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"type": "MarkdownNote",
|
||||||
|
"pos": [
|
||||||
|
50, 300
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
320.9985656738281,
|
||||||
|
179.52735900878906
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 1,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"properties": {},
|
||||||
|
"widgets_values": [
|
||||||
|
"# Bar\n123"
|
||||||
|
],
|
||||||
|
"color": "#432",
|
||||||
|
"bgcolor": "#653"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 3,
|
||||||
|
"last_link_id": 1,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "PrimitiveNode",
|
||||||
|
"pos": [14, 43],
|
||||||
|
"size": [203.1999969482422, 40.36840057373047],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "connect to widget input",
|
||||||
|
"type": "*",
|
||||||
|
"links": [],
|
||||||
|
"slot_index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Run widget replace on values": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"type": "CLIPTextEncode",
|
||||||
|
"pos": [306.2463684082031, 45.30042266845703],
|
||||||
|
"size": [400, 200],
|
||||||
|
"flags": {},
|
||||||
|
"order": 1,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "clip",
|
||||||
|
"type": "CLIP",
|
||||||
|
"link": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "CONDITIONING",
|
||||||
|
"type": "CONDITIONING",
|
||||||
|
"links": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "CLIPTextEncode"
|
||||||
|
},
|
||||||
|
"widgets_values": [""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
101
browser_tests/assets/renamed_converted_widget.json
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 4,
|
||||||
|
"last_link_id": 2,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"type": "EmptyLatentImage",
|
||||||
|
"pos": [
|
||||||
|
380.51641845703125,
|
||||||
|
191.39659118652344
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
315,
|
||||||
|
106
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 1,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "breadth",
|
||||||
|
"type": "INT",
|
||||||
|
"widget": {
|
||||||
|
"name": "breadth"
|
||||||
|
},
|
||||||
|
"link": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "LATENT",
|
||||||
|
"type": "LATENT",
|
||||||
|
"links": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "EmptyLatentImage"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
512,
|
||||||
|
512,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"type": "PrimitiveNode",
|
||||||
|
"pos": [
|
||||||
|
73.6164321899414,
|
||||||
|
197.9966278076172
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
210,
|
||||||
|
82
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "INT",
|
||||||
|
"type": "INT",
|
||||||
|
"widget": {
|
||||||
|
"name": "bredth"
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
2
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "breadth",
|
||||||
|
"properties": {
|
||||||
|
"Run widget replace on values": false
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
512,
|
||||||
|
"fixed"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
0,
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
"INT"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {
|
||||||
|
"VHS_latentpreview": true,
|
||||||
|
"VHS_latentpreviewrate": 0,
|
||||||
|
"VHS_MetadataImage": false,
|
||||||
|
"VHS_KeepIntermediate": false
|
||||||
|
},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
110
browser_tests/assets/reroute/native_reroute.json
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 25,
|
||||||
|
"last_link_id": 33,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"type": "CheckpointLoaderSimple",
|
||||||
|
"pos": [160, 240],
|
||||||
|
"size": [315, 98],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "MODEL",
|
||||||
|
"type": "MODEL",
|
||||||
|
"slot_index": 0,
|
||||||
|
"links": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CLIP",
|
||||||
|
"type": "CLIP",
|
||||||
|
"slot_index": 1,
|
||||||
|
"links": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "VAE",
|
||||||
|
"type": "VAE",
|
||||||
|
"slot_index": 2,
|
||||||
|
"links": [33]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "CheckpointLoaderSimple"
|
||||||
|
},
|
||||||
|
"widgets_values": ["v1-5-pruned-emaonly.safetensors"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 19,
|
||||||
|
"type": "VAEDecode",
|
||||||
|
"pos": [623.0897216796875, 324.64453125],
|
||||||
|
"size": [210, 46],
|
||||||
|
"flags": {},
|
||||||
|
"order": 1,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "samples",
|
||||||
|
"type": "LATENT",
|
||||||
|
"link": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vae",
|
||||||
|
"type": "VAE",
|
||||||
|
"link": 33
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "IMAGE",
|
||||||
|
"type": "IMAGE",
|
||||||
|
"links": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "VAEDecode"
|
||||||
|
},
|
||||||
|
"widgets_values": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [[33, 4, 2, 19, 1, "VAE"]],
|
||||||
|
"floatingLinks": [
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"origin_id": 4,
|
||||||
|
"origin_slot": 2,
|
||||||
|
"target_id": -1,
|
||||||
|
"target_slot": -1,
|
||||||
|
"type": "VAE",
|
||||||
|
"parentId": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {
|
||||||
|
"reroutes": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"pos": [545.4541015625, 295.85760498046875],
|
||||||
|
"linkIds": [],
|
||||||
|
"floating": {
|
||||||
|
"slotType": "output"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"pos": [543.8283081054688, 355.45849609375],
|
||||||
|
"linkIds": [33]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"linkExtensions": [
|
||||||
|
{
|
||||||
|
"id": 33,
|
||||||
|
"parentId": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
32
browser_tests/assets/widgets/load_audio_widget.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 1,
|
||||||
|
"last_link_id": 0,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "LoadAudio",
|
||||||
|
"pos": [41.5296516418457, 16.930862426757812],
|
||||||
|
"size": [315, 82],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "AUDIO",
|
||||||
|
"type": "AUDIO",
|
||||||
|
"links": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "LoadAudio"
|
||||||
|
},
|
||||||
|
"widgets_values": [null, ""]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
46
browser_tests/assets/widgets/load_image_widget.json
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"last_node_id": 10,
|
||||||
|
"last_link_id": 10,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"type": "LoadImage",
|
||||||
|
"pos": [
|
||||||
|
50,
|
||||||
|
50
|
||||||
|
],
|
||||||
|
"size": [
|
||||||
|
315,
|
||||||
|
314
|
||||||
|
],
|
||||||
|
"flags": {},
|
||||||
|
"order": 0,
|
||||||
|
"mode": 0,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "IMAGE",
|
||||||
|
"type": "IMAGE",
|
||||||
|
"links": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MASK",
|
||||||
|
"type": "MASK",
|
||||||
|
"links": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Node name for S&R": "LoadImage"
|
||||||
|
},
|
||||||
|
"widgets_values": [
|
||||||
|
"example.png",
|
||||||
|
"image"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [],
|
||||||
|
"groups": [],
|
||||||
|
"config": {},
|
||||||
|
"extra": {},
|
||||||
|
"version": 0.4
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 105 KiB |
@@ -133,14 +133,6 @@ test.describe('Missing models warning', () => {
|
|||||||
await expect(missingModelsWarning).not.toBeVisible()
|
await expect(missingModelsWarning).not.toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should show on tutorial workflow', async ({ comfyPage }) => {
|
|
||||||
await comfyPage.setSetting('Comfy.TutorialCompleted', false)
|
|
||||||
await comfyPage.setup({ clearStorage: true })
|
|
||||||
const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models')
|
|
||||||
await expect(missingModelsWarning).toBeVisible()
|
|
||||||
expect(await comfyPage.getSetting('Comfy.TutorialCompleted')).toBe(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Flaky test after parallelization
|
// Flaky test after parallelization
|
||||||
// https://github.com/Comfy-Org/ComfyUI_frontend/pull/1400
|
// https://github.com/Comfy-Org/ComfyUI_frontend/pull/1400
|
||||||
test.skip('Should download missing model when clicking download button', async ({
|
test.skip('Should download missing model when clicking download button', async ({
|
||||||
|
|||||||
97
browser_tests/fixtures/ComfyMouse.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import type { Mouse } from '@playwright/test'
|
||||||
|
|
||||||
|
import type { ComfyPage } from './ComfyPage'
|
||||||
|
import type { Position } from './types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for drag and drop ops
|
||||||
|
* @see
|
||||||
|
* - {@link Mouse.down}
|
||||||
|
* - {@link Mouse.move}
|
||||||
|
* - {@link Mouse.up}
|
||||||
|
*/
|
||||||
|
export interface DragOptions {
|
||||||
|
button?: 'left' | 'right' | 'middle'
|
||||||
|
clickCount?: number
|
||||||
|
steps?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps mouse drag and drop to work with a canvas-based app.
|
||||||
|
*
|
||||||
|
* Requires the next frame animated before and after all steps, giving the
|
||||||
|
* canvas time to render the changes before screenshots are taken.
|
||||||
|
*/
|
||||||
|
export class ComfyMouse implements Omit<Mouse, 'move'> {
|
||||||
|
static defaultSteps = 5
|
||||||
|
static defaultOptions: DragOptions = { steps: ComfyMouse.defaultSteps }
|
||||||
|
|
||||||
|
constructor(readonly comfyPage: ComfyPage) {}
|
||||||
|
|
||||||
|
/** The normal Playwright {@link Mouse} property from {@link ComfyPage.page}. */
|
||||||
|
get mouse() {
|
||||||
|
return this.comfyPage.page.mouse
|
||||||
|
}
|
||||||
|
|
||||||
|
async nextFrame() {
|
||||||
|
await this.comfyPage.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Drags from current location to a new location and hovers there (no pointerup event) */
|
||||||
|
async drag(to: Position, options = ComfyMouse.defaultOptions) {
|
||||||
|
const { steps, ...downOptions } = options
|
||||||
|
|
||||||
|
await this.mouse.down(downOptions)
|
||||||
|
await this.nextFrame()
|
||||||
|
|
||||||
|
await this.move(to, { steps })
|
||||||
|
await this.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
async drop(options = ComfyMouse.defaultOptions) {
|
||||||
|
await this.mouse.up(options)
|
||||||
|
await this.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
async dragAndDrop(
|
||||||
|
from: Position,
|
||||||
|
to: Position,
|
||||||
|
options = ComfyMouse.defaultOptions
|
||||||
|
) {
|
||||||
|
const { steps } = options
|
||||||
|
|
||||||
|
await this.nextFrame()
|
||||||
|
|
||||||
|
await this.move(from, { steps })
|
||||||
|
await this.drag(to, options)
|
||||||
|
await this.drop(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see {@link Mouse.move} */
|
||||||
|
async move(to: Position, options = ComfyMouse.defaultOptions) {
|
||||||
|
await this.mouse.move(to.x, to.y, options)
|
||||||
|
await this.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region Pass-through
|
||||||
|
async click(...args: Parameters<Mouse['click']>) {
|
||||||
|
return await this.mouse.click(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
async dblclick(...args: Parameters<Mouse['dblclick']>) {
|
||||||
|
return await this.mouse.dblclick(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(...args: Parameters<Mouse['down']>) {
|
||||||
|
return await this.mouse.down(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
async up(...args: Parameters<Mouse['up']>) {
|
||||||
|
return await this.mouse.up(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
async wheel(...args: Parameters<Mouse['wheel']>) {
|
||||||
|
return await this.mouse.wheel(...args)
|
||||||
|
}
|
||||||
|
//#endregion Pass-through
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import type { useWorkspaceStore } from '../../src/stores/workspaceStore'
|
|||||||
import { NodeBadgeMode } from '../../src/types/nodeSource'
|
import { NodeBadgeMode } from '../../src/types/nodeSource'
|
||||||
import { ComfyActionbar } from '../helpers/actionbar'
|
import { ComfyActionbar } from '../helpers/actionbar'
|
||||||
import { ComfyTemplates } from '../helpers/templates'
|
import { ComfyTemplates } from '../helpers/templates'
|
||||||
|
import { ComfyMouse } from './ComfyMouse'
|
||||||
import { ComfyNodeSearchBox } from './components/ComfyNodeSearchBox'
|
import { ComfyNodeSearchBox } from './components/ComfyNodeSearchBox'
|
||||||
import { SettingDialog } from './components/SettingDialog'
|
import { SettingDialog } from './components/SettingDialog'
|
||||||
import {
|
import {
|
||||||
@@ -910,7 +911,10 @@ export class ComfyPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const comfyPageFixture = base.extend<{ comfyPage: ComfyPage }>({
|
export const comfyPageFixture = base.extend<{
|
||||||
|
comfyPage: ComfyPage
|
||||||
|
comfyMouse: ComfyMouse
|
||||||
|
}>({
|
||||||
comfyPage: async ({ page, request }, use, testInfo) => {
|
comfyPage: async ({ page, request }, use, testInfo) => {
|
||||||
const comfyPage = new ComfyPage(page, request)
|
const comfyPage = new ComfyPage(page, request)
|
||||||
|
|
||||||
@@ -941,6 +945,10 @@ export const comfyPageFixture = base.extend<{ comfyPage: ComfyPage }>({
|
|||||||
|
|
||||||
await comfyPage.setup()
|
await comfyPage.setup()
|
||||||
await use(comfyPage)
|
await use(comfyPage)
|
||||||
|
},
|
||||||
|
comfyMouse: async ({ comfyPage }, use) => {
|
||||||
|
const comfyMouse = new ComfyMouse(comfyPage)
|
||||||
|
use(comfyMouse)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -95,18 +95,6 @@ export class WorkflowsSidebarTab extends SidebarTab {
|
|||||||
return this.page.locator('.workflows-sidebar-tab')
|
return this.page.locator('.workflows-sidebar-tab')
|
||||||
}
|
}
|
||||||
|
|
||||||
get browseGalleryButton() {
|
|
||||||
return this.root.locator('.browse-templates-button')
|
|
||||||
}
|
|
||||||
|
|
||||||
get newBlankWorkflowButton() {
|
|
||||||
return this.root.locator('.new-blank-workflow-button')
|
|
||||||
}
|
|
||||||
|
|
||||||
get openWorkflowButton() {
|
|
||||||
return this.root.locator('.open-workflow-button')
|
|
||||||
}
|
|
||||||
|
|
||||||
async getOpenedWorkflowNames() {
|
async getOpenedWorkflowNames() {
|
||||||
return await this.root
|
return await this.root
|
||||||
.locator('.comfyui-workflows-open .node-label')
|
.locator('.comfyui-workflows-open .node-label')
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import type { Page } from '@playwright/test'
|
import type { Page } from '@playwright/test'
|
||||||
|
|
||||||
import type { NodeId } from '../../../src/types/comfyWorkflow'
|
import type { NodeId } from '../../../src/schemas/comfyWorkflowSchema'
|
||||||
import { ManageGroupNode } from '../../helpers/manageGroupNode'
|
import { ManageGroupNode } from '../../helpers/manageGroupNode'
|
||||||
import type { ComfyPage } from '../ComfyPage'
|
import type { ComfyPage } from '../ComfyPage'
|
||||||
import type { Position, Size } from '../types'
|
import type { Position, Size } from '../types'
|
||||||
|
|
||||||
|
export const getMiddlePoint = (pos1: Position, pos2: Position) => {
|
||||||
|
return {
|
||||||
|
x: (pos1.x + pos2.x) / 2,
|
||||||
|
y: (pos1.y + pos2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class NodeSlotReference {
|
export class NodeSlotReference {
|
||||||
constructor(
|
constructor(
|
||||||
readonly type: 'input' | 'output',
|
readonly type: 'input' | 'output',
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 80 KiB |
@@ -1,8 +1,10 @@
|
|||||||
import { Locator, Page } from '@playwright/test'
|
import { Locator, Page } from '@playwright/test'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
import { CORE_TEMPLATES } from '../../src/constants/coreTemplates'
|
import {
|
||||||
import { TemplateInfo } from '../../src/types/workflowTemplateTypes'
|
TemplateInfo,
|
||||||
|
WorkflowTemplates
|
||||||
|
} from '../../src/types/workflowTemplateTypes'
|
||||||
|
|
||||||
export class ComfyTemplates {
|
export class ComfyTemplates {
|
||||||
readonly content: Locator
|
readonly content: Locator
|
||||||
@@ -18,8 +20,11 @@ export class ComfyTemplates {
|
|||||||
.click()
|
.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllTemplates(): TemplateInfo[] {
|
async getAllTemplates(): Promise<TemplateInfo[]> {
|
||||||
return CORE_TEMPLATES.flatMap((category) => category.templates)
|
const templates: WorkflowTemplates[] = await this.page.evaluate(() =>
|
||||||
|
window['app'].api.getCoreWorkflowTemplates()
|
||||||
|
)
|
||||||
|
return templates.flatMap((t) => t.templates)
|
||||||
}
|
}
|
||||||
|
|
||||||
getTemplatePath(filename: string): string {
|
getTemplatePath(filename: string): string {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ test.describe('Node Interaction', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Can highlight selected', async ({ comfyPage }) => {
|
test('@2x Can highlight selected', async ({ comfyPage }) => {
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('default.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('default.png')
|
||||||
await comfyPage.clickTextEncodeNode1()
|
await comfyPage.clickTextEncodeNode1()
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('selected-node1.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('selected-node1.png')
|
||||||
@@ -103,9 +103,7 @@ test.describe('Node Interaction', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Chromium 2x cannot move link.
|
test('Can move link', async ({ comfyPage }) => {
|
||||||
// See https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/10876381315/job/30176211513
|
|
||||||
test.skip('Can move link', async ({ comfyPage }) => {
|
|
||||||
await comfyPage.dragAndDrop(
|
await comfyPage.dragAndDrop(
|
||||||
comfyPage.clipTextEncodeNode1InputSlot,
|
comfyPage.clipTextEncodeNode1InputSlot,
|
||||||
comfyPage.emptySpace
|
comfyPage.emptySpace
|
||||||
@@ -118,10 +116,7 @@ test.describe('Node Interaction', () => {
|
|||||||
await expect(comfyPage.canvas).toHaveScreenshot('moved-link.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('moved-link.png')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Copy link is not working on CI at all
|
// Shift drag copy link regressed. See https://github.com/Comfy-Org/ComfyUI_frontend/issues/2941
|
||||||
// Chromium 2x recognize it as dragging canvas.
|
|
||||||
// Chromium triggers search box after link release. The link is indeed copied.
|
|
||||||
// See https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/10876381315/job/30176211513
|
|
||||||
test.skip('Can copy link by shift-drag existing link', async ({
|
test.skip('Can copy link by shift-drag existing link', async ({
|
||||||
comfyPage
|
comfyPage
|
||||||
}) => {
|
}) => {
|
||||||
@@ -140,20 +135,14 @@ test.describe('Node Interaction', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('Auto snap&highlight when dragging link over node', async ({
|
test('Auto snap&highlight when dragging link over node', async ({
|
||||||
comfyPage
|
comfyPage,
|
||||||
|
comfyMouse
|
||||||
}) => {
|
}) => {
|
||||||
await comfyPage.setSetting('Comfy.Node.AutoSnapLinkToSlot', true)
|
await comfyPage.setSetting('Comfy.Node.AutoSnapLinkToSlot', true)
|
||||||
await comfyPage.setSetting('Comfy.Node.SnapHighlightsNode', true)
|
await comfyPage.setSetting('Comfy.Node.SnapHighlightsNode', true)
|
||||||
|
|
||||||
await comfyPage.page.mouse.move(
|
await comfyMouse.move(comfyPage.clipTextEncodeNode1InputSlot)
|
||||||
comfyPage.clipTextEncodeNode1InputSlot.x,
|
await comfyMouse.drag(comfyPage.clipTextEncodeNode2InputSlot)
|
||||||
comfyPage.clipTextEncodeNode1InputSlot.y
|
|
||||||
)
|
|
||||||
await comfyPage.page.mouse.down()
|
|
||||||
await comfyPage.page.mouse.move(
|
|
||||||
comfyPage.clipTextEncodeNode2InputSlot.x,
|
|
||||||
comfyPage.clipTextEncodeNode2InputSlot.y
|
|
||||||
)
|
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('snapped-highlighted.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('snapped-highlighted.png')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -330,16 +319,12 @@ test.describe('Node Interaction', () => {
|
|||||||
await expect(comfyPage.canvas).toHaveScreenshot('group-fit-to-contents.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('group-fit-to-contents.png')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Somehow this test fails on GitHub Actions. It works locally.
|
test('Can pin/unpin nodes', async ({ comfyPage }) => {
|
||||||
// https://github.com/Comfy-Org/ComfyUI_frontend/pull/736
|
|
||||||
test.skip('Can pin/unpin nodes with keyboard shortcut', async ({
|
|
||||||
comfyPage
|
|
||||||
}) => {
|
|
||||||
await comfyPage.select2Nodes()
|
await comfyPage.select2Nodes()
|
||||||
await comfyPage.canvas.press('KeyP')
|
await comfyPage.executeCommand('Comfy.Canvas.ToggleSelectedNodes.Pin')
|
||||||
await comfyPage.nextFrame()
|
await comfyPage.nextFrame()
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('nodes-pinned.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('nodes-pinned.png')
|
||||||
await comfyPage.canvas.press('KeyP')
|
await comfyPage.executeCommand('Comfy.Canvas.ToggleSelectedNodes.Pin')
|
||||||
await comfyPage.nextFrame()
|
await comfyPage.nextFrame()
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('nodes-unpinned.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('nodes-unpinned.png')
|
||||||
})
|
})
|
||||||
@@ -506,24 +491,24 @@ test.describe('Canvas Interaction', () => {
|
|||||||
expect(await getCursorStyle()).toBe('default')
|
expect(await getCursorStyle()).toBe('default')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Can pan when dragging a link', async ({ comfyPage }) => {
|
test('Can pan when dragging a link', async ({ comfyPage, comfyMouse }) => {
|
||||||
const posSlot1 = comfyPage.clipTextEncodeNode1InputSlot
|
const posSlot1 = comfyPage.clipTextEncodeNode1InputSlot
|
||||||
await comfyPage.page.mouse.move(posSlot1.x, posSlot1.y)
|
await comfyMouse.move(posSlot1)
|
||||||
await comfyPage.page.mouse.down()
|
|
||||||
const posEmpty = comfyPage.emptySpace
|
const posEmpty = comfyPage.emptySpace
|
||||||
await comfyPage.page.mouse.move(posEmpty.x, posEmpty.y)
|
await comfyMouse.drag(posEmpty)
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('dragging-link1.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('dragging-link1.png')
|
||||||
|
|
||||||
await comfyPage.page.keyboard.down('Space')
|
await comfyPage.page.keyboard.down('Space')
|
||||||
await comfyPage.page.mouse.move(posEmpty.x + 100, posEmpty.y + 100)
|
await comfyMouse.mouse.move(posEmpty.x + 100, posEmpty.y + 100)
|
||||||
// Canvas should be panned.
|
// Canvas should be panned.
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||||
'panning-when-dragging-link.png'
|
'panning-when-dragging-link.png'
|
||||||
)
|
)
|
||||||
await comfyPage.page.keyboard.up('Space')
|
await comfyPage.page.keyboard.up('Space')
|
||||||
await comfyPage.page.mouse.move(posEmpty.x, posEmpty.y)
|
await comfyMouse.move(posEmpty)
|
||||||
// Should be back to dragging link mode when space is released.
|
// Should be back to dragging link mode when space is released.
|
||||||
await expect(comfyPage.canvas).toHaveScreenshot('dragging-link2.png')
|
await expect(comfyPage.canvas).toHaveScreenshot('dragging-link2.png')
|
||||||
await comfyPage.page.mouse.up()
|
await comfyMouse.drop()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Can pan very far and back', async ({ comfyPage }) => {
|
test('Can pan very far and back', async ({ comfyPage }) => {
|
||||||
@@ -688,7 +673,7 @@ test.describe('Load duplicate workflow', () => {
|
|||||||
}) => {
|
}) => {
|
||||||
await comfyPage.loadWorkflow('single_ksampler')
|
await comfyPage.loadWorkflow('single_ksampler')
|
||||||
await comfyPage.menu.workflowsTab.open()
|
await comfyPage.menu.workflowsTab.open()
|
||||||
await comfyPage.menu.workflowsTab.newBlankWorkflowButton.click()
|
await comfyPage.executeCommand('Comfy.NewBlankWorkflow')
|
||||||
await comfyPage.loadWorkflow('single_ksampler')
|
await comfyPage.loadWorkflow('single_ksampler')
|
||||||
expect(await comfyPage.getGraphNodesCount()).toBe(1)
|
expect(await comfyPage.getGraphNodesCount()).toBe(1)
|
||||||
})
|
})
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 35 KiB |