Skip to content

Add option to use chrome-devtools fronted from appspot #3071

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 21, 2017
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
18 changes: 17 additions & 1 deletion PublicAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,25 @@ interface IDebugData {
*/
interface IDebugOptions {
/**
* Defines if bundled Chrome DevTools should be used or specific commit. Valid for iOS only.
* Defines if bundled Chrome DevTools should be used or specific commit.
* Default value is true for Android and false for iOS.
*/
useBundledDevTools?: boolean;

/**
* Defines if https://chrome-devtools-frontend.appspot.com should be used instead of chrome-devtools://devtools
* In case it is passed, the value of `useBundledDevTools` is disregarded.
* Default value is false.
*/
useHttpUrl?: boolean;

/**
* Defines the commit that will be used in cases where remote protocol is required.
* For Android this is the case when useHttpUrl is set to true or useBundledDevTools is set to false.
* For iOS the value is used by default and when useHttpUrl is set to true.
* Default value is 02e6bde1bbe34e43b309d4ef774b1168d25fd024 which corresponds to 55.0.2883 Chrome version
*/
devToolsCommit?: string;
}
```

Expand Down
18 changes: 17 additions & 1 deletion lib/definitions/debug.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,25 @@ interface IDebugOptions {
justlaunch?: boolean;

/**
* Defines if bundled Chrome DevTools should be used or specific commit. Valid for iOS only.
* Defines if bundled Chrome DevTools should be used or specific commit.
* Default value is true for Android and false for iOS.
*/
useBundledDevTools?: boolean;

/**
* Defines if https://chrome-devtools-frontend.appspot.com should be used instead of chrome-devtools://devtools
* In case it is passed, the value of `useBundledDevTools` is disregarded.
* Default value is false.
*/
useHttpUrl?: boolean;

/**
* Defines the commit that will be used in cases where remote protocol is required.
* For Android this is the case when useHttpUrl is set to true or useBundledDevTools is set to false.
* For iOS the value is used by default and when useHttpUrl is set to true.
* Default value is 02e6bde1bbe34e43b309d4ef774b1168d25fd024 which corresponds to 55.0.2883 Chrome version
*/
devToolsCommit?: string;
}

/**
Expand Down
17 changes: 13 additions & 4 deletions lib/services/android-debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { sleep } from "../common/helpers";
import { ChildProcess } from "child_process";
import { DebugServiceBase } from "./debug-service-base";

class AndroidDebugService extends DebugServiceBase implements IPlatformDebugService {
export class AndroidDebugService extends DebugServiceBase implements IPlatformDebugService {
private _device: Mobile.IAndroidDevice = null;
private _debuggerClientProcess: ChildProcess;

Expand Down Expand Up @@ -49,6 +49,14 @@ class AndroidDebugService extends DebugServiceBase implements IPlatformDebugServ
return;
}

protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
const debugOpts = _.cloneDeep(debugOptions);
debugOpts.useBundledDevTools = debugOpts.useBundledDevTools === undefined ? true : debugOpts.useBundledDevTools;

const chromeDebugUrl = super.getChromeDebugUrl(debugOpts, port);
return chromeDebugUrl;
}

private async debugOnEmulator(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string> {
// Assure we've detected the emulator as device
// For example in case deployOnEmulator had stated new emulator instance
Expand Down Expand Up @@ -124,11 +132,12 @@ class AndroidDebugService extends DebugServiceBase implements IPlatformDebugServ
this.$errors.failWithoutHelp(`The application ${packageName} does not appear to be running on ${deviceId} or is not built with debugging enabled.`);
}

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

let port = await this.getForwardedLocalDebugPortForPackageName(deviceId, packageName);
return `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${port}`;
const port = await this.getForwardedLocalDebugPortForPackageName(deviceId, packageName);

return this.getChromeDebugUrl(debugOptions, port);
}

private detachDebugger(packageName: string): Promise<void> {
Expand Down
19 changes: 19 additions & 0 deletions lib/services/debug-service-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,23 @@ export abstract class DebugServiceBase extends EventEmitter implements IPlatform
}
};
}

protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
// corresponds to 55.0.2883 Chrome version
const commitSHA = debugOptions.devToolsCommit || "02e6bde1bbe34e43b309d4ef774b1168d25fd024";
debugOptions.useHttpUrl = debugOptions.useHttpUrl === undefined ? false : debugOptions.useHttpUrl;

let chromeDevToolsPrefix = `chrome-devtools://devtools/remote/serve_file/@${commitSHA}`;

if (debugOptions.useBundledDevTools) {
chromeDevToolsPrefix = "chrome-devtools://devtools/bundled";
}

if (debugOptions.useHttpUrl) {
chromeDevToolsPrefix = `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitSHA}`;
}

const chromeUrl = `${chromeDevToolsPrefix}/inspector.html?experiments=true&ws=localhost:${port}`;
return chromeUrl;
}
}
22 changes: 10 additions & 12 deletions lib/services/ios-debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const inspectorAppName = "NativeScript Inspector.app";
const inspectorNpmPackageName = "tns-ios-inspector";
const inspectorUiDir = "WebInspectorUI/";

class IOSDebugService extends DebugServiceBase implements IPlatformDebugService {
export class IOSDebugService extends DebugServiceBase implements IPlatformDebugService {
private _lldbProcess: ChildProcess;
private _sockets: net.Socket[] = [];
private _childProcess: ChildProcess;
Expand Down Expand Up @@ -93,6 +93,14 @@ class IOSDebugService extends DebugServiceBase implements IPlatformDebugService
}
}

protected getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
const debugOpts = _.cloneDeep(debugOptions);
debugOpts.useBundledDevTools = debugOpts.useBundledDevTools === undefined ? false : debugOpts.useBundledDevTools;

const chromeDebugUrl = super.getChromeDebugUrl(debugOpts, port);
return chromeDebugUrl;
}

private async killProcess(childProcess: ChildProcess): Promise<void> {
if (childProcess) {
return new Promise<void>((resolve, reject) => {
Expand Down Expand Up @@ -195,17 +203,7 @@ class IOSDebugService extends DebugServiceBase implements IPlatformDebugService
if (debugOptions.chrome) {
this._socketProxy = await this.$socketProxyFactory.createWebSocketProxy(this.getSocketFactory(device));

let chromeDevToolsPrefix = `chrome-devtools://devtools/`;

if (debugOptions.useBundledDevTools) {
chromeDevToolsPrefix += "bundled";
} else {
// corresponds to 55.0.2883 Chrome version
const commitSHA = "02e6bde1bbe34e43b309d4ef774b1168d25fd024";
chromeDevToolsPrefix += `remote/serve_file/@${commitSHA}`;
}

return `${chromeDevToolsPrefix}/inspector.html?experiments=true&ws=localhost:${this._socketProxy.options.port}`;
return this.getChromeDebugUrl(debugOptions, this._socketProxy.options.port);
} else {
this._socketProxy = await this.$socketProxyFactory.createTCPSocketProxy(this.getSocketFactory(device));
await this.openAppInspector(this._socketProxy.address(), debugData, debugOptions);
Expand Down
162 changes: 162 additions & 0 deletions test/services/android-debug-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { AndroidDebugService } from "../../lib/services/android-debug-service";
import { Yok } from "../../lib/common/yok";
import * as stubs from "../stubs";
import { assert } from "chai";

const expectedDevToolsCommitSha = "02e6bde1bbe34e43b309d4ef774b1168d25fd024";

class AndroidDebugServiceInheritor extends AndroidDebugService {
constructor(protected $devicesService: Mobile.IDevicesService,
$errors: IErrors,
$logger: ILogger,
$config: IConfiguration,
$androidDeviceDiscovery: Mobile.IDeviceDiscovery,
$androidProcessService: Mobile.IAndroidProcessService,
$net: INet) {
super($devicesService, $errors, $logger, $config, $androidDeviceDiscovery, $androidProcessService, $net);
}

public getChromeDebugUrl(debugOptions: IDebugOptions, port: number): string {
return super.getChromeDebugUrl(debugOptions, port);
}
}

const createTestInjector = (): IInjector => {
const testInjector = new Yok();
testInjector.register("devicesService", {});
testInjector.register("errors", stubs.ErrorsStub);
testInjector.register("logger", stubs.LoggerStub);
testInjector.register("config", {});
testInjector.register("androidDeviceDiscovery", {});
testInjector.register("androidProcessService", {});
testInjector.register("net", {});

return testInjector;
};

interface IChromeUrlTestCase {
debugOptions: IDebugOptions;
expectedChromeUrl: string;
scenarioName: string;
}

describe("androidDebugService", () => {
describe("getChromeDebugUrl", () => {
const expectedPort = 12345;
const customDevToolsCommit = "customDevToolsCommit";

const chromUrlTestCases: IChromeUrlTestCase[] = [
// Default CLI behavior:
{
scenarioName: "useBundledDevTools and useHttpUrl are not passed",
debugOptions: {},
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},

// When useBundledDevTools is true
{
scenarioName: "useBundledDevTools is true and useHttpUrl is not passed",
debugOptions: {
useBundledDevTools: true
},
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "useBundledDevTools is true and useHttpUrl is false",
debugOptions: {
useBundledDevTools: true,
useHttpUrl: false
},
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "useBundledDevTools is true and useHttpUrl is true",
debugOptions: {
useBundledDevTools: true,
useHttpUrl: true
},
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},

// When useBundledDevTools is false
{
scenarioName: "useBundledDevTools is false and useHttpUrl is not passed",
debugOptions: {
useBundledDevTools: false
},
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "useBundledDevTools is false and useHttpUrl is false",
debugOptions: {
useBundledDevTools: false,
useHttpUrl: false
},
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "useBundledDevTools is false and useHttpUrl is true",
debugOptions: {
useBundledDevTools: false,
useHttpUrl: true
},
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},

// When useBundledDevTools is not passed
{
scenarioName: "useBundledDevTools is not passed and useHttpUrl is false",
debugOptions: {
useHttpUrl: false
},
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "useBundledDevTools is not passed and useHttpUrl is true",
debugOptions: {
useHttpUrl: true
},
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},

// devToolsCommit tests
{
scenarioName: "devToolsCommit defaults to ${expectedDevToolsCommitSha} when useBundledDevTools is set to false",
debugOptions: {
useBundledDevTools: false
},
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@${expectedDevToolsCommitSha}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "devToolsCommit is disregarded when useBundledDevTools is not passed",
debugOptions: {},
expectedChromeUrl: `chrome-devtools://devtools/bundled/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "devToolsCommit is set to passed value when useBundledDevTools is set to false",
debugOptions: {
useBundledDevTools: false,
devToolsCommit: customDevToolsCommit
},
expectedChromeUrl: `chrome-devtools://devtools/remote/serve_file/@${customDevToolsCommit}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
},
{
scenarioName: "devToolsCommit is set to passed value when useHttpUrl is set to true",
debugOptions: {
useHttpUrl: true,
devToolsCommit: customDevToolsCommit
},
expectedChromeUrl: `https://chrome-devtools-frontend.appspot.com/serve_file/@${customDevToolsCommit}/inspector.html?experiments=true&ws=localhost:${expectedPort}`,
}
];

for (const testCase of chromUrlTestCases) {
it(`returns correct url when ${testCase.scenarioName}`, () => {
const testInjector = createTestInjector();
const androidDebugService = testInjector.resolve<AndroidDebugServiceInheritor>(AndroidDebugServiceInheritor);
const actualChromeUrl = androidDebugService.getChromeDebugUrl(testCase.debugOptions, expectedPort);
assert.equal(actualChromeUrl, testCase.expectedChromeUrl);
});
}
});
});
Loading