import { VueWrapper } from '@vue/test-utils' import { ComponentPublicInstance } from 'vue' export interface TestHelpers { findByText: (text: string) => HTMLElement | null findByTestId: (testId: string) => HTMLElement | null clickByText: (text: string) => Promise clickByTestId: (testId: string) => Promise fillByTestId: (testId: string, value: string) => Promise } export function createTestHelpers(wrapper: VueWrapper): TestHelpers { return { findByText: (text: string) => { return wrapper.element.textContent?.includes(text) ? wrapper.element : null }, findByTestId: (testId: string) => { return wrapper.element.querySelector(`[data-testid="${testId}"]`) }, clickByText: async (text: string) => { const element = wrapper.element.textContent?.includes(text) ? wrapper.element : null if (element) { element.click() await wrapper.vm.$nextTick() } }, clickByTestId: async (testId: string) => { const element = wrapper.element.querySelector(`[data-testid="${testId}"]`) if (element) { element.click() await wrapper.vm.$nextTick() } }, fillByTestId: async (testId: string, value: string) => { const element = wrapper.element.querySelector(`[data-testid="${testId}"]`) as HTMLInputElement if (element) { element.value = value element.dispatchEvent(new Event('input', { bubbles: true })) await wrapper.vm.$nextTick() } }, } } export function waitFor(condition: () => boolean, timeout = 5000): Promise { return new Promise((resolve, reject) => { const startTime = Date.now() const check = () => { if (condition()) { resolve() } else if (Date.now() - startTime > timeout) { reject(new Error(`Timeout waiting for condition`)) } else { setTimeout(check, 100) } } check() }) }