Skip to content
Merged
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
53 changes: 1 addition & 52 deletions lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import path, { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { log } from './logger';
import _ from 'lodash';
import { WDA_RUNNER_BUNDLE_ID, PLATFORM_NAME_TVOS } from './constants';
import { PLATFORM_NAME_TVOS } from './constants';
import B from 'bluebird';
import _fs from 'node:fs';
import { waitForCondition } from 'asyncbox';
import { arch } from 'node:os';
import type { DeviceInfo } from './types';

const PROJECT_FILE = 'project.pbxproj';

// Get current filename - works in both CommonJS and ESM
const currentFilename =
typeof __filename !== 'undefined'
Expand Down Expand Up @@ -94,47 +92,6 @@ export function isTvOS (platformName: string): boolean {
return _.toLower(platformName) === _.toLower(PLATFORM_NAME_TVOS);
}

/**
* Update WebDriverAgentRunner project bundle ID with newBundleId.
* This method assumes project file is in the correct state.
* @param agentPath - Path to the .xcodeproj directory.
* @param newBundleId the new bundle ID used to update.
*/
export async function updateProjectFile (agentPath: string, newBundleId: string): Promise<void> {
const projectFilePath = path.resolve(agentPath, PROJECT_FILE);
try {
// Assuming projectFilePath is in the correct state, create .old from projectFilePath
await fs.copyFile(projectFilePath, `${projectFilePath}.old`);
await replaceInFile(projectFilePath, new RegExp(_.escapeRegExp(WDA_RUNNER_BUNDLE_ID), 'g'), newBundleId);
log.debug(`Successfully updated '${projectFilePath}' with bundle id '${newBundleId}'`);
} catch (err: any) {
log.debug(`Error updating project file: ${err.message}`);
log.warn(`Unable to update project file '${projectFilePath}' with ` +
`bundle id '${newBundleId}'. WebDriverAgent may not start`);
}
}

/**
* Reset WebDriverAgentRunner project bundle ID to correct state.
* @param agentPath - Path to the .xcodeproj directory.
*/
export async function resetProjectFile (agentPath: string): Promise<void> {
const projectFilePath = path.join(agentPath, PROJECT_FILE);
try {
// restore projectFilePath from .old file
if (!await fs.exists(`${projectFilePath}.old`)) {
return; // no need to reset
}
await fs.mv(`${projectFilePath}.old`, projectFilePath);
log.debug(`Successfully reset '${projectFilePath}' with bundle id '${WDA_RUNNER_BUNDLE_ID}'`);
} catch (err: any) {
log.debug(`Error resetting project file: ${err.message}`);
log.warn(`Unable to reset project file '${projectFilePath}' with ` +
`bundle id '${WDA_RUNNER_BUNDLE_ID}'. WebDriverAgent has been ` +
`modified and not returned to the original state.`);
}
}

export async function setRealDeviceSecurity (keychainPath: string, keychainPassword: string): Promise<void> {
log.debug('Setting security for iOS device');
await exec('security', ['-v', 'list-keychains', '-s', keychainPath]);
Expand Down Expand Up @@ -382,12 +339,4 @@ async function getPIDsUsingPattern (pattern: string): Promise<string[]> {
}
}

async function replaceInFile (file: string, find: string | RegExp, replace: string): Promise<void> {
const contents = await fs.readFile(file, 'utf8');

const newContents = contents.replace(find, replace);
if (newContents !== contents) {
await fs.writeFile(file, newContents, 'utf8');
}
}

1 change: 0 additions & 1 deletion lib/webdriveragent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ export class WebDriverAgent {
this.log.info('Shutting down sub-processes');
if (this._xcodebuild) {
await this.xcodebuild.quit();
await this.xcodebuild.reset();
}
} else {
this.log.debug('Do not stop xcodebuild nor XCTest session ' +
Expand Down
34 changes: 6 additions & 28 deletions lib/xcodebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { log as defaultLogger } from './logger';
import B from 'bluebird';
import {
setRealDeviceSecurity, setXctestrunFile,
updateProjectFile, resetProjectFile, killProcess,
getWDAUpgradeTimestamp, isTvOS
killProcess, getWDAUpgradeTimestamp, isTvOS
} from './utils';
import _ from 'lodash';
import path from 'path';
Expand Down Expand Up @@ -135,7 +134,7 @@ export class XcodeBuild {

/**
* Initializes the XcodeBuild instance with a no-session proxy.
* Sets up xctestrun file if needed, or updates project bundle ID for real devices.
* Sets up xctestrun file if needed.
* @param noSessionProxy - The proxy instance for WDA communication
*/
async init (noSessionProxy: NoSessionProxy): Promise<void> {
Expand All @@ -157,19 +156,6 @@ export class XcodeBuild {
});
return;
}

// if necessary, update the bundleId to user's specification
if (this.realDevice) {
// In case the project still has the user specific bundle ID, reset the project file first.
// - We do this reset even if updatedWDABundleId is not specified,
// since the previous updatedWDABundleId test has generated the user specific bundle ID project file.
// - We don't call resetProjectFile for simulator,
// since simulator test run will work with any user specific bundle ID.
await resetProjectFile(this.agentPath);
if (this.updatedWDABundleId) {
await updateProjectFile(this.agentPath, this.updatedWDABundleId);
}
}
}

/**
Expand Down Expand Up @@ -211,17 +197,6 @@ export class XcodeBuild {
return await this._derivedDataPathPromise;
}

/**
* Resets the project file to its original state.
* Restores the bundle ID to the original value for real devices if it was modified.
*/
async reset (): Promise<void> {
// if necessary, reset the bundleId to original value
if (this.realDevice && this.updatedWDABundleId) {
await resetProjectFile(this.agentPath);
}
}

/**
* Pre-builds WebDriverAgent before launching tests.
* Performs a build-only operation and sets usePrebuiltWDA flag.
Expand Down Expand Up @@ -360,7 +335,7 @@ export class XcodeBuild {
}
args.push('-destination', `id=${this.device.udid}`);

let versionMatch;
let versionMatch: RegExpMatchArray | null = null;
if (this.platformVersion && (versionMatch = new RegExp(/^(\d+)\.(\d+)/).exec(this.platformVersion))) {
args.push(
`${isTvOS(this.platformName || '') ? 'TV' : 'IPHONE'}OS_DEPLOYMENT_TARGET=${versionMatch[1]}.${versionMatch[2]}`
Expand All @@ -383,6 +358,9 @@ export class XcodeBuild {
`CODE_SIGN_IDENTITY=${this.xcodeSigningId}`,
);
}
if (this.updatedWDABundleId) {
args.push(`PRODUCT_BUNDLE_IDENTIFIER=${this.updatedWDABundleId}`);
}
}

if (!process.env.APPIUM_XCUITEST_TREAT_WARNINGS_AS_ERRORS) {
Expand Down
Loading