Skip to content

Commit 110b975

Browse files
Add option to use chrome-devtools fronted from appspot
URLs starting with `chrome-devtools://devtools/` cannot be opened in chrome with code. However, we can open the urls in https://chrome-devtools-frontend.appspot.com/, so add new option in Public API that allows using the remote version. Keep the current default behavior, i.e. for Android we are using the `bundled` DevTools, for iOS we are using a commit pointing to Chrome 55. In case both `useBundledDevTools` and `useHttpUrl` are passed, the value of `useBundledDevTools` is disregarded. Add unit tests for all of the cases.
1 parent f99762c commit 110b975

File tree

7 files changed

+334
-18
lines changed

7 files changed

+334
-18
lines changed

PublicAPI.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,17 @@ interface IDebugData {
496496
*/
497497
interface IDebugOptions {
498498
/**
499-
* Defines if bundled Chrome DevTools should be used or specific commit. Valid for iOS only.
499+
* Defines if bundled Chrome DevTools should be used or specific commit.
500+
* Default value is true for Android and false for iOS.
500501
*/
501502
useBundledDevTools?: boolean;
503+
504+
/**
505+
* Defines if https://chrome-devtools-frontend.appspot.com should be used instead of chrome-devtools://devtools
506+
* In case it is passed, the value of `useBundledDevTools` is disregarded.
507+
* Default value is false.
508+
*/
509+
useHttpUrl?: boolean;
502510
}
503511
```
504512

lib/definitions/debug.d.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,17 @@ interface IDebugOptions {
6868
justlaunch?: boolean;
6969

7070
/**
71-
* Defines if bundled Chrome DevTools should be used or specific commit. Valid for iOS only.
71+
* Defines if bundled Chrome DevTools should be used or specific commit.
72+
* Default value is true for Android and false for iOS.
7273
*/
7374
useBundledDevTools?: boolean;
75+
76+
/**
77+
* Defines if https://chrome-devtools-frontend.appspot.com should be used instead of chrome-devtools://devtools
78+
* In case it is passed, the value of `useBundledDevTools` is disregarded.
79+
* Default value is false.
80+
*/
81+
useHttpUrl?: boolean;
7482
}
7583

7684
/**

lib/services/android-debug-service.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { sleep } from "../common/helpers";
22
import { ChildProcess } from "child_process";
33
import { DebugServiceBase } from "./debug-service-base";
44

5-
class AndroidDebugService extends DebugServiceBase implements IPlatformDebugService {
5+
export class AndroidDebugService extends DebugServiceBase implements IPlatformDebugService {
66
private _device: Mobile.IAndroidDevice = null;
77
private _debuggerClientProcess: ChildProcess;
88

@@ -49,6 +49,15 @@ class AndroidDebugService extends DebugServiceBase implements IPlatformDebugServ
4949
return;
5050
}
5151

52+
protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
53+
const debugOpts = _.cloneDeep(debugOptions);
54+
debugOpts.useBundledDevTools = debugOpts.useBundledDevTools === undefined ? true : debugOpts.useBundledDevTools;
55+
debugOpts.useHttpUrl = debugOpts.useHttpUrl === undefined ? false : debugOpts.useHttpUrl;
56+
57+
const chromeDebugUrl = super.getChromeDebugUrl(debugOpts, port);
58+
return chromeDebugUrl;
59+
}
60+
5261
private async debugOnEmulator(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
5362
// Assure we've detected the emulator as device
5463
// For example in case deployOnEmulator had stated new emulator instance
@@ -124,11 +133,12 @@ class AndroidDebugService extends DebugServiceBase implements IPlatformDebugServ
124133
this.$errors.failWithoutHelp(`The application ${packageName} does not appear to be running on ${deviceId} or is not built with debugging enabled.`);
125134
}
126135

127-
let startDebuggerCommand = ["am", "broadcast", "-a", `\"${packageName}-debug\"`, "--ez", "enable", "true"];
136+
const startDebuggerCommand = ["am", "broadcast", "-a", `\"${packageName}-debug\"`, "--ez", "enable", "true"];
128137
await this.device.adb.executeShellCommand(startDebuggerCommand);
129138

130-
let port = await this.getForwardedLocalDebugPortForPackageName(deviceId, packageName);
131-
return `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${port}`;
139+
const port = await this.getForwardedLocalDebugPortForPackageName(deviceId, packageName);
140+
141+
return this.getChromeDebugUrl(debugOptions, port);
132142
}
133143

134144
private detachDebugger(packageName: string): Promise<void> {

lib/services/debug-service-base.ts

+17
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,21 @@ export abstract class DebugServiceBase extends EventEmitter implements IPlatform
2626
}
2727
};
2828
}
29+
30+
protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
31+
// corresponds to 55.0.2883 Chrome version
32+
const commitSHA = "02e6bde1bbe34e43b309d4ef774b1168d25fd024";
33+
let chromeDevToolsPrefix = `chrome-devtools://devtools/remote/serve_file/@${commitSHA}`;
34+
35+
if (debugOptions.useBundledDevTools) {
36+
chromeDevToolsPrefix = "chrome-devtools://devtools/bundled";
37+
}
38+
39+
if (debugOptions.useHttpUrl) {
40+
chromeDevToolsPrefix = `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitSHA}`;
41+
}
42+
43+
const chromeUrl = `${chromeDevToolsPrefix}/inspector.html?experiments=true&ws=localhost:${port}`;
44+
return chromeUrl;
45+
}
2946
}

lib/services/ios-debug-service.ts

+11-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const inspectorAppName = "NativeScript Inspector.app";
1414
const inspectorNpmPackageName = "tns-ios-inspector";
1515
const inspectorUiDir = "WebInspectorUI/";
1616

17-
class IOSDebugService extends DebugServiceBase implements IPlatformDebugService {
17+
export class IOSDebugService extends DebugServiceBase implements IPlatformDebugService {
1818
private _lldbProcess: ChildProcess;
1919
private _sockets: net.Socket[] = [];
2020
private _childProcess: ChildProcess;
@@ -93,6 +93,15 @@ class IOSDebugService extends DebugServiceBase implements IPlatformDebugService
9393
}
9494
}
9595

96+
protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
97+
const debugOpts = _.cloneDeep(debugOptions);
98+
debugOpts.useBundledDevTools = debugOpts.useBundledDevTools === undefined ? false : debugOpts.useBundledDevTools;
99+
debugOpts.useHttpUrl = debugOpts.useHttpUrl === undefined ? false : debugOpts.useHttpUrl;
100+
101+
const chromeDebugUrl = super.getChromeDebugUrl(debugOpts, port);
102+
return chromeDebugUrl;
103+
}
104+
96105
private async killProcess(childProcess: ChildProcess): Promise<void> {
97106
if (childProcess) {
98107
return new Promise<void>((resolve, reject) => {
@@ -195,17 +204,7 @@ class IOSDebugService extends DebugServiceBase implements IPlatformDebugService
195204
if (debugOptions.chrome) {
196205
this._socketProxy = await this.$socketProxyFactory.createWebSocketProxy(this.getSocketFactory(device));
197206

198-
let chromeDevToolsPrefix = `chrome-devtools://devtools/`;
199-
200-
if (debugOptions.useBundledDevTools) {
201-
chromeDevToolsPrefix += "bundled";
202-
} else {
203-
// corresponds to 55.0.2883 Chrome version
204-
const commitSHA = "02e6bde1bbe34e43b309d4ef774b1168d25fd024";
205-
chromeDevToolsPrefix += `remote/serve_file/@${commitSHA}`;
206-
}
207-
208-
return `${chromeDevToolsPrefix}/inspector.html?experiments=true&ws=localhost:${this._socketProxy.options.port}`;
207+
return this.getChromeDebugUrl(debugOptions, this._socketProxy.options.port);
209208
} else {
210209
this._socketProxy = await this.$socketProxyFactory.createTCPSocketProxy(this.getSocketFactory(device));
211210
await this.openAppInspector(this._socketProxy.address(), debugData, debugOptions);
+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { AndroidDebugService } from "../../lib/services/android-debug-service";
2+
import { Yok } from "../../lib/common/yok";
3+
import * as stubs from "../stubs";
4+
import { assert } from "chai";
5+
6+
class AndroidDebugServiceInheritor extends AndroidDebugService {
7+
constructor(protected $devicesService: Mobile.IDevicesService,
8+
$errors: IErrors,
9+
$logger: ILogger,
10+
$config: IConfiguration,
11+
$androidDeviceDiscovery: Mobile.IDeviceDiscovery,
12+
$androidProcessService: Mobile.IAndroidProcessService,
13+
$net: INet) {
14+
super($devicesService, $errors, $logger, $config, $androidDeviceDiscovery, $androidProcessService, $net);
15+
}
16+
17+
public getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
18+
return super.getChromeDebugUrl(debugOptions, port);
19+
}
20+
}
21+
22+
const createTestInjector = (): IInjector => {
23+
const testInjector = new Yok();
24+
testInjector.register("devicesService", {});
25+
testInjector.register("errors", stubs.ErrorsStub);
26+
testInjector.register("logger", stubs.LoggerStub);
27+
testInjector.register("config", {});
28+
testInjector.register("androidDeviceDiscovery", {});
29+
testInjector.register("androidProcessService", {});
30+
testInjector.register("net", {});
31+
32+
return testInjector;
33+
};
34+
35+
interface IChromeUrlTestCase {
36+
debugOptions: IDebugOptions;
37+
expectedChromeUrl: string;
38+
scenarioName: string;
39+
}
40+
41+
describe("androidDebugService", () => {
42+
describe("getChromeDebugUrl", () => {
43+
const expectedPort = 12345;
44+
const chromUrlTestCases: IChromeUrlTestCase[] = [
45+
// Default CLI behavior:
46+
{
47+
scenarioName: "useBundledDevTools and useHttpUrl are not passed",
48+
debugOptions: {},
49+
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
50+
},
51+
52+
// When useBundledDevTools is true
53+
{
54+
scenarioName: "useBundledDevTools is true and useHttpUrl is not passed",
55+
debugOptions: {
56+
useBundledDevTools: true
57+
},
58+
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
59+
},
60+
{
61+
scenarioName: "useBundledDevTools is true and useHttpUrl is false",
62+
debugOptions: {
63+
useBundledDevTools: true,
64+
useHttpUrl: false
65+
},
66+
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
67+
},
68+
{
69+
scenarioName: "useBundledDevTools is true and useHttpUrl is true",
70+
debugOptions: {
71+
useBundledDevTools: true,
72+
useHttpUrl: true
73+
},
74+
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@02e6bde1bbe34e43b309d4ef774b1168d25fd024/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
75+
},
76+
77+
// When useBundledDevTools is false
78+
{
79+
scenarioName: "useBundledDevTools is false and useHttpUrl is not passed",
80+
debugOptions: {
81+
useBundledDevTools: false
82+
},
83+
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@02e6bde1bbe34e43b309d4ef774b1168d25fd024/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
84+
},
85+
{
86+
scenarioName: "useBundledDevTools is false and useHttpUrl is false",
87+
debugOptions: {
88+
useBundledDevTools: false,
89+
useHttpUrl: false
90+
},
91+
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@02e6bde1bbe34e43b309d4ef774b1168d25fd024/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
92+
},
93+
{
94+
scenarioName: "useBundledDevTools is false and useHttpUrl is true",
95+
debugOptions: {
96+
useBundledDevTools: false,
97+
useHttpUrl: true
98+
},
99+
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@02e6bde1bbe34e43b309d4ef774b1168d25fd024/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
100+
},
101+
102+
// When useBundledDevTools is not passed
103+
{
104+
scenarioName: "useBundledDevTools is not passed and useHttpUrl is false",
105+
debugOptions: {
106+
useHttpUrl: false
107+
},
108+
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
109+
},
110+
{
111+
scenarioName: "useBundledDevTools is not passed and useHttpUrl is true",
112+
debugOptions: {
113+
useHttpUrl: true
114+
},
115+
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@02e6bde1bbe34e43b309d4ef774b1168d25fd024/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
116+
}
117+
118+
];
119+
120+
for (const testCase of chromUrlTestCases) {
121+
it(`returns correct url when ${testCase.scenarioName}`, () => {
122+
const testInjector = createTestInjector();
123+
const androidDebugService = testInjector.resolve<AndroidDebugServiceInheritor>(AndroidDebugServiceInheritor);
124+
const actualChromeUrl = androidDebugService.getChromeDebugUrl(testCase.debugOptions, expectedPort);
125+
assert.equal(actualChromeUrl, testCase.expectedChromeUrl);
126+
});
127+
}
128+
});
129+
});

0 commit comments

Comments
 (0)