AI_UIAutomation/utils/common/feedback.helper.ts

86 lines
3.0 KiB
TypeScript

import { DeviceDriver } from '../../drivers/types';
import { sleep, waitForSource } from './element.helper';
import { extractTicketId, setSharedTicketId } from './zendesk.helper';
export async function navigateToFeedback(driver: DeviceDriver): Promise<boolean> {
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<boolean> {
// 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<string | null> {
// 提交成功页可能需要一两秒渲染工单号
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;
}