test: subgraph integration contracts and expanded Playwright coverage (#10123)

## Summary

Add integration contract tests (unit) and expanded Playwright coverage
for subgraph promotion, hydration, navigation, and lifecycle edge
behaviors.

## Changes

- **What**: 22 unit/integration tests across 9 files covering promotion
store sync, widget view lifecycle, input link resolution, pseudo-widget
cache, navigation viewport restore, and subgraph operations. 13
Playwright E2E tests covering proxyWidgets hydration stability, promoted
source removal cleanup, pseudo-preview unpack/remove, multi-link
representative round-trip, nested promotion retarget, and navigation
state on workflow switch.
- **Helpers**: Added `isPseudoPreviewEntry`, `getPseudoPreviewWidgets`,
`getNonPreviewPromotedWidgets` to promotedWidgets helper. Added
`SubgraphHelper.getNodeCount()`.

## Review Focus

- Test-only PR — no production code changes
- Validates existing subgraph behaviors are covered by regression tests
before further feature work
- Phase 4 (unit/integration contracts) and Phase 5 (Playwright
expansion) of the subgraph test coverage plan

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10123-test-subgraph-integration-contracts-and-expanded-Playwright-coverage-3256d73d365081258023e3a763859e00)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Alexander Brown
2026-03-19 16:54:15 -07:00
committed by GitHub
parent 6dfc7b4306
commit 4d57c41fdb
59 changed files with 3455 additions and 1100 deletions

View File

@@ -244,7 +244,10 @@ describe('Graph Clearing and Callbacks', () => {
graph.id = graphId
const promotionStore = usePromotionStore()
promotionStore.promote(graphId, 1 as NodeId, '10', 'seed')
promotionStore.promote(graphId, 1 as NodeId, {
sourceNodeId: '10',
sourceWidgetName: 'seed'
})
const widgetValueStore = useWidgetValueStore()
widgetValueStore.registerWidget(graphId, {
@@ -258,14 +261,24 @@ describe('Graph Clearing and Callbacks', () => {
disabled: undefined
})
expect(promotionStore.isPromotedByAny(graphId, '10', 'seed')).toBe(true)
expect(
promotionStore.isPromotedByAny(graphId, {
sourceNodeId: '10',
sourceWidgetName: 'seed'
})
).toBe(true)
expect(widgetValueStore.getWidget(graphId, '10' as NodeId, 'seed')).toEqual(
expect.objectContaining({ value: 1 })
)
graph.clear()
expect(promotionStore.isPromotedByAny(graphId, '10', 'seed')).toBe(false)
expect(
promotionStore.isPromotedByAny(graphId, {
sourceNodeId: '10',
sourceWidgetName: 'seed'
})
).toBe(false)
expect(
widgetValueStore.getWidget(graphId, '10' as NodeId, 'seed')
).toBeUndefined()