diff --git a/.github/workflows/pr-playwright-deploy.yaml b/.github/workflows/pr-playwright-deploy.yaml
index 12051fa99..19bb28253 100644
--- a/.github/workflows/pr-playwright-deploy.yaml
+++ b/.github/workflows/pr-playwright-deploy.yaml
@@ -1,4 +1,4 @@
-name: PR Playwright Deploy and Comment
+name: PR Playwright Deploy (Forks)
on:
workflow_run:
@@ -9,272 +9,84 @@ env:
DATE_FORMAT: '+%m/%d/%Y, %I:%M:%S %p'
jobs:
- deploy-reports:
+ deploy-and-comment-forked-pr:
runs-on: ubuntu-latest
- if: github.repository == 'Comfy-Org/ComfyUI_frontend' && github.event.workflow_run.event == 'pull_request' && github.event.action == 'completed'
+ if: |
+ github.repository == 'Comfy-Org/ComfyUI_frontend' &&
+ github.event.workflow_run.event == 'pull_request' &&
+ github.event.workflow_run.head_repository != null &&
+ github.event.workflow_run.repository != null &&
+ github.event.workflow_run.head_repository.full_name != github.event.workflow_run.repository.full_name
permissions:
+ pull-requests: write
actions: read
- strategy:
- fail-fast: false
- matrix:
- browser: [chromium, chromium-2x, chromium-0.5x, mobile-chrome]
steps:
- - name: Get PR info
- id: pr-info
+ - name: Log workflow trigger info
+ run: |
+ echo "Repository: ${{ github.repository }}"
+ echo "Event: ${{ github.event.workflow_run.event }}"
+ echo "Head repo: ${{ github.event.workflow_run.head_repository.full_name || 'null' }}"
+ echo "Base repo: ${{ github.event.workflow_run.repository.full_name || 'null' }}"
+ echo "Is forked: ${{ github.event.workflow_run.head_repository.full_name != github.event.workflow_run.repository.full_name }}"
+
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Get PR Number
+ id: pr
uses: actions/github-script@v7
with:
script: |
- const { data: pullRequests } = await github.rest.pulls.list({
+ const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
- head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`,
});
- if (pullRequests.length === 0) {
- console.log('No open PR found for this branch');
- return { number: null, sanitized_branch: null };
+ const pr = prs.find(p => p.head.sha === context.payload.workflow_run.head_sha);
+
+ if (!pr) {
+ console.log('No PR found for SHA:', context.payload.workflow_run.head_sha);
+ return null;
}
- const pr = pullRequests[0];
- const branchName = context.payload.workflow_run.head_branch;
- const sanitizedBranch = branchName.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/^-|-$/g, '');
-
- return {
- number: pr.number,
- sanitized_branch: sanitizedBranch
- };
+ console.log(`Found PR #${pr.number} from fork: ${context.payload.workflow_run.head_repository.full_name}`);
+ return pr.number;
- - name: Set project name
- if: fromJSON(steps.pr-info.outputs.result).number != null
- id: project-name
+ - name: Handle Test Start
+ if: steps.pr.outputs.result != 'null' && github.event.action == 'requested'
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
run: |
- if [ "${{ matrix.browser }}" = "chromium-0.5x" ]; then
- echo "name=comfyui-playwright-chromium-0-5x" >> $GITHUB_OUTPUT
- else
- echo "name=comfyui-playwright-${{ matrix.browser }}" >> $GITHUB_OUTPUT
- fi
- echo "branch=${{ fromJSON(steps.pr-info.outputs.result).sanitized_branch }}" >> $GITHUB_OUTPUT
+ chmod +x scripts/cicd/pr-playwright-deploy-and-comment.sh
+ ./scripts/cicd/pr-playwright-deploy-and-comment.sh \
+ "${{ steps.pr.outputs.result }}" \
+ "${{ github.event.workflow_run.head_branch }}" \
+ "starting" \
+ "$(date -u '${{ env.DATE_FORMAT }}')"
- - name: Download playwright report
- if: fromJSON(steps.pr-info.outputs.result).number != null
+ - name: Download and Deploy Reports
+ if: steps.pr.outputs.result != 'null' && github.event.action == 'completed'
uses: actions/download-artifact@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- name: playwright-report-${{ matrix.browser }}
- path: playwright-report
-
- - name: Install Wrangler
- if: fromJSON(steps.pr-info.outputs.result).number != null
- run: npm install -g wrangler
-
- - name: Deploy to Cloudflare Pages (${{ matrix.browser }})
- if: fromJSON(steps.pr-info.outputs.result).number != null
- id: cloudflare-deploy
- continue-on-error: true
- run: |
- # Retry logic for wrangler deploy (3 attempts)
- RETRY_COUNT=0
- MAX_RETRIES=3
- SUCCESS=false
+ pattern: playwright-report-*
+ path: reports
- while [ $RETRY_COUNT -lt $MAX_RETRIES ] && [ $SUCCESS = false ]; do
- RETRY_COUNT=$((RETRY_COUNT + 1))
- echo "Deployment attempt $RETRY_COUNT of $MAX_RETRIES..."
-
- if npx wrangler pages deploy playwright-report --project-name=${{ steps.project-name.outputs.name }} --branch=${{ steps.project-name.outputs.branch }}; then
- SUCCESS=true
- echo "Deployment successful on attempt $RETRY_COUNT"
- else
- echo "Deployment failed on attempt $RETRY_COUNT"
- if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
- echo "Retrying in 10 seconds..."
- sleep 10
- fi
- fi
- done
-
- if [ $SUCCESS = false ]; then
- echo "All deployment attempts failed"
- exit 1
- fi
+ - name: Handle Test Completion
+ if: steps.pr.outputs.result != 'null' && github.event.action == 'completed'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
-
- comment-tests-starting:
- runs-on: ubuntu-latest
- if: github.repository == 'Comfy-Org/ComfyUI_frontend' && github.event.workflow_run.event == 'pull_request' && github.event.action == 'requested'
- permissions:
- pull-requests: write
- actions: read
- steps:
- - name: Get PR number
- id: pr
- uses: actions/github-script@v7
- with:
- script: |
- const { data: pullRequests } = await github.rest.pulls.list({
- owner: context.repo.owner,
- repo: context.repo.repo,
- state: 'open',
- head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`,
- });
-
- if (pullRequests.length === 0) {
- console.log('No open PR found for this branch');
- return null;
- }
-
- return pullRequests[0].number;
-
- - name: Get completion time
- id: completion-time
- run: echo "time=$(date -u '${{ env.DATE_FORMAT }}')" >> $GITHUB_OUTPUT
-
- - name: Generate comment body for start
- if: steps.pr.outputs.result != 'null'
- id: comment-body-start
+ GITHUB_TOKEN: ${{ github.token }}
run: |
- echo "" > comment.md
- echo "## ๐ญ Playwright Test Results" >> comment.md
- echo "" >> comment.md
- echo "
**Tests are starting...** " >> comment.md
- echo "" >> comment.md
- echo "โฐ Started at: ${{ steps.completion-time.outputs.time }} UTC" >> comment.md
- echo "" >> comment.md
- echo "### ๐ Running Tests" >> comment.md
- echo "- ๐งช **chromium**: Running tests..." >> comment.md
- echo "- ๐งช **chromium-0.5x**: Running tests..." >> comment.md
- echo "- ๐งช **chromium-2x**: Running tests..." >> comment.md
- echo "- ๐งช **mobile-chrome**: Running tests..." >> comment.md
- echo "" >> comment.md
- echo "---" >> comment.md
- echo "โฑ๏ธ Please wait while tests are running across all browsers..." >> comment.md
-
- - name: Comment PR - Tests Started
- if: steps.pr.outputs.result != 'null'
- uses: edumserrano/find-create-or-update-comment@82880b65c8a3a6e4c70aa05a204995b6c9696f53 # v3.0.0
- with:
- issue-number: ${{ steps.pr.outputs.result }}
- body-includes: ''
- comment-author: 'github-actions[bot]'
- edit-mode: replace
- body-path: comment.md
-
- comment-tests-completed:
- runs-on: ubuntu-latest
- needs: deploy-reports
- if: github.repository == 'Comfy-Org/ComfyUI_frontend' && github.event.workflow_run.event == 'pull_request' && github.event.action == 'completed' && always()
- permissions:
- pull-requests: write
- actions: read
- steps:
- - name: Get PR number
- id: pr
- uses: actions/github-script@v7
- with:
- script: |
- const { data: pullRequests } = await github.rest.pulls.list({
- owner: context.repo.owner,
- repo: context.repo.repo,
- state: 'open',
- head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`,
- });
-
- if (pullRequests.length === 0) {
- console.log('No open PR found for this branch');
- return null;
- }
-
- return pullRequests[0].number;
-
- - name: Download all deployment info
- if: steps.pr.outputs.result != 'null'
- uses: actions/download-artifact@v4
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- run-id: ${{ github.event.workflow_run.id }}
- pattern: deployment-info-*
- merge-multiple: true
- path: deployment-info
-
- - name: Get completion time
- id: completion-time
- run: echo "time=$(date -u '${{ env.DATE_FORMAT }}')" >> $GITHUB_OUTPUT
-
- - name: Generate comment body for completion
- if: steps.pr.outputs.result != 'null'
- id: comment-body-completed
- run: |
- echo "" > comment.md
- echo "## ๐ญ Playwright Test Results" >> comment.md
- echo "" >> comment.md
-
- # Check if all tests passed
- ALL_PASSED=true
- for file in deployment-info/*.txt; do
- if [ -f "$file" ]; then
- browser=$(basename "$file" .txt)
- info=$(cat "$file")
- exit_code=$(echo "$info" | cut -d'|' -f2)
- if [ "$exit_code" != "0" ]; then
- ALL_PASSED=false
- break
- fi
- fi
- done
-
- if [ "$ALL_PASSED" = "true" ]; then
- echo "โ
**All tests passed across all browsers!**" >> comment.md
- else
- echo "โ **Some tests failed!**" >> comment.md
- fi
-
- echo "" >> comment.md
- echo "โฐ Completed at: ${{ steps.completion-time.outputs.time }} UTC" >> comment.md
- echo "" >> comment.md
- echo "### ๐ Test Reports by Browser" >> comment.md
-
- for file in deployment-info/*.txt; do
- if [ -f "$file" ]; then
- browser=$(basename "$file" .txt)
- info=$(cat "$file")
- exit_code=$(echo "$info" | cut -d'|' -f2)
- url=$(echo "$info" | cut -d'|' -f3)
-
- # Validate URLs before using them in comments
- sanitized_url=$(echo "$url" | grep -E '^https://[a-z0-9.-]+\.pages\.dev(/.*)?$' || echo "INVALID_URL")
- if [ "$sanitized_url" = "INVALID_URL" ]; then
- echo "Invalid deployment URL detected: $url"
- url="#" # Use safe fallback
- fi
-
- if [ "$exit_code" = "0" ]; then
- status="โ
"
- else
- status="โ"
- fi
-
- echo "- $status **$browser**: [View Report]($url)" >> comment.md
- fi
- done
-
- echo "" >> comment.md
- echo "---" >> comment.md
- if [ "$ALL_PASSED" = "true" ]; then
- echo "๐ Your tests are passing across all browsers!" >> comment.md
- else
- echo "โ ๏ธ Please check the test reports for details on failures." >> comment.md
- fi
-
- - name: Comment PR - Tests Complete
- if: steps.pr.outputs.result != 'null'
- uses: edumserrano/find-create-or-update-comment@82880b65c8a3a6e4c70aa05a204995b6c9696f53 # v3.0.0
- with:
- issue-number: ${{ steps.pr.outputs.result }}
- body-includes: ''
- comment-author: 'github-actions[bot]'
- edit-mode: replace
- body-path: comment.md
\ No newline at end of file
+ # Rename merged report if exists
+ [ -d "reports/playwright-report-chromium-merged" ] && \
+ mv reports/playwright-report-chromium-merged reports/playwright-report-chromium
+
+ chmod +x scripts/cicd/pr-playwright-deploy-and-comment.sh
+ ./scripts/cicd/pr-playwright-deploy-and-comment.sh \
+ "${{ steps.pr.outputs.result }}" \
+ "${{ github.event.workflow_run.head_branch }}" \
+ "completed"
\ No newline at end of file
diff --git a/.github/workflows/test-ui.yaml b/.github/workflows/test-ui.yaml
index 451c4b903..f8f6cf955 100644
--- a/.github/workflows/test-ui.yaml
+++ b/.github/workflows/test-ui.yaml
@@ -284,3 +284,65 @@ jobs:
name: playwright-report-chromium
path: ComfyUI_frontend/playwright-report/
retention-days: 30
+
+ #### BEGIN Deployment and commenting (non-forked PRs only)
+ # when using pull_request event, we have permission to comment directly
+ # if its a forked repo, we need to use workflow_run event in a separate workflow (pr-playwright-deploy.yaml)
+
+ # Post starting comment for non-forked PRs
+ comment-on-pr-start:
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
+ permissions:
+ pull-requests: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Get start time
+ id: start-time
+ run: echo "time=$(date -u '+%m/%d/%Y, %I:%M:%S %p')" >> $GITHUB_OUTPUT
+
+ - name: Post starting comment
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ chmod +x scripts/cicd/pr-playwright-deploy-and-comment.sh
+ ./scripts/cicd/pr-playwright-deploy-and-comment.sh \
+ "${{ github.event.pull_request.number }}" \
+ "${{ github.head_ref }}" \
+ "starting" \
+ "${{ steps.start-time.outputs.time }}"
+
+ # Deploy and comment for non-forked PRs only
+ deploy-and-comment:
+ needs: [playwright-tests, merge-reports]
+ runs-on: ubuntu-latest
+ if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
+ permissions:
+ pull-requests: write
+ contents: read
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Download all playwright reports
+ uses: actions/download-artifact@v4
+ with:
+ pattern: playwright-report-*
+ path: reports
+
+ - name: Make deployment script executable
+ run: chmod +x scripts/cicd/pr-playwright-deploy-and-comment.sh
+
+ - name: Deploy reports and comment on PR
+ env:
+ CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: |
+ ./scripts/cicd/pr-playwright-deploy-and-comment.sh \
+ "${{ github.event.pull_request.number }}" \
+ "${{ github.head_ref }}" \
+ "completed"
+ #### END Deployment and commenting (non-forked PRs only)
\ No newline at end of file
diff --git a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-mobile-chromium-linux.png b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-mobile-chromium-linux.png
index 604c23351..fadb02348 100644
Binary files a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-mobile-chromium-linux.png and b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-mobile-chromium-linux.png differ
diff --git a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-tablet-chromium-linux.png b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-tablet-chromium-linux.png
index 1e2a1017c..350b01a28 100644
Binary files a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-tablet-chromium-linux.png and b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-tablet-chromium-linux.png differ
diff --git a/browser_tests/tests/widget.spec.ts-snapshots/animated-image-preview-saved-webp-chromium-linux.png b/browser_tests/tests/widget.spec.ts-snapshots/animated-image-preview-saved-webp-chromium-linux.png
index b2fe8bb40..d50dc1135 100644
Binary files a/browser_tests/tests/widget.spec.ts-snapshots/animated-image-preview-saved-webp-chromium-linux.png and b/browser_tests/tests/widget.spec.ts-snapshots/animated-image-preview-saved-webp-chromium-linux.png differ
diff --git a/knip.config.ts b/knip.config.ts
index 9df077d77..e7fa5db8a 100644
--- a/knip.config.ts
+++ b/knip.config.ts
@@ -51,7 +51,8 @@ const config: KnipConfig = {
tags: [
'-knipIgnoreUnusedButUsedByCustomNodes',
'-knipIgnoreUnusedButUsedByVueNodesBranch'
- ]
+ ],
+ ignoreUnresolved: ['^~icons/']
}
export default config
diff --git a/scripts/cicd/pr-playwright-deploy-and-comment.sh b/scripts/cicd/pr-playwright-deploy-and-comment.sh
new file mode 100755
index 000000000..767a7f514
--- /dev/null
+++ b/scripts/cicd/pr-playwright-deploy-and-comment.sh
@@ -0,0 +1,241 @@
+#!/bin/bash
+set -e
+
+# Deploy Playwright test reports to Cloudflare Pages and comment on PR
+# Usage: ./pr-playwright-deploy-and-comment.sh [start_time]
+
+# Input validation
+# Validate PR number is numeric
+case "$1" in
+ ''|*[!0-9]*)
+ echo "Error: PR_NUMBER must be numeric" >&2
+ exit 1
+ ;;
+esac
+PR_NUMBER="$1"
+
+# Sanitize and validate branch name (allow alphanumeric, dots, dashes, underscores, slashes)
+BRANCH_NAME=$(echo "$2" | sed 's/[^a-zA-Z0-9._/-]//g')
+if [ -z "$BRANCH_NAME" ]; then
+ echo "Error: Invalid or empty branch name" >&2
+ exit 1
+fi
+
+# Validate status parameter
+STATUS="${3:-completed}"
+case "$STATUS" in
+ starting|completed) ;;
+ *)
+ echo "Error: STATUS must be 'starting' or 'completed'" >&2
+ exit 1
+ ;;
+esac
+
+START_TIME="${4:-$(date -u '+%m/%d/%Y, %I:%M:%S %p')}"
+
+# Required environment variables
+: "${GITHUB_TOKEN:?GITHUB_TOKEN is required}"
+: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"
+
+# Cloudflare variables only required for deployment
+if [ "$STATUS" = "completed" ]; then
+ : "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN is required for deployment}"
+ : "${CLOUDFLARE_ACCOUNT_ID:?CLOUDFLARE_ACCOUNT_ID is required for deployment}"
+fi
+
+# Configuration
+COMMENT_MARKER=""
+# Use dot notation for artifact names (as Playwright creates them)
+BROWSERS="chromium chromium-2x chromium-0.5x mobile-chrome"
+
+# Install wrangler if not available (output to stderr for debugging)
+if ! command -v wrangler > /dev/null 2>&1; then
+ echo "Installing wrangler v4..." >&2
+ npm install -g wrangler@^4.0.0 >&2 || {
+ echo "Failed to install wrangler" >&2
+ echo "failed"
+ return
+ }
+fi
+
+# Deploy a single browser report, WARN: ensure inputs are sanitized before calling this function
+deploy_report() {
+ dir="$1"
+ browser="$2"
+ branch="$3"
+
+ [ ! -d "$dir" ] && echo "failed" && return
+
+
+ # Project name with dots converted to dashes for Cloudflare
+ sanitized_browser=$(echo "$browser" | sed 's/\./-/g')
+ project="comfyui-playwright-${sanitized_browser}"
+
+ echo "Deploying $browser to project $project on branch $branch..." >&2
+
+ # Try deployment up to 3 times
+ i=1
+ while [ $i -le 3 ]; do
+ echo "Deployment attempt $i of 3..." >&2
+ # Branch and project are already sanitized, use them directly
+ # Branch was sanitized at script start, project uses sanitized_browser
+ if output=$(wrangler pages deploy "$dir" \
+ --project-name="$project" \
+ --branch="$branch" 2>&1); then
+
+ # Extract URL from output (improved regex for valid URL characters)
+ url=$(echo "$output" | grep -oE 'https://[a-zA-Z0-9.-]+\.pages\.dev\S*' | head -1)
+ result="${url:-https://${branch}.${project}.pages.dev}"
+ echo "Success! URL: $result" >&2
+ echo "$result" # Only this goes to stdout for capture
+ return
+ else
+ echo "Deployment failed on attempt $i: $output" >&2
+ fi
+ [ $i -lt 3 ] && sleep 10
+ i=$((i + 1))
+ done
+
+ echo "failed"
+}
+
+# Post or update GitHub comment
+post_comment() {
+ body="$1"
+ temp_file=$(mktemp)
+ echo "$body" > "$temp_file"
+
+ if command -v gh > /dev/null 2>&1; then
+ # Find existing comment ID
+ existing=$(gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \
+ --jq ".[] | select(.body | contains(\"$COMMENT_MARKER\")) | .id" | head -1)
+
+ if [ -n "$existing" ]; then
+ # Update specific comment by ID
+ gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/comments/$existing" \
+ --field body="$(cat "$temp_file")"
+ else
+ # Create new comment
+ gh pr comment "$PR_NUMBER" --body-file "$temp_file"
+ fi
+ else
+ echo "GitHub CLI not available, outputting comment:"
+ cat "$temp_file"
+ fi
+
+ rm -f "$temp_file"
+}
+
+# Main execution
+if [ "$STATUS" = "starting" ]; then
+ # Post starting comment
+ comment=$(cat < **Tests are starting...**
+
+โฐ Started at: $START_TIME UTC
+
+### ๐ Running Tests
+- ๐งช **chromium**: Running tests...
+- ๐งช **chromium-0.5x**: Running tests...
+- ๐งช **chromium-2x**: Running tests...
+- ๐งช **mobile-chrome**: Running tests...
+
+---
+โฑ๏ธ Please wait while tests are running...
+EOF
+)
+ post_comment "$comment"
+
+else
+ # Deploy and post completion comment
+ # Convert branch name to Cloudflare-compatible format (lowercase, only alphanumeric and dashes)
+ cloudflare_branch=$(echo "$BRANCH_NAME" | tr '[:upper:]' '[:lower:]' | \
+ sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
+
+ echo "Looking for reports in: $(pwd)/reports"
+ echo "Available reports:"
+ ls -la reports/ 2>/dev/null || echo "Reports directory not found"
+
+ # Deploy all reports in parallel and collect URLs
+ temp_dir=$(mktemp -d)
+ pids=""
+ i=0
+
+ # Start parallel deployments
+ for browser in $BROWSERS; do
+ if [ -d "reports/playwright-report-$browser" ]; then
+ echo "Found report for $browser, deploying in parallel..."
+ (
+ url=$(deploy_report "reports/playwright-report-$browser" "$browser" "$cloudflare_branch")
+ echo "$url" > "$temp_dir/$i.url"
+ echo "Deployment result for $browser: $url"
+ ) &
+ pids="$pids $!"
+ else
+ echo "Report not found for $browser at reports/playwright-report-$browser"
+ echo "failed" > "$temp_dir/$i.url"
+ fi
+ i=$((i + 1))
+ done
+
+ # Wait for all deployments to complete
+ for pid in $pids; do
+ wait $pid
+ done
+
+ # Collect URLs in order
+ urls=""
+ i=0
+ for browser in $BROWSERS; do
+ if [ -f "$temp_dir/$i.url" ]; then
+ url=$(cat "$temp_dir/$i.url")
+ else
+ url="failed"
+ fi
+ if [ -z "$urls" ]; then
+ urls="$url"
+ else
+ urls="$urls $url"
+ fi
+ i=$((i + 1))
+ done
+
+ # Clean up temp directory
+ rm -rf "$temp_dir"
+
+ # Generate completion comment
+ comment="$COMMENT_MARKER
+## ๐ญ Playwright Test Results
+
+โ
**Tests completed successfully!**
+
+โฐ Completed at: $(date -u '+%m/%d/%Y, %I:%M:%S %p') UTC
+
+### ๐ Test Reports by Browser"
+
+ # Add browser results
+ i=0
+ for browser in $BROWSERS; do
+ # Get URL at position i
+ url=$(echo "$urls" | cut -d' ' -f$((i + 1)))
+
+ if [ "$url" != "failed" ] && [ -n "$url" ]; then
+ comment="$comment
+- โ
**${browser}**: [View Report](${url})"
+ else
+ comment="$comment
+- โ **${browser}**: Deployment failed"
+ fi
+ i=$((i + 1))
+ done
+
+ comment="$comment
+
+---
+๐ Click on the links above to view detailed test results for each browser configuration."
+
+ post_comment "$comment"
+fi
\ No newline at end of file
diff --git a/src/assets/css/style.css b/src/assets/css/style.css
index ee6e697f0..8e4ecf6ae 100644
--- a/src/assets/css/style.css
+++ b/src/assets/css/style.css
@@ -7,65 +7,6 @@
@config '../../../tailwind.config.ts';
-@layer tailwind-utilities {
- /* Set default values to prevent some styles from not working properly. */
- *, ::before, ::after {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(66 153 225 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
- }
-
- @tailwind components;
- @tailwind utilities;
-}
:root {
--fg-color: #000;
diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue
index c6eb86404..ee9bea3ba 100644
--- a/src/components/graph/GraphCanvas.vue
+++ b/src/components/graph/GraphCanvas.vue
@@ -96,7 +96,6 @@ import NodeSearchboxPopover from '@/components/searchbox/NodeSearchBoxPopover.vu
import SideToolbar from '@/components/sidebar/SideToolbar.vue'
import SecondRowWorkflowTabs from '@/components/topbar/SecondRowWorkflowTabs.vue'
import { useChainCallback } from '@/composables/functional/useChainCallback'
-import { useNodeEventHandlers } from '@/composables/graph/useNodeEventHandlers'
import { useViewportCulling } from '@/composables/graph/useViewportCulling'
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
import { useNodeBadge } from '@/composables/node/useNodeBadge'
@@ -116,6 +115,7 @@ import { SelectedNodeIdsKey } from '@/renderer/core/canvas/injectionKeys'
import TransformPane from '@/renderer/core/layout/TransformPane.vue'
import MiniMap from '@/renderer/extensions/minimap/MiniMap.vue'
import VueGraphNode from '@/renderer/extensions/vueNodes/components/LGraphNode.vue'
+import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
import { UnauthorizedError, api } from '@/scripts/api'
import { app as comfyApp } from '@/scripts/app'
import { ChangeTracker } from '@/scripts/changeTracker'
diff --git a/src/components/widget/SampleModelSelector.vue b/src/components/widget/SampleModelSelector.vue
index 8a5ea674e..704bb42f8 100644
--- a/src/components/widget/SampleModelSelector.vue
+++ b/src/components/widget/SampleModelSelector.vue
@@ -87,8 +87,6 @@
-
-
import { provide, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
+import DownloadIcon from '~icons/lucide/download'
+import Grid3x3Icon from '~icons/lucide/grid-3-x-3'
+import LayersIcon from '~icons/lucide/layers'
+import TagIcon from '~icons/lucide/tag'
import IconButton from '@/components/button/IconButton.vue'
import IconTextButton from '@/components/button/IconTextButton.vue'
@@ -175,20 +177,20 @@ const sortOptions = ref([
])
const tempNavigation = ref<(NavItemData | NavGroupData)[]>([
- { id: 'installed', label: 'Installed' },
+ { id: 'installed', label: 'Installed', icon: DownloadIcon },
{
title: 'TAGS',
items: [
- { id: 'tag-sd15', label: 'SD 1.5' },
- { id: 'tag-sdxl', label: 'SDXL' },
- { id: 'tag-utility', label: 'Utility' }
+ { id: 'tag-sd15', label: 'SD 1.5', icon: TagIcon },
+ { id: 'tag-sdxl', label: 'SDXL', icon: TagIcon },
+ { id: 'tag-utility', label: 'Utility', icon: TagIcon }
]
},
{
title: 'CATEGORIES',
items: [
- { id: 'cat-models', label: 'Models' },
- { id: 'cat-nodes', label: 'Nodes' }
+ { id: 'cat-models', label: 'Models', icon: LayersIcon },
+ { id: 'cat-nodes', label: 'Nodes', icon: Grid3x3Icon }
]
}
])
diff --git a/src/components/widget/layout/BaseWidget.stories.ts b/src/components/widget/layout/BaseWidget.stories.ts
index 0ac0341de..2087ad490 100644
--- a/src/components/widget/layout/BaseWidget.stories.ts
+++ b/src/components/widget/layout/BaseWidget.stories.ts
@@ -14,7 +14,7 @@ import {
Upload,
X
} from 'lucide-vue-next'
-import { provide, ref } from 'vue'
+import { h, provide, ref } from 'vue'
import IconButton from '@/components/button/IconButton.vue'
import IconTextButton from '@/components/button/IconTextButton.vue'
@@ -118,20 +118,44 @@ const createStoryTemplate = (args: StoryArgs) => ({
provide(OnCloseKey, onClose)
const tempNavigation = ref<(NavItemData | NavGroupData)[]>([
- { id: 'installed', label: 'Installed' },
+ {
+ id: 'installed',
+ label: 'Installed',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ },
{
title: 'TAGS',
items: [
- { id: 'tag-sd15', label: 'SD 1.5' },
- { id: 'tag-sdxl', label: 'SDXL' },
- { id: 'tag-utility', label: 'Utility' }
+ {
+ id: 'tag-sd15',
+ label: 'SD 1.5',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ },
+ {
+ id: 'tag-sdxl',
+ label: 'SDXL',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ },
+ {
+ id: 'tag-utility',
+ label: 'Utility',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ }
]
},
{
title: 'CATEGORIES',
items: [
- { id: 'cat-models', label: 'Models' },
- { id: 'cat-nodes', label: 'Nodes' }
+ {
+ id: 'cat-models',
+ label: 'Models',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ },
+ {
+ id: 'cat-nodes',
+ label: 'Nodes',
+ icon: { render: () => h(Folder, { size: 14 }) } as any
+ }
]
}
])
diff --git a/src/components/widget/nav/NavIcon.vue b/src/components/widget/nav/NavIcon.vue
new file mode 100644
index 000000000..162e9d4b8
--- /dev/null
+++ b/src/components/widget/nav/NavIcon.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/src/components/widget/nav/NavItem.stories.ts b/src/components/widget/nav/NavItem.stories.ts
new file mode 100644
index 000000000..34bf1e718
--- /dev/null
+++ b/src/components/widget/nav/NavItem.stories.ts
@@ -0,0 +1,123 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import { Download, Folder, Grid3x3, Layers, Tag, Wrench } from 'lucide-vue-next'
+import { h } from 'vue'
+
+import NavItem from './NavItem.vue'
+
+const meta: Meta = {
+ title: 'Components/Widget/Nav/NavItem',
+ component: NavItem,
+ argTypes: {
+ icon: {
+ control: 'select',
+ description: 'Icon component to display'
+ },
+ active: {
+ control: 'boolean',
+ description: 'Active state of the nav item'
+ },
+ onClick: {
+ table: { disable: true }
+ },
+ default: {
+ control: 'text',
+ description: 'Text content for the nav item'
+ }
+ },
+ args: {
+ active: false,
+ onClick: () => {},
+ default: 'Navigation Item'
+ }
+}
+
+export default meta
+type Story = StoryObj
+
+export const Interactive: Story = {
+ args: {
+ icon: Folder,
+ active: false,
+ default: 'Navigation Item'
+ },
+ render: (args) => ({
+ components: { NavItem },
+ setup() {
+ const IconComponent = args.icon
+ const WrappedIcon = {
+ render() {
+ return h(IconComponent, { size: 14 })
+ }
+ }
+ return { args, WrappedIcon }
+ },
+ template: `
+
+ {{ args.default }}
+
+ `
+ })
+}
+
+export const InteractiveList: Story = {
+ render: () => ({
+ components: { NavItem },
+ template: `
+
+
+ {{ item.label }}
+
+
+ `,
+ data() {
+ return {
+ selectedId: 'downloads'
+ }
+ },
+ setup() {
+ const items = [
+ {
+ id: 'downloads',
+ label: 'Downloads',
+ wrappedIcon: () => h(Download, { size: 14 })
+ },
+ {
+ id: 'models',
+ label: 'Models',
+ wrappedIcon: () => h(Layers, { size: 14 })
+ },
+ {
+ id: 'nodes',
+ label: 'Nodes',
+ wrappedIcon: () => h(Grid3x3, { size: 14 })
+ },
+ {
+ id: 'tags',
+ label: 'Tags',
+ wrappedIcon: () => h(Tag, { size: 14 })
+ },
+ {
+ id: 'settings',
+ label: 'Settings',
+ wrappedIcon: () => h(Wrench, { size: 14 })
+ },
+ {
+ id: 'default',
+ label: 'Default Icon',
+ wrappedIcon: () => h(Folder, { size: 14 })
+ }
+ ]
+
+ return { items }
+ }
+ }),
+ parameters: {
+ controls: { disable: true }
+ }
+}
diff --git a/src/components/widget/nav/NavItem.vue b/src/components/widget/nav/NavItem.vue
index 4d96327ea..c159dc6d5 100644
--- a/src/components/widget/nav/NavItem.vue
+++ b/src/components/widget/nav/NavItem.vue
@@ -9,7 +9,8 @@
role="button"
@click="onClick"
>
-
+
+
@@ -17,12 +18,12 @@
+
+
+
+
diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue
new file mode 100644
index 000000000..6e91171b3
--- /dev/null
+++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberInput.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.test.ts b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.test.ts
similarity index 95%
rename from src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.test.ts
rename to src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.test.ts
index 3e554023f..179c342d2 100644
--- a/src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.test.ts
+++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.test.ts
@@ -7,9 +7,9 @@ import { describe, expect, it } from 'vitest'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
-import WidgetSlider from './WidgetSlider.vue'
+import WidgetInputNumberSlider from './WidgetInputNumberSlider.vue'
-describe('WidgetSlider Value Binding', () => {
+describe('WidgetInputNumberSlider Value Binding', () => {
const createMockWidget = (
value: number = 5,
options: Partial = {},
@@ -27,7 +27,7 @@ describe('WidgetSlider Value Binding', () => {
modelValue: number,
readonly = false
) => {
- return mount(WidgetSlider, {
+ return mount(WidgetInputNumberSlider, {
global: {
plugins: [PrimeVue],
components: { InputText, Slider }
diff --git a/src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.vue b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.vue
similarity index 98%
rename from src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.vue
rename to src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.vue
index a303b4923..c9894f4b8 100644
--- a/src/renderer/extensions/vueNodes/widgets/components/WidgetSlider.vue
+++ b/src/renderer/extensions/vueNodes/widgets/components/WidgetInputNumberSlider.vue
@@ -16,8 +16,6 @@
v-model="inputDisplayValue"
:disabled="readonly"
type="number"
- :min="widget.options?.min"
- :max="widget.options?.max"
:step="stepValue"
class="w-[4em] text-center text-xs px-0 !border-none !shadow-none !bg-transparent"
size="small"
diff --git a/src/renderer/extensions/vueNodes/widgets/registry/widgetRegistry.ts b/src/renderer/extensions/vueNodes/widgets/registry/widgetRegistry.ts
index c8b0b0a49..b07c89e5b 100644
--- a/src/renderer/extensions/vueNodes/widgets/registry/widgetRegistry.ts
+++ b/src/renderer/extensions/vueNodes/widgets/registry/widgetRegistry.ts
@@ -9,12 +9,12 @@ import WidgetColorPicker from '../components/WidgetColorPicker.vue'
import WidgetFileUpload from '../components/WidgetFileUpload.vue'
import WidgetGalleria from '../components/WidgetGalleria.vue'
import WidgetImageCompare from '../components/WidgetImageCompare.vue'
+import WidgetInputNumber from '../components/WidgetInputNumber.vue'
import WidgetInputText from '../components/WidgetInputText.vue'
import WidgetMarkdown from '../components/WidgetMarkdown.vue'
import WidgetMultiSelect from '../components/WidgetMultiSelect.vue'
import WidgetSelect from '../components/WidgetSelect.vue'
import WidgetSelectButton from '../components/WidgetSelectButton.vue'
-import WidgetSlider from '../components/WidgetSlider.vue'
import WidgetTextarea from '../components/WidgetTextarea.vue'
import WidgetToggleSwitch from '../components/WidgetToggleSwitch.vue'
import WidgetTreeSelect from '../components/WidgetTreeSelect.vue'
@@ -38,11 +38,11 @@ const coreWidgetDefinitions: Array<[string, WidgetDefinition]> = [
essential: false
}
],
- ['int', { component: WidgetSlider, aliases: ['INT'], essential: true }],
+ ['int', { component: WidgetInputNumber, aliases: ['INT'], essential: true }],
[
'float',
{
- component: WidgetSlider,
+ component: WidgetInputNumber,
aliases: ['FLOAT', 'number', 'slider'],
essential: true
}
diff --git a/src/types/navTypes.ts b/src/types/navTypes.ts
index 785faedb4..702ecefa6 100644
--- a/src/types/navTypes.ts
+++ b/src/types/navTypes.ts
@@ -1,6 +1,9 @@
+import { DefineComponent, FunctionalComponent } from 'vue'
+
export interface NavItemData {
id: string
label: string
+ icon: DefineComponent | FunctionalComponent
}
export interface NavGroupData {
diff --git a/tests-ui/tests/composables/graph/useNodeEventHandlers.test.ts b/tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeEventHandlers.test.ts
similarity index 96%
rename from tests-ui/tests/composables/graph/useNodeEventHandlers.test.ts
rename to tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeEventHandlers.test.ts
index d98a2134f..51a0ae235 100644
--- a/tests-ui/tests/composables/graph/useNodeEventHandlers.test.ts
+++ b/tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeEventHandlers.test.ts
@@ -1,13 +1,11 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue'
-import type {
- VueNodeData,
- useGraphNodeManager
-} from '@/composables/graph/useGraphNodeManager'
-import { useNodeEventHandlers } from '@/composables/graph/useNodeEventHandlers'
+import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
+import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import type { LGraphCanvas, LGraphNode } from '@/lib/litegraph/src/litegraph'
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
+import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
import { useCanvasStore } from '@/stores/graphStore'
vi.mock('@/stores/graphStore', () => ({
diff --git a/tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeZIndex.test.ts b/tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeZIndex.test.ts
new file mode 100644
index 000000000..f9c669cd4
--- /dev/null
+++ b/tests-ui/tests/renderer/extensions/vueNodes/composables/useNodeZIndex.test.ts
@@ -0,0 +1,98 @@
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+
+import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
+import { LayoutSource } from '@/renderer/core/layout/types'
+import { useNodeZIndex } from '@/renderer/extensions/vueNodes/composables/useNodeZIndex'
+
+// Mock the layout mutations module
+vi.mock('@/renderer/core/layout/operations/layoutMutations')
+
+const mockedUseLayoutMutations = vi.mocked(useLayoutMutations)
+
+describe('useNodeZIndex', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ })
+
+ describe('bringNodeToFront', () => {
+ it('should bring node to front with default source', () => {
+ const mockSetSource = vi.fn()
+ const mockBringNodeToFront = vi.fn()
+
+ mockedUseLayoutMutations.mockReturnValue({
+ setSource: mockSetSource,
+ bringNodeToFront: mockBringNodeToFront
+ } as Partial> as ReturnType<
+ typeof useLayoutMutations
+ >)
+
+ const { bringNodeToFront } = useNodeZIndex()
+
+ bringNodeToFront('node1')
+
+ expect(mockSetSource).toHaveBeenCalledWith(LayoutSource.Vue)
+ expect(mockBringNodeToFront).toHaveBeenCalledWith('node1')
+ })
+
+ it('should bring node to front with custom source', () => {
+ const mockSetSource = vi.fn()
+ const mockBringNodeToFront = vi.fn()
+
+ mockedUseLayoutMutations.mockReturnValue({
+ setSource: mockSetSource,
+ bringNodeToFront: mockBringNodeToFront
+ } as Partial> as ReturnType<
+ typeof useLayoutMutations
+ >)
+
+ const { bringNodeToFront } = useNodeZIndex()
+
+ bringNodeToFront('node2', LayoutSource.Canvas)
+
+ expect(mockSetSource).toHaveBeenCalledWith(LayoutSource.Canvas)
+ expect(mockBringNodeToFront).toHaveBeenCalledWith('node2')
+ })
+
+ it('should use custom layout source from options', () => {
+ const mockSetSource = vi.fn()
+ const mockBringNodeToFront = vi.fn()
+
+ mockedUseLayoutMutations.mockReturnValue({
+ setSource: mockSetSource,
+ bringNodeToFront: mockBringNodeToFront
+ } as Partial> as ReturnType<
+ typeof useLayoutMutations
+ >)
+
+ const { bringNodeToFront } = useNodeZIndex({
+ layoutSource: LayoutSource.External
+ })
+
+ bringNodeToFront('node3')
+
+ expect(mockSetSource).toHaveBeenCalledWith(LayoutSource.External)
+ expect(mockBringNodeToFront).toHaveBeenCalledWith('node3')
+ })
+
+ it('should override layout source with explicit source parameter', () => {
+ const mockSetSource = vi.fn()
+ const mockBringNodeToFront = vi.fn()
+
+ mockedUseLayoutMutations.mockReturnValue({
+ setSource: mockSetSource,
+ bringNodeToFront: mockBringNodeToFront
+ } as Partial> as ReturnType<
+ typeof useLayoutMutations
+ >)
+
+ const { bringNodeToFront } = useNodeZIndex({
+ layoutSource: LayoutSource.External
+ })
+
+ bringNodeToFront('node4', LayoutSource.Canvas)
+
+ expect(mockSetSource).toHaveBeenCalledWith(LayoutSource.Canvas)
+ expect(mockBringNodeToFront).toHaveBeenCalledWith('node4')
+ })
+ })
+})
diff --git a/tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts b/tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts
index 4a363ebd1..64a8d614c 100644
--- a/tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts
+++ b/tests-ui/tests/renderer/extensions/vueNodes/widgets/composables/useWidgetRenderer.test.ts
@@ -3,10 +3,10 @@ import { describe, expect, it } from 'vitest'
import WidgetButton from '@/renderer/extensions/vueNodes/widgets/components/WidgetButton.vue'
import WidgetColorPicker from '@/renderer/extensions/vueNodes/widgets/components/WidgetColorPicker.vue'
import WidgetFileUpload from '@/renderer/extensions/vueNodes/widgets/components/WidgetFileUpload.vue'
+import WidgetInputNumber from '@/renderer/extensions/vueNodes/widgets/components/WidgetInputNumber.vue'
import WidgetInputText from '@/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue'
import WidgetMarkdown from '@/renderer/extensions/vueNodes/widgets/components/WidgetMarkdown.vue'
import WidgetSelect from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelect.vue'
-import WidgetSlider from '@/renderer/extensions/vueNodes/widgets/components/WidgetSlider.vue'
import WidgetTextarea from '@/renderer/extensions/vueNodes/widgets/components/WidgetTextarea.vue'
import WidgetToggleSwitch from '@/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.vue'
import {
@@ -20,15 +20,15 @@ describe('widgetRegistry', () => {
// Test number type mappings
describe('number types', () => {
it('should map int types to slider widget', () => {
- expect(getComponent('int')).toBe(WidgetSlider)
- expect(getComponent('INT')).toBe(WidgetSlider)
+ expect(getComponent('int')).toBe(WidgetInputNumber)
+ expect(getComponent('INT')).toBe(WidgetInputNumber)
})
it('should map float types to slider widget', () => {
- expect(getComponent('float')).toBe(WidgetSlider)
- expect(getComponent('FLOAT')).toBe(WidgetSlider)
- expect(getComponent('number')).toBe(WidgetSlider)
- expect(getComponent('slider')).toBe(WidgetSlider)
+ expect(getComponent('float')).toBe(WidgetInputNumber)
+ expect(getComponent('FLOAT')).toBe(WidgetInputNumber)
+ expect(getComponent('number')).toBe(WidgetInputNumber)
+ expect(getComponent('slider')).toBe(WidgetInputNumber)
})
})