microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
678db279088f7b3fd6c7888d37be778e758ff688

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

test/debugger/android/androidPlatform.test.ts

287lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as Q from "q";
5import * as fs from "fs";
6import * as path from "path";
7import * as mockFs from "mock-fs";
8
9import {AndroidPlatform} from "../../../src/common/android/androidPlatform";
10import {IAndroidRunOptions} from "../../../src/common/launchArgs";
11import {FileSystem} from "../../../src/common/node/fileSystem";
12import {ReactNative022} from "../../resources/reactNative022";
13import {AdbSimulator} from "../../resources/simulators/adbSimulator";
14import {AVDManager} from "../../resources/simulators/avdManager";
15import {FakeExtensionMessageSender} from "../../resources/fakeExtensionMessageSender";
16import {ExtensionMessage} from "../../../src/common/extensionMessaging";
17import {RecordingsHelper} from "../../resources/recordingsHelper";
18import {RemoteExtension} from "../../../src/common/remoteExtension";
19
20import "should";
21
22// TODO: Launch the extension server
23
24suite("androidPlatform", function () {
25 suite("debuggerContext", function () {
26 const projectRoot = "C:/projects/SampleApplication_21/";
27 const androidProjectPath = path.join(projectRoot, "android");
28 const applicationName = "SampleApplication";
29 const androidPackageName = "com.sampleapplication";
30 const genericRunOptions: IAndroidRunOptions = { platform: "android", projectRoot: projectRoot };
31
32 const rnProjectContent = fs.readFileSync(ReactNative022.DEFAULT_PROJECT_FILE, "utf8");
33
34 let fileSystem: FileSystem;
35 let adb: AdbSimulator;
36 let simulatedAVDManager: AVDManager;
37 let reactNative: ReactNative022;
38 let fakeExtensionMessageSender: FakeExtensionMessageSender;
39 let androidPlatform: AndroidPlatform;
40
41 function createAndroidPlatform(runOptions: IAndroidRunOptions): AndroidPlatform {
42 return new AndroidPlatform(runOptions, {
43 adb: adb,
44 reactNative: reactNative,
45 fileSystem: fileSystem,
46 remoteExtension: new RemoteExtension(fakeExtensionMessageSender),
47 });
48 }
49
50 function shouldHaveReceivedSingleLogCatMessage(deviceId: string): void {
51 const expectedMessage = { message: ExtensionMessage.START_MONITORING_LOGCAT, args: [deviceId] };
52
53 const messagesSent = fakeExtensionMessageSender.getAllMessagesSent();
54 const messagesWithoutUndefineds = messagesSent.map(message => {
55 return {
56 message: message.message,
57 args: message.args && message.args.filter(value => value) || [],
58 };
59 });
60 messagesWithoutUndefineds.should.eql([expectedMessage]);
61 }
62
63 function shouldHaveReceivedNoLogCatMessages(): void {
64 fakeExtensionMessageSender.getAllMessagesSent().should.eql([]);
65 }
66
67 setup(() => {
68 mockFs();
69
70 // Configure all the dependencies we'll use in our tests
71 fileSystem = new FileSystem();
72 adb = new AdbSimulator(fileSystem);
73 simulatedAVDManager = new AVDManager(adb);
74 reactNative = new ReactNative022(adb, fileSystem);
75 fakeExtensionMessageSender = new FakeExtensionMessageSender();
76 androidPlatform = createAndroidPlatform(genericRunOptions);
77
78 // Create a React-Native project we'll use in our tests
79 return reactNative
80 .fromProjectFileContent(rnProjectContent)
81 .createProject(projectRoot, applicationName);
82 });
83
84 teardown(() => {
85 mockFs.restore();
86 });
87
88 const testWithRecordings = new RecordingsHelper(() => reactNative).test;
89
90 testWithRecordings("runApp launches the app when a single emulator is connected",
91 [
92 "react-native/run-android/win10-rn0.21.0/succeedsWithOneVSEmulator",
93 "react-native/run-android/win10-rn0.22.2/succeedsWithOneVSEmulator",
94 "react-native/run-android/osx10.10-rn0.21.0/succeedsWithOneVSEmulator",
95 ], () => {
96 return Q({})
97 .then(() => {
98 return simulatedAVDManager.createAndLaunch("Nexus_5");
99 }).then(() => {
100 return androidPlatform.runApp();
101 }).then(() => {
102 return adb.isAppRunning(androidPackageName);
103 }).then(isRunning => {
104 isRunning.should.be.true();
105 shouldHaveReceivedSingleLogCatMessage("Nexus_5");
106 });
107 });
108
109 testWithRecordings("runApp launches the app when two emulators are connected",
110 ["react-native/run-android/win10-rn0.21.0/succeedsWithTwoVSEmulators"], () => {
111 return Q({})
112 .then(() => {
113 return simulatedAVDManager.createAndLaunchAll(["Nexus_5", "Nexus_6"]);
114 }).then(() => {
115 return androidPlatform.runApp();
116 }).then(() => {
117 return Q.all([
118 adb.isAppRunning(androidPackageName, "Nexus_5"),
119 adb.isAppRunning(androidPackageName, "Nexus_6"),
120 ]);
121 }).spread((isRunningOnNexus5, isRunningOnNexus6) => {
122 // It should be running in exactly one of these two devices
123 isRunningOnNexus5.should.not.eql(isRunningOnNexus6);
124 const emulatorWithAppRunningId = isRunningOnNexus5 ? "Nexus_5" : "Nexus_6";
125 shouldHaveReceivedSingleLogCatMessage(emulatorWithAppRunningId);
126 });
127 });
128
129 testWithRecordings("runApp launches the app when three emulators are connected",
130 ["react-native/run-android/win10-rn0.21.0/succeedsWithThreeVSEmulators"], () => {
131 const devicesIds = ["Nexus_5", "Nexus_6", "Other_Nexus_6"];
132 return Q({})
133 .then(() => {
134 return simulatedAVDManager.createAndLaunchAll(devicesIds);
135 }).then(() => {
136 return androidPlatform.runApp();
137 }).then(() => {
138 return Q.all([
139 adb.isAppRunning(androidPackageName, "Nexus_5"),
140 adb.isAppRunning(androidPackageName, "Nexus_6"),
141 adb.isAppRunning(androidPackageName, "Other_Nexus_6"),
142 ]);
143 }).then(isRunningList => {
144 // It should be running in exactly one of these three devices
145 isRunningList.filter(v => v).should.eql([true]);
146
147 // Get index of running emulator
148 const index = isRunningList.indexOf(true);
149 const emulatorWithAppRunningId = devicesIds[index];
150 shouldHaveReceivedSingleLogCatMessage(emulatorWithAppRunningId);
151 });
152 });
153
154 testWithRecordings("runApp fails if no devices are connected",
155 ["react-native/run-android/win10-rn0.21.0/failsDueToNoDevicesConnected"], () => {
156 return Q({})
157 .then(() => {
158 return androidPlatform.runApp();
159 }).then(() => {
160 should.assert(false, "runApp should've exited with an error");
161 }, reason => {
162 reason.message.should.eql("Unknown error");
163 shouldHaveReceivedNoLogCatMessages();
164 });
165 });
166
167 testWithRecordings("runApp launches the app in an online emulator only",
168 ["react-native/run-android/win10-rn0.21.0/succeedsWithFiveVSEmulators"], () => {
169 const onlineDevicesIds = ["Nexus_11"];
170 const offineDevicesIds = ["Nexus_5", "Nexus_6", "Nexus_10", "Nexus_12"];
171 return Q({})
172 .then(() => {
173 return simulatedAVDManager.createAndLaunchAll(onlineDevicesIds.concat(offineDevicesIds));
174 }).then(() => {
175 return adb.notifyDevicesAreOffline(offineDevicesIds);
176 }).then(() => {
177 return androidPlatform.runApp();
178 }).then(() => {
179 return adb.isAppRunning(androidPackageName, "Nexus_11");
180 }).then((isRunningOnNexus11) => {
181 isRunningOnNexus11.should.be.true();
182 shouldHaveReceivedSingleLogCatMessage("Nexus_11");
183 });
184 });
185
186 testWithRecordings("runApp launches the app in the device specified as target",
187 ["react-native/run-android/win10-rn0.21.0/succeedsWithFiveVSEmulators"], () => {
188 return Q({})
189 .then(() => {
190 return simulatedAVDManager.createAndLaunchAll(["Nexus_5", "Nexus_6", "Nexus_10", "Nexus_11", "Nexus_12"]);
191 }).then(() => {
192 const runOptions: IAndroidRunOptions = { platform: "android", projectRoot: projectRoot, target: "Nexus_12" };
193 return createAndroidPlatform(runOptions).runApp();
194 }).then(() => {
195 return adb.isAppRunning(androidPackageName, "Nexus_12");
196 }).then((isRunningOnNexus12) => {
197 isRunningOnNexus12.should.be.true();
198 shouldHaveReceivedSingleLogCatMessage("Nexus_12");
199 });
200 });
201
202 testWithRecordings("runApp launches the app in a random online device if the target is offline",
203 ["react-native/run-android/win10-rn0.21.0/succeedsWithTenVSEmulators"], () => {
204 const onlineDevicesIds = ["Nexus_11", "Nexus_13", "Nexus_14", "Nexus_15", "Nexus_16", "Nexus_17"];
205 const offineDevicesIds = ["Nexus_5", "Nexus_6", "Nexus_10", "Nexus_12"];
206 return Q({})
207 .then(() => {
208 return simulatedAVDManager.createAndLaunchAll(onlineDevicesIds.concat(offineDevicesIds));
209 }).then(() => {
210 return adb.notifyDevicesAreOffline(offineDevicesIds);
211 }).then(() => {
212 const runOptions: IAndroidRunOptions = { platform: "android", projectRoot: projectRoot, target: "Nexus_12" };
213 return createAndroidPlatform(runOptions).runApp();
214 }).then(() => {
215 return adb.findDevicesRunningApp(androidPackageName);
216 }).then((devicesRunningAppId) => {
217 devicesRunningAppId.length.should.eql(1);
218 onlineDevicesIds.should.containEql(devicesRunningAppId[0]);
219 shouldHaveReceivedSingleLogCatMessage(devicesRunningAppId[0]);
220 });
221 });
222
223 testWithRecordings("runApp doesn't fail even if the call to start the LogCat does fail",
224 [
225 "react-native/run-android/win10-rn0.21.0/succeedsWithOneVSEmulator",
226 "react-native/run-android/win10-rn0.22.2/succeedsWithOneVSEmulator",
227 "react-native/run-android/osx10.10-rn0.21.0/succeedsWithOneVSEmulator",
228 ], () => {
229 fakeExtensionMessageSender.setMessageResponse(Q.reject<void>("Unknown error"));
230
231 return Q({})
232 .then(() => {
233 return simulatedAVDManager.createAndLaunch("Nexus_5");
234 }).then(() => {
235 return androidPlatform.runApp();
236 }).then(() => {
237 return adb.isAppRunning(androidPackageName);
238 }).then(isRunning => {
239 isRunning.should.be.true();
240 shouldHaveReceivedSingleLogCatMessage("Nexus_5");
241 });
242 });
243
244 testWithRecordings("runApp fails when the android project doesn't exist, and shows a nice error message",
245 [
246 "react-native/run-android/win10-rn0.21.0/failsDueToAndroidFolderMissing",
247 "react-native/run-android/win10-rn0.22.2/failsDueToAndroidFolderMissing",
248 ], () => {
249 return Q({})
250 .then(() => {
251 return fileSystem.rmdir(androidProjectPath);
252 }).then(() => {
253 return simulatedAVDManager.createAndLaunch("Nexus_5");
254 }).then(() => {
255 return androidPlatform.runApp();
256 }).then(() => {
257 should.assert(false, "Expected runApp to end up with an error");
258 return false;
259 }, reason => {
260 reason.message.should.eql("Android project not found.");
261 return adb.isAppRunning(androidPackageName);
262 }).then(isRunning => {
263 isRunning.should.be.false();
264 shouldHaveReceivedNoLogCatMessages();
265 });
266 });
267
268 testWithRecordings("runApp fails when the android emulator shell is unresponsive, and shows a nice error message",
269 ["react-native/run-android/osx10.10-rn0.21.0/failsDueToAdbCommandTimeout"], () => {
270 return Q({})
271 .then(() => {
272 return simulatedAVDManager.createAndLaunch("Nexus_5");
273 }).then(() => {
274 return androidPlatform.runApp();
275 }).then(() => {
276 should.assert(false, "Expected runApp to end up with an error");
277 return false;
278 }, reason => {
279 "An Android shell command timed-out. Please retry the operation.".should.eql(reason.message);
280 return adb.isAppRunning(androidPackageName);
281 }).then(isRunning => {
282 isRunning.should.be.false();
283 shouldHaveReceivedNoLogCatMessages();
284 });
285 });
286 });
287});
288