appium-ios-remotexpc 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/src/index.d.ts +2 -1
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +1 -0
- package/build/src/lib/types.d.ts +114 -0
- package/build/src/lib/types.d.ts.map +1 -1
- package/build/src/lib/types.js +2 -0
- package/build/src/service-connection.d.ts +6 -0
- package/build/src/service-connection.d.ts.map +1 -1
- package/build/src/service-connection.js +8 -0
- package/build/src/services/index.d.ts +3 -1
- package/build/src/services/index.d.ts.map +1 -1
- package/build/src/services/index.js +3 -1
- package/build/src/services/ios/power-assertion/index.d.ts +40 -0
- package/build/src/services/ios/power-assertion/index.d.ts.map +1 -0
- package/build/src/services/ios/power-assertion/index.js +64 -0
- package/build/src/services/ios/webinspector/index.d.ts +114 -0
- package/build/src/services/ios/webinspector/index.d.ts.map +1 -0
- package/build/src/services/ios/webinspector/index.js +286 -0
- package/build/src/services.d.ts +3 -1
- package/build/src/services.d.ts.map +1 -1
- package/build/src/services.js +24 -0
- package/package.json +3 -1
- package/src/index.ts +6 -0
- package/src/lib/types.ts +149 -0
- package/src/service-connection.ts +9 -0
- package/src/services/index.ts +4 -0
- package/src/services/ios/power-assertion/index.ts +100 -0
- package/src/services/ios/webinspector/index.ts +372 -0
- package/src/services.ts +36 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { logger } from '@appium/support';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import { ServiceConnection } from '../../../service-connection.js';
|
|
5
|
+
import { BaseService } from '../base-service.js';
|
|
6
|
+
const log = logger.getLogger('WebInspectorService');
|
|
7
|
+
/**
|
|
8
|
+
* WebInspectorService provides an API to:
|
|
9
|
+
* - Send messages to webinspectord
|
|
10
|
+
* - Listen to messages from webinspectord
|
|
11
|
+
* - Communicate with web views and Safari on iOS devices
|
|
12
|
+
*
|
|
13
|
+
* This service is used for web automation, inspection, and debugging.
|
|
14
|
+
*/
|
|
15
|
+
export class WebInspectorService extends BaseService {
|
|
16
|
+
static RSD_SERVICE_NAME = 'com.apple.webinspector.shim.remote';
|
|
17
|
+
// RPC method selectors
|
|
18
|
+
static RPC_REPORT_IDENTIFIER = '_rpc_reportIdentifier:';
|
|
19
|
+
static RPC_REQUEST_APPLICATION_LAUNCH = '_rpc_requestApplicationLaunch:';
|
|
20
|
+
static RPC_GET_CONNECTED_APPLICATIONS = '_rpc_getConnectedApplications:';
|
|
21
|
+
static RPC_FORWARD_GET_LISTING = '_rpc_forwardGetListing:';
|
|
22
|
+
static RPC_FORWARD_AUTOMATION_SESSION_REQUEST = '_rpc_forwardAutomationSessionRequest:';
|
|
23
|
+
static RPC_FORWARD_SOCKET_SETUP = '_rpc_forwardSocketSetup:';
|
|
24
|
+
static RPC_FORWARD_SOCKET_DATA = '_rpc_forwardSocketData:';
|
|
25
|
+
static RPC_FORWARD_INDICATE_WEB_VIEW = '_rpc_forwardIndicateWebView:';
|
|
26
|
+
connection = null;
|
|
27
|
+
messageEmitter = new EventEmitter();
|
|
28
|
+
isReceiving = false;
|
|
29
|
+
connectionId;
|
|
30
|
+
receivePromise = null;
|
|
31
|
+
constructor(address) {
|
|
32
|
+
super(address);
|
|
33
|
+
this.connectionId = randomUUID().toUpperCase();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Send a message to the WebInspector service
|
|
37
|
+
* @param selector The RPC selector (e.g., '_rpc_reportIdentifier:')
|
|
38
|
+
* @param args The arguments dictionary for the message
|
|
39
|
+
* @returns Promise that resolves when the message is sent
|
|
40
|
+
*/
|
|
41
|
+
async sendMessage(selector, args = {}) {
|
|
42
|
+
const connection = await this.connectToWebInspectorService();
|
|
43
|
+
// Add connection identifier to all messages
|
|
44
|
+
const message = {
|
|
45
|
+
__selector: selector,
|
|
46
|
+
__argument: {
|
|
47
|
+
...args,
|
|
48
|
+
WIRConnectionIdentifierKey: this.connectionId,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
log.debug(`Sending WebInspector message: ${selector}`);
|
|
52
|
+
connection.sendPlist(message);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Listen to messages from the WebInspector service using async generator
|
|
56
|
+
* @yields PlistMessage - Messages received from the WebInspector service
|
|
57
|
+
*/
|
|
58
|
+
async *listenMessage() {
|
|
59
|
+
await this.connectToWebInspectorService();
|
|
60
|
+
// Start receiving messages in background if not already started
|
|
61
|
+
if (!this.isReceiving) {
|
|
62
|
+
this.startMessageReceiver();
|
|
63
|
+
}
|
|
64
|
+
const queue = [];
|
|
65
|
+
let resolveNext = null;
|
|
66
|
+
let stopped = false;
|
|
67
|
+
const messageHandler = (message) => {
|
|
68
|
+
if (resolveNext) {
|
|
69
|
+
resolveNext({ value: message, done: false });
|
|
70
|
+
resolveNext = null;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
queue.push(message);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const stopHandler = () => {
|
|
77
|
+
stopped = true;
|
|
78
|
+
if (resolveNext) {
|
|
79
|
+
resolveNext({ value: undefined, done: true });
|
|
80
|
+
resolveNext = null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
this.messageEmitter.on('message', messageHandler);
|
|
84
|
+
this.messageEmitter.once('stop', stopHandler);
|
|
85
|
+
try {
|
|
86
|
+
while (!stopped) {
|
|
87
|
+
if (queue.length > 0) {
|
|
88
|
+
yield queue.shift();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const message = await new Promise((resolve) => {
|
|
92
|
+
if (stopped) {
|
|
93
|
+
resolve(null);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
resolveNext = (result) => {
|
|
97
|
+
resolve(result.done ? null : result.value);
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
if (message === null) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
yield message;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
this.messageEmitter.off('message', messageHandler);
|
|
109
|
+
this.messageEmitter.off('stop', stopHandler);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Stop listening to messages
|
|
114
|
+
*/
|
|
115
|
+
stopListening() {
|
|
116
|
+
this.isReceiving = false;
|
|
117
|
+
this.messageEmitter.emit('stop');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Close the connection and clean up resources
|
|
121
|
+
*/
|
|
122
|
+
async close() {
|
|
123
|
+
this.stopListening();
|
|
124
|
+
if (this.connection) {
|
|
125
|
+
await this.connection.close();
|
|
126
|
+
this.connection = null;
|
|
127
|
+
log.debug('WebInspector connection closed');
|
|
128
|
+
}
|
|
129
|
+
if (this.receivePromise) {
|
|
130
|
+
await this.receivePromise;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the connection ID being used for this service
|
|
135
|
+
* @returns The connection identifier
|
|
136
|
+
*/
|
|
137
|
+
getConnectionId() {
|
|
138
|
+
return this.connectionId;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Request application launch
|
|
142
|
+
* @param bundleId The bundle identifier of the application to launch
|
|
143
|
+
*/
|
|
144
|
+
async requestApplicationLaunch(bundleId) {
|
|
145
|
+
await this.sendMessage(WebInspectorService.RPC_REQUEST_APPLICATION_LAUNCH, {
|
|
146
|
+
WIRApplicationBundleIdentifierKey: bundleId,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get connected applications
|
|
151
|
+
*/
|
|
152
|
+
async getConnectedApplications() {
|
|
153
|
+
await this.sendMessage(WebInspectorService.RPC_GET_CONNECTED_APPLICATIONS, {});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Forward get listing for an application
|
|
157
|
+
* @param appId The application identifier
|
|
158
|
+
*/
|
|
159
|
+
async forwardGetListing(appId) {
|
|
160
|
+
await this.sendMessage(WebInspectorService.RPC_FORWARD_GET_LISTING, {
|
|
161
|
+
WIRApplicationIdentifierKey: appId,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Forward automation session request
|
|
166
|
+
* @param sessionId The session identifier
|
|
167
|
+
* @param appId The application identifier
|
|
168
|
+
* @param capabilities Optional session capabilities
|
|
169
|
+
*/
|
|
170
|
+
async forwardAutomationSessionRequest(sessionId, appId, capabilities) {
|
|
171
|
+
const defaultCapabilities = {
|
|
172
|
+
'org.webkit.webdriver.webrtc.allow-insecure-media-capture': true,
|
|
173
|
+
'org.webkit.webdriver.webrtc.suppress-ice-candidate-filtering': false,
|
|
174
|
+
};
|
|
175
|
+
await this.sendMessage(WebInspectorService.RPC_FORWARD_AUTOMATION_SESSION_REQUEST, {
|
|
176
|
+
WIRApplicationIdentifierKey: appId,
|
|
177
|
+
WIRSessionIdentifierKey: sessionId,
|
|
178
|
+
WIRSessionCapabilitiesKey: {
|
|
179
|
+
...defaultCapabilities,
|
|
180
|
+
...(capabilities ?? {}),
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Forward socket setup for inspector connection
|
|
186
|
+
* @param sessionId The session identifier
|
|
187
|
+
* @param appId The application identifier
|
|
188
|
+
* @param pageId The page identifier
|
|
189
|
+
* @param automaticallyPause Whether to automatically pause (defaults to true)
|
|
190
|
+
*/
|
|
191
|
+
async forwardSocketSetup(sessionId, appId, pageId, automaticallyPause = true) {
|
|
192
|
+
const message = {
|
|
193
|
+
WIRApplicationIdentifierKey: appId,
|
|
194
|
+
WIRPageIdentifierKey: pageId,
|
|
195
|
+
WIRSenderKey: sessionId,
|
|
196
|
+
WIRMessageDataTypeChunkSupportedKey: 0,
|
|
197
|
+
};
|
|
198
|
+
if (!automaticallyPause) {
|
|
199
|
+
message.WIRAutomaticallyPause = false;
|
|
200
|
+
}
|
|
201
|
+
await this.sendMessage(WebInspectorService.RPC_FORWARD_SOCKET_SETUP, message);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Forward socket data to a page
|
|
205
|
+
* @param sessionId The session identifier
|
|
206
|
+
* @param appId The application identifier
|
|
207
|
+
* @param pageId The page identifier
|
|
208
|
+
* @param data The data to send (will be JSON stringified)
|
|
209
|
+
*/
|
|
210
|
+
async forwardSocketData(sessionId, appId, pageId, data) {
|
|
211
|
+
const socketData = typeof data === 'string' ? data : JSON.stringify(data);
|
|
212
|
+
await this.sendMessage(WebInspectorService.RPC_FORWARD_SOCKET_DATA, {
|
|
213
|
+
WIRApplicationIdentifierKey: appId,
|
|
214
|
+
WIRPageIdentifierKey: pageId,
|
|
215
|
+
WIRSessionIdentifierKey: sessionId,
|
|
216
|
+
WIRSenderKey: sessionId,
|
|
217
|
+
WIRSocketDataKey: Buffer.from(socketData, 'utf-8'),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Forward indicate web view
|
|
222
|
+
* @param appId The application identifier
|
|
223
|
+
* @param pageId The page identifier
|
|
224
|
+
* @param enable Whether to enable indication
|
|
225
|
+
*/
|
|
226
|
+
async forwardIndicateWebView(appId, pageId, enable) {
|
|
227
|
+
await this.sendMessage(WebInspectorService.RPC_FORWARD_INDICATE_WEB_VIEW, {
|
|
228
|
+
WIRApplicationIdentifierKey: appId,
|
|
229
|
+
WIRPageIdentifierKey: pageId,
|
|
230
|
+
WIRIndicateEnabledKey: enable,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Connect to the WebInspector service
|
|
235
|
+
* @returns Promise resolving to the ServiceConnection instance
|
|
236
|
+
*/
|
|
237
|
+
async connectToWebInspectorService() {
|
|
238
|
+
if (this.connection) {
|
|
239
|
+
return this.connection;
|
|
240
|
+
}
|
|
241
|
+
const service = {
|
|
242
|
+
serviceName: WebInspectorService.RSD_SERVICE_NAME,
|
|
243
|
+
port: this.address[1].toString(),
|
|
244
|
+
};
|
|
245
|
+
this.connection = await this.startLockdownService(service);
|
|
246
|
+
// Consume the StartService response from RSDCheckin
|
|
247
|
+
const startServiceResponse = await this.connection.receive();
|
|
248
|
+
if (startServiceResponse?.Request !== 'StartService') {
|
|
249
|
+
log.warn(`Expected StartService response, got: ${JSON.stringify(startServiceResponse)}`);
|
|
250
|
+
}
|
|
251
|
+
// Send initial identifier report
|
|
252
|
+
await this.sendMessage(WebInspectorService.RPC_REPORT_IDENTIFIER, {});
|
|
253
|
+
log.debug('Connected to WebInspector service');
|
|
254
|
+
return this.connection;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Start receiving messages from the WebInspector service in the background
|
|
258
|
+
*/
|
|
259
|
+
startMessageReceiver() {
|
|
260
|
+
if (this.isReceiving || !this.connection) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
this.isReceiving = true;
|
|
264
|
+
this.receivePromise = (async () => {
|
|
265
|
+
try {
|
|
266
|
+
while (this.isReceiving && this.connection) {
|
|
267
|
+
try {
|
|
268
|
+
const message = await this.connection.receive();
|
|
269
|
+
this.messageEmitter.emit('message', message);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (this.isReceiving) {
|
|
273
|
+
log.error('Error receiving message:', error);
|
|
274
|
+
this.messageEmitter.emit('error', error);
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
this.isReceiving = false;
|
|
282
|
+
}
|
|
283
|
+
})();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export default WebInspectorService;
|
package/build/src/services.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { RemoteXpcConnection } from './lib/remote-xpc/remote-xpc-connection.js';
|
|
2
|
-
import type { DiagnosticsServiceWithConnection, MobileConfigServiceWithConnection, MobileImageMounterServiceWithConnection, NotificationProxyServiceWithConnection, SpringboardServiceWithConnection, SyslogService as SyslogServiceType } from './lib/types.js';
|
|
2
|
+
import type { DiagnosticsServiceWithConnection, MobileConfigServiceWithConnection, MobileImageMounterServiceWithConnection, NotificationProxyServiceWithConnection, PowerAssertionServiceWithConnection, SpringboardServiceWithConnection, SyslogService as SyslogServiceType, WebInspectorServiceWithConnection } from './lib/types.js';
|
|
3
3
|
export declare function startDiagnosticsService(udid: string): Promise<DiagnosticsServiceWithConnection>;
|
|
4
4
|
export declare function startNotificationProxyService(udid: string): Promise<NotificationProxyServiceWithConnection>;
|
|
5
5
|
export declare function startMobileConfigService(udid: string): Promise<MobileConfigServiceWithConnection>;
|
|
6
6
|
export declare function startMobileImageMounterService(udid: string): Promise<MobileImageMounterServiceWithConnection>;
|
|
7
7
|
export declare function startSpringboardService(udid: string): Promise<SpringboardServiceWithConnection>;
|
|
8
|
+
export declare function startPowerAssertionService(udid: string): Promise<PowerAssertionServiceWithConnection>;
|
|
8
9
|
export declare function startSyslogService(udid: string): Promise<SyslogServiceType>;
|
|
10
|
+
export declare function startWebInspectorService(udid: string): Promise<WebInspectorServiceWithConnection>;
|
|
9
11
|
export declare function createRemoteXPCConnection(udid: string): Promise<{
|
|
10
12
|
remoteXPC: RemoteXpcConnection;
|
|
11
13
|
tunnelConnection: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/services.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAGhF,OAAO,KAAK,EACV,gCAAgC,EAChC,iCAAiC,EACjC,uCAAuC,EACvC,sCAAsC,EACtC,gCAAgC,EAChC,aAAa,IAAI,iBAAiB,
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/services.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAGhF,OAAO,KAAK,EACV,gCAAgC,EAChC,iCAAiC,EACjC,uCAAuC,EACvC,sCAAsC,EACtC,mCAAmC,EACnC,gCAAgC,EAChC,aAAa,IAAI,iBAAiB,EAClC,iCAAiC,EAClC,MAAM,gBAAgB,CAAC;AAaxB,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gCAAgC,CAAC,CAY3C;AAED,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,sCAAsC,CAAC,CAYjD;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iCAAiC,CAAC,CAY5C;AACD,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,uCAAuC,CAAC,CAYlD;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gCAAgC,CAAC,CAY3C;AAED,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,mCAAmC,CAAC,CAY9C;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,CAG5B;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iCAAiC,CAAC,CAY5C;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM;;;;;;;;GAO3D"}
|
package/build/src/services.js
CHANGED
|
@@ -6,8 +6,10 @@ import DiagnosticsService from './services/ios/diagnostic-service/index.js';
|
|
|
6
6
|
import { MobileConfigService } from './services/ios/mobile-config/index.js';
|
|
7
7
|
import MobileImageMounterService from './services/ios/mobile-image-mounter/index.js';
|
|
8
8
|
import { NotificationProxyService } from './services/ios/notification-proxy/index.js';
|
|
9
|
+
import { PowerAssertionService } from './services/ios/power-assertion/index.js';
|
|
9
10
|
import { SpringBoardService } from './services/ios/springboard-service/index.js';
|
|
10
11
|
import SyslogService from './services/ios/syslog-service/index.js';
|
|
12
|
+
import { WebInspectorService } from './services/ios/webinspector/index.js';
|
|
11
13
|
const APPIUM_XCUITEST_DRIVER_NAME = 'appium-xcuitest-driver';
|
|
12
14
|
const TUNNEL_REGISTRY_PORT = 'tunnelRegistryPort';
|
|
13
15
|
export async function startDiagnosticsService(udid) {
|
|
@@ -65,10 +67,32 @@ export async function startSpringboardService(udid) {
|
|
|
65
67
|
]),
|
|
66
68
|
};
|
|
67
69
|
}
|
|
70
|
+
export async function startPowerAssertionService(udid) {
|
|
71
|
+
const { remoteXPC, tunnelConnection } = await createRemoteXPCConnection(udid);
|
|
72
|
+
const powerAssertionService = remoteXPC.findService(PowerAssertionService.RSD_SERVICE_NAME);
|
|
73
|
+
return {
|
|
74
|
+
remoteXPC: remoteXPC,
|
|
75
|
+
powerAssertionService: new PowerAssertionService([
|
|
76
|
+
tunnelConnection.host,
|
|
77
|
+
parseInt(powerAssertionService.port, 10),
|
|
78
|
+
]),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
68
81
|
export async function startSyslogService(udid) {
|
|
69
82
|
const { tunnelConnection } = await createRemoteXPCConnection(udid);
|
|
70
83
|
return new SyslogService([tunnelConnection.host, tunnelConnection.port]);
|
|
71
84
|
}
|
|
85
|
+
export async function startWebInspectorService(udid) {
|
|
86
|
+
const { remoteXPC, tunnelConnection } = await createRemoteXPCConnection(udid);
|
|
87
|
+
const webInspectorService = remoteXPC.findService(WebInspectorService.RSD_SERVICE_NAME);
|
|
88
|
+
return {
|
|
89
|
+
remoteXPC: remoteXPC,
|
|
90
|
+
webInspectorService: new WebInspectorService([
|
|
91
|
+
tunnelConnection.host,
|
|
92
|
+
parseInt(webInspectorService.port, 10),
|
|
93
|
+
]),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
72
96
|
export async function createRemoteXPCConnection(udid) {
|
|
73
97
|
const tunnelConnection = await getTunnelInformation(udid);
|
|
74
98
|
const remoteXPC = await startService(tunnelConnection.host, tunnelConnection.port);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-ios-remotexpc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"main": "build/src/index.js",
|
|
5
5
|
"types": "build/src/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"test:image-mounter": "mocha test/integration/mobile-image-mounter-test.ts --exit --timeout 1m",
|
|
33
33
|
"test:mobile-config": "mocha test/integration/mobile-config-test.ts --exit --timeout 1m",
|
|
34
34
|
"test:springboard": "mocha test/integration/springboard-service-test.ts --exit --timeout 1m",
|
|
35
|
+
"test:webinspector": "mocha test/integration/webinspector-test.ts --exit --timeout 1m",
|
|
36
|
+
"test:power-assertion": "mocha test/integration/power-assertion-test.ts --exit --timeout 1m",
|
|
35
37
|
"test:unit": "mocha 'test/unit/**/*.ts' --exit --timeout 2m",
|
|
36
38
|
"test:tunnel-creation": "sudo tsx scripts/test-tunnel-creation.ts",
|
|
37
39
|
"test:tunnel-creation:lsof": "sudo tsx scripts/test-tunnel-creation.ts --keep-open"
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,10 @@ export type {
|
|
|
17
17
|
MobileImageMounterService,
|
|
18
18
|
NotificationProxyService,
|
|
19
19
|
MobileConfigService,
|
|
20
|
+
PowerAssertionService,
|
|
21
|
+
PowerAssertionOptions,
|
|
20
22
|
SpringboardService,
|
|
23
|
+
WebInspectorService,
|
|
21
24
|
SyslogService,
|
|
22
25
|
SocketInfo,
|
|
23
26
|
TunnelResult,
|
|
@@ -27,8 +30,11 @@ export type {
|
|
|
27
30
|
MobileImageMounterServiceWithConnection,
|
|
28
31
|
NotificationProxyServiceWithConnection,
|
|
29
32
|
MobileConfigServiceWithConnection,
|
|
33
|
+
PowerAssertionServiceWithConnection,
|
|
30
34
|
SpringboardServiceWithConnection,
|
|
35
|
+
WebInspectorServiceWithConnection,
|
|
31
36
|
} from './lib/types.js';
|
|
37
|
+
export { PowerAssertionType } from './lib/types.js';
|
|
32
38
|
export {
|
|
33
39
|
createUsbmux,
|
|
34
40
|
Services,
|
package/src/lib/types.ts
CHANGED
|
@@ -6,10 +6,15 @@ import { EventEmitter } from 'events';
|
|
|
6
6
|
|
|
7
7
|
import type { ServiceConnection } from '../service-connection.js';
|
|
8
8
|
import type { BaseService, Service } from '../services/ios/base-service.js';
|
|
9
|
+
import type { PowerAssertionOptions } from '../services/ios/power-assertion/index.js';
|
|
10
|
+
import { PowerAssertionType } from '../services/ios/power-assertion/index.js';
|
|
9
11
|
import type { InterfaceOrientation } from '../services/ios/springboard-service/index.js';
|
|
10
12
|
import type { RemoteXpcConnection } from './remote-xpc/remote-xpc-connection.js';
|
|
11
13
|
import type { Device } from './usbmux/index.js';
|
|
12
14
|
|
|
15
|
+
export type { PowerAssertionOptions };
|
|
16
|
+
export { PowerAssertionType };
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Represents a value that can be stored in a plist
|
|
15
20
|
*/
|
|
@@ -213,6 +218,24 @@ export interface NotificationProxyService extends BaseService {
|
|
|
213
218
|
expectNotification(timeout?: number): Promise<PlistMessage>;
|
|
214
219
|
}
|
|
215
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Represents the PowerAssertionService for preventing system sleep
|
|
223
|
+
*/
|
|
224
|
+
export interface PowerAssertionService extends BaseService {
|
|
225
|
+
/**
|
|
226
|
+
* Create a power assertion to prevent system sleep
|
|
227
|
+
* @param options Options for creating the power assertion
|
|
228
|
+
* @returns Promise that resolves when the assertion is created
|
|
229
|
+
*/
|
|
230
|
+
createPowerAssertion(options: PowerAssertionOptions): Promise<void>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Close the connection to the power assertion service
|
|
234
|
+
* @returns Promise that resolves when the connection is closed
|
|
235
|
+
*/
|
|
236
|
+
close(): Promise<void>;
|
|
237
|
+
}
|
|
238
|
+
|
|
216
239
|
/**
|
|
217
240
|
* Represents the static side of MobileConfigService
|
|
218
241
|
*/
|
|
@@ -312,6 +335,132 @@ export interface MobileConfigServiceWithConnection {
|
|
|
312
335
|
remoteXPC: RemoteXpcConnection;
|
|
313
336
|
}
|
|
314
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Represents a PowerAssertionService instance with its associated RemoteXPC connection
|
|
340
|
+
* This allows callers to properly manage the connection lifecycle
|
|
341
|
+
*/
|
|
342
|
+
export interface PowerAssertionServiceWithConnection {
|
|
343
|
+
/** The PowerAssertionService instance */
|
|
344
|
+
powerAssertionService: PowerAssertionService;
|
|
345
|
+
/** The RemoteXPC connection that can be used to close the connection */
|
|
346
|
+
remoteXPC: RemoteXpcConnection;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Represents the WebInspectorService
|
|
351
|
+
*/
|
|
352
|
+
export interface WebInspectorService extends BaseService {
|
|
353
|
+
/**
|
|
354
|
+
* Send a message to the WebInspector service
|
|
355
|
+
* @param selector The RPC selector (e.g., '_rpc_reportIdentifier:')
|
|
356
|
+
* @param args The arguments dictionary for the message
|
|
357
|
+
* @returns Promise that resolves when the message is sent
|
|
358
|
+
*/
|
|
359
|
+
sendMessage(selector: string, args?: PlistDictionary): Promise<void>;
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Listen to messages from the WebInspector service using async generator
|
|
363
|
+
* @yields PlistMessage - Messages received from the WebInspector service
|
|
364
|
+
*/
|
|
365
|
+
listenMessage(): AsyncGenerator<PlistMessage, void, unknown>;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Stop listening to messages
|
|
369
|
+
*/
|
|
370
|
+
stopListening(): void;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Close the connection and clean up resources
|
|
374
|
+
*/
|
|
375
|
+
close(): Promise<void>;
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Get the connection ID being used for this service
|
|
379
|
+
* @returns The connection identifier
|
|
380
|
+
*/
|
|
381
|
+
getConnectionId(): string;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Request application launch
|
|
385
|
+
* @param bundleId The bundle identifier of the application to launch
|
|
386
|
+
*/
|
|
387
|
+
requestApplicationLaunch(bundleId: string): Promise<void>;
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Get connected applications
|
|
391
|
+
*/
|
|
392
|
+
getConnectedApplications(): Promise<void>;
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Forward get listing for an application
|
|
396
|
+
* @param appId The application identifier
|
|
397
|
+
*/
|
|
398
|
+
forwardGetListing(appId: string): Promise<void>;
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Forward automation session request
|
|
402
|
+
* @param sessionId The session identifier
|
|
403
|
+
* @param appId The application identifier
|
|
404
|
+
* @param capabilities Optional session capabilities
|
|
405
|
+
*/
|
|
406
|
+
forwardAutomationSessionRequest(
|
|
407
|
+
sessionId: string,
|
|
408
|
+
appId: string,
|
|
409
|
+
capabilities?: PlistDictionary,
|
|
410
|
+
): Promise<void>;
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Forward socket setup for inspector connection
|
|
414
|
+
* @param sessionId The session identifier
|
|
415
|
+
* @param appId The application identifier
|
|
416
|
+
* @param pageId The page identifier
|
|
417
|
+
* @param automaticallyPause Whether to automatically pause (defaults to true)
|
|
418
|
+
*/
|
|
419
|
+
forwardSocketSetup(
|
|
420
|
+
sessionId: string,
|
|
421
|
+
appId: string,
|
|
422
|
+
pageId: number,
|
|
423
|
+
automaticallyPause?: boolean,
|
|
424
|
+
): Promise<void>;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Forward socket data to a page
|
|
428
|
+
* @param sessionId The session identifier
|
|
429
|
+
* @param appId The application identifier
|
|
430
|
+
* @param pageId The page identifier
|
|
431
|
+
* @param data The data to send (will be JSON stringified)
|
|
432
|
+
*/
|
|
433
|
+
forwardSocketData(
|
|
434
|
+
sessionId: string,
|
|
435
|
+
appId: string,
|
|
436
|
+
pageId: number,
|
|
437
|
+
data: any,
|
|
438
|
+
): Promise<void>;
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Forward indicate web view
|
|
442
|
+
* @param appId The application identifier
|
|
443
|
+
* @param pageId The page identifier
|
|
444
|
+
* @param enable Whether to enable indication
|
|
445
|
+
*/
|
|
446
|
+
forwardIndicateWebView(
|
|
447
|
+
appId: string,
|
|
448
|
+
pageId: number,
|
|
449
|
+
enable: boolean,
|
|
450
|
+
): Promise<void>;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Represents a WebInspectorService instance with its associated RemoteXPC connection
|
|
455
|
+
* This allows callers to properly manage the connection lifecycle
|
|
456
|
+
*/
|
|
457
|
+
export interface WebInspectorServiceWithConnection {
|
|
458
|
+
/** The WebInspectorService instance */
|
|
459
|
+
webInspectorService: WebInspectorService;
|
|
460
|
+
/** The RemoteXPC connection that can be used to close the connection */
|
|
461
|
+
remoteXPC: RemoteXpcConnection;
|
|
462
|
+
}
|
|
463
|
+
|
|
315
464
|
/**
|
|
316
465
|
* Options for configuring syslog capture
|
|
317
466
|
*/
|
|
@@ -60,6 +60,15 @@ export class ServiceConnection extends BasePlistService {
|
|
|
60
60
|
return this.sendAndReceive(requestObj, timeout);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Sends a plist message without waiting for a response
|
|
65
|
+
* This is useful for fire-and-forget style communication
|
|
66
|
+
* @param message The message to send
|
|
67
|
+
*/
|
|
68
|
+
sendPlist(message: PlistDictionary): void {
|
|
69
|
+
this.send(message);
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
/**
|
|
64
73
|
* Gets the underlying socket
|
|
65
74
|
* @returns The socket used by this service
|
package/src/services/index.ts
CHANGED
|
@@ -4,14 +4,18 @@ import {
|
|
|
4
4
|
} from '../lib/tunnel/tunnel-registry-server.js';
|
|
5
5
|
import * as diagnostics from './ios/diagnostic-service/index.js';
|
|
6
6
|
import * as mobileImageMounter from './ios/mobile-image-mounter/index.js';
|
|
7
|
+
import * as powerAssertion from './ios/power-assertion/index.js';
|
|
7
8
|
import * as syslog from './ios/syslog-service/index.js';
|
|
8
9
|
import * as tunnel from './ios/tunnel-service/index.js';
|
|
10
|
+
import * as webinspector from './ios/webinspector/index.js';
|
|
9
11
|
|
|
10
12
|
export {
|
|
11
13
|
diagnostics,
|
|
12
14
|
mobileImageMounter,
|
|
15
|
+
powerAssertion,
|
|
13
16
|
syslog,
|
|
14
17
|
tunnel,
|
|
18
|
+
webinspector,
|
|
15
19
|
TunnelRegistryServer,
|
|
16
20
|
startTunnelRegistryServer,
|
|
17
21
|
};
|