UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

102 lines 4.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrashReportsClient = void 0; const remotexpc_utils_1 = require("./remotexpc-utils"); const logger_1 = require("../logger"); const CRASH_REPORT_EXTENSIONS = ['.ips']; const MAX_FILES_IN_ERROR = 10; /** * Lists and exports device crash reports (`.ips`) on real hardware over RemoteXPC. * * Requires **iOS/tvOS 18+** and the optional **`appium-ios-remotexpc`** package. * Used by {@link IOSCrashLog} for BiDi / `crashlog` collection on real devices. */ class CrashReportsClient { crashReportsService; remoteXPCConnection; constructor(crashReportsService, remoteXPCConnection) { this.crashReportsService = crashReportsService; this.remoteXPCConnection = remoteXPCConnection; } /** * Opens a RemoteXPC crash-reports service for the given UDID. * * @param udid - Real device UDID * @param useRemoteXPC - Must be `true`; callers derive this from `isIos18OrNewer` / session options * @throws {Error} If `useRemoteXPC` is false, or RemoteXPC setup fails */ static async create(udid, useRemoteXPC) { if (!useRemoteXPC) { throw new Error('Real device crash report access requires iOS/tvOS 18 or newer with the appium-ios-remotexpc ' + 'package installed.'); } let remoteXPCConnection; let succeeded = false; try { const Services = await (0, remotexpc_utils_1.getRemoteXPCServices)(); const { crashReportsService, remoteXPC } = await Services.startCrashReportsService(udid); remoteXPCConnection = remoteXPC; const client = new CrashReportsClient(crashReportsService, remoteXPCConnection); succeeded = true; return client; } catch (err) { throw new Error(`Failed to create crash reports client via RemoteXPC: ${err.message}. ` + 'Ensure appium-ios-remotexpc is installed and the device is supported.', { cause: err }); } finally { if (remoteXPCConnection && !succeeded) { try { await remoteXPCConnection.close(); } catch { // ignore } } } } /** * @returns Basenames of crash report files on the device (e.g. `MyApp-2024-01-01-120000.ips`) */ async listCrashes() { const allFiles = await this.crashReportsService.ls('/', -1); return allFiles .filter((filePath) => CRASH_REPORT_EXTENSIONS.some((ext) => filePath.endsWith(ext))) .map((filePath) => { const parts = filePath.split('/'); return parts[parts.length - 1]; }); } /** * Pulls a single crash report off the device into a local folder. * * @param name - Crash file basename as returned by {@link CrashReportsClient.listCrashes} * @param dstFolder - Existing local directory to write into * @throws {Error} If the named report is not found on the device */ async exportCrash(name, dstFolder) { const allFiles = await this.crashReportsService.ls('/', -1); const fullPath = allFiles.find((p) => p.endsWith(`/${name}`) || p === `/${name}`); if (!fullPath) { const filesList = allFiles.slice(0, MAX_FILES_IN_ERROR).join(', '); const hasMore = allFiles.length > MAX_FILES_IN_ERROR; throw new Error(`Crash report '${name}' not found on device. ` + `Available files: ${filesList}${hasMore ? `, ... and ${allFiles.length - MAX_FILES_IN_ERROR} more` : ''}`); } await this.crashReportsService.pull(dstFolder, fullPath); } /** * Tears down the crash-reports service and closes the RemoteXPC connection. */ async close() { this.crashReportsService.close(); try { await this.remoteXPCConnection.close(); } catch (err) { logger_1.log.warn(`Error closing RemoteXPC connection for crash reports: ${err.message}`); } } } exports.CrashReportsClient = CrashReportsClient; //# sourceMappingURL=crash-reports-client.js.map