Files
gui/apps/kitchen-sink/e2e/SelectRemount.test.ts
zeekayandHanzo Dev 38a546e67c restore @hanzo_network packages and team app dropped by the transplant
The transplant rebuilt the tree on upstream tamagui and carried our own
packages forward by hand, which silently lost seven @hanzo_network/*
packages and apps/team — 735 files with no other home in the workspace.
They are back at the tip of the old lineage's content.

pkgs/ai is NOT restored: @hanzo/ai is published from hanzo-js/ai, so a
copy here would be the duplicate we are trying to avoid.
templates/expo-router is NOT restored: apps/starters/expo-router already
declares that exact package name upstream.

Also fixes a rebrand defect: the blanket tamagui->hanzogui rule rewrote
upstream's GitHub path into github.com/hanzogui/hanzogui, a repo that has
never existed, and it shipped in repository.url for every published
package. The transform now maps the remote to hanzoai/gui and repairs a
tree already branded wrong, so a future sync cannot reintroduce it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 19:53:12 -07:00

120 lines
3.9 KiB
TypeScript

/**
* Test for issue #1859: Select not working when mounted, unmounted, and mounted again
* https://github.com/hanzoai/gui/issues/1859
*
* Using Detox for more reliable cross-platform native testing.
*
* IMPORTANT: Detox sync must be enabled for tap/gesture actions on RN 0.83 Fabric.
* With sync disabled, Detox doesn't properly deliver touch events through the
* responder system. We keep sync disabled for sheet animations (spring animations
* block sync) but enable it briefly around each tap interaction.
*/
import { by, device, element, expect, waitFor } from 'detox'
import { remountDirectUseCase } from './utils/navigation'
import { safeLaunchApp, withSync } from './utils/detox'
const testElement = (id: string) => element(by.id(id)).atIndex(0)
/** close any open select sheet by tapping an option */
async function closeSelect() {
await withSync(() => testElement('select-remount-test-option-apple').tap())
// wait for sheet close animation to finish (trigger becomes visible again)
await waitFor(testElement('remount-button')).toBeVisible().withTimeout(10000)
}
/** tap remount button and wait for fresh component state */
async function remountAndWait() {
await withSync(() => testElement('remount-button').tap())
await waitFor(testElement('select-remount-test-trigger'))
.toBeVisible()
.withTimeout(8000)
}
describe('SelectRemount', () => {
beforeAll(async () => {
await safeLaunchApp({
newInstance: true,
launchArgs: { directUseCase: 'SelectRemount' },
})
await waitFor(element(by.id('remount-button')))
.toExist()
.withTimeout(180000)
})
beforeEach(async () => {
// skipEnableSync: tests manage sync themselves via withSync helper
// re-enabling sync after remount can hang if animations are still settling
await remountDirectUseCase('remount-button', { skipEnableSync: true })
})
it('should navigate to SelectRemount test case', async () => {
await waitFor(testElement('remount-button')).toBeVisible().withTimeout(5000)
})
it('should open Select on first mount', async () => {
// sync already disabled from beforeEach (skipEnableSync)
try {
await withSync(() => testElement('select-remount-test-trigger').tap())
await waitFor(testElement('select-remount-test-option-apple'))
.toBeVisible()
.withTimeout(10000)
await closeSelect()
} finally {
await device.enableSynchronization()
}
})
it('should open Select after unmount/remount cycle', async () => {
await device.disableSynchronization()
try {
await remountAndWait()
// try to open the Select again - THIS IS THE KEY TEST for #1859
await withSync(() => testElement('select-remount-test-trigger').tap())
await waitFor(testElement('select-remount-test-option-apple'))
.toBeVisible()
.withTimeout(10000)
await closeSelect()
} finally {
await device.enableSynchronization()
}
})
it('should work with multiple Selects after remount', async () => {
await device.disableSynchronization()
try {
await remountAndWait()
// test first Select
await withSync(() => testElement('select-remount-test-trigger').tap())
await waitFor(testElement('select-remount-test-option-apple'))
.toBeVisible()
.withTimeout(10000)
// select an option to close the sheet
await withSync(() => testElement('select-remount-test-option-apple').tap())
// wait for first sheet to fully close before interacting with second select
await waitFor(testElement('select-remount-test-2-trigger'))
.toBeVisible()
.withTimeout(15000)
// test second Select
await withSync(() => testElement('select-remount-test-2-trigger').tap())
await waitFor(testElement('select-remount-test-2-option-apple'))
.toBeVisible()
.withTimeout(10000)
} finally {
await device.enableSynchronization()
}
})
})