UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

735 lines (678 loc) 20.2 kB
import type {AnyCase, Element, HTTPHeaders, Location, Size, StringRecord} from '@appium/types'; import type B from 'bluebird'; import type {EventEmitter} from 'node:events'; import type {Page} from '../types'; import type {AuthorizationStatus, BatteryState, ThermalState} from './enum'; export type Direction = 'up' | 'down' | 'left' | 'right'; export type LocationWithAltitude = Location & {altitude: number}; /** * Battery information. Returned by the `mobile: getBatteryInfo` execute method. */ export interface BatteryInfo { /** * Battery level in range `[0.0, 1.0]`, where `1.0` means 100% charge. */ level: number; /** * Battery state */ state: BatteryState; } /** * Options for `stopRecordingScreen` command */ export interface StopRecordingScreenOptions { /** * The path to the remote location, where the resulting video should be * uploaded. * * The following protocols are supported: `http`, `https`, `ftp`. Null or empty * string value (the default setting) means the content of resulting file * should be encoded as Base64 and passed as the endpoint response value. An * exception will be thrown if the generated media file is too big to fit into * the available process memory. */ remotePath?: string; /** * The name of the user for the remote authentication. * * Only works if `remotePath` is provided. */ user?: string; /** * The password for the remote authentication. * * Only works if `remotePath` is provided. */ pass?: string; /** * Additional headers mapping for multipart http(s) uploads */ headers?: HTTPHeaders; /** * The name of the form field where the file content BLOB should be stored for * http(s) uploads */ fileFieldName?: string; /** * Additional form fields for multipart http(s) uploads */ formFields?: Record<string, any> | [string, any][]; /** * The http multipart upload method name. * * Only works if `remotePath` is provided. * * @defaultValue 'PUT' */ method?: 'PUT' | 'POST' | 'PATCH'; } export type VideoQuality = 'low' | 'medium' | 'high' | 'photo'; /** * Options for `startRecordingScreen` command */ export interface StartRecordingScreenOptions extends StopRecordingScreenOptions { /** * The video codec type used for encoding of the be recorded screen capture. * * Execute `ffmpeg -codecs` in the terminal to see the list of supported video codecs. * @defaultValue 'mjpeg' */ videoType?: string; /** * The video encoding quality * @defaultValue 'medium' */ videoQuality?: VideoQuality | number; /** * The Frames Per Second rate of the recorded video. * * Change this value if the resulting video is too slow or too fast. * @defaultValue 10 */ videoFps?: string | number; /** * The FFMPEG video filters to apply. * * These filters allow to scale, flip, rotate and do many other useful transformations on the source video stream. See [FFMPEG documentation](https://ffmpeg.org/ffmpeg-filters.html) for formatting help. * @see https://ffmpeg.org/ffmpeg-filters.html */ videoFilters?: string; /** * The scaling value to apply. * * See [the FFMPEG wiki](https://trac.ffmpeg.org/wiki/Scaling) for possible values. * * No scale is applied by default. If both `videoFilters` and `videoScale` are set, then only `videoFilters` value will be respected. * @see https://trac.ffmpeg.org/wiki/Scaling */ videoScale?: string; /** * Output pixel format. * * Execute `ffmpeg -pix_fmts` to list possible values. For Quicktime * compatibility, set to `yuv420p` along with videoType: `libx264`. */ pixelFormat?: string; /** * If `true`, ignore errors and restart immediately. If `false` or not provided, try to catch and upload/return the currently running screen recording. * @defaultValue false */ forceRestart?: boolean; /** * The maximum recording time, in seconds. * The maximum value is 600 (10 minutes). * @defaultValue 180 */ timeLimit?: string | number; /** * Hardware acceleration to be used by FFMPEG for decoding, encoding and scaling. * * * * `videoToolbox` Apple Silicon * * `cuda` NVIDIA GPU * * `amf_dx11` AMD and DirectX 11 * * `qsv` Intel Quick Sync Video * * `vaapi` Video Acceleration API (VAAPI) * * @see {@link https://trac.ffmpeg.org/wiki/HWAccelIntro#PlatformAPIAvailability| Platform API Availability } * @see {@link https://trac.ffmpeg.org/wiki/HWAccelIntro#VideoToolbox| VideoToolbox} * @see {@link https://trac.ffmpeg.org/wiki/HWAccelIntro#CUDANVENCNVDEC|Cuda} * @see {@link https://trac.ffmpeg.org/wiki/Hardware/AMF|AMF} * @see {@link https://trac.ffmpeg.org/wiki/Hardware/QuickSync|QSV} * @see {@link https://trac.ffmpeg.org/wiki/Hardware/VAAPI|VAAPI} */ hardwareAcceleration?: 'cuda' | 'videoToolbox' | 'amf_dx11' | 'qsv' | 'vaapi'; } export interface PageChangeNotification { pageArray: Page[]; appIdKey: string; } /** * Either a string that contains full path to the mount root for real devices, or a function which accepts two parameters * (bundle identifier and optional container type) and returns (or resolves) the full path to the container root folder on the local filesystem. */ export type ContainerRootSupplier = ( bundleId: string, containerType: string | null, ) => string | Promise<string>; export interface WaitingAtoms { count: number; alertNotifier: EventEmitter; alertMonitor: B<void>; } export interface ContainerObject { /** * The parsed bundle identifier */ bundleId: string; /** * The absolute full path of the item on the local filesystem */ pathInContainer: string; /** * The container type */ containerType: string | null; } export type AtomsElement<S extends string = string> = Omit< Element<S>, 'element-6066-11e4-a52e-4f735466cecf' >; export interface Context { /** * The identifier of the context. * * The native context will be `NATIVE_APP` and the webviews will be `WEBVIEW_xxx` */ id: string; /** * The title associated with the webview content */ title?: string; /** * The URL associated with the webview content */ url?: string; } export type ViewContext = Context & {view?: View}; export type NativeAppId = 'NATIVE_APP'; export type FullContext = Omit<View, 'id'> & ViewContext; export interface View { /** * @privateRemarks Type of this is best guess */ id?: number | string; title?: string; url?: string; bundleId?: string; } /** * Page tree source representation formats. * * - `xml`: Generates the output similar to what the `getPageSource` standard API returns. * - `description`: This is how XCTest "sees" the page internally and is the same string as the [`debugDescription`](https://developer.apple.com/documentation/xctest/xcuielement/1500909-debugdescription?language=objc) API would return for the root application element. * This source representation format is useful for debugging purposes and is the fastest * one to fetch. * - `json`: Similar to `xml`, but the tree hierarchy is represented as JSON elements. */ export type SourceFormat = 'xml' | 'json' | 'description'; /** @deprecated */ export type AppInstallStrategy = 'serial' | 'parallel' | 'ios-deploy'; export interface ProfileManifest { Description: string; IsActive: boolean; } export interface ProfileMetadata { PayloadDescription: string; PayloadDisplayName: string; PayloadOrganization: string; PayloadRemovalDisallowed: boolean; PayloadUUID: string; PayloadVersion: number; } export interface CertificateList { OrderedIdentifiers: string[]; ProfileManifest: Record<string, ProfileManifest>; ProfileMetadata: Record<string, ProfileMetadata>; Status: 'Acknowledged'; } /** * Returned by `mobile: deviceInfo` command. */ export interface DeviceInfo { currentLocale: string; timeZone: string; name: string; model: string; uuid: 'unknown' | string; userInterfaceIdiom: string; userInterfaceStyle: string; isSimulator: boolean; thermalState?: ThermalState; } /** * Returned within response from `mobile: deviceInfo` command on real devices. * @group Real Device Only * @author Ionic Team <hi@ionicframework.com> (https://ionicframework.com) * @privateRemarks Copied from https://github.com/ionic-team/native-run/blob/2e431d373a3adc75ab402b2bf6a2235360efa0d2/src/ios/lib/client/lockdownd.ts#L12-L41 */ export interface LockdownInfo { BasebandCertId: number; BasebandKeyHashInformation: { AKeyStatus: number; SKeyHash: Buffer; SKeyStatus: number; }; BasebandSerialNumber: Buffer; BasebandVersion: string; BoardId: number; BuildVersion: string; ChipID: number; DeviceClass: string; DeviceColor: string; DeviceName: string; DieID: number; HardwareModel: string; HasSiDP: boolean; PartitionType: string; ProductName: string; ProductType: string; ProductVersion: string; ProductionSOC: boolean; ProtocolVersion: string; TelephonyCapability: boolean; UniqueChipID: number; UniqueDeviceID: string; WiFiAddress: string; [key: string]: any; } /** * Response of the `mobile: activeAppInfo` command. * @remarks Derived from https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Commands/FBCustomCommands.m */ export interface ActiveAppInfo { pid: number; bundleId: string; name: string; processArguments: ProcessArguments; } /** * Returned within an {@linkcode ActiveAppInfo} object. * @remarks Derived from https://github.com/appium/WebDriverAgent/blob/master/WebDriverAgentLib/Commands/FBCustomCommands.m */ export interface ProcessArguments { env: StringRecord<string>; args: string[]; } /** * Accessibility audit item returned by the audit command. */ export interface AccessibilityAuditItem { /** * The detailed description of the found accessibility issue. */ detailedDescription: string; /** * The compact description of the found accessibility issue. */ compactDescription: string; /** * The name of the audit type this issue belongs to. Could be * a number if the type name is unknown. */ auditType: string | number; /** * The description of the element this issue was found for. */ element: string; } /** * Pressable button names; used by the {@linkcode XCUITest.mobilePressButton mobile: pressButton} command. */ export type ButtonName = AnyCase< | 'home' | 'volumeup' | 'volumedown' | 'up' | 'down' | 'left' | 'right' | 'menu' | 'playpause' | 'select' >; /** * Returned in the {@linkcode XCUITest.mobileGetAppearance mobile: getAppearance} command response. */ export type Style = 'dark' | 'light' | 'unsupported' | 'unknown'; /** * Returned in the {@linkcode XCUITest.mobileGetIncreaseContrast mobile: getIncreaseContrast} command response. */ export type IncreaseContrastResult = | 'enabled' | 'disabled' | 'unsupported' | 'unknown'; /** * Argument in the {@linkcode XCUITest.mobileSetIncreaseContrast mobile: setIncreaseContrast} command. */ export type IncreaseContrastAction = | 'enabled' | 'disabled'; /** * Argument in the {@linkcode XCUITest.mobileSetContentSize mobile: setContentSize} command. */ export type ContentSizeAction = | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large' | 'extra-extra-large' | 'extra-extra-extra-large' | 'accessibility-medium' | 'accessibility-large' | 'accessibility-extra-large' | 'accessibility-extra-extra-large' | 'accessibility-extra-extra-extra-large' | 'increment' | 'decrement'; /** * Returned in the {@linkcode XCUITest.mobileGetContentSize mobile: getContentSize} command response. */ export type ContentSizeResult = | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large' | 'extra-extra-large' | 'extra-extra-extra-large' | 'accessibility-medium' | 'accessibility-large' | 'accessibility-extra-large' | 'accessibility-extra-extra-large' | 'accessibility-extra-extra-extra-large' | 'unknown' | 'unsupported'; export interface ScreenInfo { /** * Status bar dimensions * * @see https://developer.apple.com/documentation/xctest/xcuielementtypequeryprovider/1500428-statusbars */ statusBarSize: Size; /** * Scale of the screen * * @see https://developer.apple.com/documentation/uikit/uiscreen/1617836-scale */ scale: number; } export interface WDALocationInfo extends LocationWithAltitude { authorizationStatus: AuthorizationStatus; } /** * Payload for {@linkcode XCUITestDriver.mobilePushNotification}. * * Check the output of `xcrun simctl help push` command for more details. */ export interface PushPayload { /** * The `aps` dictionary. * * Read the [Setting up a Remote Notification Server documentation](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943359) under "Create a JSON Payload" for more details. * * @privateRemarks The keys of `aps` [are documented](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943360) and we should add them. */ aps: StringRecord; } /** * Either `plain` to wait for a notification from the default notification center or `darwin` to wait for a system notification. */ export type NotificationType = 'plain' | 'darwin'; export type BiometricFeature = 'touchId' | 'faceId'; /** * Permission state * * Details: * * - `yes`: To grant the permission * - `no`: To revoke the permission * - `unset`: To reset the permission * - `limited`: To grant the permission as limited access (Only for photos) */ export type PermissionState = 'yes' | 'no' | 'unset' | 'limited'; /** * Access rules for the `mobile: setPermission` execute method. * * Details: * * - `all`: Apply the action to all services. * - `calendar`: Allow access to calendar. * - `contacts-limited`: Allow access to basic contact info. * - `contacts`: Allow access to full contact details. * - `location`: Allow access to location services when app is in use. * - `location-always`: Allow access to location services at all times. * - `photos-add`: Allow adding photos to the photo library. * - `photos`: Allow full access to the photo library. * - `media-library`: Allow access to the media library. * - `microphone`: Allow access to audio input. * - `motion`: Allow access to motion and fitness data. * - `reminders`: Allow access to reminders. * - `siri`: Allow use of the app with Siri. * * @remarks This is similar to--but not exactly the same as--{@linkcode PermissionService}. */ export type AccessRule = | 'all' | 'calendar' | 'contacts-limited' | 'contacts' | 'location' | 'location-always' | 'photos-add' | 'photos' | 'media-library' | 'microphone' | 'motion' | 'reminders' | 'siri'; /** * On-screen keyboard properties. * * To see possible combinations, execute `xcrun simctl spawn booted defaults read .GlobalPreferences.plist AppleKeyboards` */ export interface KeyboardOptions { /** * The name of the keyboard locale, for example `en_US` or `de_CH` */ name: string; /** * The keyboard layout, for example `QUERTY` or `Ukrainian` */ layout: string; hardware?: 'Automatic'; } /** * System language properties * * To see possible combinations, execute `xcrun simctl spawn booted defaults read .GlobalPreferences.plist AppleLanguages`. */ export interface LanguageOptions { /** * The name of the language, for example `de` or `zh-Hant-CN` */ name: string; } /** * System locale properties. * * To see possible combinations, execute `xcrun simctl spawn booted defaults read .GlobalPreferences.plist AppleLocale`. */ export interface LocaleOptions { /** * The name of the system locale, for example `de_CH` or `zh_CN` */ name: string; /** * Optional calendar format, for example `gregorian` or `persian` */ calendar?: string; } /** * The result of an XCTest run. */ export interface XCTestResult { /** * Name of the test (e.g.: `XCTesterAppUITests - XCTesterAppUITests.XCTesterAppUITests/testExample`) */ testName: string; /** * Did the test pass? */ passed: boolean; /** * Did the test crash? */ crashed: boolean; /** * Test result status (e.g.: 'passed', 'failed', 'crashed') * @privateRemarks This should be a union of string literals. Fix it */ status: string; /** * How long the test took to run (in seconds) */ duration: number; /** * The failure message (if applicable) */ failureMessage?: string; /** * The geolocation of the test (if applicable) * @privateRemarks Document the type */ location?: string; } export interface RunXCTestResult { /** * The results of each test run */ results: XCTestResult[]; /** * Exit code of the process. `0` means success */ code: number; /** * The signal that terminated the process (or null) (e.g.: `SIGTERM`) * @privateRemarks This should be a union of string literals. Fix it */ signal: string | null; /** * If all tests passed */ passed: boolean; } /** * Representation of a viewport. * * @see https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html */ export interface Viewport { /** * Distance from left of screen */ left: 0; /** * Distance from top of screen */ top: number; /** * Screen width */ width: number; /** * Screen height */ height: number; } export interface KeyboardKey { /** * Represents a key to type (see * https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc * and https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc) */ key: string; /** * Set of modifier flags * (https://developer.apple.com/documentation/xctest/xcuikeymodifierflags?language=objc) * to use when typing the key. */ modifierFlags?: number; } export interface LogEntry { timestamp: number; level: string, message: string; } export type LogListener = (logEntry: LogEntry) => any; /** * Condition inducer profile configuration */ export interface Profile { name: string; /** The property is profileID used in {@linkcode XCUITestDriver.enableConditionInducer} */ identifier: string; /** Configuration details */ description: string; } /** * We can use the returned data to determine whether the Condition is enabled and the currently enabled configuration information */ export interface Condition { profiles: Profile[]; /** The property is conditionID used in {@linkcode XCUITestDriver.enableConditionInducer} */ identifier: string; profilesSorted: boolean; isDestructive: boolean; isInternal: boolean; /** `true` if this condition identifier is enabled */ isActive: boolean; /** Enabled profiles identifier */ activeProfile: string; } /** * Information about an XCTest screen recording session */ export interface XcTestScreenRecordingInfo { /** Unique identifier of the video being recorded */ uuid: string; /** FPS value */ fps: number; /** Video codec, where 0 is h264 */ codec: number; /** The timestamp when the screen recording has started in float Unix seconds */ startedAt: number; } /** * XCTest screen recording result with payload */ export interface XcTestScreenRecording extends XcTestScreenRecordingInfo { /** * Base64-encoded content of the recorded media file if `remotePath` parameter is empty or null or an empty string otherwise. * The media is expected to a be a valid QuickTime movie (.mov). */ payload: string; } /** * Options for AudioRecorder */ export interface AudioRecorderOptions { audioSource: string; audioCodec: string; audioBitrate: string; audioChannels: number; audioRate: number; }