UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

140 lines 5.28 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SAFARI_BUNDLE_ID = void 0; exports.unzipFile = unzipFile; exports.unzipStream = unzipStream; exports.buildSafariPreferences = buildSafariPreferences; exports.findApps = findApps; const node_path_1 = __importDefault(require("node:path")); const utils_1 = require("../../utils"); const support_1 = require("appium/support"); const logger_1 = require("../../logger"); const node_child_process_1 = require("node:child_process"); exports.SAFARI_BUNDLE_ID = 'com.apple.mobilesafari'; const SAFARI_OPTS_ALIASES_MAP = { safariAllowPopups: [ ['WebKitJavaScriptCanOpenWindowsAutomatically', 'JavaScriptCanOpenWindowsAutomatically'], (x) => Number(Boolean(x)), ], safariIgnoreFraudWarning: [['WarnAboutFraudulentWebsites'], (x) => Number(!x)], safariOpenLinksInBackground: [['OpenLinksInBackground'], (x) => Number(Boolean(x))], }; const MACOS_RESOURCE_FOLDER = '__MACOSX'; /** * Unzips a ZIP archive on the local file system. * * @param archivePath Full path to a .zip archive * @returns Temporary folder root where the archive has been extracted */ async function unzipFile(archivePath) { const useSystemUnzipEnv = process.env.APPIUM_PREFER_SYSTEM_UNZIP; const useSystemUnzip = (0, utils_1.isEmpty)(useSystemUnzipEnv) || !['0', 'false'].includes(String(useSystemUnzipEnv).toLowerCase()); const tmpRoot = await support_1.tempDir.openDir(); try { await support_1.zip.extractAllTo(archivePath, tmpRoot, { useSystemUnzip, // https://github.com/appium/appium/issues/14100 fileNamesEncoding: 'utf8', }); } catch (e) { await support_1.fs.rimraf(tmpRoot); throw e; } return { rootDir: tmpRoot, archiveSize: (await support_1.fs.stat(archivePath)).size, }; } /** * Unzips a ZIP archive from a stream. * Uses bdstar tool for this purpose. * This allows to optimize the time needed to prepare the app under test * to MAX(download, unzip) instead of SUM(download, unzip) */ async function unzipStream(zipStream) { const tmpRoot = await support_1.tempDir.openDir(); const bsdtarProcess = (0, node_child_process_1.spawn)(await support_1.fs.which('bsdtar'), ['-x', '--exclude', MACOS_RESOURCE_FOLDER, '--exclude', `${MACOS_RESOURCE_FOLDER}/*`, '-'], { cwd: tmpRoot, }); let archiveSize = 0; bsdtarProcess.stderr.on('data', (chunk) => { const stderr = chunk.toString(); if (stderr.trim()) { logger_1.log.warn(stderr); } }); bsdtarProcess.stdin.on('error', (e) => { logger_1.log.warn(`Error occurred while writing to bsdtar stdin: ${e.message}`); }); zipStream.on('data', (chunk) => { archiveSize += chunk.length; }); zipStream.pipe(bsdtarProcess.stdin); try { await new Promise((resolve, reject) => { zipStream.once('error', reject); bsdtarProcess.once('exit', (code, signal) => { zipStream.unpipe(bsdtarProcess.stdin); logger_1.log.debug(`bsdtar process exited with code ${code}, signal ${signal}`); if (code === 0) { resolve(undefined); } else { reject(new Error('Is it a valid ZIP archive?')); } }); bsdtarProcess.once('error', (e) => { zipStream.unpipe(bsdtarProcess.stdin); reject(e); }); }); } catch (err) { bsdtarProcess.kill(9); await support_1.fs.rimraf(tmpRoot); throw new Error(`The response data cannot be unzipped: ${err.message}`, { cause: err }); } finally { bsdtarProcess.removeAllListeners(); zipStream.removeAllListeners(); } return { rootDir: tmpRoot, archiveSize, }; } /** * Builds Safari preferences object based on the given session capabilities */ function buildSafariPreferences(opts) { const safariSettings = structuredClone(opts?.safariGlobalPreferences ?? {}); for (const [name, [aliases, valueConverter]] of Object.entries(SAFARI_OPTS_ALIASES_MAP)) { const optName = name; if (!Object.hasOwn(opts, optName)) { continue; } for (const alias of aliases) { safariSettings[alias] = valueConverter(opts[optName]); } } return safariSettings; } /** * Looks for items with given extensions in the given folder. * * @param appPath Full path to an app bundle * @param appExtensions List of matching item extensions * @returns List of relative paths to matched items */ async function findApps(appPath, appExtensions) { const globPattern = `**/*.+(${appExtensions.map((ext) => ext.replace(/^\./, '')).join('|')})`; const sortedBundleItems = (await support_1.fs.glob(globPattern, { cwd: appPath, })).sort((a, b) => a.split(node_path_1.default.sep).length - b.split(node_path_1.default.sep).length); return sortedBundleItems; } //# sourceMappingURL=app.js.map