Skip to content

Commit 0af152a

Browse files
Fix tests
1 parent bf3e49b commit 0af152a

File tree

3 files changed

+55
-59
lines changed

3 files changed

+55
-59
lines changed

Scripts/build-webdriveragent.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url';
33
import { asyncify } from 'asyncbox';
44
import { logger, fs } from '@appium/support';
55
import { exec } from 'teen_process';
6-
import xcode from 'appium-xcode';
6+
import * as xcode from 'appium-xcode';
77

88
const __filename = fileURLToPath(import.meta.url);
99
const __dirname = path.dirname(__filename);

Scripts/update-wda-version.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import {plist, logger} from '@appium/support';
22
import path from 'node:path';
3-
import { fileURLToPath } from 'node:url';
43
import semver from 'semver';
54

6-
const __filename = fileURLToPath(import.meta.url);
7-
const __dirname = path.dirname(__filename);
8-
95
const log = logger.getLogger('Versioner');
106

117
/**

lib/utils.ts

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
import { fs, plist } from '@appium/support';
22
import { exec, SubProcess } from 'teen_process';
3-
import path from 'path';
3+
import path, { dirname } from 'node:path';
4+
import { fileURLToPath } from 'node:url';
45
import { log } from './logger';
56
import _ from 'lodash';
67
import { WDA_RUNNER_BUNDLE_ID, PLATFORM_NAME_TVOS } from './constants';
78
import B from 'bluebird';
8-
import _fs from 'fs';
9+
import _fs from 'node:fs';
910
import { waitForCondition } from 'asyncbox';
10-
import { arch } from 'os';
11+
import { arch } from 'node:os';
1112
import type { DeviceInfo } from './types';
12-
import { fileURLToPath } from 'url';
1313

1414
const PROJECT_FILE = 'project.pbxproj';
1515

16+
// Get current filename - works in both CommonJS and ESM
17+
const currentFilename =
18+
typeof __filename !== 'undefined'
19+
? __filename
20+
: fileURLToPath(new Function('return import.meta.url')());
21+
22+
const currentDirname = dirname(currentFilename);
23+
1624
/**
1725
* Calculates the path to the current module's root folder
1826
*
1927
* @returns {string} The full path to module root
2028
* @throws {Error} If the current module root folder cannot be determined
2129
*/
2230
const getModuleRoot = _.memoize(function getModuleRoot (): string {
23-
// In TypeScript/ESM, we need to use import.meta.url to get the current file path
24-
// @ts-ignore - __filename may be available in CommonJS context
25-
const currentFile = typeof __filename !== 'undefined' ? __filename : fileURLToPath(import.meta.url);
26-
let currentDir = path.dirname(path.resolve(currentFile));
31+
let currentDir = currentDirname;
2732
let isAtFsRoot = false;
2833
while (!isAtFsRoot) {
2934
const manifestPath = path.join(currentDir, 'package.json');
@@ -41,24 +46,7 @@ const getModuleRoot = _.memoize(function getModuleRoot (): string {
4146

4247
export const BOOTSTRAP_PATH = getModuleRoot();
4348

44-
async function getPIDsUsingPattern (pattern: string): Promise<string[]> {
45-
const args = [
46-
'-if', // case insensitive, full cmdline match
47-
pattern,
48-
];
49-
try {
50-
const {stdout} = await exec('pgrep', args);
51-
return stdout.split(/\s+/)
52-
.map((x) => parseInt(x, 10))
53-
.filter(_.isInteger)
54-
.map((x) => `${x}`);
55-
} catch (err: any) {
56-
log.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);
57-
return [];
58-
}
59-
}
60-
61-
async function killAppUsingPattern (pgrepPattern: string): Promise<void> {
49+
export async function killAppUsingPattern (pgrepPattern: string): Promise<void> {
6250
const signals = [2, 15, 9];
6351
for (const signal of signals) {
6452
const matchedPids = await getPIDsUsingPattern(pgrepPattern);
@@ -102,26 +90,17 @@ async function killAppUsingPattern (pgrepPattern: string): Promise<void> {
10290
* @param platformName The name of the platorm
10391
* @returns Return true if the platformName is tvOS
10492
*/
105-
function isTvOS (platformName: string): boolean {
93+
export function isTvOS (platformName: string): boolean {
10694
return _.toLower(platformName) === _.toLower(PLATFORM_NAME_TVOS);
10795
}
10896

109-
async function replaceInFile (file: string, find: string | RegExp, replace: string): Promise<void> {
110-
const contents = await fs.readFile(file, 'utf8');
111-
112-
const newContents = contents.replace(find, replace);
113-
if (newContents !== contents) {
114-
await fs.writeFile(file, newContents, 'utf8');
115-
}
116-
}
117-
11897
/**
11998
* Update WebDriverAgentRunner project bundle ID with newBundleId.
12099
* This method assumes project file is in the correct state.
121100
* @param agentPath - Path to the .xcodeproj directory.
122101
* @param newBundleId the new bundle ID used to update.
123102
*/
124-
async function updateProjectFile (agentPath: string, newBundleId: string): Promise<void> {
103+
export async function updateProjectFile (agentPath: string, newBundleId: string): Promise<void> {
125104
const projectFilePath = path.resolve(agentPath, PROJECT_FILE);
126105
try {
127106
// Assuming projectFilePath is in the correct state, create .old from projectFilePath
@@ -139,7 +118,7 @@ async function updateProjectFile (agentPath: string, newBundleId: string): Promi
139118
* Reset WebDriverAgentRunner project bundle ID to correct state.
140119
* @param agentPath - Path to the .xcodeproj directory.
141120
*/
142-
async function resetProjectFile (agentPath: string): Promise<void> {
121+
export async function resetProjectFile (agentPath: string): Promise<void> {
143122
const projectFilePath = path.join(agentPath, PROJECT_FILE);
144123
try {
145124
// restore projectFilePath from .old file
@@ -156,7 +135,7 @@ async function resetProjectFile (agentPath: string): Promise<void> {
156135
}
157136
}
158137

159-
async function setRealDeviceSecurity (keychainPath: string, keychainPassword: string): Promise<void> {
138+
export async function setRealDeviceSecurity (keychainPath: string, keychainPassword: string): Promise<void> {
160139
log.debug('Setting security for iOS device');
161140
await exec('security', ['-v', 'list-keychains', '-s', keychainPath]);
162141
await exec('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath]);
@@ -188,7 +167,7 @@ export interface XctestrunFileArgs {
188167
* or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath,
189168
* then it will throw a file not found exception
190169
*/
191-
async function setXctestrunFile (args: XctestrunFileArgs): Promise<string> {
170+
export async function setXctestrunFile (args: XctestrunFileArgs): Promise<string> {
192171
const {deviceInfo, sdkVersion, bootstrapPath, wdaRemotePort, wdaBindingIP} = args;
193172
const xctestrunFilePath = await getXctestrunFilePath(deviceInfo, sdkVersion, bootstrapPath);
194173
const xctestRunContent = await plist.parsePlistFile(xctestrunFilePath);
@@ -206,7 +185,7 @@ async function setXctestrunFile (args: XctestrunFileArgs): Promise<string> {
206185
* @param wdaBindingIP - The IP address to bind to. If not given, it binds to all interfaces.
207186
* @return returns a runner object which has USE_PORT and optionally USE_IP
208187
*/
209-
function getAdditionalRunContent (platformName: string, wdaRemotePort: number | string, wdaBindingIP?: string): Record<string, any> {
188+
export function getAdditionalRunContent (platformName: string, wdaRemotePort: number | string, wdaBindingIP?: string): Record<string, any> {
210189
const runner = `WebDriverAgentRunner${isTvOS(platformName) ? '_tvOS' : ''}`;
211190
return {
212191
[runner]: {
@@ -225,7 +204,7 @@ function getAdditionalRunContent (platformName: string, wdaRemotePort: number |
225204
* @param sdkVersion - The Xcode SDK version of OS.
226205
* @param bootstrapPath - The folder path containing xctestrun file.
227206
*/
228-
async function getXctestrunFilePath (deviceInfo: DeviceInfo, sdkVersion: string, bootstrapPath: string): Promise<string> {
207+
export async function getXctestrunFilePath (deviceInfo: DeviceInfo, sdkVersion: string, bootstrapPath: string): Promise<string> {
229208
// First try the SDK path, for Xcode 10 (at least)
230209
const sdkBased: [string, string] = [
231210
path.resolve(bootstrapPath, `${deviceInfo.udid}_${sdkVersion}.xctestrun`),
@@ -266,7 +245,7 @@ async function getXctestrunFilePath (deviceInfo: DeviceInfo, sdkVersion: string,
266245
* @param version - The Xcode SDK version of OS.
267246
* @return returns xctestrunFilePath for given device
268247
*/
269-
function getXctestrunFileName (deviceInfo: DeviceInfo, version: string): string {
248+
export function getXctestrunFileName (deviceInfo: DeviceInfo, version: string): string {
270249
const archSuffix = deviceInfo.isRealDevice
271250
? `os${version}-arm64`
272251
: `simulator${version}-${arch() === 'arm64' ? 'arm64' : 'x86_64'}`;
@@ -276,7 +255,7 @@ function getXctestrunFileName (deviceInfo: DeviceInfo, version: string): string
276255
/**
277256
* Ensures the process is killed after the timeout
278257
*/
279-
async function killProcess (name: string, proc: SubProcess | null | undefined): Promise<void> {
258+
export async function killProcess (name: string, proc: SubProcess | null | undefined): Promise<void> {
280259
if (!proc || !proc.isRunning) {
281260
return;
282261
}
@@ -309,14 +288,14 @@ async function killProcess (name: string, proc: SubProcess | null | undefined):
309288
/**
310289
* Generate a random integer in range [low, high). `low` is inclusive and `high` is exclusive.
311290
*/
312-
function randomInt (low: number, high: number): number {
291+
export function randomInt (low: number, high: number): number {
313292
return Math.floor(Math.random() * (high - low) + low);
314293
}
315294

316295
/**
317296
* Retrieves WDA upgrade timestamp. The manifest only gets modified on package upgrade.
318297
*/
319-
async function getWDAUpgradeTimestamp (): Promise<number | null> {
298+
export async function getWDAUpgradeTimestamp (): Promise<number | null> {
320299
const packageManifest = path.resolve(getModuleRoot(), 'package.json');
321300
if (!await fs.exists(packageManifest)) {
322301
return null;
@@ -328,7 +307,7 @@ async function getWDAUpgradeTimestamp (): Promise<number | null> {
328307
/**
329308
* Kills running XCTest processes for the particular device.
330309
*/
331-
async function resetTestProcesses (udid: string, isSimulator: boolean): Promise<void> {
310+
export async function resetTestProcesses (udid: string, isSimulator: boolean): Promise<void> {
332311
const processPatterns = [`xcodebuild.*${udid}`];
333312
if (isSimulator) {
334313
processPatterns.push(`${udid}.*XCTRunner`);
@@ -352,7 +331,7 @@ async function resetTestProcesses (udid: string, isSimulator: boolean): Promise<
352331
* from the resulting array.
353332
* @returns - the list of matched process ids.
354333
*/
355-
async function getPIDsListeningOnPort (port: string | number, filteringFunc: ((cmdline: string) => boolean | Promise<boolean>) | null = null): Promise<string[]> {
334+
export async function getPIDsListeningOnPort (port: string | number, filteringFunc: ((cmdline: string) => boolean | Promise<boolean>) | null = null): Promise<string[]> {
356335
const result: string[] = [];
357336
try {
358337
// This only works since Mac OS X El Capitan
@@ -384,10 +363,31 @@ async function getPIDsListeningOnPort (port: string | number, filteringFunc: ((c
384363
});
385364
}
386365

387-
export { updateProjectFile, resetProjectFile, setRealDeviceSecurity,
388-
getAdditionalRunContent, getXctestrunFileName,
389-
setXctestrunFile, getXctestrunFilePath, killProcess, randomInt,
390-
getWDAUpgradeTimestamp, resetTestProcesses,
391-
getPIDsListeningOnPort, killAppUsingPattern, isTvOS
392-
};
366+
// Private functions
367+
368+
async function getPIDsUsingPattern (pattern: string): Promise<string[]> {
369+
const args = [
370+
'-if', // case insensitive, full cmdline match
371+
pattern,
372+
];
373+
try {
374+
const {stdout} = await exec('pgrep', args);
375+
return stdout.split(/\s+/)
376+
.map((x) => parseInt(x, 10))
377+
.filter(_.isInteger)
378+
.map((x) => `${x}`);
379+
} catch (err: any) {
380+
log.debug(`'pgrep ${args.join(' ')}' didn't detect any matching processes. Return code: ${err.code}`);
381+
return [];
382+
}
383+
}
384+
385+
async function replaceInFile (file: string, find: string | RegExp, replace: string): Promise<void> {
386+
const contents = await fs.readFile(file, 'utf8');
387+
388+
const newContents = contents.replace(find, replace);
389+
if (newContents !== contents) {
390+
await fs.writeFile(file, newContents, 'utf8');
391+
}
392+
}
393393

0 commit comments

Comments
 (0)