mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 16:40:05 +00:00
test: add Window type augmentation and standardize window access
- Add browser_tests/types/globals.d.ts with Window interface augmentation - Add types for app, graph, LiteGraph, LGraphBadge and test globals - Standardize window['prop'] to window.prop across 37 test files - Update browser_tests/tsconfig.json to include new type definitions Amp-Thread-ID: https://ampcode.com/threads/T-019c16b3-cc31-70ea-9727-a933cb0ee942 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -83,7 +83,7 @@ class ComfyMenu {
|
||||
await this.themeToggleButton.click()
|
||||
await this.page.waitForFunction(
|
||||
(prevTheme) => {
|
||||
const settings = window['app']?.ui?.settings
|
||||
const settings = window.app?.ui?.settings
|
||||
return (
|
||||
settings &&
|
||||
settings.getSettingValue('Comfy.ColorPalette') !== prevTheme
|
||||
@@ -96,9 +96,7 @@ class ComfyMenu {
|
||||
|
||||
async getThemeId() {
|
||||
return await this.page.evaluate(async () => {
|
||||
return await window['app'].ui.settings.getSettingValue(
|
||||
'Comfy.ColorPalette'
|
||||
)
|
||||
return await window.app.ui.settings.getSettingValue('Comfy.ColorPalette')
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -136,7 +134,7 @@ class ConfirmDialog {
|
||||
|
||||
// Wait for workflow service to finish if it's busy
|
||||
await this.page.waitForFunction(
|
||||
() => window['app']?.extensionManager?.workflow?.isBusy === false,
|
||||
() => window.app?.extensionManager?.workflow?.isBusy === false,
|
||||
undefined,
|
||||
{ timeout: 3000 }
|
||||
)
|
||||
@@ -307,9 +305,9 @@ export class ComfyPage {
|
||||
await this.page.waitForFunction(() => document.fonts.ready)
|
||||
await this.page.waitForFunction(
|
||||
() =>
|
||||
// window['app'] => GraphCanvas ready
|
||||
// window['app'].extensionManager => GraphView ready
|
||||
window['app'] && window['app'].extensionManager
|
||||
// window.app => GraphCanvas ready
|
||||
// window.app.extensionManager => GraphView ready
|
||||
window.app && window.app.extensionManager
|
||||
)
|
||||
await this.page.waitForSelector('.p-blockui-mask', { state: 'hidden' })
|
||||
await this.nextFrame()
|
||||
@@ -384,7 +382,7 @@ export class ComfyPage {
|
||||
|
||||
async setFocusMode(focusMode: boolean) {
|
||||
await this.page.evaluate((focusMode) => {
|
||||
window['app'].extensionManager.focusMode = focusMode
|
||||
window.app.extensionManager.focusMode = focusMode
|
||||
}, focusMode)
|
||||
await this.nextFrame()
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ export class WorkflowsSidebarTab extends SidebarTab {
|
||||
|
||||
// Wait for workflow service to finish renaming
|
||||
await this.page.waitForFunction(
|
||||
() => !window['app']?.extensionManager?.workflow?.isBusy,
|
||||
() => !window.app?.extensionManager?.workflow?.isBusy,
|
||||
undefined,
|
||||
{ timeout: 3000 }
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ export class Topbar {
|
||||
|
||||
// Wait for workflow service to finish saving
|
||||
await this.page.waitForFunction(
|
||||
() => !window['app'].extensionManager.workflow.isBusy,
|
||||
() => !window.app.extensionManager.workflow.isBusy,
|
||||
undefined,
|
||||
{ timeout: 3000 }
|
||||
)
|
||||
|
||||
@@ -93,13 +93,13 @@ export class CanvasHelper {
|
||||
|
||||
async getScale(): Promise<number> {
|
||||
return this.page.evaluate(() => {
|
||||
return window['app'].canvas.ds.scale
|
||||
return window.app.canvas.ds.scale
|
||||
})
|
||||
}
|
||||
|
||||
async setScale(scale: number): Promise<void> {
|
||||
await this.page.evaluate((s) => {
|
||||
window['app'].canvas.ds.scale = s
|
||||
window.app.canvas.ds.scale = s
|
||||
}, scale)
|
||||
await this.nextFrame()
|
||||
}
|
||||
@@ -108,13 +108,13 @@ export class CanvasHelper {
|
||||
pos: [number, number]
|
||||
): Promise<[number, number]> {
|
||||
return this.page.evaluate((pos) => {
|
||||
return window['app'].canvas.ds.convertOffsetToCanvas(pos)
|
||||
return window.app.canvas.ds.convertOffsetToCanvas(pos)
|
||||
}, pos)
|
||||
}
|
||||
|
||||
async getNodeCenterByTitle(title: string): Promise<Position | null> {
|
||||
return this.page.evaluate((title) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const node = app.graph.nodes.find(
|
||||
(n: { title: string }) => n.title === title
|
||||
)
|
||||
@@ -129,7 +129,7 @@ export class CanvasHelper {
|
||||
|
||||
async getGroupPosition(title: string): Promise<Position> {
|
||||
const pos = await this.page.evaluate((title) => {
|
||||
const groups = window['app'].graph.groups
|
||||
const groups = window.app.graph.groups
|
||||
const group = groups.find((g: { title: string }) => g.title === title)
|
||||
if (!group) return null
|
||||
return { x: group.pos[0], y: group.pos[1] }
|
||||
@@ -145,7 +145,7 @@ export class CanvasHelper {
|
||||
}): Promise<void> {
|
||||
const { name, deltaX, deltaY } = options
|
||||
const screenPos = await this.page.evaluate((title) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const groups = app.graph.groups
|
||||
const group = groups.find((g: { title: string }) => g.title === title)
|
||||
if (!group) return null
|
||||
|
||||
@@ -7,7 +7,7 @@ export class CommandHelper {
|
||||
|
||||
async executeCommand(commandId: string): Promise<void> {
|
||||
await this.page.evaluate((id: string) => {
|
||||
return window['app'].extensionManager.command.execute(id)
|
||||
return window.app.extensionManager.command.execute(id)
|
||||
}, commandId)
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class CommandHelper {
|
||||
): Promise<void> {
|
||||
await this.page.evaluate(
|
||||
({ commandId, commandStr }) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const randomSuffix = Math.random().toString(36).substring(2, 8)
|
||||
const extensionName = `TestExtension_${randomSuffix}`
|
||||
|
||||
@@ -41,7 +41,7 @@ export class CommandHelper {
|
||||
): Promise<void> {
|
||||
await this.page.evaluate(
|
||||
({ keyCombo, commandStr }) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const randomSuffix = Math.random().toString(36).substring(2, 8)
|
||||
const extensionName = `TestExtension_${randomSuffix}`
|
||||
const commandId = `TestCommand_${randomSuffix}`
|
||||
|
||||
@@ -19,14 +19,14 @@ export class NodeOperationsHelper {
|
||||
|
||||
async getGraphNodesCount(): Promise<number> {
|
||||
return await this.page.evaluate(() => {
|
||||
return window['app']?.graph?.nodes?.length || 0
|
||||
return window.app?.graph?.nodes?.length || 0
|
||||
})
|
||||
}
|
||||
|
||||
async getSelectedGraphNodesCount(): Promise<number> {
|
||||
return await this.page.evaluate(() => {
|
||||
return (
|
||||
window['app']?.graph?.nodes?.filter(
|
||||
window.app?.graph?.nodes?.filter(
|
||||
(node: LGraphNode) => node.is_selected === true
|
||||
).length || 0
|
||||
)
|
||||
@@ -35,19 +35,19 @@ export class NodeOperationsHelper {
|
||||
|
||||
async getNodes(): Promise<LGraphNode[]> {
|
||||
return await this.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
return window.app.graph.nodes
|
||||
})
|
||||
}
|
||||
|
||||
async waitForGraphNodes(count: number): Promise<void> {
|
||||
await this.page.waitForFunction((count) => {
|
||||
return window['app']?.canvas.graph?.nodes?.length === count
|
||||
return window.app?.canvas.graph?.nodes?.length === count
|
||||
}, count)
|
||||
}
|
||||
|
||||
async getFirstNodeRef(): Promise<NodeReference | null> {
|
||||
const id = await this.page.evaluate(() => {
|
||||
return window['app'].graph.nodes[0]?.id
|
||||
return window.app.graph.nodes[0]?.id
|
||||
})
|
||||
if (!id) return null
|
||||
return this.getNodeRefById(id)
|
||||
@@ -66,7 +66,7 @@ export class NodeOperationsHelper {
|
||||
await this.page.evaluate(
|
||||
({ type, includeSubgraph }) => {
|
||||
const graph = (
|
||||
includeSubgraph ? window['app'].canvas.graph : window['app'].graph
|
||||
includeSubgraph ? window.app.canvas.graph : window.app.graph
|
||||
) as LGraph
|
||||
const nodes = graph.nodes
|
||||
return nodes
|
||||
@@ -83,7 +83,7 @@ export class NodeOperationsHelper {
|
||||
return Promise.all(
|
||||
(
|
||||
await this.page.evaluate((title) => {
|
||||
return window['app'].graph.nodes
|
||||
return window.app.graph.nodes
|
||||
.filter((n: LGraphNode) => n.title === title)
|
||||
.map((n: LGraphNode) => n.id)
|
||||
}, title)
|
||||
|
||||
@@ -6,7 +6,7 @@ export class SettingsHelper {
|
||||
async setSetting(settingId: string, settingValue: unknown): Promise<void> {
|
||||
await this.page.evaluate(
|
||||
async ({ id, value }) => {
|
||||
await window['app'].extensionManager.setting.set(id, value)
|
||||
await window.app.extensionManager.setting.set(id, value)
|
||||
},
|
||||
{ id: settingId, value: settingValue }
|
||||
)
|
||||
@@ -14,7 +14,7 @@ export class SettingsHelper {
|
||||
|
||||
async getSetting<T = unknown>(settingId: string): Promise<T> {
|
||||
return await this.page.evaluate(async (id) => {
|
||||
return await window['app'].extensionManager.setting.get(id)
|
||||
return await window.app.extensionManager.setting.get(id)
|
||||
}, settingId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ export class SubgraphHelper {
|
||||
const foundSlot = await this.page.evaluate(
|
||||
async (params) => {
|
||||
const { slotType, action, targetSlotName } = params
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const currentGraph = app.canvas.graph
|
||||
|
||||
// Check if we're in a subgraph
|
||||
|
||||
@@ -45,7 +45,7 @@ export class WorkflowHelper {
|
||||
}
|
||||
|
||||
await this.comfyPage.page.evaluate(async () => {
|
||||
await window['app'].extensionManager.workflow.syncWorkflows()
|
||||
await window.app.extensionManager.workflow.syncWorkflows()
|
||||
})
|
||||
|
||||
// Wait for Vue to re-render the workflow list
|
||||
@@ -86,23 +86,23 @@ export class WorkflowHelper {
|
||||
|
||||
async getUndoQueueSize(): Promise<number | undefined> {
|
||||
return this.comfyPage.page.evaluate(() => {
|
||||
const workflow = (window['app'].extensionManager as WorkspaceStore)
|
||||
.workflow.activeWorkflow
|
||||
const workflow = (window.app.extensionManager as WorkspaceStore).workflow
|
||||
.activeWorkflow
|
||||
return workflow?.changeTracker.undoQueue.length
|
||||
})
|
||||
}
|
||||
|
||||
async getRedoQueueSize(): Promise<number | undefined> {
|
||||
return this.comfyPage.page.evaluate(() => {
|
||||
const workflow = (window['app'].extensionManager as WorkspaceStore)
|
||||
.workflow.activeWorkflow
|
||||
const workflow = (window.app.extensionManager as WorkspaceStore).workflow
|
||||
.activeWorkflow
|
||||
return workflow?.changeTracker.redoQueue.length
|
||||
})
|
||||
}
|
||||
|
||||
async isCurrentWorkflowModified(): Promise<boolean | undefined> {
|
||||
return this.comfyPage.page.evaluate(() => {
|
||||
return (window['app'].extensionManager as WorkspaceStore).workflow
|
||||
return (window.app.extensionManager as WorkspaceStore).workflow
|
||||
.activeWorkflow?.isModified
|
||||
})
|
||||
}
|
||||
@@ -110,7 +110,7 @@ export class WorkflowHelper {
|
||||
async getExportedWorkflow(options?: { api?: boolean }): Promise<any> {
|
||||
const api = options?.api ?? false
|
||||
return this.comfyPage.page.evaluate(async (api) => {
|
||||
return (await window['app'].graphToPrompt())[api ? 'output' : 'workflow']
|
||||
return (await window.app.graphToPrompt())[api ? 'output' : 'workflow']
|
||||
}, api)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class SubgraphSlotReference {
|
||||
async getPosition(): Promise<Position> {
|
||||
const pos: [number, number] = await this.comfyPage.page.evaluate(
|
||||
([type, slotName]) => {
|
||||
const currentGraph = window['app'].canvas.graph
|
||||
const currentGraph = window.app.canvas.graph
|
||||
|
||||
// Check if we're in a subgraph
|
||||
if (currentGraph.constructor.name !== 'Subgraph') {
|
||||
@@ -52,7 +52,7 @@ export class SubgraphSlotReference {
|
||||
}
|
||||
|
||||
// Convert from offset to canvas coordinates
|
||||
const canvasPos = window['app'].canvas.ds.convertOffsetToCanvas([
|
||||
const canvasPos = window.app.canvas.ds.convertOffsetToCanvas([
|
||||
slot.pos[0],
|
||||
slot.pos[1]
|
||||
])
|
||||
@@ -70,7 +70,7 @@ export class SubgraphSlotReference {
|
||||
async getOpenSlotPosition(): Promise<Position> {
|
||||
const pos: [number, number] = await this.comfyPage.page.evaluate(
|
||||
([type]) => {
|
||||
const currentGraph = window['app'].canvas.graph
|
||||
const currentGraph = window.app.canvas.graph
|
||||
|
||||
if (currentGraph.constructor.name !== 'Subgraph') {
|
||||
throw new Error(
|
||||
@@ -86,7 +86,7 @@ export class SubgraphSlotReference {
|
||||
}
|
||||
|
||||
// Convert from offset to canvas coordinates
|
||||
const canvasPos = window['app'].canvas.ds.convertOffsetToCanvas([
|
||||
const canvasPos = window.app.canvas.ds.convertOffsetToCanvas([
|
||||
node.emptySlot.pos[0],
|
||||
node.emptySlot.pos[1]
|
||||
])
|
||||
@@ -112,12 +112,11 @@ class NodeSlotReference {
|
||||
const pos: [number, number] = await this.node.comfyPage.page.evaluate(
|
||||
([type, id, index]) => {
|
||||
// Use canvas.graph to get the current graph (works in both main graph and subgraphs)
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
|
||||
const rawPos = node.getConnectionPos(type === 'input', index)
|
||||
const convertedPos =
|
||||
window['app'].canvas.ds.convertOffsetToCanvas(rawPos)
|
||||
const convertedPos = window.app.canvas.ds.convertOffsetToCanvas(rawPos)
|
||||
|
||||
// Debug logging - convert Float64Arrays to regular arrays for visibility
|
||||
console.warn(
|
||||
@@ -127,7 +126,7 @@ class NodeSlotReference {
|
||||
nodeSize: [node.size[0], node.size[1]],
|
||||
rawConnectionPos: [rawPos[0], rawPos[1]],
|
||||
convertedPos: [convertedPos[0], convertedPos[1]],
|
||||
currentGraphType: window['app'].canvas.graph.constructor.name
|
||||
currentGraphType: window.app.canvas.graph.constructor.name
|
||||
}
|
||||
)
|
||||
|
||||
@@ -143,7 +142,7 @@ class NodeSlotReference {
|
||||
async getLinkCount() {
|
||||
return await this.node.comfyPage.page.evaluate(
|
||||
([type, id, index]) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
if (type === 'input') {
|
||||
return node.inputs[index].link == null ? 0 : 1
|
||||
@@ -156,7 +155,7 @@ class NodeSlotReference {
|
||||
async removeLinks() {
|
||||
await this.node.comfyPage.page.evaluate(
|
||||
([type, id, index]) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
if (type === 'input') {
|
||||
node.disconnectInput(index)
|
||||
@@ -181,15 +180,15 @@ class NodeWidgetReference {
|
||||
async getPosition(): Promise<Position> {
|
||||
const pos: [number, number] = await this.node.comfyPage.page.evaluate(
|
||||
([id, index]) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
const widget = node.widgets[index]
|
||||
if (!widget) throw new Error(`Widget ${index} not found.`)
|
||||
|
||||
const [x, y, w, h] = node.getBounding()
|
||||
return window['app'].canvasPosToClientPos([
|
||||
return window.app.canvasPosToClientPos([
|
||||
x + w / 2,
|
||||
y + window['LiteGraph']['NODE_TITLE_HEIGHT'] + widget.last_y + 1
|
||||
y + window.LiteGraph['NODE_TITLE_HEIGHT'] + widget.last_y + 1
|
||||
])
|
||||
},
|
||||
[this.node.id, this.index] as const
|
||||
@@ -206,7 +205,7 @@ class NodeWidgetReference {
|
||||
async getSocketPosition(): Promise<Position> {
|
||||
const pos: [number, number] = await this.node.comfyPage.page.evaluate(
|
||||
([id, index]) => {
|
||||
const node = window['app'].graph.getNodeById(id)
|
||||
const node = window.app.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
const widget = node.widgets[index]
|
||||
if (!widget) throw new Error(`Widget ${index} not found.`)
|
||||
@@ -217,9 +216,9 @@ class NodeWidgetReference {
|
||||
if (!slot) throw new Error(`Socket ${widget.name} not found.`)
|
||||
|
||||
const [x, y] = node.getBounding()
|
||||
return window['app'].canvasPosToClientPos([
|
||||
return window.app.canvasPosToClientPos([
|
||||
x + slot.pos[0],
|
||||
y + slot.pos[1] + window['LiteGraph']['NODE_TITLE_HEIGHT']
|
||||
y + slot.pos[1] + window.LiteGraph['NODE_TITLE_HEIGHT']
|
||||
])
|
||||
},
|
||||
[this.node.id, this.index] as const
|
||||
@@ -255,7 +254,7 @@ class NodeWidgetReference {
|
||||
async getValue() {
|
||||
return await this.node.comfyPage.page.evaluate(
|
||||
([id, index]) => {
|
||||
const node = window['app'].graph.getNodeById(id)
|
||||
const node = window.app.graph.getNodeById(id)
|
||||
if (!node) throw new Error(`Node ${id} not found.`)
|
||||
const widget = node.widgets[index]
|
||||
if (!widget) throw new Error(`Widget ${index} not found.`)
|
||||
@@ -272,7 +271,7 @@ export class NodeReference {
|
||||
) {}
|
||||
async exists(): Promise<boolean> {
|
||||
return await this.comfyPage.page.evaluate((id) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
return !!node
|
||||
}, this.id)
|
||||
}
|
||||
@@ -291,7 +290,7 @@ export class NodeReference {
|
||||
async getBounding(): Promise<Position & Size> {
|
||||
const [x, y, width, height]: [number, number, number, number] =
|
||||
await this.comfyPage.page.evaluate((id) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error('Node not found')
|
||||
return node.getBounding()
|
||||
}, this.id)
|
||||
@@ -329,7 +328,7 @@ export class NodeReference {
|
||||
async getProperty<T>(prop: string): Promise<T> {
|
||||
return await this.comfyPage.page.evaluate(
|
||||
([id, prop]) => {
|
||||
const node = window['app'].canvas.graph.getNodeById(id)
|
||||
const node = window.app.canvas.graph.getNodeById(id)
|
||||
if (!node) throw new Error('Node not found')
|
||||
return node[prop]
|
||||
},
|
||||
@@ -453,7 +452,7 @@ export class NodeReference {
|
||||
}
|
||||
async navigateIntoSubgraph() {
|
||||
const titleHeight = await this.comfyPage.page.evaluate(() => {
|
||||
return window['LiteGraph']['NODE_TITLE_HEIGHT']
|
||||
return window.LiteGraph['NODE_TITLE_HEIGHT']
|
||||
})
|
||||
const nodePos = await this.getPosition()
|
||||
const nodeSize = await this.getSize()
|
||||
@@ -467,7 +466,7 @@ export class NodeReference {
|
||||
|
||||
const checkIsInSubgraph = async () => {
|
||||
return this.comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph?.constructor?.name === 'Subgraph'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,13 +42,13 @@ class ComfyQueueButtonOptions {
|
||||
|
||||
public async setMode(mode: AutoQueueMode) {
|
||||
await this.page.evaluate((mode) => {
|
||||
window['app'].extensionManager.queueSettings.mode = mode
|
||||
window.app.extensionManager.queueSettings.mode = mode
|
||||
}, mode)
|
||||
}
|
||||
|
||||
public async getMode() {
|
||||
return await this.page.evaluate(() => {
|
||||
return window['app'].extensionManager.queueSettings.mode
|
||||
return window.app.extensionManager.queueSettings.mode
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function fitToViewInstant(
|
||||
{ selectionOnly: boolean }
|
||||
>(
|
||||
({ selectionOnly }) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
if (!app?.canvas) return null
|
||||
|
||||
const canvas = app.canvas
|
||||
@@ -90,7 +90,7 @@ export async function fitToViewInstant(
|
||||
|
||||
await comfyPage.page.evaluate(
|
||||
({ bounds, zoom }) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
if (!app?.canvas) return
|
||||
|
||||
const canvas = app.canvas
|
||||
|
||||
@@ -33,7 +33,7 @@ export class ComfyTemplates {
|
||||
|
||||
async getAllTemplates(): Promise<TemplateInfo[]> {
|
||||
const templates: WorkflowTemplates[] = await this.page.evaluate(() =>
|
||||
window['app'].api.getCoreWorkflowTemplates()
|
||||
window.app.api.getCoreWorkflowTemplates()
|
||||
)
|
||||
return templates.flatMap((t) => t.templates)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ test.describe('Actionbar', { tag: '@ui' }, () => {
|
||||
// Find and set the width on the latent node
|
||||
const triggerChange = async (value: number) => {
|
||||
return await comfyPage.page.evaluate((value) => {
|
||||
const node = window['app'].graph._nodes.find(
|
||||
const node = window.app.graph._nodes.find(
|
||||
(n) => n.type === 'EmptyLatentImage'
|
||||
)
|
||||
node.widgets[0].value = value
|
||||
|
||||
@@ -11,7 +11,7 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => {
|
||||
|
||||
test('Can display workflow name', async ({ comfyPage }) => {
|
||||
const workflowName = await comfyPage.page.evaluate(async () => {
|
||||
return window['app'].extensionManager.workflow.activeWorkflow.filename
|
||||
return window.app.extensionManager.workflow.activeWorkflow.filename
|
||||
})
|
||||
expect(await comfyPage.page.title()).toBe(`*${workflowName} - ComfyUI`)
|
||||
})
|
||||
@@ -22,7 +22,7 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
const workflowName = await comfyPage.page.evaluate(async () => {
|
||||
return window['app'].extensionManager.workflow.activeWorkflow.filename
|
||||
return window.app.extensionManager.workflow.activeWorkflow.filename
|
||||
})
|
||||
expect(await comfyPage.page.title()).toBe(`${workflowName} - ComfyUI`)
|
||||
|
||||
@@ -38,7 +38,7 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => {
|
||||
|
||||
// Delete the saved workflow for cleanup.
|
||||
await comfyPage.page.evaluate(async () => {
|
||||
return window['app'].extensionManager.workflow.activeWorkflow.delete()
|
||||
return window.app.extensionManager.workflow.activeWorkflow.delete()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,12 +7,12 @@ import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositio
|
||||
|
||||
async function beforeChange(comfyPage: ComfyPage) {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].canvas.emitBeforeChange()
|
||||
window.app.canvas.emitBeforeChange()
|
||||
})
|
||||
}
|
||||
async function afterChange(comfyPage: ComfyPage) {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].canvas.emitAfterChange()
|
||||
window.app.canvas.emitAfterChange()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => {
|
||||
test('Can detect changes in workflow.extra', async ({ comfyPage }) => {
|
||||
expect(await comfyPage.workflow.getUndoQueueSize()).toBe(0)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].graph.extra.foo = 'bar'
|
||||
window.app.graph.extra.foo = 'bar'
|
||||
})
|
||||
// Click empty space to trigger a change detection.
|
||||
await comfyPage.canvasOps.clickEmptySpace(
|
||||
|
||||
@@ -179,7 +179,7 @@ test.describe('Color Palette', { tag: ['@screenshot', '@settings'] }, () => {
|
||||
|
||||
test('Can add custom color palette', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate((p) => {
|
||||
window['app'].extensionManager.colorPalette.addCustomColorPalette(p)
|
||||
window.app.extensionManager.colorPalette.addCustomColorPalette(p)
|
||||
}, customColorPalettes.obsidian_dark)
|
||||
expect(await comfyPage.toast.getToastErrorCount()).toBe(0)
|
||||
|
||||
|
||||
@@ -9,25 +9,25 @@ test.beforeEach(async ({ comfyPage }) => {
|
||||
test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
test('Should execute command', async ({ comfyPage }) => {
|
||||
await comfyPage.command.registerCommand('TestCommand', () => {
|
||||
window['foo'] = true
|
||||
window.foo = true
|
||||
})
|
||||
|
||||
await comfyPage.command.executeCommand('TestCommand')
|
||||
expect(await comfyPage.page.evaluate(() => window['foo'])).toBe(true)
|
||||
expect(await comfyPage.page.evaluate(() => window.foo)).toBe(true)
|
||||
})
|
||||
|
||||
test('Should execute async command', async ({ comfyPage }) => {
|
||||
await comfyPage.command.registerCommand('TestCommand', async () => {
|
||||
await new Promise<void>((resolve) =>
|
||||
setTimeout(() => {
|
||||
window['foo'] = true
|
||||
window.foo = true
|
||||
resolve()
|
||||
}, 5)
|
||||
)
|
||||
})
|
||||
|
||||
await comfyPage.command.executeCommand('TestCommand')
|
||||
expect(await comfyPage.page.evaluate(() => window['foo'])).toBe(true)
|
||||
expect(await comfyPage.page.evaluate(() => window.foo)).toBe(true)
|
||||
})
|
||||
|
||||
test('Should handle command errors', async ({ comfyPage }) => {
|
||||
|
||||
@@ -345,7 +345,7 @@ test.describe('Error dialog', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const graph = window['graph']
|
||||
const graph = window.graph
|
||||
graph.configure = () => {
|
||||
throw new Error('Error on configure!')
|
||||
}
|
||||
@@ -361,7 +361,7 @@ test.describe('Error dialog', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page.evaluate(async () => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
app.api.queuePrompt = () => {
|
||||
throw new Error('Error on queuePrompt!')
|
||||
}
|
||||
@@ -391,7 +391,7 @@ test.describe('Signin dialog', () => {
|
||||
await textBox.press('Control+c')
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
void window['app'].extensionManager.dialog.showSignInDialog()
|
||||
void window.app.extensionManager.dialog.showSignInDialog()
|
||||
})
|
||||
|
||||
const input = comfyPage.page.locator('#comfy-org-sign-in-password')
|
||||
|
||||
@@ -10,14 +10,14 @@ test.describe('Topbar commands', () => {
|
||||
|
||||
test('Should allow registering topbar commands', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
commands: [
|
||||
{
|
||||
id: 'foo',
|
||||
label: 'foo-command',
|
||||
function: () => {
|
||||
window['foo'] = true
|
||||
window.foo = true
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -31,7 +31,7 @@ test.describe('Topbar commands', () => {
|
||||
})
|
||||
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['ext', 'foo-command'])
|
||||
expect(await comfyPage.page.evaluate(() => window['foo'])).toBe(true)
|
||||
expect(await comfyPage.page.evaluate(() => window.foo)).toBe(true)
|
||||
})
|
||||
|
||||
test('Should not allow register command defined in other extension', async ({
|
||||
@@ -39,7 +39,7 @@ test.describe('Topbar commands', () => {
|
||||
}) => {
|
||||
await comfyPage.command.registerCommand('foo', () => alert(1))
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
menuCommands: [
|
||||
{
|
||||
@@ -56,14 +56,14 @@ test.describe('Topbar commands', () => {
|
||||
|
||||
test('Should allow registering keybindings', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
commands: [
|
||||
{
|
||||
id: 'TestCommand',
|
||||
function: () => {
|
||||
window['TestCommand'] = true
|
||||
window.TestCommand = true
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -77,15 +77,13 @@ test.describe('Topbar commands', () => {
|
||||
})
|
||||
|
||||
await comfyPage.page.keyboard.press('k')
|
||||
expect(await comfyPage.page.evaluate(() => window['TestCommand'])).toBe(
|
||||
true
|
||||
)
|
||||
expect(await comfyPage.page.evaluate(() => window.TestCommand)).toBe(true)
|
||||
})
|
||||
|
||||
test.describe('Settings', () => {
|
||||
test('Should allow adding settings', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
settings: [
|
||||
{
|
||||
@@ -94,14 +92,14 @@ test.describe('Topbar commands', () => {
|
||||
type: 'text',
|
||||
defaultValue: 'Hello, world!',
|
||||
onChange: () => {
|
||||
window['changeCount'] = (window['changeCount'] ?? 0) + 1
|
||||
window.changeCount = (window.changeCount ?? 0) + 1
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
// onChange is called when the setting is first added
|
||||
expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(1)
|
||||
expect(await comfyPage.page.evaluate(() => window.changeCount)).toBe(1)
|
||||
expect(await comfyPage.settings.getSetting('TestSetting')).toBe(
|
||||
'Hello, world!'
|
||||
)
|
||||
@@ -110,12 +108,12 @@ test.describe('Topbar commands', () => {
|
||||
expect(await comfyPage.settings.getSetting('TestSetting')).toBe(
|
||||
'Hello, universe!'
|
||||
)
|
||||
expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(2)
|
||||
expect(await comfyPage.page.evaluate(() => window.changeCount)).toBe(2)
|
||||
})
|
||||
|
||||
test('Should allow setting boolean settings', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
settings: [
|
||||
{
|
||||
@@ -124,7 +122,7 @@ test.describe('Topbar commands', () => {
|
||||
type: 'boolean',
|
||||
defaultValue: false,
|
||||
onChange: () => {
|
||||
window['changeCount'] = (window['changeCount'] ?? 0) + 1
|
||||
window.changeCount = (window.changeCount ?? 0) + 1
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -134,14 +132,14 @@ test.describe('Topbar commands', () => {
|
||||
expect(await comfyPage.settings.getSetting('Comfy.TestSetting')).toBe(
|
||||
false
|
||||
)
|
||||
expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(1)
|
||||
expect(await comfyPage.page.evaluate(() => window.changeCount)).toBe(1)
|
||||
|
||||
await comfyPage.settingDialog.open()
|
||||
await comfyPage.settingDialog.toggleBooleanSetting('Comfy.TestSetting')
|
||||
expect(await comfyPage.settings.getSetting('Comfy.TestSetting')).toBe(
|
||||
true
|
||||
)
|
||||
expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(2)
|
||||
expect(await comfyPage.page.evaluate(() => window.changeCount)).toBe(2)
|
||||
})
|
||||
|
||||
test.describe('Passing through attrs to setting components', () => {
|
||||
@@ -199,7 +197,7 @@ test.describe('Topbar commands', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page.evaluate((config) => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
settings: [
|
||||
{
|
||||
@@ -232,7 +230,7 @@ test.describe('Topbar commands', () => {
|
||||
test.describe('About panel', () => {
|
||||
test('Should allow adding badges', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
aboutPageBadges: [
|
||||
{
|
||||
@@ -255,7 +253,7 @@ test.describe('Topbar commands', () => {
|
||||
test.describe('Dialog', () => {
|
||||
test('Should allow showing a prompt dialog', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
void window['app'].extensionManager.dialog
|
||||
void window.app.extensionManager.dialog
|
||||
.prompt({
|
||||
title: 'Test Prompt',
|
||||
message: 'Test Prompt Message'
|
||||
@@ -275,7 +273,7 @@ test.describe('Topbar commands', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
void window['app'].extensionManager.dialog
|
||||
void window.app.extensionManager.dialog
|
||||
.confirm({
|
||||
title: 'Test Confirm',
|
||||
message: 'Test Confirm Message'
|
||||
@@ -292,7 +290,7 @@ test.describe('Topbar commands', () => {
|
||||
test('Should allow dismissing a dialog', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['value'] = 'foo'
|
||||
void window['app'].extensionManager.dialog
|
||||
void window.app.extensionManager.dialog
|
||||
.confirm({
|
||||
title: 'Test Confirm',
|
||||
message: 'Test Confirm Message'
|
||||
@@ -317,7 +315,7 @@ test.describe('Topbar commands', () => {
|
||||
}) => {
|
||||
// Register an extension with a selection toolbox command
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
commands: [
|
||||
{
|
||||
|
||||
@@ -38,11 +38,11 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
// Monitor for server feature flags
|
||||
const checkInterval = setInterval(() => {
|
||||
if (
|
||||
window['app']?.api?.serverFeatureFlags &&
|
||||
Object.keys(window['app'].api.serverFeatureFlags).length > 0
|
||||
window.app?.api?.serverFeatureFlags &&
|
||||
Object.keys(window.app.api.serverFeatureFlags).length > 0
|
||||
) {
|
||||
window.__capturedMessages!.serverFeatureFlags =
|
||||
window['app'].api.serverFeatureFlags
|
||||
window.app.api.serverFeatureFlags
|
||||
clearInterval(checkInterval)
|
||||
}
|
||||
}, 100)
|
||||
@@ -96,7 +96,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}) => {
|
||||
// Get the actual server feature flags from the backend
|
||||
const serverFlags = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.serverFeatureFlags
|
||||
return window.app!.api.serverFeatureFlags
|
||||
})
|
||||
|
||||
// Verify we received real feature flags from the backend
|
||||
@@ -115,26 +115,22 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}) => {
|
||||
// Test serverSupportsFeature with real backend flags
|
||||
const supportsPreviewMetadata = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.serverSupportsFeature(
|
||||
'supports_preview_metadata'
|
||||
)
|
||||
return window.app!.api.serverSupportsFeature('supports_preview_metadata')
|
||||
})
|
||||
// The method should return a boolean based on the backend's value
|
||||
expect(typeof supportsPreviewMetadata).toBe('boolean')
|
||||
|
||||
// Test non-existent feature - should always return false
|
||||
const supportsNonExistent = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.serverSupportsFeature(
|
||||
'non_existent_feature_xyz'
|
||||
)
|
||||
return window.app!.api.serverSupportsFeature('non_existent_feature_xyz')
|
||||
})
|
||||
expect(supportsNonExistent).toBe(false)
|
||||
|
||||
// Test that the method only returns true for boolean true values
|
||||
const testResults = await comfyPage.page.evaluate(() => {
|
||||
// Temporarily modify serverFeatureFlags to test behavior
|
||||
const original = window['app']!.api.serverFeatureFlags
|
||||
window['app']!.api.serverFeatureFlags = {
|
||||
const original = window.app!.api.serverFeatureFlags
|
||||
window.app!.api.serverFeatureFlags = {
|
||||
bool_true: true,
|
||||
bool_false: false,
|
||||
string_value: 'yes',
|
||||
@@ -143,15 +139,15 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}
|
||||
|
||||
const results = {
|
||||
bool_true: window['app']!.api.serverSupportsFeature('bool_true'),
|
||||
bool_false: window['app']!.api.serverSupportsFeature('bool_false'),
|
||||
string_value: window['app']!.api.serverSupportsFeature('string_value'),
|
||||
number_value: window['app']!.api.serverSupportsFeature('number_value'),
|
||||
null_value: window['app']!.api.serverSupportsFeature('null_value')
|
||||
bool_true: window.app!.api.serverSupportsFeature('bool_true'),
|
||||
bool_false: window.app!.api.serverSupportsFeature('bool_false'),
|
||||
string_value: window.app!.api.serverSupportsFeature('string_value'),
|
||||
number_value: window.app!.api.serverSupportsFeature('number_value'),
|
||||
null_value: window.app!.api.serverSupportsFeature('null_value')
|
||||
}
|
||||
|
||||
// Restore original
|
||||
window['app']!.api.serverFeatureFlags = original
|
||||
window.app!.api.serverFeatureFlags = original
|
||||
return results
|
||||
})
|
||||
|
||||
@@ -168,20 +164,20 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}) => {
|
||||
// Test getServerFeature method
|
||||
const previewMetadataValue = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.getServerFeature('supports_preview_metadata')
|
||||
return window.app!.api.getServerFeature('supports_preview_metadata')
|
||||
})
|
||||
expect(typeof previewMetadataValue).toBe('boolean')
|
||||
|
||||
// Test getting max_upload_size
|
||||
const maxUploadSize = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.getServerFeature('max_upload_size')
|
||||
return window.app!.api.getServerFeature('max_upload_size')
|
||||
})
|
||||
expect(typeof maxUploadSize).toBe('number')
|
||||
expect(maxUploadSize).toBeGreaterThan(0)
|
||||
|
||||
// Test getServerFeature with default value for non-existent feature
|
||||
const defaultValue = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.getServerFeature(
|
||||
return window.app!.api.getServerFeature(
|
||||
'non_existent_feature_xyz',
|
||||
'default'
|
||||
)
|
||||
@@ -194,7 +190,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}) => {
|
||||
// Test getServerFeatures returns all flags
|
||||
const allFeatures = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.api.getServerFeatures()
|
||||
return window.app!.api.getServerFeatures()
|
||||
})
|
||||
|
||||
expect(allFeatures).toBeTruthy()
|
||||
@@ -207,14 +203,14 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
test('Client feature flags are immutable', async ({ comfyPage }) => {
|
||||
// Test that getClientFeatureFlags returns a copy
|
||||
const immutabilityTest = await comfyPage.page.evaluate(() => {
|
||||
const flags1 = window['app']!.api.getClientFeatureFlags()
|
||||
const flags2 = window['app']!.api.getClientFeatureFlags()
|
||||
const flags1 = window.app!.api.getClientFeatureFlags()
|
||||
const flags2 = window.app!.api.getClientFeatureFlags()
|
||||
|
||||
// Modify the first object
|
||||
flags1.test_modification = true
|
||||
|
||||
// Get flags again to check if original was modified
|
||||
const flags3 = window['app']!.api.getClientFeatureFlags()
|
||||
const flags3 = window.app!.api.getClientFeatureFlags()
|
||||
|
||||
return {
|
||||
areEqual: flags1 === flags2,
|
||||
@@ -240,14 +236,14 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
}) => {
|
||||
const immutabilityTest = await comfyPage.page.evaluate(() => {
|
||||
// Get a copy of server features
|
||||
const features1 = window['app']!.api.getServerFeatures()
|
||||
const features1 = window.app!.api.getServerFeatures()
|
||||
|
||||
// Try to modify it
|
||||
features1.supports_preview_metadata = false
|
||||
features1.new_feature = 'added'
|
||||
|
||||
// Get another copy
|
||||
const features2 = window['app']!.api.getServerFeatures()
|
||||
const features2 = window.app!.api.getServerFeatures()
|
||||
|
||||
return {
|
||||
modifiedValue: features1.supports_preview_metadata,
|
||||
@@ -286,7 +282,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
// Monitor when feature flags arrive by checking periodically
|
||||
const checkFeatureFlags = setInterval(() => {
|
||||
if (
|
||||
window['app']?.api?.serverFeatureFlags?.supports_preview_metadata !==
|
||||
window.app?.api?.serverFeatureFlags?.supports_preview_metadata !==
|
||||
undefined
|
||||
) {
|
||||
window.__appReadiness = {
|
||||
@@ -299,7 +295,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
|
||||
// Monitor API initialization
|
||||
const checkApi = setInterval(() => {
|
||||
if (window['app']?.api) {
|
||||
if (window.app?.api) {
|
||||
window.__appReadiness = {
|
||||
...window.__appReadiness,
|
||||
apiInitialized: true
|
||||
@@ -310,7 +306,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
|
||||
// Monitor app initialization
|
||||
const checkApp = setInterval(() => {
|
||||
if (window['app']?.graph) {
|
||||
if (window.app?.graph) {
|
||||
window.__appReadiness = {
|
||||
...window.__appReadiness,
|
||||
appInitialized: true
|
||||
@@ -333,7 +329,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
// Wait for feature flags to be received
|
||||
await newPage.waitForFunction(
|
||||
() =>
|
||||
window['app']?.api?.serverFeatureFlags?.supports_preview_metadata !==
|
||||
window.app?.api?.serverFeatureFlags?.supports_preview_metadata !==
|
||||
undefined,
|
||||
{
|
||||
timeout: 10000
|
||||
@@ -344,7 +340,7 @@ test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => {
|
||||
const readiness = await newPage.evaluate(() => {
|
||||
return {
|
||||
...window.__appReadiness,
|
||||
currentFlags: window['app']!.api.serverFeatureFlags
|
||||
currentFlags: window.app!.api.serverFeatureFlags
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ test.describe('Graph', { tag: ['@smoke', '@canvas'] }, () => {
|
||||
await comfyPage.workflow.loadWorkflow('inputs/input_order_swap')
|
||||
expect(
|
||||
await comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.links.get(1)?.target_slot
|
||||
return window.app.graph.links.get(1)?.target_slot
|
||||
})
|
||||
).toBe(1)
|
||||
})
|
||||
|
||||
@@ -26,7 +26,7 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
'canvas-with-hidden-links.png'
|
||||
)
|
||||
const hiddenLinkRenderMode = await comfyPage.page.evaluate(() => {
|
||||
return window['LiteGraph'].HIDDEN_LINK
|
||||
return window.LiteGraph.HIDDEN_LINK
|
||||
})
|
||||
expect(await comfyPage.settings.getSetting('Comfy.LinkRenderMode')).toBe(
|
||||
hiddenLinkRenderMode
|
||||
|
||||
@@ -158,7 +158,7 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
const totalInputCount = await comfyPage.page.evaluate((nodeName) => {
|
||||
const {
|
||||
extra: { groupNodes }
|
||||
} = window['app'].graph
|
||||
} = window.app.graph
|
||||
const { nodes } = groupNodes[nodeName]
|
||||
return nodes.reduce((acc: number, node) => {
|
||||
return acc + node.inputs.length
|
||||
@@ -166,7 +166,7 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
}, groupNodeName)
|
||||
|
||||
const visibleInputCount = await comfyPage.page.evaluate((id) => {
|
||||
const node = window['app'].graph.getNodeById(id)
|
||||
const node = window.app.graph.getNodeById(id)
|
||||
return node.inputs.length
|
||||
}, groupNodeId)
|
||||
|
||||
@@ -233,7 +233,7 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
|
||||
const isRegisteredLitegraph = async (comfyPage: ComfyPage) => {
|
||||
return await comfyPage.page.evaluate((nodeType: string) => {
|
||||
return !!window['LiteGraph'].registered_node_types[nodeType]
|
||||
return !!window.LiteGraph.registered_node_types[nodeType]
|
||||
}, GROUP_NODE_TYPE)
|
||||
}
|
||||
|
||||
@@ -307,12 +307,12 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
|
||||
await comfyPage.clipboard.paste()
|
||||
const currentGraphState = await comfyPage.page.evaluate(() =>
|
||||
window['app'].graph.serialize()
|
||||
window.app.graph.serialize()
|
||||
)
|
||||
|
||||
await test.step('Load workflow containing a group node pasted from a different workflow', async () => {
|
||||
await comfyPage.page.evaluate(
|
||||
(workflow) => window['app'].loadGraphData(workflow),
|
||||
(workflow) => window.app.loadGraphData(workflow),
|
||||
currentGraphState
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -11,14 +11,14 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.command.registerKeybinding({ key: 'k' }, () => {
|
||||
window['TestCommand'] = true
|
||||
window.TestCommand = true
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await textBox.click()
|
||||
await textBox.fill('k')
|
||||
await expect(textBox).toHaveValue('k')
|
||||
expect(await comfyPage.page.evaluate(() => window['TestCommand'])).toBe(
|
||||
expect(await comfyPage.page.evaluate(() => window.TestCommand)).toBe(
|
||||
undefined
|
||||
)
|
||||
})
|
||||
@@ -27,7 +27,7 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.command.registerKeybinding({ key: 'k', ctrl: true }, () => {
|
||||
window['TestCommand'] = true
|
||||
window.TestCommand = true
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
@@ -35,23 +35,21 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
await textBox.fill('q')
|
||||
await textBox.press('Control+k')
|
||||
await expect(textBox).toHaveValue('q')
|
||||
expect(await comfyPage.page.evaluate(() => window['TestCommand'])).toBe(
|
||||
true
|
||||
)
|
||||
expect(await comfyPage.page.evaluate(() => window.TestCommand)).toBe(true)
|
||||
})
|
||||
|
||||
test('Should not trigger keybinding reserved by text input when typing in input fields', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.command.registerKeybinding({ key: 'Ctrl+v' }, () => {
|
||||
window['TestCommand'] = true
|
||||
window.TestCommand = true
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await textBox.click()
|
||||
await textBox.press('Control+v')
|
||||
await expect(textBox).toBeFocused()
|
||||
expect(await comfyPage.page.evaluate(() => window['TestCommand'])).toBe(
|
||||
expect(await comfyPage.page.evaluate(() => window.TestCommand)).toBe(
|
||||
undefined
|
||||
)
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Get initial LOD state and settings
|
||||
const initialState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale,
|
||||
@@ -36,7 +36,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const aboveThresholdState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
@@ -54,7 +54,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Check that LOD is now active
|
||||
const zoomedOutState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
@@ -70,7 +70,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Check that LOD is now inactive
|
||||
const zoomedInState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
@@ -94,7 +94,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Check that font size updated
|
||||
const newState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
minFontSize: canvas.min_font_size_for_lod
|
||||
}
|
||||
@@ -105,7 +105,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// At default zoom, LOD should still be inactive (scale is exactly 1.0, not less than)
|
||||
const lodState = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].canvas.low_quality
|
||||
return window.app.canvas.low_quality
|
||||
})
|
||||
expect(lodState).toBe(false)
|
||||
|
||||
@@ -114,7 +114,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const afterZoom = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
@@ -139,7 +139,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// LOD should remain disabled even at very low zoom
|
||||
const state = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale,
|
||||
@@ -164,8 +164,8 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Zoom to target level
|
||||
await comfyPage.page.evaluate((zoom) => {
|
||||
window['app'].canvas.ds.scale = zoom
|
||||
window['app'].canvas.setDirty(true, true)
|
||||
window.app.canvas.ds.scale = zoom
|
||||
window.app.canvas.setDirty(true, true)
|
||||
}, targetZoom)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -175,7 +175,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
)
|
||||
|
||||
const lowQualityState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
@@ -196,7 +196,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
)
|
||||
|
||||
const highQualityState = await comfyPage.page.evaluate(() => {
|
||||
const canvas = window['app'].canvas
|
||||
const canvas = window.app.canvas
|
||||
return {
|
||||
lowQuality: canvas.low_quality,
|
||||
scale: canvas.ds.scale
|
||||
|
||||
@@ -11,7 +11,7 @@ test.describe('Menu', { tag: '@ui' }, () => {
|
||||
const initialChildrenCount = await comfyPage.menu.buttons.count()
|
||||
|
||||
await comfyPage.page.evaluate(async () => {
|
||||
window['app'].extensionManager.registerSidebarTab({
|
||||
window.app.extensionManager.registerSidebarTab({
|
||||
id: 'search',
|
||||
icon: 'pi pi-search',
|
||||
title: 'search',
|
||||
@@ -155,7 +155,7 @@ test.describe('Menu', { tag: '@ui' }, () => {
|
||||
|
||||
test('Can catch error when executing command', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestExtension1',
|
||||
commands: [
|
||||
{
|
||||
|
||||
@@ -8,9 +8,7 @@ test.describe('Minimap', { tag: '@canvas' }, () => {
|
||||
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', true)
|
||||
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true)
|
||||
await comfyPage.workflow.loadWorkflow('default')
|
||||
await comfyPage.page.waitForFunction(
|
||||
() => window['app'] && window['app'].canvas
|
||||
)
|
||||
await comfyPage.page.waitForFunction(() => window.app && window.app.canvas)
|
||||
})
|
||||
|
||||
test('Validate minimap is visible by default', async ({ comfyPage }) => {
|
||||
|
||||
@@ -12,8 +12,8 @@ test.beforeEach(async ({ comfyPage }) => {
|
||||
test.describe('Node Badge', { tag: ['@screenshot', '@smoke', '@node'] }, () => {
|
||||
test('Can add badge', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const LGraphBadge = window['LGraphBadge']
|
||||
const app = window['app'] as ComfyApp
|
||||
const LGraphBadge = window.LGraphBadge
|
||||
const app = window.app as ComfyApp
|
||||
const graph = app.graph
|
||||
const nodes = graph.nodes
|
||||
|
||||
@@ -29,8 +29,8 @@ test.describe('Node Badge', { tag: ['@screenshot', '@smoke', '@node'] }, () => {
|
||||
|
||||
test('Can add multiple badges', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const LGraphBadge = window['LGraphBadge']
|
||||
const app = window['app'] as ComfyApp
|
||||
const LGraphBadge = window.LGraphBadge
|
||||
const app = window.app as ComfyApp
|
||||
const graph = app.graph
|
||||
const nodes = graph.nodes
|
||||
|
||||
@@ -49,8 +49,8 @@ test.describe('Node Badge', { tag: ['@screenshot', '@smoke', '@node'] }, () => {
|
||||
|
||||
test('Can add badge left-side', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const LGraphBadge = window['LGraphBadge']
|
||||
const app = window['app'] as ComfyApp
|
||||
const LGraphBadge = window.LGraphBadge
|
||||
const app = window.app as ComfyApp
|
||||
const graph = app.graph
|
||||
const nodes = graph.nodes
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ async function selectNodeWithPan(comfyPage: ComfyPage, nodeRef: NodeReference) {
|
||||
const nodePos = await nodeRef.getPosition()
|
||||
|
||||
await comfyPage.page.evaluate((pos) => {
|
||||
const app = window['app']!
|
||||
const app = window.app!
|
||||
const canvas = app.canvas
|
||||
canvas.ds.offset[0] = -pos.x + canvas.canvas.width / 2
|
||||
canvas.ds.offset[1] = -pos.y + canvas.canvas.height / 2 + 100
|
||||
@@ -356,7 +356,7 @@ This is documentation for a custom node.
|
||||
|
||||
// Find and select a custom/group node
|
||||
const nodeRefs = await comfyPage.page.evaluate(() => {
|
||||
return window['app']!.graph!.nodes.map((n) => n.id)
|
||||
return window.app!.graph!.nodes.map((n) => n.id)
|
||||
})
|
||||
if (nodeRefs.length > 0) {
|
||||
const firstNode = await comfyPage.nodeOps.getNodeRefById(nodeRefs[0])
|
||||
|
||||
@@ -26,21 +26,21 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {
|
||||
nodeName: string
|
||||
): Promise<string[] | undefined> => {
|
||||
return await comfyPage.page.evaluate((name) => {
|
||||
const node = window['app'].graph.nodes.find((node) => node.title === name)
|
||||
const node = window.app.graph.nodes.find((node) => node.title === name)
|
||||
return node.widgets[0].options.values
|
||||
}, nodeName)
|
||||
}
|
||||
|
||||
const getWidgetValue = async (comfyPage: ComfyPage, nodeName: string) => {
|
||||
return await comfyPage.page.evaluate((name) => {
|
||||
const node = window['app'].graph.nodes.find((node) => node.title === name)
|
||||
const node = window.app.graph.nodes.find((node) => node.title === name)
|
||||
return node.widgets[0].value
|
||||
}, nodeName)
|
||||
}
|
||||
|
||||
const clickRefreshButton = (comfyPage: ComfyPage, nodeName: string) => {
|
||||
return comfyPage.page.evaluate((name) => {
|
||||
const node = window['app'].graph.nodes.find((node) => node.title === name)
|
||||
const node = window.app.graph.nodes.find((node) => node.title === name)
|
||||
const buttonWidget = node.widgets.find((w) => w.name === 'refresh')
|
||||
return buttonWidget?.callback()
|
||||
}, nodeName)
|
||||
@@ -92,7 +92,7 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {
|
||||
await comfyPage.workflow.loadWorkflow('inputs/remote_widget')
|
||||
|
||||
const node = await comfyPage.page.evaluate((name) => {
|
||||
return window['app'].graph.nodes.find((node) => node.title === name)
|
||||
return window.app.graph.nodes.find((node) => node.title === name)
|
||||
}, nodeName)
|
||||
expect(node).toBeDefined()
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => {
|
||||
|
||||
// Get initial slot label
|
||||
const initialInputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || graph.inputs?.[0]?.name || null
|
||||
})
|
||||
|
||||
@@ -56,7 +56,7 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => {
|
||||
|
||||
// Verify the rename worked
|
||||
const afterFirstRename = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
const slot = graph.inputs?.[0]
|
||||
return {
|
||||
label: slot?.label || null,
|
||||
@@ -99,7 +99,7 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => {
|
||||
|
||||
// Verify the second rename worked
|
||||
const afterSecondRename = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
expect(afterSecondRename).toBe(SECOND_RENAMED_NAME)
|
||||
@@ -115,7 +115,7 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => {
|
||||
|
||||
// Get initial output slot label
|
||||
const initialOutputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.outputs?.[0]?.label || graph.outputs?.[0]?.name || null
|
||||
})
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
type: 'inputs' | 'outputs'
|
||||
): Promise<number> {
|
||||
return await comfyPage.page.evaluate((slotType) => {
|
||||
return window['app'].canvas.graph[slotType]?.length || 0
|
||||
return window.app.canvas.graph[slotType]?.length || 0
|
||||
}, type)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
comfyPage: typeof test.prototype.comfyPage
|
||||
): Promise<number> {
|
||||
return await comfyPage.page.evaluate(() => {
|
||||
return window['app'].canvas.graph.nodes?.length || 0
|
||||
return window.app.canvas.graph.nodes?.length || 0
|
||||
})
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
comfyPage: typeof test.prototype.comfyPage
|
||||
): Promise<boolean> {
|
||||
return await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph?.constructor?.name === 'Subgraph'
|
||||
})
|
||||
}
|
||||
@@ -132,7 +132,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
const initialInputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -151,7 +151,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const newInputName = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -166,7 +166,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
const initialInputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -183,7 +183,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const newInputName = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -198,7 +198,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
const initialOutputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.outputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -216,7 +216,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const newOutputName = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.outputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -233,7 +233,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
const initialInputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -254,7 +254,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const newInputName = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -271,13 +271,13 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
const initialInputLabel = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
// Use direct pointer event approach to double-click on label
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const graph = app.canvas.graph
|
||||
const input = graph.inputs?.[0]
|
||||
|
||||
@@ -326,7 +326,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const newInputName = await comfyPage.page.evaluate(() => {
|
||||
const graph = window['app'].canvas.graph
|
||||
const graph = window.app.canvas.graph
|
||||
return graph.inputs?.[0]?.label || null
|
||||
})
|
||||
|
||||
@@ -340,7 +340,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
'subgraphs/subgraph-compressed-target-slot'
|
||||
)
|
||||
const step = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes[0].widgets[0].options.step
|
||||
return window.app.graph.nodes[0].widgets[0].options.step
|
||||
})
|
||||
expect(step).toBe(10)
|
||||
})
|
||||
@@ -459,7 +459,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
const initialNodeCount = await getGraphNodeCount(comfyPage)
|
||||
|
||||
const nodesInSubgraph = await comfyPage.page.evaluate(() => {
|
||||
const nodes = window['app'].canvas.graph.nodes
|
||||
const nodes = window.app.canvas.graph.nodes
|
||||
return nodes?.[0]?.id || null
|
||||
})
|
||||
|
||||
@@ -689,7 +689,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
|
||||
// Check that the subgraph node has no widgets after removing the text slot
|
||||
const widgetCount = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].canvas.graph.nodes[0].widgets?.length || 0
|
||||
return window.app.canvas.graph.nodes[0].widgets?.length || 0
|
||||
})
|
||||
|
||||
expect(widgetCount).toBe(0)
|
||||
|
||||
@@ -10,7 +10,7 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
// Register test settings to verify hidden/deprecated filtering
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].registerExtension({
|
||||
window.app.registerExtension({
|
||||
name: 'TestSettingsExtension',
|
||||
settings: [
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ async function getInputLinkDetails(
|
||||
) {
|
||||
return await page.evaluate(
|
||||
([targetNodeId, targetSlot]) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) return null
|
||||
|
||||
@@ -437,7 +437,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
|
||||
// This avoids relying on an exact path hit-test position.
|
||||
await comfyPage.page.evaluate(
|
||||
([targetNodeId, targetSlot, clientPoint]) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) throw new Error('Graph not available')
|
||||
const node = graph.getNodeById(targetNodeId)
|
||||
@@ -525,7 +525,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
|
||||
// This avoids relying on an exact path hit-test position.
|
||||
await comfyPage.page.evaluate(
|
||||
([targetNodeId, targetSlot, clientPoint]) => {
|
||||
const app = window['app']
|
||||
const app = window.app
|
||||
const graph = app?.canvas?.graph ?? app?.graph
|
||||
if (!graph) throw new Error('Graph not available')
|
||||
const node = graph.getNodeById(targetNodeId)
|
||||
@@ -906,7 +906,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
|
||||
|
||||
// Pinned endpoint should not change with mouse movement while menu is open
|
||||
const before = await comfyPage.page.evaluate(() => {
|
||||
const snap = window['app']?.canvas?.linkConnector?.state?.snapLinksPos
|
||||
const snap = window.app?.canvas?.linkConnector?.state?.snapLinksPos
|
||||
return Array.isArray(snap) ? [snap[0], snap[1]] : null
|
||||
})
|
||||
expect(before).not.toBeNull()
|
||||
@@ -914,7 +914,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => {
|
||||
// Move mouse elsewhere and verify snap position is unchanged
|
||||
await comfyMouse.move({ x: dropPos.x + 160, y: dropPos.y + 100 })
|
||||
const after = await comfyPage.page.evaluate(() => {
|
||||
const snap = window['app']?.canvas?.linkConnector?.state?.snapLinksPos
|
||||
const snap = window.app?.canvas?.linkConnector?.state?.snapLinksPos
|
||||
return Array.isArray(snap) ? [snap[0], snap[1]] : null
|
||||
})
|
||||
expect(after).toEqual(before)
|
||||
|
||||
@@ -13,17 +13,17 @@ test.describe('Vue Widget Reactivity', () => {
|
||||
'css=[data-testid="node-body-4"] > .lg-node-widgets > div'
|
||||
)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['4']
|
||||
const node = window.graph._nodes_by_id['4']
|
||||
node.widgets.push(node.widgets[0])
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(2)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['4']
|
||||
const node = window.graph._nodes_by_id['4']
|
||||
node.widgets[2] = node.widgets[0]
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(3)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['4']
|
||||
const node = window.graph._nodes_by_id['4']
|
||||
node.widgets.splice(0, 0, node.widgets[0])
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(4)
|
||||
@@ -33,17 +33,17 @@ test.describe('Vue Widget Reactivity', () => {
|
||||
'css=[data-testid="node-body-3"] > .lg-node-widgets > div'
|
||||
)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['3']
|
||||
const node = window.graph._nodes_by_id['3']
|
||||
node.widgets.pop()
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(5)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['3']
|
||||
const node = window.graph._nodes_by_id['3']
|
||||
node.widgets.length--
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(4)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const node = window['graph']._nodes_by_id['3']
|
||||
const node = window.graph._nodes_by_id['3']
|
||||
node.widgets.splice(0, 1)
|
||||
})
|
||||
await expect(loadCheckpointNode).toHaveCount(3)
|
||||
|
||||
@@ -58,7 +58,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
}) => {
|
||||
const getComboValues = async () =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
return window.app.graph.nodes
|
||||
.find((node) => node.title === 'Node With Optional Combo Input')
|
||||
.widgets.find((widget) => widget.name === 'optional_combo_input')
|
||||
.options.values
|
||||
@@ -93,7 +93,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
// get the combo widget's values
|
||||
const comboValues = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
return window.app.graph.nodes
|
||||
.find((node) => node.title === 'Node With V2 Combo Input')
|
||||
.widgets.find((widget) => widget.name === 'combo_input').options.values
|
||||
})
|
||||
@@ -121,16 +121,16 @@ test.describe('Slider widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
const widget = await node.getWidget(0)
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
const widget = window.app.graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
window.widgetValue = value
|
||||
}
|
||||
})
|
||||
await widget.dragHorizontal(50)
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('slider_widget_dragged.png')
|
||||
|
||||
expect(
|
||||
await comfyPage.page.evaluate(() => window['widgetValue'])
|
||||
await comfyPage.page.evaluate(() => window.widgetValue)
|
||||
).toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -142,16 +142,16 @@ test.describe('Number widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
const node = (await comfyPage.nodeOps.getFirstNodeRef())!
|
||||
const widget = await node.getWidget(0)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
const widget = window.app.graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
window.widgetValue = value
|
||||
}
|
||||
})
|
||||
await widget.dragHorizontal(50)
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('seed_widget_dragged.png')
|
||||
|
||||
expect(
|
||||
await comfyPage.page.evaluate(() => window['widgetValue'])
|
||||
await comfyPage.page.evaluate(() => window.widgetValue)
|
||||
).toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -166,8 +166,8 @@ test.describe(
|
||||
await comfyPage.workflow.loadWorkflow('nodes/single_ksampler')
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['graph'].nodes[0].addWidget('number', 'new_widget', 10)
|
||||
window['graph'].setDirtyCanvas(true, true)
|
||||
window.graph.nodes[0].addWidget('number', 'new_widget', 10)
|
||||
window.graph.setDirtyCanvas(true, true)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -349,7 +349,7 @@ test.describe(
|
||||
await comfyPage.page.evaluate(
|
||||
([loadId, saveId]) => {
|
||||
// Set the output of the SaveAnimatedWEBP node to equal the loader node's image
|
||||
window['app'].nodeOutputs[saveId] = window['app'].nodeOutputs[loadId]
|
||||
window.app.nodeOutputs[saveId] = window.app.nodeOutputs[loadId]
|
||||
app.canvas.setDirty(true)
|
||||
},
|
||||
[loadAnimatedWebpNode.id, saveAnimatedWebpNode.id]
|
||||
|
||||
@@ -7,5 +7,10 @@
|
||||
"noUnusedParameters": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["**/*.ts", "../src/types/**/*.d.ts", "../global.d.ts"]
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"../src/types/**/*.d.ts",
|
||||
"../global.d.ts",
|
||||
"types/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
36
browser_tests/types/globals.d.ts
vendored
Normal file
36
browser_tests/types/globals.d.ts
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { ComfyApp } from '@/scripts/app'
|
||||
import type { LGraph } from '@/lib/litegraph'
|
||||
import type { LiteGraphGlobal } from '@/lib/litegraph/src/LiteGraphGlobal'
|
||||
import type { LGraphBadge } from '@/lib/litegraph/src/LGraphBadge'
|
||||
|
||||
interface AppReadiness {
|
||||
featureFlagsReceived: boolean
|
||||
apiInitialized: boolean
|
||||
appInitialized: boolean
|
||||
}
|
||||
|
||||
interface CapturedMessages {
|
||||
clientFeatureFlags: unknown
|
||||
serverFeatureFlags: unknown
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
app?: ComfyApp
|
||||
graph?: LGraph
|
||||
LiteGraph?: LiteGraphGlobal
|
||||
LGraphBadge?: typeof LGraphBadge
|
||||
|
||||
// Test-specific globals used for assertions
|
||||
foo?: boolean
|
||||
TestCommand?: boolean
|
||||
changeCount?: number
|
||||
widgetValue?: unknown
|
||||
|
||||
// Feature flags test globals
|
||||
__capturedMessages?: CapturedMessages
|
||||
__appReadiness?: AppReadiness
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
Reference in New Issue
Block a user