diff --git a/src/common/PreviewUtils.ts b/src/common/PreviewUtils.ts index 7097bc4..498b71d 100644 --- a/src/common/PreviewUtils.ts +++ b/src/common/PreviewUtils.ts @@ -12,6 +12,7 @@ import path from 'node:path'; import { createRequire } from 'node:module'; import Ajv from 'ajv'; +import { CommandLineUtils } from './Common.js'; import { CommonUtils } from './CommonUtils.js'; import { AndroidAppPreviewConfig, IOSAppPreviewConfig, PreviewConfigFile } from './PreviewConfigFile.js'; @@ -128,4 +129,45 @@ export class PreviewUtils { return undefined; } } + + /** + * For the new Local Development Preview approach where a new local dev server is being used, + * the local dev server needs to be configured to use a web socket url for local previewing. + * This method generates an appropriate web socket url to be used by the local dev server. + * + * @param platform a platform flag (desktop , ios, android). + * @param port the port number that the local dev server is configured to use. + * @returns A string representing a web socket url to be used by the local dev server. + */ + public static generateWebSocketUrlForLocalDevServer(platform: string, port: string): string { + /* + - For desktop browsers other than Safari, local development use cases will target ws://localhost: connections to the local dev server + - For the Safari desktop browser, target wss://localhost: + + - For mobile (webview in native apps), local development use cases will target: + - iOS: wss://localhost: + - Android: wss://10.0.2.2: + */ + + if (CommandLineUtils.platformFlagIsIOS(platform)) { + return `wss://localhost:${port}`; + } + + if (CommandLineUtils.platformFlagIsAndroid(platform)) { + return `wss://10.0.2.2:${port}`; + } + + if (process.platform !== 'darwin') { + return `ws://localhost:${port}`; // cannot be Safari since it is only available on Mac + } + + // If we've made it this far then it means that platform=desktop and we're on a Mac + // macOS use case: check to see if the default browser is Safari + // From https://apple.stackexchange.com/questions/313454/applescript-find-the-users-set-default-browser + const cmd = + "defaults read ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure | awk -F'\"' '/http;/{print window[(NR)-1]}{window[NR]=$2}'"; + const result = CommonUtils.executeCommandSync(cmd).trim().toLowerCase(); + const isSafari = result.includes('safari') || result === ''; + return isSafari ? `wss://localhost:${port}` : `ws://localhost:${port}`; + } } diff --git a/test/unit/common/PreviewUtils.test.ts b/test/unit/common/PreviewUtils.test.ts index ae1e8b8..b7efe33 100644 --- a/test/unit/common/PreviewUtils.test.ts +++ b/test/unit/common/PreviewUtils.test.ts @@ -183,4 +183,39 @@ describe('Preview utils tests', () => { ); expect(bundlePath).to.be.equal('sample/path/to/app/bundle'); }); + + it('Generates correct websocket url', async () => { + // ensure that for iOS the proper url is generated + expect(PreviewUtils.generateWebSocketUrlForLocalDevServer('ios', '1234')).to.be.equal('wss://localhost:1234'); + + // ensure that for Android the proper url is generated + expect(PreviewUtils.generateWebSocketUrlForLocalDevServer('android', '1234')).to.be.equal( + 'wss://10.0.2.2:1234' + ); + + // ensure that for non-Mac desktop, the proper url is generated + let stub1 = $$.SANDBOX.stub(process, 'platform').value('win32'); // sinon.stub(process, 'platform').value('win32'); + expect(PreviewUtils.generateWebSocketUrlForLocalDevServer('desktop', '1234')).to.be.equal( + 'ws://localhost:1234' + ); + stub1.restore(); + + // ensure that for Mac desktop where Safari IS NOT default browser, the proper url is generated + stub1 = $$.SANDBOX.stub(process, 'platform').value('darwin'); + let stub2 = stubMethod($$.SANDBOX, CommonUtils, 'executeCommandSync').returns('com.google.chrome'); + expect(PreviewUtils.generateWebSocketUrlForLocalDevServer('desktop', '1234')).to.be.equal( + 'ws://localhost:1234' + ); + stub1.restore(); + stub2.restore(); + + // ensure that for Mac desktop where Safari IS default browser, the proper url is generated + stub1 = $$.SANDBOX.stub(process, 'platform').value('darwin'); + stub2 = stubMethod($$.SANDBOX, CommonUtils, 'executeCommandSync').returns('com.apple.safari'); + expect(PreviewUtils.generateWebSocketUrlForLocalDevServer('desktop', '1234')).to.be.equal( + 'wss://localhost:1234' + ); + stub1.restore(); + stub2.restore(); + }); });