@burojs/test-helpers 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/form-view.ts","../src/list-view.ts","../src/picker-object.ts","../src/show-view.ts","../src/resource-object.ts","../src/buro-page.ts","../src/confirm-dialog.ts","../src/data-provider-contract.ts","../src/index.ts"],"names":["expect","validateBatchResult","isDataError","describe","it","validateMutationResult","resolveDataCapability"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { PlaywrightLocator, PlaywrightPage } from './types.js';\n\nexport interface FormFieldObject {\n input: () => PlaywrightLocator;\n error: () => PlaywrightLocator;\n help: () => PlaywrightLocator;\n}\n\nexport interface FormView {\n field: (fieldName: string) => FormFieldObject;\n section: (sectionKey: string) => PlaywrightLocator;\n submit: () => PlaywrightLocator;\n cancel: () => PlaywrightLocator;\n action: (actionName: string) => PlaywrightLocator;\n}\n\nexport function createFormView(\n page: PlaywrightPage,\n resource: string,\n view: 'create' | 'edit' | 'show',\n): FormView {\n return {\n field: (fieldName) => {\n page.getByTestId(`form-field:${resource}:${view}:${fieldName}`);\n return {\n input: () => page.getByTestId(`form-field-input:${resource}:${view}:${fieldName}`),\n error: () => page.getByTestId(`form-field-error:${resource}:${view}:${fieldName}`),\n help: () => page.getByTestId(`form-field-help:${resource}:${view}:${fieldName}`),\n };\n },\n section: (sectionKey) => page.getByTestId(`form-section:${resource}:${view}:${sectionKey}`),\n submit: () => page.getByTestId(`form-submit:${resource}:${view}`),\n cancel: () => page.getByTestId(`form-cancel:${resource}:${view}`),\n action: (actionName) => page.getByTestId(`form-action:${resource}:${view}:${actionName}`),\n };\n}\n","import type { PlaywrightLocator, PlaywrightPage } from './types.js';\n\n/**\n * A row's address inside the filter-builder draft: `[]` is the root group,\n * `[0]` is its first row, `[1, 0]` is the first row of the group nested at\n * top-level index 1. Mirrors `DraftPath` in\n * `packages/ui-shadcn/src/list-kit/filter-builder/draft.ts` — the testid\n * suffix is `path.join('-')` (an empty path renders as the empty string, so\n * the root group's own testid carries a trailing `:`, e.g.\n * `list-filter:<r>:group::add-row`).\n */\nexport type FilterRowPath = readonly number[];\n\nexport interface ListView {\n goto: () => Promise<void>;\n row: (recordId: string) => RowObject;\n search: () => PlaywrightLocator;\n // ── Filter builder (SP2) ─────────────────────────────────────────────\n // The chip toolbar this file used to model (`list-dyn-filter:*`,\n // `list-add-filter:*`) is gone — SP2 replaced it with a popover panel:\n // open the panel, add a row, pick a field/operator/value, Apply. Applied\n // rows then render as removable badges OUTSIDE the panel. See\n // `packages/ui-shadcn/src/list-kit/filter-builder/*` for the components\n // these testids come from.\n /** The filter region container — `list-filters:<resource>`. */\n filtersContainer: () => PlaywrightLocator;\n /** Opens/closes the filter-builder popover. */\n filterButton: () => PlaywrightLocator;\n /** The popover body once open. */\n filterPanel: () => PlaywrightLocator;\n /** \"+ Filter\" — appends a new predicate row to the group at `groupPath` (root: `[]`). */\n filterAddRow: (groupPath?: FilterRowPath) => PlaywrightLocator;\n /** Field-select trigger for the row at `path`. */\n filterRowField: (path: FilterRowPath) => PlaywrightLocator;\n /** One field option inside an open field-select. */\n filterRowFieldOption: (path: FilterRowPath, field: string) => PlaywrightLocator;\n /** Operator-select trigger for the row at `path`. */\n filterRowOp: (path: FilterRowPath) => PlaywrightLocator;\n /** One operator option inside an open operator-select. */\n filterRowOpOption: (path: FilterRowPath, op: string) => PlaywrightLocator;\n /** Value control trigger/input for the row at `path` — shape depends on the field kind (text box, enum/relation/boolean popover). */\n filterRowValue: (path: FilterRowPath) => PlaywrightLocator;\n /** Removes the row at `path` from the draft (inside the panel, before Apply). */\n filterRowRemove: (path: FilterRowPath) => PlaywrightLocator;\n /** Commits the draft — applies it and closes the panel. */\n filterApply: () => PlaywrightLocator;\n /** Clears the draft back to empty (still requires Apply to take effect). */\n filterReset: () => PlaywrightLocator;\n /** One applied-filter badge outside the panel, by its top-level index. */\n filterBadge: (index: number) => PlaywrightLocator;\n /** A badge's × — removes that row immediately, no Apply needed. */\n filterBadgeRemove: (index: number) => PlaywrightLocator;\n /** \"Clear all\" — empties both the pinned slot and the builder group. */\n filterClearAll: () => PlaywrightLocator;\n /** An always-visible pinned control (`views.list.filters.pinned`) for `field`, rendered outside the panel. */\n filterPinned: (field: string) => PlaywrightLocator;\n paginationPrev: () => PlaywrightLocator;\n paginationNext: () => PlaywrightLocator;\n empty: () => PlaywrightLocator;\n toolbar: () => PlaywrightLocator;\n table: () => PlaywrightLocator;\n}\n\nexport interface RowObject {\n cell: (fieldName: string) => PlaywrightLocator;\n action: (actionName: string) => PlaywrightLocator;\n checkbox: () => PlaywrightLocator;\n open: () => Promise<void>;\n}\n\nexport interface ListViewOptions {\n basePath?: string;\n}\n\n/** `path.join('-')` — see `FilterRowPath`'s doc for the empty-path edge case. */\nfunction pathStr(path: FilterRowPath): string {\n return path.join('-');\n}\n\nexport function createListView(\n page: PlaywrightPage,\n resource: string,\n options: ListViewOptions = {},\n): ListView {\n const path = options.basePath ?? `/${resource}`;\n const filterBase = `list-filter:${resource}`;\n const rowBase = (rowPath: FilterRowPath) => `${filterBase}:row:${pathStr(rowPath)}`;\n const groupBase = (groupPath: FilterRowPath) => `${filterBase}:group:${pathStr(groupPath)}`;\n return {\n goto: async () => {\n await page.goto(path);\n },\n row: (recordId) => createRowObject(page, resource, recordId),\n search: () => page.getByTestId(`list-search:${resource}`),\n filtersContainer: () => page.getByTestId(`list-filters:${resource}`),\n filterButton: () => page.getByTestId(`${filterBase}:button`),\n filterPanel: () => page.getByTestId(`${filterBase}:panel`),\n filterAddRow: (groupPath = []) => page.getByTestId(`${groupBase(groupPath)}:add-row`),\n filterRowField: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:field`),\n filterRowFieldOption: (rowPath, field) =>\n page.getByTestId(`${rowBase(rowPath)}:field:option:${field}`),\n filterRowOp: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:op`),\n filterRowOpOption: (rowPath, op) => page.getByTestId(`${rowBase(rowPath)}:op:option:${op}`),\n filterRowValue: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:value`),\n filterRowRemove: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:remove`),\n filterApply: () => page.getByTestId(`${filterBase}:apply`),\n filterReset: () => page.getByTestId(`${filterBase}:reset`),\n filterBadge: (index) => page.getByTestId(`${filterBase}:badge:${index}`),\n filterBadgeRemove: (index) => page.getByTestId(`${filterBase}:badge:${index}:remove`),\n filterClearAll: () => page.getByTestId(`${filterBase}:clear-all`),\n filterPinned: (field) => page.getByTestId(`${filterBase}:pinned:${field}`),\n paginationPrev: () => page.getByTestId(`list-pagination-prev:${resource}`),\n paginationNext: () => page.getByTestId(`list-pagination-next:${resource}`),\n empty: () => page.getByTestId(`list-empty:${resource}`),\n toolbar: () => page.getByTestId(`list-toolbar:${resource}`),\n table: () => page.getByTestId(`list-table:${resource}`),\n };\n}\n\nfunction createRowObject(page: PlaywrightPage, resource: string, recordId: string): RowObject {\n const rowId = `list-row:${resource}:${recordId}`;\n return {\n cell: (fieldName) => page.getByTestId(`list-cell:${resource}:${recordId}:${fieldName}`),\n action: (actionName) =>\n page.getByTestId(`list-row-action:${resource}:${recordId}:${actionName}`),\n checkbox: () => page.getByTestId(`list-row-checkbox:${resource}:${recordId}`),\n open: async () => {\n await page.getByTestId(rowId).click();\n },\n };\n}\n","import type { PlaywrightLocator, PlaywrightPage } from './types.js';\n\nexport interface PickerObject {\n dialog: () => PlaywrightLocator;\n popover: () => PlaywrightLocator;\n option: (value: string) => PlaywrightLocator;\n search: () => PlaywrightLocator;\n clear: () => PlaywrightLocator;\n quickCreate: () => PlaywrightLocator;\n}\n\nexport function createPickerObject(page: PlaywrightPage, targetResource: string): PickerObject {\n return {\n dialog: () => page.getByTestId(`picker-dialog:${targetResource}`),\n popover: () => page.getByTestId(`picker-popover:${targetResource}`),\n option: (value) => page.getByTestId(`picker-option:${targetResource}:${value}`),\n search: () => page.getByTestId(`picker-search:${targetResource}`),\n clear: () => page.getByTestId(`picker-clear:${targetResource}`),\n quickCreate: () => page.getByTestId(`picker-quickcreate:${targetResource}`),\n };\n}\n","import { type FormView, createFormView } from './form-view.js';\nimport type { PlaywrightPage } from './types.js';\n\nexport type ShowView = FormView;\n\nexport function createShowView(page: PlaywrightPage, resource: string): ShowView {\n return createFormView(page, resource, 'show');\n}\n","import { type FormView, createFormView } from './form-view.js';\nimport { type ListView, type ListViewOptions, createListView } from './list-view.js';\nimport { type PickerObject, createPickerObject } from './picker-object.js';\nimport { type ShowView, createShowView } from './show-view.js';\nimport type { PlaywrightPage } from './types.js';\n\nexport interface ResourceObject {\n name: string;\n list: (options?: ListViewOptions) => ListView;\n edit: (recordId: string) => FormView;\n show: (recordId: string) => ShowView;\n create: () => FormView;\n picker: () => PickerObject;\n}\n\nexport function createResourceObject(page: PlaywrightPage, name: string): ResourceObject {\n return {\n name,\n list: (options) => createListView(page, name, options),\n edit: (_recordId) => createFormView(page, name, 'edit'),\n show: (_recordId) => createShowView(page, name),\n create: () => createFormView(page, name, 'create'),\n picker: () => createPickerObject(page, name),\n };\n}\n","import { type ResourceObject, createResourceObject } from './resource-object.js';\nimport type { PlaywrightLocator, PlaywrightPage } from './types.js';\n\nexport interface BuroPage {\n resource: (name: string) => ResourceObject;\n contextPicker: (sliceName: string) => PlaywrightLocator;\n notification: (type: 'success' | 'error' | 'progress' | 'info') => PlaywrightLocator;\n actionConfirm: (resource: string, scope: string, actionName: string) => PlaywrightLocator;\n page: PlaywrightPage;\n}\n\nexport function createBuroPage(page: PlaywrightPage): BuroPage {\n return {\n resource: (name) => createResourceObject(page, name),\n contextPicker: (sliceName) => page.getByTestId(`context-picker:${sliceName}`),\n notification: (type) => page.getByTestId(`notification:${type}`),\n actionConfirm: (resource, scope, actionName) =>\n page.getByTestId(`action-confirm-dialog:${resource}:${scope}:${actionName}`),\n page,\n };\n}\n","import type { PlaywrightLocator, PlaywrightPage } from './types.js';\n\nexport interface ConfirmDialogObject {\n dialog: () => PlaywrightLocator;\n yes: () => PlaywrightLocator;\n no: () => PlaywrightLocator;\n}\n\nexport function createConfirmDialog(\n page: PlaywrightPage,\n resource: string,\n scope: string,\n actionName: string,\n): ConfirmDialogObject {\n return {\n dialog: () => page.getByTestId(`action-confirm-dialog:${resource}:${scope}:${actionName}`),\n yes: () => page.getByTestId(`action-confirm-yes:${resource}:${scope}:${actionName}`),\n no: () => page.getByTestId(`action-confirm-no:${resource}:${scope}:${actionName}`),\n };\n}\n","import {\n resolveDataCapability,\n isDataError,\n validateBatchResult,\n validateMutationResult,\n type BatchedQueryOperation,\n type DataError,\n type DataProvider,\n type ErasedMutationDescriptor,\n type ErasedQueryDescriptor,\n type LiveObserver,\n} from '@burojs/core';\nimport { describe, expect, it } from 'vitest';\n\ntype QueryKind = ErasedQueryDescriptor['kind'];\ntype MutationKind = ErasedMutationDescriptor['kind'];\n\nexport interface ProviderObservedCall {\n readonly lifecycle: 'query' | 'mutation' | 'batch' | 'live-open' | 'live-subscribe';\n readonly kind?: QueryKind | MutationKind;\n readonly descriptor?: ErasedQueryDescriptor | ErasedMutationDescriptor;\n readonly descriptors?: readonly ErasedQueryDescriptor[];\n readonly signal?: AbortSignal;\n}\n\n/** Specimens supplied by an adapter author; unsupported optional methods are omitted. */\nexport interface ProviderContractDescriptors {\n readonly queries?: Partial<Record<QueryKind, ErasedQueryDescriptor>>;\n readonly mutations?: Partial<Record<MutationKind, ErasedMutationDescriptor>>;\n readonly batch?: readonly BatchedQueryOperation[];\n /** Independent batch groups prove that grouping is explicit, never merged by the helper. */\n readonly batchGroups?: readonly (readonly BatchedQueryOperation[])[];\n /** List specimens for both pagination protocols, including expected totals/pageInfo. */\n readonly pagination?: {\n readonly offset?: ErasedQueryDescriptor;\n readonly cursor?: ErasedQueryDescriptor;\n };\n readonly live?: ErasedQueryDescriptor;\n /** Error specimens must make the selected handler reject with a DataError. */\n readonly errors?: readonly ProviderContractErrorSpecimen[];\n /** Hand-authored mapped results; assertions never derive expectations from an adapter. */\n readonly expected?: {\n readonly queries?: Partial<Record<QueryKind, unknown>>;\n readonly mutations?: Partial<Record<MutationKind, unknown>>;\n readonly batch?: unknown;\n readonly pagination?: { readonly offset?: unknown; readonly cursor?: unknown };\n };\n}\n\nexport type ProviderContractErrorSpecimen =\n | {\n readonly lifecycle: 'query';\n readonly kind: QueryKind;\n readonly descriptor: ErasedQueryDescriptor;\n }\n | {\n readonly lifecycle: 'mutation';\n readonly kind: MutationKind;\n readonly descriptor: ErasedMutationDescriptor;\n };\n\nexport interface ProviderContractFixture {\n create(): DataProvider | Promise<DataProvider>;\n descriptors: ProviderContractDescriptors;\n observeCalls(): readonly ProviderObservedCall[];\n}\n\nconst SESSION = Object.freeze({\n sessionKey: 'contract-session',\n scopeKey: 'contract-scope',\n generation: 1,\n});\nconst REQUEST_CONTEXT = Object.freeze({ contract: 'provider' });\n\nfunction context(signal: AbortSignal) {\n return Object.freeze({\n signal,\n requestContext: REQUEST_CONTEXT,\n session: SESSION,\n providerServiceKey: 'contract-provider',\n });\n}\n\nfunction queryShape(kind: QueryKind, value: unknown): void {\n if (kind === 'custom') return;\n expect(value).toBeTypeOf('object');\n if (kind === 'list' || kind === 'many')\n expect((value as { data?: unknown }).data).toBeInstanceOf(Array);\n if (kind === 'one') expect(value).toHaveProperty('data');\n if (kind === 'count')\n expect([null, 'number']).toContain(typeof (value as { total?: unknown }).total);\n}\n\nfunction observed(\n fixture: ProviderContractFixture,\n expected: Omit<ProviderObservedCall, 'signal'>,\n signal: AbortSignal,\n): void {\n expect(fixture.observeCalls()).toContainEqual(expect.objectContaining({ ...expected, signal }));\n}\n\nasync function assertBatch(\n provider: DataProvider,\n fixture: ProviderContractFixture,\n operations: readonly BatchedQueryOperation[],\n expected: unknown,\n): Promise<void> {\n expect(provider.batch?.queries).toBeTypeOf('function');\n const controller = new AbortController();\n const result = await provider.batch!.queries(operations, context(controller.signal));\n validateBatchResult(operations, result);\n if (expected !== undefined) expect(result).toEqual(expected);\n for (const entry of result.results) if (entry.status === 'error') dataError(entry.error);\n observed(\n fixture,\n { lifecycle: 'batch', descriptors: operations.map((operation) => operation.descriptor) },\n controller.signal,\n );\n}\n\nfunction dataError(value: unknown): asserts value is DataError {\n expect(isDataError(value)).toBe(true);\n}\n\n/**\n * A supplied `descriptors.live` IS the adapter author's declaration that this\n * descriptor should produce a plan — an adapter with no live support omits the\n * descriptor (or the `live` slot) and is skipped instead. So a null plan here\n * is a failure, not a skip.\n *\n * Split out as its own assertion, rather than left inline, so the suite's own\n * tests can prove it rejects — the same reason `queryShape`/`observed`/`batch`\n * already are.\n */\nfunction livePlan(value: unknown): void {\n expect(value, 'descriptors.live was supplied, so live.open must return a plan').not.toBeNull();\n expect(value).toBeTypeOf('object');\n expect((value as { subscribe?: unknown } | null)?.subscribe).toBeTypeOf('function');\n}\n\n/**\n * The OTHER door into the same free green. `livePlan` closes \"supplied a\n * descriptor, returned a null plan\"; this closes \"provider has a `live` slot,\n * fixture supplied no descriptor\" — which used to `return` silently, leaving\n * the live cell green with nothing executed. Deleting the single line\n * `live: listDescriptor` from a fixture left `examples/marketplace-ops`'s\n * hasura contract at 35/35 green with the live `it` still passing.\n *\n * The rule is asymmetric on purpose: a provider with NO `live` slot is a\n * provider without live support, and skipping is right. A provider that HAS\n * one and a fixture that says nothing about it is an untested capability\n * reported as a pass.\n *\n * Split out for the same reason `livePlan` is: the suite's own tests drive it\n * directly to prove it rejects.\n */\nfunction liveDescriptorRequired(hasLiveSlot: boolean, descriptor: unknown): void {\n if (!hasLiveSlot) return;\n expect(\n descriptor,\n 'the provider exposes a `live` slot, so the fixture must supply `descriptors.live` — omitting it silently skips the whole live cell',\n ).toBeDefined();\n}\n\n/** @internal Direct assertion seam for the contract suite's intentionally broken-provider tests. */\nexport const __providerContractAssertions = Object.freeze({\n queryShape,\n observed,\n batch: validateBatchResult,\n mutation: validateMutationResult,\n dataError,\n livePlan,\n liveDescriptorRequired,\n});\n\n/**\n * Registers transport-agnostic provider conformance tests. It intentionally\n * imports only core contracts: adapters supply their own deterministic client\n * and expose provider-boundary observations through the fixture.\n */\nexport function dataProviderContract(name: string, fixture: ProviderContractFixture): void {\n describe(`${name} data provider contract`, () => {\n for (const kind of ['list', 'one', 'many', 'count', 'custom'] as const) {\n it(`preserves the ${kind} query descriptor and AbortSignal`, async () => {\n const provider = await fixture.create();\n const descriptor = fixture.descriptors.queries?.[kind];\n const handler = provider.queries?.[kind];\n if (descriptor === undefined || handler === undefined) return;\n const controller = new AbortController();\n const result = await handler(descriptor as never, context(controller.signal));\n queryShape(kind, result);\n const expected = fixture.descriptors.expected?.queries?.[kind];\n if (expected !== undefined) expect(result).toEqual(expected);\n observed(fixture, { lifecycle: 'query', kind, descriptor }, controller.signal);\n });\n }\n\n for (const kind of [\n 'createOne',\n 'createMany',\n 'updateOne',\n 'updateMany',\n 'deleteOne',\n 'deleteMany',\n 'custom',\n ] as const) {\n it(`validates ${kind} mutation output and preserves its request`, async () => {\n const provider = await fixture.create();\n const descriptor = fixture.descriptors.mutations?.[kind];\n const handler = provider.mutations?.[kind];\n if (descriptor === undefined || handler === undefined) return;\n const controller = new AbortController();\n const result = await handler(descriptor as never, context(controller.signal));\n validateMutationResult(descriptor, result);\n const expected = fixture.descriptors.expected?.mutations?.[kind];\n if (expected !== undefined) expect(result).toEqual(expected);\n observed(fixture, { lifecycle: 'mutation', kind, descriptor }, controller.signal);\n });\n }\n\n for (const specimen of fixture.descriptors.errors ?? []) {\n it(`returns a structured error for the ${specimen.lifecycle}.${specimen.kind} error specimen`, async () => {\n const provider = await fixture.create();\n const controller = new AbortController();\n const handler =\n specimen.lifecycle === 'query'\n ? provider.queries?.[specimen.kind as QueryKind]\n : provider.mutations?.[specimen.kind as MutationKind];\n expect(handler).toBeTypeOf('function');\n try {\n await (\n handler as (\n descriptor: never,\n operation: ReturnType<typeof context>,\n ) => Promise<unknown>\n )(specimen.descriptor as never, context(controller.signal));\n throw new Error('Provider error specimen resolved instead of rejecting.');\n } catch (error) {\n dataError(error);\n }\n observed(\n fixture,\n { lifecycle: specimen.lifecycle, kind: specimen.kind, descriptor: specimen.descriptor },\n controller.signal,\n );\n });\n }\n\n it('reports absent optional capabilities without invoking fallback handlers', async () => {\n const provider = await fixture.create();\n const before = fixture.observeCalls().length;\n for (const kind of ['list', 'one', 'many', 'count', 'custom'] as const) {\n if (provider.queries?.[kind] === undefined) {\n const capability = resolveDataCapability(provider, { lifecycle: 'query', kind });\n expect(capability).toMatchObject({ kind: 'capability', code: 'missing-data-capability' });\n }\n }\n for (const kind of [\n 'createOne',\n 'createMany',\n 'updateOne',\n 'updateMany',\n 'deleteOne',\n 'deleteMany',\n 'custom',\n ] as const) {\n if (provider.mutations?.[kind] === undefined) {\n const capability = resolveDataCapability(provider, { lifecycle: 'mutation', kind });\n expect(capability).toMatchObject({ kind: 'capability', code: 'missing-data-capability' });\n }\n }\n expect(fixture.observeCalls()).toHaveLength(before);\n });\n\n it('validates batch IDs, kinds, partial errors, and the shared AbortSignal', async () => {\n const provider = await fixture.create();\n const operations = fixture.descriptors.batch;\n if (provider.batch?.queries === undefined || operations === undefined) return;\n await assertBatch(provider, fixture, operations, fixture.descriptors.expected?.batch);\n });\n\n for (const [index, operations] of (fixture.descriptors.batchGroups ?? []).entries()) {\n it(`keeps batch group ${index + 1} isolated and validates its partial results`, async () => {\n const provider = await fixture.create();\n await assertBatch(provider, fixture, operations, undefined);\n });\n }\n\n for (const kind of ['offset', 'cursor'] as const) {\n it(`preserves ${kind} pagination and its mapped total/page shape`, async () => {\n const provider = await fixture.create();\n const descriptor = fixture.descriptors.pagination?.[kind];\n if (descriptor === undefined || provider.queries?.list === undefined) return;\n const controller = new AbortController();\n const result = await provider.queries.list(descriptor as never, context(controller.signal));\n queryShape('list', result);\n const expected = fixture.descriptors.expected?.pagination?.[kind];\n if (expected !== undefined) expect(result).toEqual(expected);\n observed(fixture, { lifecycle: 'query', kind: 'list', descriptor }, controller.signal);\n });\n }\n\n it('opens live plans with the complete descriptor and subscribes with an AbortSignal', async () => {\n const provider = await fixture.create();\n const descriptor = fixture.descriptors.live;\n liveDescriptorRequired(provider.live !== undefined, descriptor);\n if (provider.live === undefined || descriptor === undefined) return;\n const openController = new AbortController();\n const plan = await provider.live.open(descriptor, context(openController.signal));\n observed(fixture, { lifecycle: 'live-open', descriptor }, openController.signal);\n // A null plan used to `return` here, which handed every adapter a free\n // green on the whole live cell: `subscribe` was never reached, so\n // nothing about the plan was ever checked, and the `it` passed for an\n // adapter that had done no live work at all.\n livePlan(plan);\n if (plan === null) return; // unreachable past `livePlan`; narrows the type\n const subscribeController = new AbortController();\n const observer: LiveObserver = {\n next: () => undefined,\n status: () => undefined,\n error: () => undefined,\n complete: () => undefined,\n };\n const unsubscribe = await plan.subscribe(observer, { signal: subscribeController.signal });\n observed(fixture, { lifecycle: 'live-subscribe' }, subscribeController.signal);\n await unsubscribe();\n });\n });\n}\n","// Constants\nexport const PACKAGE_NAME = '@burojs/test-helpers' as const;\nexport const PACKAGE_VERSION = '0.0.0' as const;\n\n// Types\nexport type { PlaywrightPage, PlaywrightLocator } from './types.js';\n\n// Page object factories\nexport { createBuroPage, type BuroPage } from './buro-page.js';\nexport { createResourceObject, type ResourceObject } from './resource-object.js';\nexport {\n createListView,\n type ListView,\n type RowObject,\n type ListViewOptions,\n} from './list-view.js';\nexport { createFormView, type FormView, type FormFieldObject } from './form-view.js';\nexport { createShowView, type ShowView } from './show-view.js';\nexport { createPickerObject, type PickerObject } from './picker-object.js';\nexport { createConfirmDialog, type ConfirmDialogObject } from './confirm-dialog.js';\nexport {\n dataProviderContract,\n type ProviderContractDescriptors,\n type ProviderContractFixture,\n type ProviderObservedCall,\n} from './data-provider-contract.js';\n"]}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/form-view.ts","../src/list-view.ts","../src/picker-object.ts","../src/show-view.ts","../src/resource-object.ts","../src/buro-page.ts","../src/confirm-dialog.ts","../src/index.ts"],"sourcesContent":["import type { ClickableLocator, PlaywrightPage } from './types.js';\n\nexport interface FormFieldObject<L> {\n input: () => L;\n error: () => L;\n help: () => L;\n}\n\nexport interface FormView<L extends ClickableLocator> {\n field: (fieldName: string) => FormFieldObject<L>;\n submit: () => L;\n cancel: () => L;\n action: (actionName: string) => L;\n /**\n * A keyed node of the record screen (a panel, tabs, a step) by its key,\n * inside `[data-buro-region=\"<region>\"]` (default the body). Nodes carry no\n * test id of their own: the key and the region locate them.\n */\n node: (key: string, region?: 'record-header' | 'record-body') => L;\n}\n\nexport function createFormView<L extends ClickableLocator>(\n page: PlaywrightPage<L>,\n resource: string,\n view: 'create' | 'edit' | 'show',\n): FormView<L> {\n return {\n field: (fieldName) => {\n page.getByTestId(`form-field:${resource}:${view}:${fieldName}`);\n return {\n input: () => page.getByTestId(`form-field-input:${resource}:${view}:${fieldName}`),\n error: () => page.getByTestId(`form-field-error:${resource}:${view}:${fieldName}`),\n help: () => page.getByTestId(`form-field-help:${resource}:${view}:${fieldName}`),\n };\n },\n submit: () => page.getByTestId(`form-submit:${resource}:${view}`),\n cancel: () => page.getByTestId(`form-cancel:${resource}:${view}`),\n action: (actionName) => page.getByTestId(`form-action:${resource}:${view}:${actionName}`),\n node: (key, region = 'record-body') =>\n page.locator(`[data-buro-region=\"${region}\"] [data-buro-key=\"${key}\"]`),\n };\n}\n","import type { ClickableLocator, PlaywrightPage } from './types.js';\n\n/**\n * A row's address inside the filter-builder draft: `[]` is the root group,\n * `[0]` is its first row, `[1, 0]` is the first row of the group nested at\n * top-level index 1. Mirrors `DraftPath` in\n * `packages/ui-shadcn/src/list-kit/filter-builder/draft.ts` — the testid\n * suffix is `path.join('-')` (an empty path renders as the empty string, so\n * the root group's own testid carries a trailing `:`, e.g.\n * `list-filter:<r>:group::add-row`).\n */\nexport type FilterRowPath = readonly number[];\n\nexport interface ListView<L extends ClickableLocator> {\n goto: () => Promise<void>;\n row: (recordId: string) => RowObject<L>;\n /**\n * EVERY rendered row of this resource, as one locator — the set, not a\n * named member of it. `row(recordId)` cannot express it: a row's testid\n * embeds its record id, so the set is only addressable by prefix.\n *\n * This is the accessor a list assertion is actually built on\n * (`await expect(list.rows()).toHaveCount(n)`), and it was missing for as\n * long as the only consumer of this package was a mock that never counted\n * anything.\n */\n rows: () => L;\n /**\n * One column across every rendered row, in row order — again a set, again\n * prefix-addressed. Reading a whole column through ONE locator matters for\n * more than convenience: a per-row loop awaits between reads and can meet a\n * detached node mid-re-render, which turns a polling wait into a thrown\n * error instead of another attempt.\n */\n column: (fieldName: string) => L;\n /** The column header's menu trigger (sort / pin / hide / move). */\n columnMenu: (fieldName: string) => L;\n /** The sort item inside an OPEN column header menu. */\n columnSort: (fieldName: string, direction: 'asc' | 'desc') => L;\n /**\n * The reorder item inside an OPEN column header menu — moves the column one\n * position left or right.\n *\n * ⚠️ What it moves is **column layout**, which is a different persistence\n * mechanism from everything else on this object: order, width and pinning\n * live in raw `localStorage` under `buro:table-layout:<resource>:{order,\n * sizing,pinning}` and are carried by neither the URL nor a saved view. See\n * {@link ListView.savedViews}.\n */\n columnMove: (fieldName: string, direction: 'left' | 'right') => L;\n /** The Columns menu trigger — show/hide columns, reset widths, restore defaults. */\n columnsToggle: () => L;\n /**\n * One column's row inside the OPEN Columns menu. A column the resource\n * declares in `views.list.columns` is REQUIRED unless\n * `views.list.requiredColumns` says otherwise, and renders `disabled` with\n * `data-required=\"true\"` — only `optionalColumns` are actually clickable.\n */\n columnsOption: (columnId: string) => L;\n /** The rows-per-page select trigger; its text is the active page size. */\n pageSize: () => L;\n search: () => L;\n // ── Filter builder (SP2) ─────────────────────────────────────────────\n // The chip toolbar this file used to model (`list-dyn-filter:*`,\n // `list-add-filter:*`) is gone — SP2 replaced it with a popover panel:\n // open the panel, add a row, pick a field/operator/value, Apply. Applied\n // rows then render as removable badges OUTSIDE the panel. See\n // `packages/ui-shadcn/src/list-kit/filter-builder/*` for the components\n // these testids come from.\n /** The filter region container — `list-filters:<resource>`. */\n filtersContainer: () => L;\n /** Opens/closes the filter-builder popover. */\n filterButton: () => L;\n /** The popover body once open. */\n filterPanel: () => L;\n /** \"+ Filter\" — appends a new predicate row to the group at `groupPath` (root: `[]`). */\n filterAddRow: (groupPath?: FilterRowPath) => L;\n /** Field-select trigger for the row at `path`. */\n filterRowField: (path: FilterRowPath) => L;\n /** One field option inside an open field-select. */\n filterRowFieldOption: (path: FilterRowPath, field: string) => L;\n /** Operator-select trigger for the row at `path`. */\n filterRowOp: (path: FilterRowPath) => L;\n /** One operator option inside an open operator-select. */\n filterRowOpOption: (path: FilterRowPath, op: string) => L;\n /** Value control trigger/input for the row at `path` — shape depends on the field kind (text box, enum/relation/boolean popover). */\n filterRowValue: (path: FilterRowPath) => L;\n /** Removes the row at `path` from the draft (inside the panel, before Apply). */\n filterRowRemove: (path: FilterRowPath) => L;\n /** Commits the draft — applies it and closes the panel. */\n filterApply: () => L;\n /** Clears the draft back to empty (still requires Apply to take effect). */\n filterReset: () => L;\n /** One applied-filter badge outside the panel, by its top-level index. */\n filterBadge: (index: number) => L;\n /** A badge's × — removes that row immediately, no Apply needed. */\n filterBadgeRemove: (index: number) => L;\n /** \"Clear all\" — empties both the pinned slot and the builder group. */\n filterClearAll: () => L;\n /** An always-visible pinned control (`views.list.filters.pinned`) for `field`, rendered outside the panel. */\n filterPinned: (field: string) => L;\n /**\n * The floating bulk bar, which appears as soon as ANY row is selected —\n * even for a resource that declares no bulk action, because it also carries\n * the built-in Export entry and the selection count.\n */\n bulkBar: () => L;\n /** One declared bulk action's button inside the bar (`actions.bulk`). */\n bulkAction: (actionName: string) => L;\n paginationPrev: () => L;\n paginationNext: () => L;\n /**\n * The load-more button a CURSOR-paginated list renders instead of the\n * numbered pager (`views.list.pagination: 'cursor'` → `<CursorLoadMore>`).\n *\n * ⚠️ NOT resource-scoped, because the control itself is not: `CursorLoadMore`\n * carries a bare `data-testid=\"cursor-load-more\"` with no resource segment,\n * unlike every other id above. A page rendering two cursor lists at once\n * would need `.first()`/`.nth()` to tell them apart. Recorded rather than\n * papered over — inventing a scoped id here would only make this object\n * disagree with the component.\n *\n * ⚠️ `<CursorLoadMore>` renders NOTHING when there is no next page, so the\n * end of a cursor list is \"this locator resolves to no element\", not a\n * disabled button. That is what makes it usable as an end-of-list assertion.\n *\n * Like `columnMenu`/`columnSort`, this id has no `useTestIds` factory behind\n * it, so `page-object-vocabulary` tests have nothing to check it against\n * (the pre-existing F6 gap — see the saved-views block below for what that\n * costs, measured).\n */\n loadMore: () => L;\n empty: () => L;\n toolbar: () => L;\n table: () => L;\n // ── Saved views ──────────────────────────────────────────────────────\n // `<ResourceListPage>` renders the Views dropdown UNCONDITIONALLY, and\n // `<BuroProvider>` mounts a localStorage-backed settings store when the\n // adopter supplies none — so \"Save current view…\" is on every list screen\n // of every app built on this framework, whether or not anyone declared\n // `views.list.savedViews`. Until these accessors existed, no page object\n // could address any of it: the only browser tests that ever tried\n // (the since-deleted `apps/playground`'s saved-views spec) spelled the ids by\n // hand, and marked six of their eleven tests `test.fixme` — including both\n // round-trips.\n //\n // ⚠️ **A view carries exactly six keys** — `filters`, `filterGroup`,\n // `sort`, `pageSize`, `search`, `visibleColumns`\n // (`SavedViewSettingValue`). NOT the page number (applying a view always\n // opens page one), NOT the selection, and NOT column layout: width, order\n // and pinning are a separate store (see {@link ListView.columnMove}), so a\n // view restores WHICH columns are shown and never HOW WIDE or in what\n // order.\n //\n // ⚠️ **NONE OF THE THIRTEEN ACCESSORS ADDED WITH THIS BLOCK HAS A\n // `useTestIds` FACTORY** (saved views, the Columns menu, the page-size\n // select and `columnMove`), so `page-object-vocabulary.test.tsx` has nothing\n // to compare them against — the F6 gap again, with thirteen more instances.\n // SP5 task 8 settled it as: NOT closed, and here is the measured cost, so\n // that the next person decides on numbers rather than on the word \"gap\".\n //\n // Both sides are independently pinned, just never against each other:\n // `tests/buro-page.test.ts` pins the string THIS file hands out, and on the\n // component side eight of the thirteen ids are spelled as literals in\n // `packages/ui-shadcn/tests/*` while ten of the thirteen accessors are\n // driven by `examples/marketplace-ops`' browser suite. So a rename in\n // `@burojs/ui-shadcn` reddens something in every case **but one**:\n //\n // `savedViewsMenu` (`list-saved-views-menu:<r>`) is spelled by no package\n // test and addressed by no browser spec, so renaming it in\n // `resource-list-page.tsx` is invisible everywhere and this accessor would\n // quietly point at nothing.\n //\n // Closing the family properly means ~13 new factories on the public\n // `TestIdBuilder` plus rewiring `resource-list-page.tsx`,\n // `columns-toggle.tsx` and `resource-list.tsx` to compose through them —\n // a public-surface decision, not a test fix, and it covers\n // `columnMenu`/`columnSort`/`columnMove` and `loadMore` at the same time.\n /** The Views dropdown trigger in the list toolbar. */\n savedViews: () => L;\n /** The dropdown body once open. */\n savedViewsMenu: () => L;\n /**\n * EVERY view entry in the open dropdown (adopter presets and user-saved\n * alike), as one locator — the set, not a named member of it, because a\n * user view's id is a uuid minted at save time and no test can know it in\n * advance. Prefix-addressed for the same reason {@link ListView.rows} is.\n */\n savedViewEntries: () => L;\n /** One view entry by id — for an adopter preset declared in `views.list.savedViews`, whose id IS known. */\n savedView: (viewId: string) => L;\n /** \"Save current view…\" — opens the save dialog. */\n savedViewSave: () => L;\n /** The label input inside the open save dialog. */\n savedViewSaveInput: () => L;\n /** The save dialog's confirm button; disabled while the label is empty. */\n savedViewSaveConfirm: () => L;\n /**\n * \"Manage views…\" — opens the manage dialog. Rendered only when at least\n * one entry exists, so `toHaveCount(0)` is a usable \"this browser has no\n * saved views\" assertion.\n */\n savedViewManage: () => L;\n /** One entry's Delete button inside the open manage dialog. */\n savedViewManageDelete: (viewId: string) => L;\n}\n\nexport interface RowObject<L extends ClickableLocator> {\n /**\n * The row element itself. Without it a caller cannot say \"this row is on\n * screen\" or \"this row is gone\" — the two assertions a list test needs\n * most, and the ones `cell()`/`action()` cannot stand in for (a row can be\n * present while a given cell or action is not).\n */\n root: () => L;\n cell: (fieldName: string) => L;\n action: (actionName: string) => L;\n checkbox: () => L;\n open: () => Promise<void>;\n}\n\nexport interface ListViewOptions {\n /**\n * What {@link ListView.goto} navigates to. Defaults to `/<resource>`, which\n * assumes the route is named after the resource — often false (a `order`\n * resource routed at `/orders`), and it carries no query string, so an app\n * whose test isolation travels on the URL has to pass its whole launch URL\n * here.\n */\n basePath?: string;\n}\n\n/** `path.join('-')` — see `FilterRowPath`'s doc for the empty-path edge case. */\nfunction pathStr(path: FilterRowPath): string {\n return path.join('-');\n}\n\nexport function createListView<L extends ClickableLocator>(\n page: PlaywrightPage<L>,\n resource: string,\n options: ListViewOptions = {},\n): ListView<L> {\n const path = options.basePath ?? `/${resource}`;\n const filterBase = `list-filter:${resource}`;\n const sortBase = (field: string) => `list-sort:${resource}:${field}`;\n const rowBase = (rowPath: FilterRowPath) => `${filterBase}:row:${pathStr(rowPath)}`;\n const groupBase = (groupPath: FilterRowPath) => `${filterBase}:group:${pathStr(groupPath)}`;\n return {\n goto: async () => {\n await page.goto(path);\n },\n row: (recordId) => createRowObject(page, resource, recordId),\n rows: () => page.locator(`[data-testid^=\"list-row:${resource}:\"]`),\n column: (fieldName) =>\n page.locator(`[data-testid^=\"list-cell:${resource}:\"][data-testid$=\":${fieldName}\"]`),\n columnMenu: (fieldName) => page.getByTestId(sortBase(fieldName)),\n columnSort: (fieldName, direction) =>\n page.getByTestId(`${sortBase(fieldName)}:sort-${direction}`),\n columnMove: (fieldName, direction) =>\n page.getByTestId(`${sortBase(fieldName)}:move-${direction}`),\n columnsToggle: () => page.getByTestId(`list-columns:${resource}`),\n columnsOption: (columnId) => page.getByTestId(`list-columns-option:${resource}:${columnId}`),\n pageSize: () => page.getByTestId(`list-page-size:${resource}`),\n search: () => page.getByTestId(`list-search:${resource}`),\n filtersContainer: () => page.getByTestId(`list-filters:${resource}`),\n filterButton: () => page.getByTestId(`${filterBase}:button`),\n filterPanel: () => page.getByTestId(`${filterBase}:panel`),\n filterAddRow: (groupPath = []) => page.getByTestId(`${groupBase(groupPath)}:add-row`),\n filterRowField: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:field`),\n filterRowFieldOption: (rowPath, field) =>\n page.getByTestId(`${rowBase(rowPath)}:field:option:${field}`),\n filterRowOp: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:op`),\n filterRowOpOption: (rowPath, op) => page.getByTestId(`${rowBase(rowPath)}:op:option:${op}`),\n filterRowValue: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:value`),\n filterRowRemove: (rowPath) => page.getByTestId(`${rowBase(rowPath)}:remove`),\n filterApply: () => page.getByTestId(`${filterBase}:apply`),\n filterReset: () => page.getByTestId(`${filterBase}:reset`),\n filterBadge: (index) => page.getByTestId(`${filterBase}:badge:${index}`),\n filterBadgeRemove: (index) => page.getByTestId(`${filterBase}:badge:${index}:remove`),\n filterClearAll: () => page.getByTestId(`${filterBase}:clear-all`),\n filterPinned: (field) => page.getByTestId(`${filterBase}:pinned:${field}`),\n bulkBar: () => page.getByTestId(`list-bulk-bar:${resource}`),\n bulkAction: (actionName) => page.getByTestId(`bulk-action:${resource}:${actionName}`),\n paginationPrev: () => page.getByTestId(`list-pagination-prev:${resource}`),\n paginationNext: () => page.getByTestId(`list-pagination-next:${resource}`),\n // Deliberately unscoped — see the interface doc: the component's own id\n // carries no resource segment.\n loadMore: () => page.getByTestId('cursor-load-more'),\n empty: () => page.getByTestId(`list-empty:${resource}`),\n toolbar: () => page.getByTestId(`list-toolbar:${resource}`),\n table: () => page.getByTestId(`list-table:${resource}`),\n savedViews: () => page.getByTestId(`list-saved-views:${resource}`),\n savedViewsMenu: () => page.getByTestId(`list-saved-views-menu:${resource}`),\n // The trailing colon is load-bearing: it separates an ENTRY\n // (`list-saved-view:<r>:<uuid>`) from the trigger\n // (`list-saved-views:<r>`, plural) and from every sibling control\n // (`list-saved-view-save:<r>`, `list-saved-view-section:<r>:<id>`, …).\n savedViewEntries: () => page.locator(`[data-testid^=\"list-saved-view:${resource}:\"]`),\n savedView: (viewId) => page.getByTestId(`list-saved-view:${resource}:${viewId}`),\n savedViewSave: () => page.getByTestId(`list-saved-view-save:${resource}`),\n savedViewSaveInput: () => page.getByTestId(`list-saved-view-save-input:${resource}`),\n savedViewSaveConfirm: () => page.getByTestId(`list-saved-view-save-confirm:${resource}`),\n savedViewManage: () => page.getByTestId(`list-saved-view-manage:${resource}`),\n savedViewManageDelete: (viewId) =>\n page.getByTestId(`list-saved-view-manage-delete:${resource}:${viewId}`),\n };\n}\n\nfunction createRowObject<L extends ClickableLocator>(\n page: PlaywrightPage<L>,\n resource: string,\n recordId: string,\n): RowObject<L> {\n const rowId = `list-row:${resource}:${recordId}`;\n return {\n root: () => page.getByTestId(rowId),\n cell: (fieldName) => page.getByTestId(`list-cell:${resource}:${recordId}:${fieldName}`),\n action: (actionName) =>\n page.getByTestId(`list-row-action:${resource}:${recordId}:${actionName}`),\n checkbox: () => page.getByTestId(`list-row-checkbox:${resource}:${recordId}`),\n open: async () => {\n await page.getByTestId(rowId).click();\n },\n };\n}\n","import type { PlaywrightPage } from './types.js';\n\n/**\n * The relation picker's addresses, as a test drives them.\n *\n * ⚠️ **Every id here was wrong until SP9 task 5, and nothing could see it.**\n * This object used to ask for `picker-dialog:` / `picker-popover:` /\n * `picker-search:` / `picker-option:` / `picker-clear:` /\n * `picker-quickcreate:`, and `@burojs/react`'s `useTestIds()` composed exactly\n * the same six — while `@burojs/ui-shadcn`'s `<RelationPicker>` has always\n * emitted `relation-picker:<target>:…`. Neither vocabulary had a single\n * producer. The cross-check that exists to prevent this\n * (`examples/marketplace-ops/tests/page-object-vocabulary.test.tsx`) was green\n * throughout, because it compared these two copies with each other and neither\n * of them with the component. The producer side is pinned now, in\n * `packages/ui-shadcn/tests/relation-picker-testids.test.tsx`.\n *\n * `quickCreate` is not re-spelled but REMOVED: quick-create inside the picker\n * is deferred to the picker's v2 and there is no element to address. `popover`\n * is likewise gone — the popover content carries no id; {@link PickerObject.list}\n * is the element inside it that does.\n *\n * **`trigger()` is the standalone spelling.** Inside a record form the\n * form overrides the trigger's testid with its own\n * `form-field-input:<resource>:<view>:<field>`, so a form field's picker is\n * opened through `resource(r).create().field(f).input()` and only its popover\n * children are addressed through this object.\n */\nexport interface PickerObject<L> {\n /** The standalone trigger button. In a form, use the form field's `input()`. */\n trigger: () => L;\n /** The popover's search box. */\n search: () => L;\n /** The popover's result list. */\n list: () => L;\n /** One result row, by the target record's id. */\n option: (value: string) => L;\n /** The \"No results.\" row. */\n empty: () => L;\n /** The Clear link — present only when the picker is clearable and set. */\n clear: () => L;\n /** The \"Advanced search\" link that escalates to {@link PickerObject.dialog}. */\n advanced: () => L;\n /** The \"Open list\" link to the target's own list page. */\n viewAll: () => L;\n /** The escalation modal. */\n dialog: () => L;\n /** The escalation modal's own search box. */\n dialogSearch: () => L;\n /** The disabled trigger shown when the target resource is unregistered. */\n unregistered: () => L;\n}\n\nexport function createPickerObject<L>(\n page: PlaywrightPage<L>,\n targetResource: string,\n): PickerObject<L> {\n const prefix = `relation-picker:${targetResource}`;\n return {\n trigger: () => page.getByTestId(prefix),\n search: () => page.getByTestId(`${prefix}:search`),\n list: () => page.getByTestId(`${prefix}:list`),\n option: (value) => page.getByTestId(`${prefix}:option:${value}`),\n empty: () => page.getByTestId(`${prefix}:empty`),\n clear: () => page.getByTestId(`${prefix}:clear`),\n advanced: () => page.getByTestId(`${prefix}:advanced`),\n viewAll: () => page.getByTestId(`${prefix}:view-all`),\n dialog: () => page.getByTestId(`relation-picker-dialog:${targetResource}`),\n dialogSearch: () => page.getByTestId(`relation-picker-dialog:${targetResource}:search`),\n unregistered: () => page.getByTestId(`${prefix}:unregistered`),\n };\n}\n","import { type FormView, createFormView } from './form-view.js';\nimport type { ClickableLocator, PlaywrightPage } from './types.js';\n\nexport interface ShowView<L extends ClickableLocator> extends FormView<L> {\n /**\n * The show page root — `useTestIds`' `pageShow(resource, recordId)`.\n *\n * The ONE show accessor that uses the record id. Every other locator on this\n * view comes from `createFormView`, whose testids carry no record id at all\n * (see {@link import('./resource-object.js').ResourceObject.show}), so this\n * is what lets a test assert it is looking at the show page OF A GIVEN\n * RECORD rather than at whatever detail page happens to be mounted.\n */\n root: () => L;\n}\n\nexport function createShowView<L extends ClickableLocator>(\n page: PlaywrightPage<L>,\n resource: string,\n recordId: string,\n): ShowView<L> {\n return {\n ...createFormView(page, resource, 'show'),\n root: () => page.getByTestId(`page-show:${resource}:${recordId}`),\n };\n}\n","import { type FormView, createFormView } from './form-view.js';\nimport { type ListView, type ListViewOptions, createListView } from './list-view.js';\nimport { type PickerObject, createPickerObject } from './picker-object.js';\nimport { type ShowView, createShowView } from './show-view.js';\nimport type { ClickableLocator, PlaywrightPage } from './types.js';\n\nexport interface ResourceObject<L extends ClickableLocator> {\n name: string;\n list: (options?: ListViewOptions) => ListView<L>;\n /**\n * ⚠️ `recordId` is accepted and IGNORED: the form testids\n * (`form-field:<resource>:edit:<field>`) carry no record id, so an edit view\n * addressed for record A and one addressed for record B are the same\n * locators. Only one edit form is ever mounted at a time, so this is\n * harmless in practice — but the parameter reads like a scope and is not\n * one.\n */\n edit: (recordId: string) => FormView<L>;\n /**\n * ⚠️ `recordId` reaches {@link ShowView.root} and NOTHING ELSE. The show\n * view's field/section/action locators all come from `createFormView`, whose\n * testids carry no record id, so they are the same locators for record A and\n * record B. `root()` is the one accessor that is genuinely scoped to the\n * record — assert on it first if a test needs to know WHICH record's page is\n * mounted.\n */\n show: (recordId: string) => ShowView<L>;\n create: () => FormView<L>;\n picker: () => PickerObject<L>;\n}\n\nexport function createResourceObject<L extends ClickableLocator>(\n page: PlaywrightPage<L>,\n name: string,\n): ResourceObject<L> {\n return {\n name,\n list: (options) => createListView(page, name, options),\n edit: (_recordId) => createFormView(page, name, 'edit'),\n show: (recordId) => createShowView(page, name, recordId),\n create: () => createFormView(page, name, 'create'),\n picker: () => createPickerObject(page, name),\n };\n}\n","import { type ResourceObject, createResourceObject } from './resource-object.js';\nimport type { ClickableLocator, PlaywrightPage } from './types.js';\n\nexport interface BuroPage<L extends ClickableLocator> {\n resource: (name: string) => ResourceObject<L>;\n /**\n * The sidebar entry for a registered resource — `<NavMain>`'s\n * `tid.navMenuItem(resource)`. The whole navigation half of a suite used to\n * spell this string by hand even though the factory existed (SP3 stage C\n * final review, Important 2).\n */\n navMenuItem: (resource: string) => L;\n /** The sidebar entry for an adopter-declared custom page, keyed by page key\n * rather than resource name (`tid.sidebarCustomPage`). */\n sidebarCustomPage: (pageKey: string) => L;\n contextPicker: (sliceName: string) => L;\n /** One option inside an open context picker — the half that actually\n * performs a switch. Without it a caller can open the picker and not choose. */\n contextPickerOption: (sliceName: string, value: string) => L;\n /**\n * The header language switcher (`<LanguageSwitch>`) and one locale button\n * inside it. The trigger carries `data-language-state=\"<code>\"`, which is\n * how a test reads the ACTIVE locale without opening anything.\n */\n languageSwitch: () => L;\n languageSwitchOption: (localeCode: string) => L;\n /** `<LoginForm>`'s three controls, in the order a sign-in uses them. */\n login: () => LoginFormObject<L>;\n /**\n * `<TaskRunPanel>`'s three addressable parts, keyed by the RUN's name — a\n * task run has no resource to key on (a long server-side operation has no\n * record, a bulk run spans a selection).\n *\n * `root()` carries `data-state`, which is how a spec reads the outcome\n * without matching translated text.\n */\n taskRun: (name: string) => TaskRunObject<L>;\n notification: (type: 'success' | 'error' | 'progress' | 'info') => L;\n /**\n * A flow's confirm dialog on a toolbar surface (`form-action:<resource>:<scope>:<action>`): the\n * dialog a flow with `confirm` (or a fired warning) asks through before it writes (P4). Its\n * buttons are the same id with `:proceed` / `:cancel` in place of `:dialog`. A row's flow asks\n * through `list-row-action:<resource>:<id>:<action>:confirm:dialog`.\n */\n actionConfirm: (resource: string, scope: string, actionName: string) => L;\n page: PlaywrightPage<L>;\n}\n\nexport interface TaskRunObject<L> {\n root: () => L;\n /** The bar; its `aria-valuenow`/`aria-valuemax` are the counts. */\n progress: () => L;\n /** One named unit that did not succeed — a refused row, or the step a run stopped at. */\n failure: (subject: string) => L;\n}\n\nexport interface LoginFormObject<L> {\n email: () => L;\n password: () => L;\n submit: () => L;\n}\n\nexport function createBuroPage<L extends ClickableLocator>(page: PlaywrightPage<L>): BuroPage<L> {\n return {\n resource: (name) => createResourceObject(page, name),\n navMenuItem: (resource) => page.getByTestId(`nav-menu-item:${resource}`),\n sidebarCustomPage: (pageKey) => page.getByTestId(`sidebar-custompage:${pageKey}`),\n contextPicker: (sliceName) => page.getByTestId(`context-picker:${sliceName}`),\n contextPickerOption: (sliceName, value) =>\n page.getByTestId(`context-picker-option:${sliceName}:${value}`),\n languageSwitch: () => page.getByTestId('language-switch'),\n languageSwitchOption: (localeCode) => page.getByTestId(`language-switch:${localeCode}`),\n login: () => ({\n email: () => page.getByTestId('login-email'),\n password: () => page.getByTestId('login-password'),\n submit: () => page.getByTestId('login-submit'),\n }),\n taskRun: (name) => ({\n root: () => page.getByTestId(`task-run:${name}`),\n progress: () => page.getByTestId(`task-run-progress:${name}`),\n failure: (subject) => page.getByTestId(`task-run-failure:${name}:${subject}`),\n }),\n notification: (type) => page.getByTestId(`notification:${type}`),\n actionConfirm: (resource, scope, actionName) =>\n page.getByTestId(`form-action:${resource}:${scope}:${actionName}:confirm:dialog`),\n page,\n };\n}\n","import type { PlaywrightPage } from './types.js';\n\nexport interface ConfirmDialogObject<L> {\n dialog: () => L;\n yes: () => L;\n no: () => L;\n}\n\nexport function createConfirmDialog<L>(\n page: PlaywrightPage<L>,\n resource: string,\n scope: string,\n actionName: string,\n): ConfirmDialogObject<L> {\n return {\n dialog: () => page.getByTestId(`action-confirm-dialog:${resource}:${scope}:${actionName}`),\n yes: () => page.getByTestId(`action-confirm-yes:${resource}:${scope}:${actionName}`),\n no: () => page.getByTestId(`action-confirm-no:${resource}:${scope}:${actionName}`),\n };\n}\n","/**\n * `@burojs/test-helpers` — the Playwright entry point.\n *\n * Everything exported here is loadable inside a `@playwright/test` process:\n * page objects over the testid convention `useTestIds()` (`@burojs/react`)\n * emits, and nothing else. The vitest-based provider contract moved to\n * `@burojs/test-helpers/provider-contract` — see that module for the measured\n * reason it can no longer share an entry point with these.\n */\n\n// Constants\nexport const PACKAGE_NAME = '@burojs/test-helpers' as const;\nexport const PACKAGE_VERSION = '0.0.0' as const;\n\n// Types\nexport type { PlaywrightPage, PlaywrightLocator, ClickableLocator } from './types.js';\n\n// Page object factories\nexport {\n createBuroPage,\n type BuroPage,\n type LoginFormObject,\n type TaskRunObject,\n} from './buro-page.js';\nexport { createResourceObject, type ResourceObject } from './resource-object.js';\nexport {\n createListView,\n type ListView,\n type RowObject,\n type ListViewOptions,\n type FilterRowPath,\n} from './list-view.js';\nexport { createFormView, type FormView, type FormFieldObject } from './form-view.js';\nexport { createShowView, type ShowView } from './show-view.js';\nexport { createPickerObject, type PickerObject } from './picker-object.js';\nexport { createConfirmDialog, type ConfirmDialogObject } from './confirm-dialog.js';\n"],"mappings":"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"}