import { DeviceDriver } from '../../drivers/types'; import { sleep, waitForSource } from './element.helper'; import { extractTicketId, setSharedTicketId } from './zendesk.helper'; export async function navigateToFeedback(driver: DeviceDriver): Promise { if (driver.platform === 'android') { const el = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Feedback")'); if (!el) return false; await driver.tapElement(el); await sleep(2000); return true; } const el = await driver.findElementRaw('name', 'Feedback'); if (!el) return false; await driver.tapElement(el); await sleep(2000); return true; } export async function submitFeedback( driver: DeviceDriver, category: string, description: string ): Promise { // Skeleton - implementation depends on actual app UI if (driver.platform === 'android') { const catEl = await driver.findElementRaw('-android uiautomator', `new UiSelector().text("${category}")`); if (!catEl) return false; await driver.tapElement(catEl); await sleep(1000); const textField = await driver.findElementRaw('class name', 'android.widget.EditText'); if (textField) { await driver.typeText(textField, description); await sleep(500); } const submitEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Submit")'); if (!submitEl) return false; await driver.tapElement(submitEl); await sleep(2000); return true; } // iOS const catEl = await driver.findElementRaw('name', category); if (!catEl) return false; await driver.tapElement(catEl); await sleep(1000); const textFields = await driver.findElementsRaw('class name', 'XCUIElementTypeTextView'); if (textFields.length > 0) { await driver.typeText(textFields[0], description); await sleep(500); } const submitEl = await driver.findElementRaw('name', 'Submit'); if (!submitEl) return false; await driver.tapElement(submitEl); await sleep(2000); return true; } /** * feedback 提交成功后,从结果页抓取工单号并持久化(供「获取RN插件 / 插件热更」用例消费)。 * 返回工单号;未抓到返回 null。抓到即写共享文件 reports/.zendesk-ticket.json。 * 工单号是用例间传值的变量,绝不写死——这里负责"产出",下游 resolveTicketId() 负责"取用"。 */ export async function captureFeedbackTicketId(driver: DeviceDriver): Promise { // 提交成功页可能需要一两秒渲染工单号 let ticketId: string | null = null; for (let i = 0; i < 3 && !ticketId; i++) { const source = await driver.getSource(); ticketId = extractTicketId(source); if (!ticketId) await sleep(1500); } if (ticketId) { setSharedTicketId(ticketId); console.log(`feedback 工单号已捕获并保存: ${ticketId}`); } else { console.log('feedback 提交页未解析到工单号(检查 extractTicketId 规则与实际 UI)'); } return ticketId; }