{"version":3,"file":"h-k-dev-angular-tree-testing.mjs","sources":["../../../projects/angular-tree/testing/tree-harness.ts","../../../projects/angular-tree/testing/public-api.ts","../../../projects/angular-tree/testing/h-k-dev-angular-tree-testing.ts"],"sourcesContent":["import {\n  ComponentHarness,\n  HarnessPredicate,\n  parallel,\n  type BaseHarnessFilters,\n  type ElementDimensions,\n  type TestElement,\n} from '@angular/cdk/testing';\nimport type { CheckState } from '@h-k-dev/angular-tree';\n\n/** Criteria to filter `TreeHarness` instances. */\nexport interface TreeHarnessFilters extends BaseHarnessFilters {}\n\n/** Criteria to filter tree node (row) harnesses. */\nexport interface TreeNodeHarnessFilters extends BaseHarnessFilters {\n  /** Full row text (the consumer template's rendered text). */\n  text?: string | RegExp;\n  /** The node's `expansionKey` result. */\n  key?: string;\n  /** Zero-based depth — same scale as `TreeNodeContext.level`. */\n  level?: number;\n  expanded?: boolean;\n  selected?: boolean;\n}\n\n/** Drop position relative to the target row (Phase 4 three-zone math). */\nexport type TreeDropZone = 'before' | 'inside' | 'after';\n\n/** Pointer offset into a row per zone — safely inside the 25/50/25 bands. */\nconst ZONE_RATIO: Record<TreeDropZone, number> = {\n  before: 0.1,\n  inside: 0.5,\n  after: 0.9,\n};\n\n/**\n * Fake-mouse-event payload the CDK drag internals accept: they measure\n * distance from `pageX`/`pageY` (real MouseEvents derive those from client\n * coordinates — synthetic ones must carry both), and treat `buttons === 0 ||\n * detail === 0` as a screen-reader fake that aborts the drag.\n */\nfunction mouseEventData(point: {\n  x: number;\n  y: number;\n}): Record<string, number> {\n  return {\n    button: 0,\n    buttons: 1,\n    detail: 1,\n    clientX: point.x,\n    clientY: point.y,\n    pageX: point.x,\n    pageY: point.y,\n  };\n}\n\n/**\n * Harness for one rendered tree row. Obtain via `TreeHarness.getVisibleNodes`\n * / `getNode` — virtualization renders only a window, so a node harness\n * exists exactly for rows that currently have DOM.\n */\nexport class TreeNodeHarness extends ComponentHarness {\n  static hostSelector = '.tree-node';\n\n  static with(\n    options: TreeNodeHarnessFilters = {},\n  ): HarnessPredicate<TreeNodeHarness> {\n    return new HarnessPredicate(TreeNodeHarness, options)\n      .addOption('text', options.text, (harness, text) =>\n        HarnessPredicate.stringMatches(harness.getText(), text),\n      )\n      .addOption(\n        'key',\n        options.key,\n        async (harness, key) => (await harness.getKey()) === key,\n      )\n      .addOption(\n        'level',\n        options.level,\n        async (harness, level) => (await harness.getLevel()) === level,\n      )\n      .addOption(\n        'expanded',\n        options.expanded,\n        async (harness, expanded) => (await harness.isExpanded()) === expanded,\n      )\n      .addOption(\n        'selected',\n        options.selected,\n        async (harness, selected) => (await harness.isSelected()) === selected,\n      );\n  }\n\n  /** Trimmed, whitespace-collapsed text of the whole row template. */\n  async getText(): Promise<string> {\n    return (await this.host()).text();\n  }\n\n  /** The node's stable key (`expansionKey` result). */\n  async getKey(): Promise<string> {\n    // data-node-id is a documented state hook (docs/THEMING.md), not private DOM.\n    return (await (await this.host()).getAttribute('data-node-id')) ?? '';\n  }\n\n  /** Zero-based depth (`aria-level` is 1-based; `TreeNodeContext.level` is not). */\n  async getLevel(): Promise<number> {\n    return Number(await (await this.host()).getAttribute('aria-level')) - 1;\n  }\n\n  /** Whether `childrenAccessor` reports children (aria-expanded only exists on parents). */\n  async isExpandable(): Promise<boolean> {\n    return (await (await this.host()).getAttribute('aria-expanded')) != null;\n  }\n\n  async isExpanded(): Promise<boolean> {\n    return (await (await this.host()).getAttribute('aria-expanded')) === 'true';\n  }\n\n  /** Selection state — read from `data-selected`, which holds in both plain and checkbox mode. */\n  async isSelected(): Promise<boolean> {\n    return (await (await this.host()).getAttribute('data-selected')) != null;\n  }\n\n  /** Tri-state under `checkboxSelection` (`aria-checked`; `mixed` → `indeterminate`). */\n  async getCheckState(): Promise<CheckState> {\n    const checked = await (await this.host()).getAttribute('aria-checked');\n    return checked === 'mixed'\n      ? 'indeterminate'\n      : checked === 'true'\n        ? 'checked'\n        : 'unchecked';\n  }\n\n  /** Expands via the template's `treeNodeToggle`. No-op when already expanded or a leaf. */\n  async expand(): Promise<void> {\n    if (!(await this.isExpandable()) || (await this.isExpanded())) return;\n    await (await this.#toggle()).click();\n  }\n\n  /** Collapses via the template's `treeNodeToggle`. No-op when already collapsed. */\n  async collapse(): Promise<void> {\n    if (!(await this.isExpanded())) return;\n    await (await this.#toggle()).click();\n  }\n\n  /** Plain row click — emits `activated`, never mutates selection (Gmail semantics). */\n  async activate(): Promise<void> {\n    await (await this.host()).click();\n  }\n\n  /** Toggles selection via the template's `treeNodeCheckbox` (cascade rules apply). */\n  async toggleSelection(): Promise<void> {\n    const checkbox = await this.locatorForOptional('[treeNodeCheckbox]')();\n    if (!checkbox) {\n      throw new Error(\n        'angular-tree harness: toggleSelection needs a [treeNodeCheckbox] element in the node ' +\n          'template — the tree ships no checkbox UI (see docs/THEMING.md).',\n      );\n    }\n    await checkbox.click();\n  }\n\n  async focus(): Promise<void> {\n    await (await this.host()).focus();\n  }\n\n  /** Internal (`_` per STYLE.md): `TreeHarness.dragTo` drives the pointer from outside. */\n  async _dispatchMouse(\n    type: string,\n    point: { x: number; y: number },\n  ): Promise<void> {\n    await (await this.host()).dispatchEvent(type, mouseEventData(point));\n  }\n\n  /** Internal: row rect for drop-point math (all zeros in layoutless jsdom). */\n  async _rect(): Promise<ElementDimensions> {\n    return (await this.host()).getDimensions();\n  }\n\n  /** Internal: resolved row height — the tree's fixed `itemSize`. */\n  async _height(): Promise<number> {\n    return parseFloat(await (await this.host()).getCssValue('height'));\n  }\n\n  #toggle(): Promise<TestElement> {\n    return this.locatorForOptional('[treeNodeToggle]')().then((toggle) => {\n      if (!toggle) {\n        throw new Error(\n          'angular-tree harness: expand/collapse needs a [treeNodeToggle] element in the node ' +\n            'template — the tree ships no toggle UI. Alternative: drive tree.expand() directly.',\n        );\n      }\n      return toggle;\n    });\n  }\n}\n\n/**\n * Harness for `<angular-tree>` (`@angular/cdk/testing`) — consumers test\n * expansion, selection and drag & drop without knowing the tree's DOM\n * (ROADMAP Phase 8; same DX as `MatTreeHarness`).\n */\nexport class TreeHarness extends ComponentHarness {\n  static hostSelector = 'angular-tree';\n\n  static with(options: TreeHarnessFilters = {}): HarnessPredicate<TreeHarness> {\n    return new HarnessPredicate(TreeHarness, options);\n  }\n\n  readonly #viewport = this.locatorFor('.tree-viewport');\n\n  /**\n   * Rows that currently have DOM, in visual order. Under virtualization this\n   * is the rendered window, not the whole visible set — scroll (or size the\n   * host) to materialize more.\n   */\n  async getVisibleNodes(\n    filters: TreeNodeHarnessFilters = {},\n  ): Promise<TreeNodeHarness[]> {\n    return this.locatorForAll(TreeNodeHarness.with(filters))();\n  }\n\n  /** Convenience for order assertions: `getVisibleNodes()` mapped to text. */\n  async getVisibleTexts(): Promise<string[]> {\n    const nodes = await this.getVisibleNodes();\n    return parallel(() => nodes.map((node) => node.getText()));\n  }\n\n  /** The first rendered row matching `filters`; throws when none does. */\n  async getNode(filters: TreeNodeHarnessFilters): Promise<TreeNodeHarness> {\n    return this.locatorFor(TreeNodeHarness.with(filters))();\n  }\n\n  async expandNode(filters: TreeNodeHarnessFilters): Promise<void> {\n    await (await this.getNode(filters)).expand();\n  }\n\n  async collapseNode(filters: TreeNodeHarnessFilters): Promise<void> {\n    await (await this.getNode(filters)).collapse();\n  }\n\n  /**\n   * Drags `source` onto `target` with a full pointer sequence and releases in\n   * the requested zone — ends in a `moved` intent exactly like a user drag\n   * (guards, `disableDrop`, multi-drag pruning all apply).\n   */\n  async dragTo(\n    source: TreeNodeHarnessFilters,\n    target: TreeNodeHarnessFilters,\n    zone: TreeDropZone = 'inside',\n  ): Promise<void> {\n    const sourceNode = await this.getNode(source);\n    const from = await this.#dropPoint(sourceNode, 'inside');\n    const to = await this.#dropPoint(await this.getNode(target), zone);\n\n    // CDK registers its document listeners on mousedown, and the source row\n    // leaves the DOM once the sequence starts (placeholder swap) — so the\n    // pickup happens on the row, everything after targets the viewport\n    // (document capture listeners see events on any attached element).\n    await sourceNode._dispatchMouse('mousedown', from);\n    // > 5px: crosses CDK's drag-start threshold; targeting happens on the next move.\n    await sourceNode._dispatchMouse('mousemove', { x: from.x, y: from.y + 8 });\n\n    const viewport = await this.#viewport();\n    await viewport.dispatchEvent('mousemove', mouseEventData(to));\n    await viewport.dispatchEvent('mouseup', mouseEventData(to));\n  }\n\n  /**\n   * Pointer position for a zone on a row. Prefers the row's real rect; in\n   * layoutless environments (jsdom rects are all zeros) it reconstructs the\n   * position with the same arithmetic the tree itself uses (viewport top +\n   * index × itemSize), assuming scroll offset 0 — which layoutless\n   * environments cannot scroll away from anyway.\n   */\n  async #dropPoint(\n    node: TreeNodeHarness,\n    zone: TreeDropZone,\n  ): Promise<{ x: number; y: number }> {\n    const rect = await node._rect();\n    if (rect.height > 0) {\n      return { x: rect.left + 8, y: rect.top + rect.height * ZONE_RATIO[zone] };\n    }\n\n    const viewportRect = await (await this.#viewport()).getDimensions();\n    const rows = await this.getVisibleNodes();\n    const keys = await parallel(() => rows.map((row) => row.getKey()));\n    const index = keys.indexOf(await node.getKey());\n    const itemSize = (await node._height()) || 32;\n    return {\n      x: viewportRect.left + 8,\n      y: viewportRect.top + (index + ZONE_RATIO[zone]) * itemSize,\n    };\n  }\n}\n","/*\n * Public API Surface of angular-tree/testing\n */\n\nexport * from './tree-harness';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}