Files
ComfyUI_frontend/browser_tests/fixtures/components/BottomPanel.ts
Dante e16a0bfe82 fix(knip): narrow Playwright entrypoints so browser-test dead exports are reported (FE-717) (#12496)
## Summary

Narrow Knip's Playwright `entry` to actual spec files so dead exports in
browser-test fixtures are reported instead of being hidden by treating
every helper as an entrypoint.

## Changes

- **What**:
- `knip.config.ts`: Playwright `entry` changed from the broad
`['**/*.@(spec|test)…', 'browser_tests/**/*.ts']` to
`['browser_tests/**/*.@(spec|test).?(c|m)[jt]s?(x)']`.
`globalSetup`/`globalTeardown` stay covered via Knip's playwright config
resolution; fixtures remain in the project graph so their unused exports
surface.
- Resolved the 54 dead findings this exposed: over-exported symbols used
only within their own module are now module-private (dropped `export`,
no behavioral change); genuinely unreferenced fixtures were deleted
(asset/template `ALL_*` aggregators + orphaned `STABLE_*` data,
`TemplateHelper` distribution helpers + `generateTemplates`, dead
types/utils, and the unused `nodeDefinitions.ts` module).
- **Breaking**: none — test-only changes.

## Review Focus

- Deletions are limited to fixtures with zero importers on `main`
(verified via `pnpm knip`); the bulk of the diff is `export`-keyword
removal.
- Verified: `pnpm knip` (browser_tests clean), `pnpm typecheck`, `pnpm
typecheck:browser`, oxfmt/oxlint/eslint all pass.

Linear: FE-717
2026-06-01 07:53:29 +00:00

92 lines
3.0 KiB
TypeScript

import type { Locator, Page } from '@playwright/test'
import { TestIds } from '@e2e/fixtures/selectors'
class ShortcutsTab {
readonly essentialsTab: Locator
readonly viewControlsTab: Locator
readonly manageButton: Locator
readonly keyBadges: Locator
readonly subcategoryTitles: Locator
constructor(readonly page: Page) {
this.essentialsTab = page.getByRole('tab', { name: /Essential/i })
this.viewControlsTab = page.getByRole('tab', { name: /View Controls/i })
this.manageButton = page.getByRole('button', { name: /Manage Shortcuts/i })
this.keyBadges = page.locator('.key-badge')
this.subcategoryTitles = page.locator('.subcategory-title')
}
}
class LogsTab {
readonly tab: Locator
readonly terminalRoot: Locator
readonly terminalHost: Locator
readonly copyButton: Locator
readonly errorMessage: Locator
readonly loadingSpinner: Locator
readonly xtermScreen: Locator
constructor(readonly page: Page) {
this.tab = page.getByRole('tab', { name: /Logs/i })
this.terminalRoot = page.getByTestId(TestIds.terminal.root)
this.terminalHost = page.getByTestId(TestIds.terminal.host)
this.copyButton = page.getByTestId(TestIds.terminal.copyButton)
this.errorMessage = page.getByTestId(TestIds.terminal.errorMessage)
this.loadingSpinner = page.getByTestId(TestIds.terminal.loadingSpinner)
this.xtermScreen = this.terminalHost.locator('.xterm-screen')
}
}
export class BottomPanel {
readonly root: Locator
readonly keyboardShortcutsButton: Locator
readonly toggleButton: Locator
readonly closeButton: Locator
readonly resizeGutter: Locator
readonly shortcuts: ShortcutsTab
readonly logs: LogsTab
constructor(readonly page: Page) {
this.root = page.locator('.bottom-panel')
this.keyboardShortcutsButton = page.getByRole('button', {
name: /Keyboard Shortcuts/i
})
this.toggleButton = page.getByRole('button', {
name: /Toggle Bottom Panel/i
})
this.closeButton = this.root.getByRole('button', { name: /^Close$/i })
// PrimeVue renders the splitter gutter outside the panel body.
this.resizeGutter = page.locator(
'.splitter-overlay-bottom > .p-splitter-gutter'
)
this.shortcuts = new ShortcutsTab(page)
this.logs = new LogsTab(page)
}
async toggleLogs() {
await this.toggleButton.click()
await this.logs.tab.waitFor({ state: 'visible' })
if ((await this.logs.tab.getAttribute('aria-selected')) !== 'true') {
await this.logs.tab.click()
}
}
async resizeByDragging(deltaY: number): Promise<void> {
const gutterBox = await this.resizeGutter.boundingBox()
if (!gutterBox) {
throw new Error('Bottom panel resize gutter should have layout')
}
const gutterCenterX = gutterBox.x + gutterBox.width / 2
const gutterCenterY = gutterBox.y + gutterBox.height / 2
await this.page.mouse.move(gutterCenterX, gutterCenterY)
await this.page.mouse.down()
await this.page.mouse.move(gutterCenterX, gutterCenterY + deltaY, {
steps: 5
})
await this.page.mouse.up()
}
}