Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ android-snapshot-helper/build/
android-snapshot-helper/dist/
android-multitouch-helper/build/
android-multitouch-helper/dist/
harmonyos-lab/
2 changes: 1 addition & 1 deletion src/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
SnapshotState,
} from './utils/snapshot.ts';

export type AgentDeviceBackendPlatform = 'ios' | 'android' | 'macos' | 'linux';
export type AgentDeviceBackendPlatform = 'ios' | 'android' | 'macos' | 'harmonyos' | 'linux';

export const BACKEND_CAPABILITY_NAMES = [
'android.shell',
Expand Down
8 changes: 7 additions & 1 deletion src/client-normalizers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function buildClientDevicePlatformFields(
platform: AgentDeviceDevice['platform'],
id: string,
simulatorSetPath?: string | null,
): Pick<AgentDeviceSessionDevice, 'ios' | 'android'> {
): Pick<AgentDeviceSessionDevice, 'ios' | 'android' | 'harmonyos'> {
return {
ios:
platform === 'ios'
Expand All @@ -152,6 +152,7 @@ function buildClientDevicePlatformFields(
}
: undefined,
android: platform === 'android' ? { serial: id } : undefined,
harmonyos: platform === 'harmonyos' ? { serial: id } : undefined,
};
}

Expand Down Expand Up @@ -181,6 +182,7 @@ export function normalizeOpenDevice(
(platform !== 'ios' &&
platform !== 'macos' &&
platform !== 'android' &&
platform !== 'harmonyos' &&
platform !== 'linux') ||
!id ||
!name
Expand All @@ -204,6 +206,10 @@ export function normalizeOpenDevice(
: undefined,
android:
platform === 'android' ? { serial: readOptionalString(value, 'serial') ?? id } : undefined,
harmonyos:
platform === 'harmonyos'
? { serial: readOptionalString(value, 'serial') ?? id }
: undefined,
};
}

Expand Down
13 changes: 10 additions & 3 deletions src/client-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ export function buildDeviceIdentifiers(
return {
deviceId: id,
deviceName: name,
...(platform === 'android' ? { serial: id } : platform === 'ios' ? { udid: id } : {}),
...(platform === 'android' || platform === 'harmonyos'
? { serial: id }
: platform === 'ios'
? { udid: id }
: {}),
};
}

Expand All @@ -56,9 +60,12 @@ function serializeSessionDevice(
ios_simulator_device_set: device.ios?.simulatorSetPath ?? null,
}
: {}),
...(device.platform === 'android' && includeAndroidSerial
...((device.platform === 'android' || device.platform === 'harmonyos') && includeAndroidSerial
? {
serial: device.android?.serial ?? device.id,
serial:
device.platform === 'android'
? device.android?.serial ?? device.id
: device.harmonyos?.serial ?? device.id,
}
: {}),
};
Expand Down
6 changes: 6 additions & 0 deletions src/client-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ export type AgentDeviceDevice = {
android?: {
serial: string;
};
harmonyos?: {
serial: string;
};
};

export type AgentDeviceSessionDevice = {
Expand All @@ -129,6 +132,9 @@ export type AgentDeviceSessionDevice = {
android?: {
serial: string;
};
harmonyos?: {
serial: string;
};
};

export type AgentDeviceSession = {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/client-command-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const clientCommandMetadata = [
}),
defineClientCommandMetadata('app-switcher', {}),
defineClientCommandMetadata('keyboard', {
action: enumField(['status', 'dismiss']),
action: enumField(['status', 'dismiss', 'enter', 'return']),
}),
defineClientCommandMetadata('clipboard', {
action: requiredField(enumField(CLIPBOARD_ACTION_VALUES)),
Expand Down
5 changes: 5 additions & 0 deletions src/commands/client-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ function formatAppState(data: AppStateCommandResult): string | null {
if (data.activity) lines.push(`Activity: ${data.activity}`);
return lines.join('\n');
}
if (data.platform === 'harmonyos') {
const lines = [`Foreground app: ${data.bundleId ?? 'unknown'}`];
if (data.activity) lines.push(`Ability: ${data.activity}`);
return lines.join('\n');
}
return null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/command-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
import type { DeviceTarget, PlatformSelector } from '../utils/device.ts';
import type { JsonSchema } from './command-contract.ts';

const PLATFORM_VALUES = ['ios', 'android', 'macos', 'linux', 'apple'] as const;
const PLATFORM_VALUES = ['ios', 'android', 'macos', 'harmonyos', 'linux', 'apple'] as const;
const DEVICE_TARGET_VALUES = ['mobile', 'tv', 'desktop'] as const;
const INTERACTION_TARGET_KINDS = ['ref', 'selector', 'point'] as const;

Expand Down
2 changes: 1 addition & 1 deletion src/compat/maestro/command-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function convertOpenLink(
): SessionAction {
const rawLink = readOpenLink(value, name);
const url = resolveMaestroString(rawLink, context);
if ((context.platform === 'ios' || context.platform === 'android') && config.appId) {
if ((context.platform === 'ios' || context.platform === 'android' || context.platform === 'harmonyos') && config.appId) {
return action(
'open',
[resolveMaestroString(requireAppId(config, name), context), url],
Expand Down
4 changes: 3 additions & 1 deletion src/compat/maestro/runtime-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ function filterReactNativeOverlayBlockedMatches(
}

export function readMaestroSelectorPlatform(flags: DaemonRequest['flags']): Platform {
return flags?.platform === 'android' ? 'android' : 'ios';
if (flags?.platform === 'android') return 'android';
if (flags?.platform === 'harmonyos') return 'harmonyos';
return 'ios';
}

export function extractMaestroVisibleTextQuery(selectorExpression: string): string | null {
Expand Down
4 changes: 2 additions & 2 deletions src/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export type DaemonRequestMeta = {
materializedPathRetentionMs?: number;
materializationId?: string;
lockPolicy?: DaemonLockPolicy;
lockPlatform?: 'ios' | 'macos' | 'android' | 'linux' | 'apple';
lockPlatform?: 'ios' | 'macos' | 'android' | 'harmonyos' | 'linux' | 'apple';
requestProgress?: 'replay-test';
};

Expand Down Expand Up @@ -395,7 +395,7 @@ export const daemonCommandRequestSchema = schema<DaemonRequest>((input, path) =>
lockPlatform: optionalEnum(
meta,
'lockPlatform',
['ios', 'macos', 'android', 'linux', 'apple'] as const,
['ios', 'macos', 'android', 'harmonyos', 'linux', 'apple'] as const,
`${path}.meta`,
),
},
Expand Down
Loading