mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-22 07:19:41 +00:00
fix: Add babel configuration for Playwright to handle TypeScript declare fields
- Configure babel plugins for TypeScript with allowDeclareFields option - Add module resolver for @ alias to src directory - Create custom babel plugin to stub Vue/CSS imports - Add browser globals polyfill using happy-dom for Node.js context - Update playwright.i18n.config.ts with babel configuration This enables collect-i18n tests to run with proper TypeScript and module transformations.
This commit is contained in:
18
babel-plugin-stub-vue.js
Normal file
18
babel-plugin-stub-vue.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
module.exports = function() {
|
||||||
|
return {
|
||||||
|
visitor: {
|
||||||
|
ImportDeclaration(path) {
|
||||||
|
const source = path.node.source.value;
|
||||||
|
if (source.endsWith('.vue')) {
|
||||||
|
// Replace Vue component imports with a stub
|
||||||
|
const specifiers = path.node.specifiers;
|
||||||
|
if (specifiers.length > 0) {
|
||||||
|
const name = specifiers[0].local.name;
|
||||||
|
// Create a simple stub object
|
||||||
|
path.replaceWithSourceString(`const ${name} = {};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
24
babel.config.json
Normal file
24
babel.config.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env",
|
||||||
|
[
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
{
|
||||||
|
"allowDeclareFields": true,
|
||||||
|
"onlyRemoveTypeImports": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"babel-plugin-module-resolver",
|
||||||
|
{
|
||||||
|
"root": ["./"],
|
||||||
|
"alias": {
|
||||||
|
"@": "./src"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@vue/babel-plugin-jsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
15
package.json
15
package.json
@@ -32,12 +32,17 @@
|
|||||||
"knip": "knip --cache",
|
"knip": "knip --cache",
|
||||||
"knip:no-cache": "knip",
|
"knip:no-cache": "knip",
|
||||||
"locale": "lobe-i18n locale",
|
"locale": "lobe-i18n locale",
|
||||||
"collect-i18n": "npx playwright test --config=playwright.i18n.config.ts",
|
"collect-i18n": "playwright test --config=playwright.i18n.config.ts",
|
||||||
"json-schema": "tsx scripts/generate-json-schema.ts",
|
"json-schema": "tsx scripts/generate-json-schema.ts",
|
||||||
"storybook": "nx storybook -p 6006",
|
"storybook": "nx storybook -p 6006",
|
||||||
"build-storybook": "storybook build"
|
"build-storybook": "storybook build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.28.4",
|
||||||
|
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
||||||
|
"@babel/plugin-transform-typescript": "^7.28.0",
|
||||||
|
"@babel/preset-env": "^7.28.3",
|
||||||
|
"@babel/preset-typescript": "^7.27.1",
|
||||||
"@eslint/js": "^9.8.0",
|
"@eslint/js": "^9.8.0",
|
||||||
"@iconify-json/lucide": "^1.2.66",
|
"@iconify-json/lucide": "^1.2.66",
|
||||||
"@iconify/tailwind": "^1.2.0",
|
"@iconify/tailwind": "^1.2.0",
|
||||||
@@ -62,7 +67,15 @@
|
|||||||
"@vitejs/plugin-vue": "^5.1.4",
|
"@vitejs/plugin-vue": "^5.1.4",
|
||||||
"@vitest/coverage-v8": "^3.2.4",
|
"@vitest/coverage-v8": "^3.2.4",
|
||||||
"@vitest/ui": "^3.0.0",
|
"@vitest/ui": "^3.0.0",
|
||||||
|
"@vue/babel-plugin-jsx": "^1.5.0",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
|
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||||
|
"babel-plugin-module-resolver": "^5.0.2",
|
||||||
|
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||||
|
"babel-plugin-transform-import-ignore": "^1.1.0",
|
||||||
|
"babel-plugin-transform-vue-jsx": "^3.7.0",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"babel-preset-typescript-vue3": "^2.1.1",
|
||||||
"eslint": "^9.34.0",
|
"eslint": "^9.34.0",
|
||||||
"eslint-config-prettier": "^10.1.2",
|
"eslint-config-prettier": "^10.1.2",
|
||||||
"eslint-plugin-prettier": "^5.2.6",
|
"eslint-plugin-prettier": "^5.2.6",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineConfig } from '@playwright/test'
|
import { defineConfig } from '@playwright/test'
|
||||||
|
|
||||||
export default defineConfig({
|
const config: any = defineConfig({
|
||||||
testDir: './scripts',
|
testDir: './scripts',
|
||||||
use: {
|
use: {
|
||||||
baseURL: 'http://localhost:5173',
|
baseURL: 'http://localhost:5173',
|
||||||
@@ -8,5 +8,40 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
reporter: 'list',
|
reporter: 'list',
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
testMatch: /collect-i18n-.*\.ts/
|
testMatch: /collect-i18n-.*\.ts/,
|
||||||
|
// Start dev server before running tests
|
||||||
|
webServer: {
|
||||||
|
command: 'pnpm dev',
|
||||||
|
url: 'http://localhost:5173',
|
||||||
|
reuseExistingServer: true,
|
||||||
|
timeout: 60000
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Configure babel plugins for TypeScript with declare fields and module resolution
|
||||||
|
config['@playwright/test'] = {
|
||||||
|
babelPlugins: [
|
||||||
|
// Stub Vue and CSS imports first to prevent parsing errors
|
||||||
|
['babel-plugin-stub-vue-imports'],
|
||||||
|
// Module resolver to handle @ alias
|
||||||
|
[
|
||||||
|
'babel-plugin-module-resolver',
|
||||||
|
{
|
||||||
|
root: ['./'],
|
||||||
|
alias: {
|
||||||
|
'@': './src'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// Then TypeScript transformation with declare field support
|
||||||
|
[
|
||||||
|
'@babel/plugin-transform-typescript',
|
||||||
|
{
|
||||||
|
allowDeclareFields: true,
|
||||||
|
onlyRemoveTypeImports: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
|
|||||||
1686
pnpm-lock.yaml
generated
1686
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
|||||||
|
import './setup-browser-globals.js'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
|
|
||||||
import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage'
|
import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage'
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import './setup-browser-globals.js'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
|
|
||||||
import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage'
|
import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage'
|
||||||
|
|||||||
65
scripts/setup-browser-globals.js
Normal file
65
scripts/setup-browser-globals.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Polyfill browser globals for Node.js context during test imports
|
||||||
|
import { Window } from 'happy-dom';
|
||||||
|
|
||||||
|
// Define build-time constants
|
||||||
|
if (typeof globalThis.__USE_PROD_CONFIG__ === 'undefined') {
|
||||||
|
globalThis.__USE_PROD_CONFIG__ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a happy-dom window instance
|
||||||
|
const window = new Window({
|
||||||
|
url: 'http://localhost:5173/',
|
||||||
|
width: 1024,
|
||||||
|
height: 768
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expose DOM globals (only set if not already defined)
|
||||||
|
if (!globalThis.window) globalThis.window = window;
|
||||||
|
if (!globalThis.document) globalThis.document = window.document;
|
||||||
|
if (!globalThis.location) globalThis.location = window.location;
|
||||||
|
if (!globalThis.navigator) {
|
||||||
|
try {
|
||||||
|
globalThis.navigator = window.navigator;
|
||||||
|
} catch (e) {
|
||||||
|
// navigator might be read-only in some environments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!globalThis.HTMLElement) globalThis.HTMLElement = window.HTMLElement;
|
||||||
|
if (!globalThis.Element) globalThis.Element = window.Element;
|
||||||
|
if (!globalThis.Node) globalThis.Node = window.Node;
|
||||||
|
if (!globalThis.NodeList) globalThis.NodeList = window.NodeList;
|
||||||
|
if (!globalThis.DOMParser) globalThis.DOMParser = window.DOMParser;
|
||||||
|
if (!globalThis.XMLSerializer) globalThis.XMLSerializer = window.XMLSerializer;
|
||||||
|
if (!globalThis.localStorage) globalThis.localStorage = window.localStorage;
|
||||||
|
if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage;
|
||||||
|
if (!globalThis.CustomEvent) globalThis.CustomEvent = window.CustomEvent;
|
||||||
|
if (!globalThis.Event) globalThis.Event = window.Event;
|
||||||
|
if (!globalThis.MouseEvent) globalThis.MouseEvent = window.MouseEvent;
|
||||||
|
if (!globalThis.KeyboardEvent) globalThis.KeyboardEvent = window.KeyboardEvent;
|
||||||
|
if (!globalThis.getComputedStyle) globalThis.getComputedStyle = window.getComputedStyle;
|
||||||
|
if (!globalThis.requestAnimationFrame) globalThis.requestAnimationFrame = window.requestAnimationFrame;
|
||||||
|
if (!globalThis.cancelAnimationFrame) globalThis.cancelAnimationFrame = window.cancelAnimationFrame;
|
||||||
|
|
||||||
|
// Add ResizeObserver polyfill
|
||||||
|
if (!globalThis.ResizeObserver) {
|
||||||
|
globalThis.ResizeObserver = class ResizeObserver {
|
||||||
|
constructor(callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
observe() {}
|
||||||
|
unobserve() {}
|
||||||
|
disconnect() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add IntersectionObserver polyfill
|
||||||
|
if (!globalThis.IntersectionObserver) {
|
||||||
|
globalThis.IntersectionObserver = class IntersectionObserver {
|
||||||
|
constructor(callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
observe() {}
|
||||||
|
unobserve() {}
|
||||||
|
disconnect() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user