mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-26 06:19:49 +00:00
9f9304b294
.pad.toml's url, else the CLI's configured server (pad server info), else the MCP server's own URL (Pad Cloud's MCP host maps to the app, a self-hosted /mcp to its base), else Pad Cloud. Claude-Session: https://claude.ai/code/session_01J9famMX8HvArgW2uo8mPRT
40 lines
3.0 KiB
TypeScript
40 lines
3.0 KiB
TypeScript
import { expect, test } from 'claude-code/testing'
|
|
import { arrowStep, tabStep, webBaseFromMcp } from '../hooks/register.js'
|
|
|
|
// The Browse view as drawn: six tabs, two collection rows, then the footer actions.
|
|
const ORDER = ['tab-now', 'tab-next', 'tab-browse', 'tab-find', 'tab-activity', 'tab-settings', 'coll-tasks', 'coll-conventions', 'refresh', 'add']
|
|
|
|
test('Tab and Shift+Tab walk the menu with the list as one stop', async () => {
|
|
// Tab from a row (the engine aims at the next row) leaves the list: nothing follows it, so it wraps to the first tab
|
|
expect(tabStep(ORDER, 'coll-tasks', 'coll-conventions', 'coll-tasks')).toEqual({ element: 'tab-now', engineStop: false })
|
|
// Tab across the menu
|
|
expect(tabStep(ORDER, 'tab-now', 'tab-next', 'coll-tasks')).toEqual({ element: 'tab-next', engineStop: false })
|
|
// Tab from the last tab enters the list on the row it left
|
|
expect(tabStep(ORDER, 'tab-settings', 'coll-tasks', 'coll-conventions')).toEqual({ element: 'coll-conventions', engineStop: false })
|
|
// Shift+Tab from a row (the engine aims at the row above, or the last tab) goes to the last tab
|
|
expect(tabStep(ORDER, 'coll-conventions', 'coll-tasks', 'coll-conventions')).toEqual({ element: 'tab-settings', engineStop: false })
|
|
// Shift+Tab from the first tab (the engine wraps to the last control) comes back into the list
|
|
expect(tabStep(ORDER, 'tab-now', 'add', 'coll-tasks')).toEqual({ element: 'coll-tasks', engineStop: false })
|
|
// ... or, when the engine aims at its own close mark, the same, flagged so the hook moves it itself
|
|
expect(tabStep(ORDER, 'tab-now', undefined, 'coll-tasks')).toEqual({ element: 'coll-tasks', engineStop: true })
|
|
// a click (not one step away) lands where it was aimed
|
|
expect(tabStep(ORDER, 'tab-now', 'coll-conventions', 'coll-tasks')).toBeNull()
|
|
})
|
|
|
|
test('Up and Down walk the rows; page moves and the list edges still scroll', async () => {
|
|
expect(arrowStep(ORDER, 'coll-tasks', 1, 'coll-tasks')).toBe('coll-conventions')
|
|
expect(arrowStep(ORDER, 'coll-conventions', -1, 'coll-tasks')).toBe('coll-tasks')
|
|
expect(arrowStep(ORDER, 'coll-conventions', 1, 'coll-tasks')).toBeNull() // bottom: scroll
|
|
expect(arrowStep(ORDER, 'coll-tasks', -1, 'coll-tasks')).toBeNull() // top: scroll the header into view
|
|
expect(arrowStep(ORDER, 'tab-browse', 1, 'coll-conventions')).toBe('coll-conventions') // Down from the menu enters the list
|
|
expect(arrowStep(ORDER, 'coll-tasks', 30, 'coll-tasks')).toBeNull() // a page key
|
|
expect(arrowStep(['tab-now', 'refresh'], 'tab-now', 1, undefined)).toBeNull() // a view with no list
|
|
})
|
|
|
|
test("an MCP endpoint's web app: Pad Cloud's MCP host maps to the app; a self-hosted /mcp to its base", async () => {
|
|
expect(webBaseFromMcp('https://mcp.getpad.dev')).toBe('https://app.getpad.dev')
|
|
expect(webBaseFromMcp('https://pad.example.com/mcp')).toBe('https://pad.example.com')
|
|
expect(webBaseFromMcp('http://192.168.1.89:7777/mcp/')).toBe('http://192.168.1.89:7777')
|
|
expect(webBaseFromMcp('not a url')).toBe('https://app.getpad.dev')
|
|
})
|