mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-22 21:38:52 +00:00
Replaces the Zendesk ticket form URL builder with a Pylon prefill builder and
routes each Support entry-point to the best-fit Pylon form, prefilled with the
user's email, cloud user id, environment, frontend version, OS, and browser.
- Help Center "Help" / topbar "Support" -> question form
- Error dialog & node "Get Help" -> report-a-bug form
- Subscription dialog, useSubscriptionActions, credits panel -> billing-refund-issue form
- Mobile linear-mode error -> report-a-bug form
- Cloud onboarding (signup, auth timeout, footer) -> question form
OS is normalized so Python platform names (darwin/linux/win32) are promoted to
UA-detected versions ("macOS 14.5", "Windows 10/11"); the Typeform feedback URL
is unchanged.
155 lines
4.4 KiB
TypeScript
155 lines
4.4 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { useErrorActions } from './useErrorActions'
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
trackUiButtonClicked: vi.fn(),
|
|
trackHelpResourceClicked: vi.fn(),
|
|
openSupport: vi.fn(),
|
|
telemetry: null as {
|
|
trackUiButtonClicked: ReturnType<typeof vi.fn>
|
|
trackHelpResourceClicked: ReturnType<typeof vi.fn>
|
|
} | null,
|
|
staticUrls: {
|
|
githubIssues: 'https://github.com/Comfy-Org/ComfyUI/issues'
|
|
}
|
|
}))
|
|
|
|
vi.mock('@/platform/support/useSupportContext', () => ({
|
|
useSupportContext: () => ({
|
|
openSupport: mocks.openSupport
|
|
})
|
|
}))
|
|
|
|
vi.mock('@/composables/useExternalLink', () => ({
|
|
useExternalLink: () => ({
|
|
staticUrls: mocks.staticUrls
|
|
})
|
|
}))
|
|
|
|
vi.mock('@/platform/telemetry', () => ({
|
|
useTelemetry: () => mocks.telemetry
|
|
}))
|
|
|
|
describe('useErrorActions', () => {
|
|
let windowOpenSpy: ReturnType<typeof vi.spyOn>
|
|
|
|
beforeEach(() => {
|
|
mocks.telemetry = {
|
|
trackUiButtonClicked: mocks.trackUiButtonClicked,
|
|
trackHelpResourceClicked: mocks.trackHelpResourceClicked
|
|
}
|
|
mocks.trackUiButtonClicked.mockReset()
|
|
mocks.trackHelpResourceClicked.mockReset()
|
|
mocks.openSupport.mockReset()
|
|
windowOpenSpy = vi
|
|
.spyOn(window, 'open')
|
|
.mockImplementation(() => null as unknown as Window)
|
|
})
|
|
|
|
afterEach(() => {
|
|
windowOpenSpy.mockRestore()
|
|
})
|
|
|
|
describe('openGitHubIssues', () => {
|
|
it('tracks the button click and opens the GitHub issues URL in a new tab', () => {
|
|
const { openGitHubIssues } = useErrorActions()
|
|
|
|
openGitHubIssues()
|
|
|
|
expect(mocks.trackUiButtonClicked).toHaveBeenCalledWith({
|
|
button_id: 'error_tab_github_issues_clicked'
|
|
})
|
|
expect(windowOpenSpy).toHaveBeenCalledWith(
|
|
mocks.staticUrls.githubIssues,
|
|
'_blank',
|
|
'noopener,noreferrer'
|
|
)
|
|
})
|
|
|
|
it('still opens the link when telemetry is unavailable', () => {
|
|
mocks.telemetry = null
|
|
const { openGitHubIssues } = useErrorActions()
|
|
|
|
openGitHubIssues()
|
|
|
|
expect(mocks.trackUiButtonClicked).not.toHaveBeenCalled()
|
|
expect(windowOpenSpy).toHaveBeenCalledWith(
|
|
mocks.staticUrls.githubIssues,
|
|
'_blank',
|
|
'noopener,noreferrer'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('contactSupport', () => {
|
|
it('tracks the help resource click and opens the Pylon bug-report form', () => {
|
|
const { contactSupport } = useErrorActions()
|
|
|
|
contactSupport()
|
|
|
|
expect(mocks.trackHelpResourceClicked).toHaveBeenCalledWith({
|
|
resource_type: 'help_feedback',
|
|
is_external: true,
|
|
source: 'error_dialog'
|
|
})
|
|
expect(mocks.openSupport).toHaveBeenCalledWith('report-a-bug', {
|
|
productArea: 'Workflow Error'
|
|
})
|
|
})
|
|
|
|
it('still opens the support form when telemetry is unavailable', () => {
|
|
mocks.telemetry = null
|
|
const { contactSupport } = useErrorActions()
|
|
|
|
contactSupport()
|
|
|
|
expect(mocks.trackHelpResourceClicked).not.toHaveBeenCalled()
|
|
expect(mocks.openSupport).toHaveBeenCalledWith('report-a-bug', {
|
|
productArea: 'Workflow Error'
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('findOnGitHub', () => {
|
|
it('tracks the click and opens a URL-encoded issue search with " is:issue" appended', () => {
|
|
const { findOnGitHub } = useErrorActions()
|
|
|
|
findOnGitHub('CUDA out of memory')
|
|
|
|
expect(mocks.trackUiButtonClicked).toHaveBeenCalledWith({
|
|
button_id: 'error_tab_find_existing_issues_clicked'
|
|
})
|
|
const expectedQuery = encodeURIComponent('CUDA out of memory is:issue')
|
|
expect(windowOpenSpy).toHaveBeenCalledWith(
|
|
`${mocks.staticUrls.githubIssues}?q=${expectedQuery}`,
|
|
'_blank',
|
|
'noopener,noreferrer'
|
|
)
|
|
})
|
|
|
|
it('URL-encodes messages with special characters', () => {
|
|
const { findOnGitHub } = useErrorActions()
|
|
|
|
findOnGitHub('error with spaces & symbols?')
|
|
|
|
const [[url]] = windowOpenSpy.mock.calls as unknown as [[string]]
|
|
expect(url).toContain('?q=')
|
|
const queryPart = url.split('?q=')[1]
|
|
expect(decodeURIComponent(queryPart)).toBe(
|
|
'error with spaces & symbols? is:issue'
|
|
)
|
|
})
|
|
|
|
it('still opens the link when telemetry is unavailable', () => {
|
|
mocks.telemetry = null
|
|
const { findOnGitHub } = useErrorActions()
|
|
|
|
findOnGitHub('boom')
|
|
|
|
expect(mocks.trackUiButtonClicked).not.toHaveBeenCalled()
|
|
expect(windowOpenSpy).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
})
|