Files
ComfyUI_frontend/browser_tests/fixtures/LocalhostComfyPage.ts
bymyself ae1617874f feat: Add cloud E2E testing infrastructure
Adds Playwright tests for cloud environment with Firebase auth.

Changes:
- Refactor ComfyPage to abstract base class
- Add LocalhostComfyPage (existing devtools implementation)
- Add CloudComfyPage (cloud settings API, Firebase auth)
- Add cloud fixture with auth state persistence
- Add globalSetupCloud for Firebase login
- Add playwright.cloud.config with 5x timeout
- Add basic cloud tests (load app, canvas interaction, settings)
- Update .gitignore for auth state files
- Update tsconfig to include playwright.cloud.config

Architecture:
- ComfyPage abstract with 3 backend-specific methods
- LocalhostComfyPage uses /api/devtools + multi-user
- CloudComfyPage uses /api/settings + Firebase localStorage
- No code duplication (95% shared)

Setup:
- Requires CLOUD_TEST_EMAIL and CLOUD_TEST_PASSWORD env vars
- globalSetup logs in once, saves auth to browser_tests/.auth/
- Tests reuse saved auth state (no login per test)
2025-11-06 16:23:00 -07:00

75 lines
2.0 KiB
TypeScript

import type { APIRequestContext, Page } from '@playwright/test'
import { ComfyPage } from './ComfyPage'
import type { FolderStructure } from './ComfyPage'
/**
* Localhost-specific implementation of ComfyPage.
* Uses devtools API and multi-user mode for test isolation.
*/
export class LocalhostComfyPage extends ComfyPage {
constructor(page: Page, request: APIRequestContext) {
super(page, request)
}
async setupWorkflowsDirectory(structure: FolderStructure): Promise<void> {
const resp = await this.request.post(
`${this.url}/api/devtools/setup_folder_structure`,
{
data: {
tree_structure: this.convertLeafToContent(structure),
base_path: `user/${this.id}/workflows`
}
}
)
if (resp.status() !== 200) {
throw new Error(
`Failed to setup workflows directory: ${await resp.text()}`
)
}
await this.page.evaluate(async () => {
await window['app'].extensionManager.workflow.syncWorkflows()
})
}
async setupUser(username: string): Promise<string | null> {
const res = await this.request.get(`${this.url}/api/users`)
if (res.status() !== 200)
throw new Error(`Failed to retrieve users: ${await res.text()}`)
const apiRes = await res.json()
const user = Object.entries(apiRes?.users ?? {}).find(
([, name]) => name === username
)
const id = user?.[0]
return id ? id : await this.createUser(username)
}
private async createUser(username: string): Promise<string> {
const resp = await this.request.post(`${this.url}/api/users`, {
data: { username }
})
if (resp.status() !== 200)
throw new Error(`Failed to create user: ${await resp.text()}`)
return await resp.json()
}
async setupSettings(settings: Record<string, any>): Promise<void> {
const resp = await this.request.post(
`${this.url}/api/devtools/set_settings`,
{
data: settings
}
)
if (resp.status() !== 200) {
throw new Error(`Failed to setup settings: ${await resp.text()}`)
}
}
}