@react-native-harness/platform-android 1.0.0-canary.1766225407244 → 1.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"adb-id.d.ts","sourceRoot":"","sources":["../src/adb-id.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,aAAa,EACd,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,OAE/C,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,QAAQ,aAAa,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAsBvB,CAAC"}
1
+ {"version":3,"file":"adb-id.d.ts","sourceRoot":"","sources":["../src/adb-id.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,aAAa,EACd,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,OAE/C,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,QAAQ,aAAa,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CA+BvB,CAAC"}
package/dist/adb-id.js CHANGED
@@ -14,8 +14,14 @@ export const getAdbId = async (device) => {
14
14
  }
15
15
  else if (isAndroidDevicePhysical(device)) {
16
16
  const deviceInfo = await adb.getDeviceInfo(adbId);
17
- if (deviceInfo?.manufacturer === device.manufacturer &&
18
- deviceInfo?.model === device.model) {
17
+ if (!deviceInfo) {
18
+ // This should never happen as we already checked if the device is physical.
19
+ return null;
20
+ }
21
+ const normalizedManufacturer = deviceInfo.manufacturer?.toLowerCase() ?? '';
22
+ const normalizedModel = deviceInfo.model?.toLowerCase() ?? '';
23
+ if (normalizedManufacturer === device.manufacturer &&
24
+ normalizedModel === device.model) {
19
25
  return adbId;
20
26
  }
21
27
  }
package/dist/adb.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const isAppInstalled: (adbId: string, bundleId: string) => Promise<boolean>;
2
- export declare const reversePort: (adbId: string, port: number) => Promise<void>;
2
+ export declare const reversePort: (adbId: string, port: number, hostPort?: number) => Promise<void>;
3
3
  export declare const stopApp: (adbId: string, bundleId: string) => Promise<void>;
4
4
  export declare const startApp: (adbId: string, bundleId: string, activityName: string) => Promise<void>;
5
5
  export declare const getDeviceIds: () => Promise<string[]>;
@@ -12,4 +12,12 @@ export type DeviceInfo = {
12
12
  export declare const getDeviceInfo: (adbId: string) => Promise<DeviceInfo | null>;
13
13
  export declare const isBootCompleted: (adbId: string) => Promise<boolean>;
14
14
  export declare const stopEmulator: (adbId: string) => Promise<void>;
15
+ export declare const isAppRunning: (adbId: string, bundleId: string) => Promise<boolean>;
16
+ export declare const getAvds: () => Promise<string[]>;
17
+ export type AdbDevice = {
18
+ id: string;
19
+ model: string;
20
+ manufacturer: string;
21
+ };
22
+ export declare const getConnectedDevices: () => Promise<AdbDevice[]>;
15
23
  //# sourceMappingURL=adb.d.ts.map
package/dist/adb.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAWjB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,EACb,MAAM,MAAM,KACX,OAAO,CAAC,IAAI,CAEd,CAAC;AAEF,eAAO,MAAM,OAAO,GAClB,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAEd,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,OAAO,MAAM,EACb,UAAU,MAAM,EAChB,cAAc,MAAM,KACnB,OAAO,CAAC,IAAI,CAcd,CAAC;AAEF,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,MAAM,EAAE,CAOrD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAGvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CASvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,KACZ,OAAO,CAAC,UAAU,GAAG,IAAI,CAI3B,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,OAAO,CAGpE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAE9D,CAAC"}
1
+ {"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAWjB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,WAAU,MAAa,KACtB,OAAO,CAAC,IAAI,CAQd,CAAC;AAEF,eAAO,MAAM,OAAO,GAClB,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAEd,CAAC;AAEF,eAAO,MAAM,QAAQ,GACnB,OAAO,MAAM,EACb,UAAU,MAAM,EAChB,cAAc,MAAM,KACnB,OAAO,CAAC,IAAI,CAcd,CAAC;AAEF,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,MAAM,EAAE,CAOrD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAGvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CASvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,KACZ,OAAO,CAAC,UAAU,GAAG,IAAI,CAI3B,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,OAAO,CAGpE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAE9D,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CASjB,CAAC;AAEF,eAAO,MAAM,OAAO,QAAa,OAAO,CAAC,MAAM,EAAE,CAUhD,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAa,OAAO,CAAC,SAAS,EAAE,CA8B/D,CAAC"}
package/dist/adb.js CHANGED
@@ -11,8 +11,14 @@ export const isAppInstalled = async (adbId, bundleId) => {
11
11
  ]);
12
12
  return stdout.trim() !== '';
13
13
  };
14
- export const reversePort = async (adbId, port) => {
15
- await spawn('adb', ['-s', adbId, 'reverse', `tcp:${port}`, `tcp:${port}`]);
14
+ export const reversePort = async (adbId, port, hostPort = port) => {
15
+ await spawn('adb', [
16
+ '-s',
17
+ adbId,
18
+ 'reverse',
19
+ `tcp:${port}`,
20
+ `tcp:${hostPort}`,
21
+ ]);
16
22
  };
17
23
  export const stopApp = async (adbId, bundleId) => {
18
24
  await spawn('adb', ['-s', adbId, 'shell', 'am', 'force-stop', bundleId]);
@@ -66,3 +72,50 @@ export const isBootCompleted = async (adbId) => {
66
72
  export const stopEmulator = async (adbId) => {
67
73
  await spawn('adb', ['-s', adbId, 'emu', 'kill']);
68
74
  };
75
+ export const isAppRunning = async (adbId, bundleId) => {
76
+ const { stdout } = await spawn('adb', [
77
+ '-s',
78
+ adbId,
79
+ 'shell',
80
+ 'pidof',
81
+ bundleId,
82
+ ]);
83
+ return stdout.trim() !== '';
84
+ };
85
+ export const getAvds = async () => {
86
+ try {
87
+ const { stdout } = await spawn('emulator', ['-list-avds']);
88
+ return stdout
89
+ .split('\n')
90
+ .map((line) => line.trim())
91
+ .filter((line) => line !== '');
92
+ }
93
+ catch {
94
+ return [];
95
+ }
96
+ };
97
+ export const getConnectedDevices = async () => {
98
+ const { stdout } = await spawn('adb', ['devices', '-l']);
99
+ const lines = stdout.split('\n').slice(1);
100
+ const devices = [];
101
+ for (const line of lines) {
102
+ if (line.trim() === '')
103
+ continue;
104
+ const parts = line.split(/\s+/);
105
+ const id = parts[0];
106
+ // If it's an emulator, we skip it here as we handle emulators via AVDs
107
+ if (id.startsWith('emulator-'))
108
+ continue;
109
+ // Parse model and manufacturer from 'adb devices -l' output
110
+ // Example: 0123456789ABCDEF device usb:337641472X product:sdk_gphone64_arm64 model:Pixel_6 device:oriole transport_id:1
111
+ const modelMatch = line.match(/model:(\S+)/);
112
+ const model = modelMatch ? modelMatch[1].replace(/_/g, ' ') : 'Unknown';
113
+ const manufacturer = (await getShellProperty(id, 'ro.product.manufacturer')) ?? 'Unknown';
114
+ devices.push({
115
+ id,
116
+ model,
117
+ manufacturer,
118
+ });
119
+ }
120
+ return devices;
121
+ };
@@ -0,0 +1,5 @@
1
+ import { Config, NativeTestRunnerConfig } from './types.js';
2
+ export declare function assertNativeRunner(config: Config): asserts config is Config & {
3
+ runner: NativeTestRunnerConfig;
4
+ };
5
+ //# sourceMappingURL=assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE5D,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,IAAI,MAAM,GAAG;IAAE,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAO/D"}
@@ -0,0 +1,6 @@
1
+ export function assertNativeRunner(config) {
2
+ if (config.runner.platform !== 'ios' &&
3
+ config.runner.platform !== 'android') {
4
+ throw new Error('Runner is not a native runner');
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ export type AndroidEmulator = {
2
+ adbId: string;
3
+ stop: () => Promise<void>;
4
+ };
5
+ export declare const runEmulator: (avdName: string) => Promise<AndroidEmulator>;
6
+ //# sourceMappingURL=emulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../src/emulator.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,KACd,OAAO,CAAC,eAAe,CA8BzB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { spawn } from '@react-native-harness/tools';
2
+ import * as adb from './adb.js';
3
+ export const runEmulator = async (avdName) => {
4
+ const process = spawn('emulator', ['-avd', avdName]);
5
+ await process.nodeChildProcess;
6
+ const adbId = await adb.getEmulatorName(avdName);
7
+ if (!adbId) {
8
+ throw new Error('Emulator not found');
9
+ }
10
+ // Poll for emulator status until it's fully running
11
+ const checkStatus = async () => {
12
+ const status = await adb.isBootCompleted(adbId);
13
+ if (!status) {
14
+ await new Promise((resolve) => setTimeout(resolve, 2000));
15
+ await checkStatus();
16
+ }
17
+ };
18
+ // Start checking status after a brief delay to allow emulator to start
19
+ await new Promise((resolve) => setTimeout(resolve, 3000));
20
+ await checkStatus();
21
+ return {
22
+ adbId,
23
+ stop: async () => {
24
+ await adb.stopEmulator(adbId);
25
+ },
26
+ };
27
+ };
@@ -0,0 +1,15 @@
1
+ export declare class ConfigValidationError extends Error {
2
+ readonly filePath: string;
3
+ readonly validationErrors: string[];
4
+ constructor(filePath: string, validationErrors: string[]);
5
+ }
6
+ export declare class ConfigNotFoundError extends Error {
7
+ readonly searchPath: string;
8
+ constructor(searchPath: string);
9
+ }
10
+ export declare class ConfigLoadError extends Error {
11
+ readonly filePath: string;
12
+ readonly cause?: Error;
13
+ constructor(filePath: string, cause?: Error);
14
+ }
15
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;aAExB,QAAQ,EAAE,MAAM;aAChB,gBAAgB,EAAE,MAAM,EAAE;gBAD1B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EAAE;CAKjD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aACd,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CAIjD;AAED,qBAAa,eAAgB,SAAQ,KAAK;aAGV,QAAQ,EAAE,MAAM;IAF5C,SAAyB,KAAK,CAAC,EAAE,KAAK,CAAC;gBAEX,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAK9D"}
package/dist/errors.js ADDED
@@ -0,0 +1,28 @@
1
+ export class ConfigValidationError extends Error {
2
+ filePath;
3
+ validationErrors;
4
+ constructor(filePath, validationErrors) {
5
+ super(`Invalid configuration in ${filePath}`);
6
+ this.filePath = filePath;
7
+ this.validationErrors = validationErrors;
8
+ this.name = 'ConfigValidationError';
9
+ }
10
+ }
11
+ export class ConfigNotFoundError extends Error {
12
+ searchPath;
13
+ constructor(searchPath) {
14
+ super(`Config file not found in ${searchPath} or any parent directories`);
15
+ this.searchPath = searchPath;
16
+ this.name = 'ConfigNotFoundError';
17
+ }
18
+ }
19
+ export class ConfigLoadError extends Error {
20
+ filePath;
21
+ cause;
22
+ constructor(filePath, cause) {
23
+ super(`Failed to load config file ${filePath}`);
24
+ this.filePath = filePath;
25
+ this.name = 'ConfigLoadError';
26
+ this.cause = cause;
27
+ }
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,MAAM,wBAAwB,KAC7B,eAID,CAAC;AAEH,eAAO,MAAM,qBAAqB,GAChC,cAAc,MAAM,EACpB,OAAO,MAAM,KACZ,qBAID,CAAC;AAEH,eAAO,MAAM,eAAe,GAC1B,QAAQ,qBAAqB,KAC5B,eAAe,CAAC,qBAAqB,CAItC,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,MAAM,wBAAwB,KAC7B,eAID,CAAC;AAEH,eAAO,MAAM,qBAAqB,GAChC,cAAc,MAAM,EACpB,OAAO,MAAM,KACZ,qBAID,CAAC;AAEH,eAAO,MAAM,eAAe,GAC1B,QAAQ,qBAAqB,KAC5B,eAAe,CAAC,qBAAqB,CAKtC,CAAC"}
package/dist/factory.js CHANGED
@@ -9,7 +9,8 @@ export const physicalAndroidDevice = (manufacturer, model) => ({
9
9
  model: model.toLowerCase(),
10
10
  });
11
11
  export const androidPlatform = (config) => ({
12
- name: 'android',
12
+ name: config.name,
13
13
  config,
14
14
  runner: import.meta.resolve('./runner.js'),
15
+ platformId: 'android',
15
16
  });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { androidEmulator, physicalAndroidDevice, androidPlatform, } from './factory.js';
2
2
  export type { AndroidPlatformConfig } from './config.js';
3
+ export { getRunTargets } from './targets.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { androidEmulator, physicalAndroidDevice, androidPlatform, } from './factory.js';
2
+ export { getRunTargets } from './targets.js';
@@ -0,0 +1,6 @@
1
+ import { Config } from './types.js';
2
+ export declare const getConfig: (dir: string) => Promise<{
3
+ config: Config;
4
+ projectRoot: string;
5
+ }>;
6
+ //# sourceMappingURL=reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAsElD,eAAO,MAAM,SAAS,GACpB,KAAK,MAAM,KACV,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAUjD,CAAC"}
package/dist/reader.js ADDED
@@ -0,0 +1,57 @@
1
+ import { ConfigSchema } from './types.js';
2
+ import { ConfigValidationError, ConfigNotFoundError, ConfigLoadError, } from './errors.js';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ import { createRequire } from 'node:module';
6
+ import { ZodError } from 'zod';
7
+ const extensions = ['.js', '.mjs', '.cjs', '.json'];
8
+ const importUp = async (dir, name) => {
9
+ const filePath = path.join(dir, name);
10
+ for (const ext of extensions) {
11
+ const filePathWithExt = `${filePath}${ext}`;
12
+ if (fs.existsSync(filePathWithExt)) {
13
+ let rawConfig;
14
+ try {
15
+ if (ext === '.mjs') {
16
+ rawConfig = await import(filePathWithExt).then((module) => module.default);
17
+ }
18
+ else {
19
+ const require = createRequire(import.meta.url);
20
+ rawConfig = require(filePathWithExt);
21
+ }
22
+ }
23
+ catch (error) {
24
+ throw new ConfigLoadError(filePathWithExt, error instanceof Error ? error : undefined);
25
+ }
26
+ try {
27
+ const config = ConfigSchema.parse(rawConfig);
28
+ return { config, filePathWithExt, configDir: dir };
29
+ }
30
+ catch (error) {
31
+ if (error instanceof ZodError) {
32
+ const validationErrors = error.errors.map((err) => {
33
+ const path = err.path.length > 0 ? ` at "${err.path.join('.')}"` : '';
34
+ return `${err.message}${path}`;
35
+ });
36
+ throw new ConfigValidationError(filePathWithExt, validationErrors);
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ }
42
+ const parentDir = path.dirname(dir);
43
+ if (parentDir === dir) {
44
+ throw new ConfigNotFoundError(dir);
45
+ }
46
+ return importUp(parentDir, name);
47
+ };
48
+ export const getConfig = async (dir) => {
49
+ const { config, configDir } = await importUp(dir, 'rn-harness.config');
50
+ return {
51
+ config: {
52
+ ...config,
53
+ reporter: config.reporter,
54
+ },
55
+ projectRoot: configDir,
56
+ };
57
+ };
package/dist/runner.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { HarnessPlatformRunner } from '@react-native-harness/platforms';
2
+ import { Config } from '@react-native-harness/config';
2
3
  import { type AndroidPlatformConfig } from './config.js';
3
- declare const getAndroidRunner: (config: AndroidPlatformConfig) => Promise<HarnessPlatformRunner>;
4
+ declare const getAndroidRunner: (config: AndroidPlatformConfig, harnessConfig: Config) => Promise<HarnessPlatformRunner>;
4
5
  export default getAndroidRunner;
5
6
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AAKrB,QAAA,MAAM,gBAAgB,GACpB,QAAQ,qBAAqB,KAC5B,OAAO,CAAC,qBAAqB,CA8C/B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AAKrB,QAAA,MAAM,gBAAgB,GACpB,QAAQ,qBAAqB,EAC7B,eAAe,MAAM,KACpB,OAAO,CAAC,qBAAqB,CAiD/B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
package/dist/runner.js CHANGED
@@ -3,7 +3,7 @@ import { AndroidPlatformConfigSchema, } from './config.js';
3
3
  import { getAdbId } from './adb-id.js';
4
4
  import * as adb from './adb.js';
5
5
  import { getDeviceName } from './utils.js';
6
- const getAndroidRunner = async (config) => {
6
+ const getAndroidRunner = async (config, harnessConfig) => {
7
7
  const parsedConfig = AndroidPlatformConfigSchema.parse(config);
8
8
  const adbId = await getAdbId(parsedConfig.device);
9
9
  if (!adbId) {
@@ -16,7 +16,7 @@ const getAndroidRunner = async (config) => {
16
16
  await Promise.all([
17
17
  adb.reversePort(adbId, 8081),
18
18
  adb.reversePort(adbId, 8080),
19
- adb.reversePort(adbId, 3001),
19
+ adb.reversePort(adbId, harnessConfig.webSocketPort),
20
20
  ]);
21
21
  return {
22
22
  startApp: async () => {
@@ -32,6 +32,9 @@ const getAndroidRunner = async (config) => {
32
32
  dispose: async () => {
33
33
  await adb.stopApp(adbId, parsedConfig.bundleId);
34
34
  },
35
+ isAppRunning: async () => {
36
+ return await adb.isAppRunning(adbId, parsedConfig.bundleId);
37
+ },
35
38
  };
36
39
  };
37
40
  export default getAndroidRunner;
@@ -0,0 +1,3 @@
1
+ import { RunTarget } from "@react-native-harness/platforms";
2
+ export declare const getRunTargets: () => Promise<RunTarget[]>;
3
+ //# sourceMappingURL=targets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,SAAS,EAAE,CAkCzD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import * as adb from './adb.js';
2
+ export const getRunTargets = async () => {
3
+ const [avds, connectedDevices] = await Promise.all([
4
+ adb.getAvds(),
5
+ adb.getConnectedDevices(),
6
+ ]);
7
+ const targets = [];
8
+ for (const avd of avds) {
9
+ targets.push({
10
+ type: 'emulator',
11
+ name: avd,
12
+ platform: 'android',
13
+ description: 'Android emulator',
14
+ device: {
15
+ name: avd,
16
+ },
17
+ });
18
+ }
19
+ for (const device of connectedDevices) {
20
+ targets.push({
21
+ type: 'physical',
22
+ name: `${device.manufacturer} ${device.model}`,
23
+ platform: 'android',
24
+ description: `Physical device (${device.id})`,
25
+ device: {
26
+ manufacturer: device.manufacturer,
27
+ model: device.model,
28
+ },
29
+ });
30
+ }
31
+ return targets;
32
+ };