UNPKG

appium-flutter-driver

Version:
198 lines (174 loc) 6.97 kB
/* eslint-disable @typescript-eslint/no-non-null-assertion */ import type { FlutterDriver } from '../driver'; import { reConnectFlutterDriver } from '../sessions/session'; import { longTap, scroll, scrollIntoView, scrollUntilVisible, scrollUntilTapable } from './execute/scroll'; import { waitFor, waitForAbsent, waitForTappable } from './execute/wait'; import { launchApp } from './../ios/app'; import B from 'bluebird'; const flutterCommandRegex = /^[\s]*flutter[\s]*:(.+)/; export const execute = async function( this: FlutterDriver, rawCommand: string, args: any[], ) { // flutter const matching = rawCommand.match(flutterCommandRegex); if (!matching) { throw new Error(`Command not support: "${rawCommand}"`); } const command = matching[1].trim(); switch (command) { case `launchApp`: return await flutterLaunchApp(this, args[0], args[1]); case `connectObservatoryWsUrl`: return await connectObservatoryWsUrl(this); case `getVMInfo`: return await getVMInfo(this); case `setIsolateId`: return await setIsolateId(this, args[0]); case `getIsolate`: return await getIsolate(this, args[0]); case `checkHealth`: return await checkHealth(this); case `clearTimeline`: return await clearTimeline(this); case `forceGC`: return await forceGC(this); case `getRenderTree`: return await getRenderTree(this); case `getBottomLeft`: return await getOffset(this, args[0], { offsetType: `bottomLeft` }); case `getBottomRight`: return await getOffset(this, args[0], { offsetType: `bottomRight` }); case `getCenter`: return await getOffset(this, args[0], { offsetType: `center` }); case `getTopLeft`: return await getOffset(this, args[0], { offsetType: `topLeft` }); case `getTopRight`: return await getOffset(this, args[0], { offsetType: `topRight` }); case `getRenderObjectDiagnostics`: return await getRenderObjectDiagnostics(this, args[0], args[1]); case `getSemanticsId`: return await getSemanticsId(this, args[0]); case `waitForAbsent`: return await waitForAbsent(this, args[0], args[1]); case `waitFor`: return await waitFor(this, args[0], args[1]); case `waitForTappable`: return await waitForTappable(this, args[0], args[1]); case `scroll`: return await scroll(this, args[0], args[1]); case `scrollUntilVisible`: return await scrollUntilVisible(this, args[0], args[1]); case `scrollUntilTapable`: return await scrollUntilTapable(this, args[0], args[1]); case `scrollIntoView`: return await scrollIntoView(this, args[0], args[1]); case `setTextEntryEmulation`: return await setTextEntryEmulation(this, args[0]); case `enterText`: return await enterText(this, args[0]); case `requestData`: return await requestData(this, args[0]); case `longTap`: return await longTap(this, args[0], args[1]); case `waitForFirstFrame`: return await waitForCondition(this, { conditionName: `FirstFrameRasterizedCondition`}); case `setFrameSync`: return await setFrameSync(this, args[0], args[1]); case `clickElement`: return await clickElement(this, args[0], args[1]); default: throw new Error(`Command not support: "${rawCommand}"`); } }; const flutterLaunchApp = async ( self: FlutterDriver, appId: string, opts ) => { const { arguments: args = [], environment: env = {}} = opts; await launchApp(self.internalCaps.udid!, appId, args, env); await reConnectFlutterDriver.bind(self)(self.internalCaps); }; const connectObservatoryWsUrl = async (self: FlutterDriver) => { await reConnectFlutterDriver.bind(self)(self.internalCaps); }; const checkHealth = async (self: FlutterDriver) => (await self.executeElementCommand(`get_health`)).status; const getVMInfo = async (self: FlutterDriver) => (await self.executeGetVMCommand()); const getRenderTree = async (self: FlutterDriver) => (await self.executeElementCommand(`get_render_tree`)).tree; const getOffset = async ( self: FlutterDriver, elementBase64: string, offsetType: {offsetType: string}, ) => await self.executeElementCommand(`get_offset`, elementBase64, offsetType); const waitForCondition = async ( self: FlutterDriver, conditionName: {conditionName: string}, ) => await self.executeElementCommand(`waitForCondition`, ``, conditionName); const forceGC = async (self: FlutterDriver) => { const response = await self.socket!.call(`_collectAllGarbage`, { isolateId: self.socket!.isolateId, }) as { type: string }; if (response.type !== `Success`) { throw new Error(`Could not forceGC, response was ${response}`); } }; const setIsolateId = async (self: FlutterDriver, isolateId: string) => { self.socket!.isolateId = isolateId; return await self.socket!.call(`getIsolate`, { isolateId: `${isolateId}`, }); }; const getIsolate = async ( self: FlutterDriver, isolateId: string|undefined ) => await self.executeGetIsolateCommand(isolateId || self.socket!.isolateId); const clearTimeline = async (self: FlutterDriver) => { // @todo backward compatible, need to cleanup later const call1: Promise<any> = self.socket!.call(`_clearVMTimeline`); const call2: Promise<any> = self.socket!.call(`clearVMTimeline`); const response = await B.any([call1, call2]); if (response.type !== `Success`) { throw new Error(`Could not forceGC, response was ${response}`); } }; const getRenderObjectDiagnostics = async ( self: FlutterDriver, elementBase64: string, opts: { subtreeDepth: number; includeProperties: boolean; }, ) => { const { subtreeDepth = 0, includeProperties = true } = opts; return await self.executeElementCommand( `get_diagnostics_tree`, elementBase64, { diagnosticsType: `renderObject`, includeProperties, subtreeDepth, }, ); }; const getSemanticsId = async (self: FlutterDriver, elementBase64: string) => (await self.executeElementCommand(`get_semantics_id`, elementBase64)).id; const enterText = async (self: FlutterDriver, text: string) => await self.socket!.executeSocketCommand({ command: `enter_text`, text }); const requestData = async (self: FlutterDriver, message: string) => await self.socket!.executeSocketCommand({ command: `request_data`, message }); const setFrameSync = async (self, bool: boolean, durationMilliseconds: number) => await self.socket!.executeSocketCommand({ command: `set_frame_sync`, enabled: bool, timeout: durationMilliseconds, }); const setTextEntryEmulation = async (self: FlutterDriver, enabled: boolean) => await self.socket!.executeSocketCommand({ command: `set_text_entry_emulation`, enabled }); const clickElement = async (self:FlutterDriver, elementBase64: string, opts) => { const {timeout = 1000} = opts; return await self.executeElementCommand(`tap`, elementBase64, { timeout }); };