diff --git a/src/iosDebug.ts b/src/iosDebug.ts index 838b033..0b249e0 100644 --- a/src/iosDebug.ts +++ b/src/iosDebug.ts @@ -1,8 +1,18 @@ /*--------------------------------------------------------- * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ - -import {ChromeDebugSession} from 'vscode-chrome-debug-core'; -import {IOSDebugSession} from './iosDebugSession'; -ChromeDebugSession.run(IOSDebugSession); \ No newline at end of file +import * as path from 'path'; +import {ChromeDebugSession, ChromeConnection, chromeTargetDiscoveryStrategy, logger} from 'vscode-chrome-debug-core'; +import {IOSDebugAdapter} from './iosDebugAdapter'; + +const targetFilter = target => target && (!target.type || target.type === 'page'); +const connection = new ChromeConnection(chromeTargetDiscoveryStrategy.getChromeTargetWebSocketURL, targetFilter); + +ChromeDebugSession.run(ChromeDebugSession.getSession({ + logFileDirectory: path.resolve(__dirname, '../../'), + targetFilter: targetFilter, + adapter: new IOSDebugAdapter(connection) +})); + +logger.log('debugger-for-ios-web: ' + require('../../package.json').version); \ No newline at end of file diff --git a/src/iosDebugAdapter.ts b/src/iosDebugAdapter.ts index 00cb98c..f3788fd 100644 --- a/src/iosDebugAdapter.ts +++ b/src/iosDebugAdapter.ts @@ -2,32 +2,33 @@ * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ -import {ChromeDebugAdapter, Utils, Logger} from 'vscode-chrome-debug-core'; -import * as iosUtils from './utilities'; import {spawn, ChildProcess} from 'child_process'; import * as Url from 'url'; import * as localtunnel from 'localtunnel'; + +import {ChromeDebugAdapter, utils, logger} from 'vscode-chrome-debug-core'; +import * as iosUtils from './utilities'; import {IProxySettings} from './iosDebugAdapterInterfaces'; export class IOSDebugAdapter extends ChromeDebugAdapter { private _proxyProc: ChildProcess; private _localTunnel: ILocalTunnelInfoObject; - - public constructor() { - super(); + + constructor(chromeConnection) { + super(chromeConnection) } - + public launch(args: any): Promise { if (args.port == null) { - return Utils.errP('The "port" field is required in the launch config.'); + return utils.errP('The "port" field is required in the launch config.'); } - this.initializeLogging('launch-ios', args); + super.setupLogging(args); // Process the launch arguments const settings = this._getProxySettings(args); if (typeof settings == "string") { - return Utils.errP(settings); + return utils.errP('Passed settings object is a string'); } let tunnelPort = args.tunnelPort || 0; @@ -35,20 +36,20 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { if (tunnelPort) { launchPromise = new Promise((resolve, reject) => { - Logger.log('Launching localtunnel against port ' + tunnelPort, Logger.LogLevel.Log); + logger.log('Launching localtunnel against port ' + tunnelPort); localtunnel(tunnelPort, (err: Error, tunnel: ILocalTunnelInfoObject) => { // Navigate the to the given tunneled url if (err) { - Logger.log('Failed to launch localtunnel.', Logger.LogLevel.Error); - return Utils.errP(err); + logger.error('Failed to launch localtunnel.'); + return utils.errP(err); } - Logger.log('Success.' + tunnelPort, Logger.LogLevel.Log); + logger.log('Success.' + tunnelPort); // Set the store member and listen for any errors this._localTunnel = tunnel; this._localTunnel.on('error', (err) => { - Logger.log('Tunneling proxy error: ' + err); + logger.log('Tunneling proxy error: ' + err); this.terminateSession(); }); @@ -70,22 +71,22 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { return this._spawnProxy(settings).then(() => { return launchPromise; }).then(url => { - Logger.log('Navigating to ' + url, Logger.LogLevel.Log); + logger.log('Navigating to ' + url); (this)._chromeConnection.sendMessage("Page.navigate", {url: url}); }); } public attach(args: any): Promise { if (args.port == null) { - return Utils.errP('The "port" field is required in the attach config.'); + return utils.errP('The "port" field is required in the attach config.'); } - this.initializeLogging('attach-ios', args); + super.setupLogging(args); // Process the attach arguments const settings = this._getProxySettings(args); if (typeof settings == "string") { - return Utils.errP(settings); + return utils.errP('Passed settings object is a string'); } return this._spawnProxy(settings); @@ -112,7 +113,7 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { // Check that the proxy exists const proxyPath = args.proxyExecutable || iosUtils.getProxyPath(); if (!proxyPath) { - if (Utils.getPlatform() != Utils.Platform.Windows) { + if (utils.getPlatform() != utils.Platform.Windows) { errorMessage = `No iOS proxy was found. Install an iOS proxy (https://github.com/google/ios-webkit-debug-proxy) and specify a valid 'proxyExecutable' path`; } else { errorMessage = `No iOS proxy was found. Run 'npm install -g vs-libimobile' and specify a valid 'proxyExecutable' path`; @@ -152,15 +153,15 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { private _spawnProxy(settings: IProxySettings): Promise { // Spawn the proxy with the specified settings - Logger.log(`spawn('${settings.proxyPath}', ${JSON.stringify(settings.proxyArgs) })`); + logger.log(`spawn('${settings.proxyPath}', ${JSON.stringify(settings.proxyArgs) })`); this._proxyProc = spawn(settings.proxyPath, settings.proxyArgs, { detached: true, stdio: ['ignore'] }); (this._proxyProc).unref(); this._proxyProc.on('error', (err) => { - Logger.log('device proxy error: ' + err); - Logger.log('Do you have the iTunes drivers installed?'); + logger.log('device proxy error: ' + err); + logger.log('Do you have the iTunes drivers installed?'); this.terminateSession(); }); @@ -175,7 +176,7 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { private _attachToDevice(proxyPort: number, deviceName: string): Promise { // Attach to a device over the proxy - return Utils.getURL(`http://localhost:${proxyPort}/json`).then(jsonResponse => { + return utils.getURL(`http://localhost:${proxyPort}/json`).then(jsonResponse => { let devicePort = proxyPort; try { @@ -187,7 +188,7 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { if (deviceName !== "*") { const matchingDevices = devices.filter(deviceInfo => deviceInfo.deviceName && deviceInfo.deviceName.toLowerCase() === deviceName.toLowerCase()); if (!matchingDevices.length) { - Logger.log(`Warning: Can't find a device with deviceName: ${deviceName}. Available devices: ${JSON.stringify(devices.map(d => d.deviceName))}`, Logger.LogLevel.Error); + logger.log(`Warning: Can't find a device with deviceName: ${deviceName}. Available devices: ${JSON.stringify(devices.map(d => d.deviceName))}`); } else { devices = matchingDevices; } @@ -195,7 +196,7 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { if (devices.length) { if (devices.length > 1 && deviceName !== "*") { - Logger.log(`Warning: Found more than one valid target device. Attaching to the first one. Available devices: ${JSON.stringify(devices.map(d => d.deviceName))}`, Logger.LogLevel.Error); + logger.log(`Warning: Found more than one valid target device. Attaching to the first one. Available devices: ${JSON.stringify(devices.map(d => d.deviceName))}`); } // Get the port for the actual device endpoint @@ -216,7 +217,7 @@ export class IOSDebugAdapter extends ChromeDebugAdapter { return devicePort; }, e => { - return Utils.errP('Cannot connect to the proxy: ' + e.message); + return utils.errP('Cannot connect to the proxy: ' + e.message); }); } } diff --git a/src/iosDebugSession.ts b/src/iosDebugSession.ts deleted file mode 100644 index 72181e4..0000000 --- a/src/iosDebugSession.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - -import {ChromeDebugSession, Logger} from 'vscode-chrome-debug-core'; -import {IOSDebugAdapter} from './iosDebugAdapter'; - -export class IOSDebugSession extends ChromeDebugSession { - - public constructor(targetLinesStartAt1: boolean, isServer: boolean = false) { - let version = "iOS." + require('../../package.json').version; - Logger.log(version); - super(targetLinesStartAt1, isServer, new IOSDebugAdapter()); - } -} diff --git a/src/utilities.ts b/src/utilities.ts index 9e292a6..ad5220d 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -2,14 +2,14 @@ * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ -import {Utils} from 'vscode-chrome-debug-core'; +import { utils } from 'vscode-chrome-debug-core'; import * as path from 'path'; export function getProxyPath(): string { - const platform = Utils.getPlatform(); - if (platform === Utils.Platform.Windows) { + const platform = utils.getPlatform(); + if (platform === utils.Platform.Windows) { var proxy = path.resolve(__dirname, "../../node_modules/vs-libimobile/lib/ios_webkit_debug_proxy.exe"); - if (Utils.existsSync(proxy)) { + if (utils.existsSync(proxy)) { return proxy; } } diff --git a/test/iosDebugAdapter.test.ts b/test/iosDebugAdapter.test.ts index 7de6c73..a29f659 100644 --- a/test/iosDebugAdapter.test.ts +++ b/test/iosDebugAdapter.test.ts @@ -5,16 +5,20 @@ import * as mockery from 'mockery'; import * as assert from 'assert'; import * as sinon from 'sinon'; -import {Utils, ChromeDebugAdapter, Logger} from 'vscode-chrome-debug-core'; +import {utils, ChromeDebugAdapter, ChromeConnection, chromeTargetDiscoveryStrategy, logger} from 'vscode-chrome-debug-core'; /** Not mocked - use for type only */ import {IOSDebugAdapter as _IOSDebugAdapter} from '../src/iosDebugAdapter'; const MODULE_UNDER_TEST = '../src/iosDebugAdapter'; suite('IOSDebugAdapter', () => { + function createAdapter(): _IOSDebugAdapter { const IOSDebugAdapter: typeof _IOSDebugAdapter = require(MODULE_UNDER_TEST).IOSDebugAdapter; - return new IOSDebugAdapter(); + const targetFilter = target => target && (!target.type || target.type === 'page'); + const connection = new ChromeConnection(chromeTargetDiscoveryStrategy.getChromeTargetWebSocketURL, targetFilter); + + return new IOSDebugAdapter(connection); }; setup(() => { @@ -44,8 +48,8 @@ suite('IOSDebugAdapter', () => { test('if no port, rejects the launch promise', done => { mockery.registerMock('vscode-chrome-debug-core', { ChromeDebugAdapter: () => { }, - Utils: Utils, - Logger: Logger + utils: utils, + logger: logger }); const adapter = createAdapter(); @@ -85,13 +89,13 @@ suite('IOSDebugAdapter', () => { mockery.registerMock('vscode-chrome-debug-core', { ChromeDebugAdapter: MockAdapter, - Utils: MockUtilities, - Logger: Logger + utils: MockUtilities, + logger: logger }); mockery.registerMock('child_process', MockChildProcess); adapterMock = sinon.mock(MockAdapter.prototype); - adapterMock.expects('initializeLogging').once(); + adapterMock.expects('setupLogging').once(); adapterMock.expects('attach').returns(Promise.resolve('')); chromeConnectionMock = sinon.mock(MockChromeConnection); @@ -206,8 +210,8 @@ suite('IOSDebugAdapter', () => { test('if no port, rejects the attach promise', done => { mockery.registerMock('vscode-chrome-debug-core', { ChromeDebugAdapter: () => { }, - Utils: Utils, - Logger: Logger + utils: utils, + logger: logger }); const adapter = createAdapter(); @@ -232,13 +236,13 @@ suite('IOSDebugAdapter', () => { mockery.registerMock('vscode-chrome-debug-core', { ChromeDebugAdapter: MockAdapter, - Utils: MockUtilities, - Logger: Logger + utils: MockUtilities, + logger: logger }); mockery.registerMock('child_process', MockChildProcess); adapterMock = sinon.mock(MockAdapter.prototype); - adapterMock.expects('initializeLogging').once(); + adapterMock.expects('setupLogging').once(); utilitiesMock = sinon.mock(MockUtilities); sinon.stub(MockUtilities, 'errP', () => Promise.reject('')); @@ -326,13 +330,13 @@ suite('IOSDebugAdapter', () => { mockery.registerMock('vscode-chrome-debug-core', { ChromeDebugAdapter: MockAdapter, - Utils: MockUtilities, - Logger: Logger + utils: MockUtilities, + logger: logger }); mockery.registerMock('child_process', MockChildProcess); adapterMock = sinon.mock(MockAdapter.prototype); - adapterMock.expects('initializeLogging').once(); + adapterMock.expects('setupLogging').once(); utilitiesMock = sinon.mock(MockUtilities); diff --git a/test/utilities.test.ts b/test/utilities.test.ts index d281b20..7a45ccb 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -4,7 +4,7 @@ import * as mockery from 'mockery'; import * as assert from 'assert'; -import {Utils} from 'vscode-chrome-debug-core'; +import { utils } from 'vscode-chrome-debug-core'; /** Not mocked - use for type only */ import * as _Utilities from '../src/utilities'; @@ -28,9 +28,9 @@ suite('Utilities', () => { suite('getProxyPath()', () => { test('if windows and path exists, returns correct path', () => { mockery.registerMock('vscode-chrome-debug-core', { - Utils: { + utils: { Platform: { Windows: 0, OSX: 1, Linux: 2 }, - getPlatform: () => Utils.Platform.Windows, + getPlatform: () => utils.Platform.Windows, existsSync: () => true } }); @@ -45,9 +45,9 @@ suite('Utilities', () => { test('if windows and path not found, returns null', () => { mockery.registerMock('vscode-chrome-debug-core', { - Utils: { + utils: { Platform: { Windows: 0, OSX: 1, Linux: 2 }, - getPlatform: () => Utils.Platform.Windows, + getPlatform: () => utils.Platform.Windows, existsSync: () => false } }); @@ -62,9 +62,9 @@ suite('Utilities', () => { test('if osx, returns null', () => { mockery.registerMock('vscode-chrome-debug-core', { - Utils: { + utils: { Platform: { Windows: 0, OSX: 1, Linux: 2 }, - getPlatform: () => Utils.Platform.OSX + getPlatform: () => utils.Platform.OSX } }); mockery.registerMock('path', {}); @@ -75,9 +75,9 @@ suite('Utilities', () => { test('if linux, returns null', () => { mockery.registerMock('vscode-chrome-debug-core', { - Utils: { + utils: { Platform: { Windows: 0, OSX: 1, Linux: 2 }, - getPlatform: () => Utils.Platform.Linux + getPlatform: () => utils.Platform.Linux } }); mockery.registerMock('path', {});