Skip to content

Commit

Permalink
Merge pull request forcedotcom#91 from maliroteh-sf/main
Browse files Browse the repository at this point in the history
Export CryptoUtils + some cleanup
  • Loading branch information
khawkins authored Jun 5, 2024
2 parents f65a848 + d74eb54 commit c4a574c
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 198 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@salesforce/lwc-dev-mobile-core",
"description": "Core module supporting Salesforce CLI mobile extension plug-ins",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.3",
"author": {
"name": "Meisam Seyed Aliroteh",
"email": "[email protected]",
Expand Down
9 changes: 5 additions & 4 deletions src/common/AndroidEnvironmentRequirements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Logger, Messages, SfError } from '@salesforce/core';
import { AndroidUtils } from './AndroidUtils.js';
import { PlatformConfig } from './PlatformConfig.js';
import { Requirement, RequirementList } from './Requirements.js';
import { CommonUtils } from './CommonUtils.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/lwc-dev-mobile-core', 'requirement-android');
Expand Down Expand Up @@ -49,8 +50,8 @@ export class AndroidSDKRootSetRequirement implements Requirement {
if (root) {
return Promise.resolve(
messages.getMessage(this.fulfilledMessage, [
AndroidUtils.convertToUnixPath(root.rootSource),
AndroidUtils.convertToUnixPath(root.rootLocation)
CommonUtils.convertToUnixPath(root.rootSource),
CommonUtils.convertToUnixPath(root.rootLocation)
])
);
} else {
Expand Down Expand Up @@ -103,7 +104,7 @@ export class AndroidSDKToolsInstalledRequirement implements Requirement {
public async checkFunction(): Promise<string> {
return AndroidUtils.fetchAndroidCmdLineToolsLocation()
.then((result) =>
Promise.resolve(messages.getMessage(this.fulfilledMessage, [AndroidUtils.convertToUnixPath(result)]))
Promise.resolve(messages.getMessage(this.fulfilledMessage, [CommonUtils.convertToUnixPath(result)]))
)
.catch(() => Promise.reject(new SfError(messages.getMessage(this.unfulfilledMessage))));
}
Expand All @@ -130,7 +131,7 @@ export class AndroidSDKPlatformToolsInstalledRequirement implements Requirement
public async checkFunction(): Promise<string> {
return AndroidUtils.fetchAndroidSDKPlatformToolsLocation()
.then((result) =>
Promise.resolve(messages.getMessage(this.fulfilledMessage, [AndroidUtils.convertToUnixPath(result)]))
Promise.resolve(messages.getMessage(this.fulfilledMessage, [CommonUtils.convertToUnixPath(result)]))
)
.catch((error) => {
if (error.status === 127) {
Expand Down
20 changes: 14 additions & 6 deletions src/common/AndroidLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,24 @@ export class AndroidLauncher {
const launchActivity = appConfig?.activity ?? '';

const targetAppArguments: LaunchArgument[] = appConfig?.launch_arguments ?? [];
return AndroidUtils.launchNativeApp(
compName,
projectDir,

targetAppArguments.push({ name: PreviewUtils.COMPONENT_NAME_ARG_PREFIX, value: compName });
targetAppArguments.push({ name: PreviewUtils.PROJECT_DIR_ARG_PREFIX, value: projectDir });

if (address) {
targetAppArguments.push({ name: PreviewUtils.SERVER_ADDRESS_PREFIX, value: address });
}

if (port) {
targetAppArguments.push({ name: PreviewUtils.SERVER_PORT_PREFIX, value: port });
}

return AndroidUtils.launchAppInBootedEmulator(
appBundlePath,
targetApp,
targetAppArguments,
launchActivity,
emulatorPort,
address,
port
emulatorPort
);
}
})
Expand Down
49 changes: 11 additions & 38 deletions src/common/AndroidUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { Version } from './Common.js';
import { CommonUtils } from './CommonUtils.js';
import { PlatformConfig } from './PlatformConfig.js';
import { LaunchArgument } from './PreviewConfigFile.js';
import { PreviewUtils } from './PreviewUtils.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/lwc-dev-mobile-core', 'common');
Expand Down Expand Up @@ -47,16 +46,6 @@ export class AndroidUtils {
AndroidUtils.logger.setLevel(level);
}

/**
* Converts a path to UNIX style path.
*
* @param dirPath Input path.
* @returns UNIX style path.
*/
public static convertToUnixPath(dirPath: string): string {
return dirPath.replace(/[\\]+/g, '/');
}

/**
* Indicates whether Android packages are cached or not.
*
Expand Down Expand Up @@ -809,26 +798,18 @@ export class AndroidUtils {
/**
* Attempts to launch a native app in an emulator to preview LWC components. If the app is not installed then this method will attempt to install it first.
*
* @param compName Name of the LWC component.
* @param projectDir Path to the LWC project root directory.
* @param appBundlePath Optional path to the app bundle of the native app. This will be used to install the app if not already installed.
* @param targetApp The bundle ID of the app to be launched.
* @param targetAppArguments Extra arguments to be passed to the app upon launch.
* @param launchActivity Activity name to be used for launching the app.
* @param portNumber The ADB port of an Android virtual device.
* @param serverAddress Optional address for the server that is serving the LWC component. This will be passed to the app as an extra argument upon launch.
* @param serverPort Optional port for the server that is serving the LWC component. This will be passed to the app as an extra argument upon launch.
* @param emulatorPort The ADB port of an Android virtual device.
*/
public static async launchNativeApp(
compName: string,
projectDir: string,
public static async launchAppInBootedEmulator(
appBundlePath: string | undefined,
targetApp: string,
targetAppArguments: LaunchArgument[],
launchActivity: string,
portNumber: number,
serverAddress: string | undefined,
serverPort: string | undefined
emulatorPort: number
): Promise<void> {
let thePromise: Promise<string>;
if (appBundlePath && appBundlePath.trim().length > 0) {
Expand All @@ -837,27 +818,16 @@ export class AndroidUtils {
CommonUtils.startCliAction(messages.getMessage('launchAppAction'), installMsg);
const pathQuote = process.platform === WINDOWS_OS ? '"' : "'";
const installCommand = `install -r -t ${pathQuote}${appBundlePath.trim()}${pathQuote}`;
thePromise = AndroidUtils.executeAdbCommand(installCommand, portNumber);
thePromise = AndroidUtils.executeAdbCommand(installCommand, emulatorPort);
} else {
thePromise = Promise.resolve('');
}

return thePromise
.then(() => {
let launchArgs =
`--es "${PreviewUtils.COMPONENT_NAME_ARG_PREFIX}" "${compName}"` +
` --es "${PreviewUtils.PROJECT_DIR_ARG_PREFIX}" "${projectDir}"`;

if (serverAddress) {
launchArgs += ` --es "${PreviewUtils.SERVER_ADDRESS_PREFIX}" "${serverAddress}"`;
}

if (serverPort) {
launchArgs += ` --es "${PreviewUtils.SERVER_PORT_PREFIX}" "${serverPort}"`;
}

let launchArgs = '';
targetAppArguments.forEach((arg) => {
launchArgs += ` --es "${arg.name}" "${arg.value}"`;
launchArgs += `--es "${arg.name}" "${arg.value}" `;
});

const launchCommand =
Expand All @@ -870,9 +840,12 @@ export class AndroidUtils {
AndroidUtils.logger.info(launchMsg);
CommonUtils.updateCliAction(launchMsg);

return AndroidUtils.executeAdbCommand(launchCommand, portNumber);
return AndroidUtils.executeAdbCommand(launchCommand, emulatorPort);
})
.then(() => Promise.resolve());
.then(() => {
CommonUtils.stopCliAction();
return Promise.resolve();
});
}

// This method is public for testing purposes.
Expand Down
10 changes: 10 additions & 0 deletions src/common/CommonUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ export class CommonUtils {
CommonUtils.logger.setLevel(level);
}

/**
* Converts a path to UNIX style path.
*
* @param dirPath Input path.
* @returns UNIX style path.
*/
public static convertToUnixPath(dirPath: string): string {
return dirPath.replace(/[\\]+/g, '/');
}

/**
* Returns a Promise that supports timeout
*
Expand Down
2 changes: 1 addition & 1 deletion src/common/CryptoUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class CryptoUtils {
const attrs = [
{ name: 'commonName', value: hostname },
{ name: 'countryName', value: 'US' },
{ name: 'organizationName', value: 'Salesforce Local Development Server Self-Signed Cert' }
{ name: 'organizationName', value: 'Salesforce Local Development Server Self Signed Cert' }
];

cert.setSubject(attrs);
Expand Down
18 changes: 13 additions & 5 deletions src/common/IOSLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,23 @@ export class IOSLauncher {
} else {
CommonUtils.updateCliAction(messages.getMessage('launchAppStatus', [targetApp]));
const targetAppArguments: LaunchArgument[] = appConfig?.launch_arguments ?? [];

targetAppArguments.push({ name: PreviewUtils.COMPONENT_NAME_ARG_PREFIX, value: compName });
targetAppArguments.push({ name: PreviewUtils.PROJECT_DIR_ARG_PREFIX, value: projectDir });

if (address) {
targetAppArguments.push({ name: PreviewUtils.SERVER_ADDRESS_PREFIX, value: address });
}

if (port) {
targetAppArguments.push({ name: PreviewUtils.SERVER_PORT_PREFIX, value: port });
}

return IOSUtils.launchAppInBootedSimulator(
deviceUDID,
compName,
projectDir,
appBundlePath,
targetApp,
targetAppArguments,
address,
port
targetAppArguments
);
}
})
Expand Down
31 changes: 7 additions & 24 deletions src/common/IOSUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { CommonUtils } from './CommonUtils.js';
import { IOSSimulatorDevice } from './IOSTypes.js';
import { PlatformConfig } from './PlatformConfig.js';
import { LaunchArgument } from './PreviewConfigFile.js';
import { PreviewUtils } from './PreviewUtils.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/lwc-dev-mobile-core', 'common');
Expand Down Expand Up @@ -266,23 +265,15 @@ export class IOSUtils {
* Attempts to launch a native app in a simulator to preview LWC components. If the app is not installed then this method will attempt to install it first.
*
* @param udid The UDID of the simulator.
* @param compName Name of the LWC component.
* @param projectDir Path to the LWC project root directory.
* @param appBundlePath Optional path to the app bundle of the native app. This will be used to install the app if not already installed.
* @param targetApp The bundle ID of the app to be launched.
* @param targetAppArguments Extra arguments to be passed to the app upon launch.
* @param serverAddress Optional address for the server that is serving the LWC component. This will be passed to the app as an extra argument upon launch.
* @param serverPort Optional port for the server that is serving the LWC component. This will be passed to the app as an extra argument upon launch.
*/
public static async launchAppInBootedSimulator(
udid: string,
compName: string,
projectDir: string,
appBundlePath: string | undefined,
targetApp: string,
targetAppArguments: LaunchArgument[],
serverAddress: string | undefined,
serverPort: string | undefined
targetAppArguments: LaunchArgument[]
): Promise<void> {
let thePromise: Promise<{ stdout: string; stderr: string }>;
if (appBundlePath && appBundlePath.trim().length > 0) {
Expand All @@ -297,20 +288,9 @@ export class IOSUtils {

return thePromise
.then(async () => {
let launchArgs =
`${PreviewUtils.COMPONENT_NAME_ARG_PREFIX}=${compName}` +
` ${PreviewUtils.PROJECT_DIR_ARG_PREFIX}=${projectDir}`;

if (serverAddress) {
launchArgs += ` ${PreviewUtils.SERVER_ADDRESS_PREFIX}=${serverAddress}`;
}

if (serverPort) {
launchArgs += ` ${PreviewUtils.SERVER_PORT_PREFIX}=${serverPort}`;
}

let launchArgs = '';
targetAppArguments.forEach((arg) => {
launchArgs += ` ${arg.name}=${arg.value}`;
launchArgs += `${arg.name}=${arg.value} `;
});

const terminateCommand = `${XCRUN_CMD} simctl terminate "${udid}" ${targetApp}`;
Expand All @@ -332,7 +312,10 @@ export class IOSUtils {
CommonUtils.updateCliAction(launchMsg);
return CommonUtils.executeCommandAsync(launchCommand);
})
.then(() => Promise.resolve());
.then(() => {
CommonUtils.stopCliAction();
return Promise.resolve();
});
}

private static logger: Logger = new Logger(LOGGER_NAME);
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from './common/AndroidUtils.js';
export * from './common/BaseCommand.js';
export * from './common/Common.js';
export * from './common/CommonUtils.js';
export * from './common/CryptoUtils.js';
export * from './common/IOSEnvironmentRequirements.js';
export * from './common/IOSLauncher.js';
export * from './common/IOSTypes.js';
Expand Down
2 changes: 1 addition & 1 deletion test/unit/common/AndroidEnvironmentRequirements.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Android environment requirement tests', () => {

const $$ = new TestContext();
const logger = new Logger('test');
const mockCmdLineToolsBin = AndroidUtils.convertToUnixPath(
const mockCmdLineToolsBin = CommonUtils.convertToUnixPath(
path.join(MOCK_ANDROID_HOME, 'cmdline-tools', 'latest', 'bin')
);

Expand Down
24 changes: 15 additions & 9 deletions test/unit/common/AndroidLauncher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { expect } from 'chai';
import { CommonUtils } from '../../../src/common/CommonUtils.js';
import { AndroidLauncher } from '../../../src/common/AndroidLauncher.js';
import { AndroidUtils } from '../../../src/common/AndroidUtils.js';
import { PreviewUtils } from '../../../src/common/PreviewUtils.js';
import { AndroidMockData } from './AndroidMockData.js';

describe('Android Launcher tests', () => {
Expand All @@ -32,7 +33,7 @@ describe('Android Launcher tests', () => {
const launcher = new AndroidLauncher('Pixel XL');
await launcher.launchPreview('helloWorld', '~', undefined, 'browser', undefined, '3333');

expect(launchUrlMock.calledWith('http://10.0.2.2:3333/lwc/preview/c/helloWorld', 5572));
expect(launchUrlMock.calledWith('http://10.0.2.2:3333/lwc/preview/c/helloWorld', 5572)).to.be.true;
});

it('Should attempt to invoke preview in native app', async () => {
Expand All @@ -43,23 +44,28 @@ describe('Android Launcher tests', () => {
stubMethod($$.SANDBOX, AndroidUtils, 'hasEmulator').resolves(true);
stubMethod($$.SANDBOX, AndroidUtils, 'startEmulator').resolves(5572);

const launchAppMock = stubMethod($$.SANDBOX, AndroidUtils, 'launchNativeApp').resolves();
const launchAppMock = stubMethod($$.SANDBOX, AndroidUtils, 'launchAppInBootedEmulator').resolves();

const launcher = new AndroidLauncher('Pixel XL');
await launcher.launchPreview('helloWorld', '~', undefined, 'com.salesforce.test', undefined, '3333');

expect(
launchAppMock.calledWith(
'helloWorld',
'~',
undefined,
'com.salesforce.test',
[],
[
{
name: PreviewUtils.COMPONENT_NAME_ARG_PREFIX,
value: 'helloWorld'
},
{
name: PreviewUtils.PROJECT_DIR_ARG_PREFIX,
value: '~'
}
],
'',
5572,
undefined,
undefined
5572
)
);
).to.be.true;
});
});
Loading

0 comments on commit c4a574c

Please sign in to comment.