Skip to content

Commit 1e60d7c

Browse files
committed
Merge branch 'main' into @KeyJayY/DiagnosticsTests
2 parents 3e8e09b + 11021b7 commit 1e60d7c

File tree

20 files changed

+402
-79
lines changed

20 files changed

+402
-79
lines changed

.github/matrices/autorun_test_params.json

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,42 @@
1313
"node": "22",
1414
"isRecording": "true",
1515
"testsToRun": "",
16-
"isAndroid": "true",
1716
"testsToExclude": "",
1817
"codeVersion": "latest"
1918
},
2019
{
21-
"testApp": "expo-53",
20+
"testApp": "expo-54",
2221
"node": "22",
2322
"isRecording": "true",
2423
"testsToRun": "",
2524
"testsToExclude": "",
2625
"codeVersion": "latest"
2726
},
2827
{
29-
"testApp": "expo-54",
28+
"testApp": "react-native-81",
3029
"node": "22",
3130
"isRecording": "true",
3231
"testsToRun": "",
3332
"testsToExclude": "",
34-
"codeVersion": "latest"
33+
"codeVersion": "1.99.1"
3534
},
3635
{
3736
"testApp": "react-native-81",
3837
"node": "22",
3938
"isRecording": "true",
4039
"testsToRun": "",
40+
"isAndroid": "true",
4141
"testsToExclude": "",
42-
"codeVersion": "1.99.1"
42+
"codeVersion": "latest"
43+
},
44+
{
45+
"testApp": "expo-53",
46+
"node": "22",
47+
"isRecording": "true",
48+
"testsToRun": "",
49+
"isAndroid": "true",
50+
"testsToExclude": "",
51+
"codeVersion": "latest"
4352
},
4453
{
4554
"testApp": "expo-52-prebuild-with-plugins",
@@ -56,6 +65,15 @@
5665
"testsToRun": "16",
5766
"testsToExclude": "",
5867
"codeVersion": "latest"
68+
},
69+
{
70+
"testApp": "react-native-81-additional-libs",
71+
"node": "22",
72+
"isRecording": "true",
73+
"testsToRun": "8",
74+
"isAndroid": "false",
75+
"testsToExclude": "",
76+
"codeVersion": "latest"
5977
}
6078
]
6179
}

.github/workflows/ui-tests.yaml

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ jobs:
165165
npm run setup-run-tests -- ${{ matrix.testsToRun }} --exclude ${{ matrix.testsToExclude }} \
166166
| tee artifacts/test-output-${{ matrix.testApp }}-${{ matrix.codeVersion }}.txt
167167
working-directory: packages/vscode-extension-tester
168+
timeout-minutes: 90
168169
env:
169170
PROJECT_NAME: ${{ matrix.testApp }}
170171
IS_RECORDING: ${{ matrix.isRecording }}
@@ -178,7 +179,7 @@ jobs:
178179
uses: actions/upload-artifact@v4
179180
timeout-minutes: 1
180181
with:
181-
name: test-output-${{ matrix.testApp }}-${{ matrix.codeVersion }}
182+
name: test-output-${{ matrix.testApp }}-${{ matrix.codeVersion }}-${{ matrix.isAndroid && 'android' || 'ios' }}
182183
path: packages/vscode-extension-tester/artifacts/test-output-${{ matrix.testApp }}-${{ matrix.codeVersion }}.txt
183184
retention-days: 7
184185

@@ -192,7 +193,7 @@ jobs:
192193
if: failure()
193194
uses: actions/upload-artifact@v4
194195
with:
195-
name: vscode-ui-screenshots-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}
196+
name: vscode-ui-screenshots-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}-${{ matrix.isAndroid && 'android' || 'ios' }}
196197
path: packages/vscode-extension-tester/screenshots/
197198
retention-days: 7
198199

@@ -201,7 +202,7 @@ jobs:
201202
uses: actions/upload-artifact@v4
202203
timeout-minutes: 1
203204
with:
204-
name: output-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}
205+
name: output-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}-${{ matrix.isAndroid && 'android' || 'ios' }}
205206
path: packages/vscode-extension-tester/output.txt
206207
retention-days: 7
207208

@@ -210,7 +211,7 @@ jobs:
210211
uses: actions/upload-artifact@v4
211212
timeout-minutes: 1
212213
with:
213-
name: vscode-ui-recording-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}
214+
name: vscode-ui-recording-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}-${{ matrix.isAndroid && 'android' || 'ios' }}
214215
path: packages/vscode-extension-tester/videos/vscode-ui-recording.mp4
215216
retention-days: 7
216217

@@ -219,25 +220,16 @@ jobs:
219220
uses: actions/upload-artifact@v4
220221
timeout-minutes: 1
221222
with:
222-
name: radon-screenshot-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}
223+
name: radon-screenshot-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}-${{ matrix.isAndroid && 'android' || 'ios' }}
223224
path: packages/vscode-extension-tester/data/screenshotTest..png
224225
retention-days: 7
225226

226-
- name: Upload automatedTests.tsx
227-
if: ${{ always() }}
228-
uses: actions/upload-artifact@v4
229-
timeout-minutes: 1
230-
with:
231-
name: automatedTests.tsx
232-
path: packages/vscode-extension-tester/data/react-native-app/shared/automatedTests.tsx
233-
retention-days: 7
234-
235227
- name: Upload recording made by radon
236228
if: ${{ always() && matrix.isRecording == 'true' }}
237229
uses: actions/upload-artifact@v4
238230
timeout-minutes: 1
239231
with:
240-
name: radon-recording-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}
232+
name: radon-recording-${{ github.run_id }}-${{matrix.testApp}}-${{matrix.codeVersion}}-${{ matrix.isAndroid && 'android' || 'ios' }}
241233
path: packages/vscode-extension-tester/data/recordingTest..mp4
242234
retention-days: 7
243235

packages/docs/docs/guides/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ Here, we list other attributes that can be configured using launch configuration
239239
`metro.config.js` or `metro.config.ts`.
240240
- `isExpo` — Boolean that can be set to `true` if IDE doesn't automatically detect the project should use Expo CLI. By default, the IDE tries to detect whether project is Expo-base or based on the React Native community CLI, so in most of the cases this options shouldn't be needed.
241241
- `usePrebuild` — Boolean that when set to `true` makes Radon IDE run `expo prebuild` command before building the app and when set to `false` Radon IDE will always skip it. By default, Radon uses Prebuild for projects with `expo dev-client` and skips it for other projects.
242+
- `expoStartArgs` - Extra arguments to pass to Expo start command. (e.g. ["--scheme", "your_scheme"]).
242243

243244
Below is a sample `launch.json` config file with `appRoot`, `metroConfigPath`, and `env` setting specified:
244245

packages/vscode-extension-tester/services/appManipulationService.js

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as fs from "fs";
2-
import { By, BottomBarPanel } from "vscode-extension-tester";
2+
import { By, BottomBarPanel, Key } from "vscode-extension-tester";
33
import getConfiguration from "../configuration.js";
44
import { centerCoordinates } from "../utils/helpers.js";
55
import { waitForMessage } from "../server/webSocketServer.js";
@@ -41,25 +41,32 @@ export default class AppManipulationService {
4141
throw new Error("App error popup displayed");
4242
}
4343

44-
const messageElement = await this.elementHelperService.safeFind(
45-
By.css('[data-testid="startup-message"]')
46-
);
47-
48-
if (!messageElement) return false;
49-
50-
const message = (await messageElement.getText())
51-
.replace(/\./g, "")
52-
.trim();
44+
try {
45+
const messageElement = await this.elementHelperService.safeFind(
46+
By.css('[data-testid="startup-message"]')
47+
);
5348

54-
// in case the device startup process has frozen
55-
if (!currentMessage.includes("Building") && currentMessage == message) {
56-
if (Date.now() - currentMessageFirstAppear > 100000)
57-
await this.restartDevice();
58-
} else {
59-
currentMessage = message;
60-
currentMessageFirstAppear = Date.now();
49+
if (!messageElement) return false;
50+
51+
const message = (await messageElement.getText())
52+
.replace(/\./g, "")
53+
.replace(/\s+/g, "")
54+
.trim();
55+
56+
// in case the device startup process has frozen
57+
if (
58+
!currentMessage.includes("Building") &&
59+
currentMessage == message
60+
) {
61+
if (Date.now() - currentMessageFirstAppear > 100000)
62+
await this.restartDevice();
63+
} else {
64+
currentMessage = message;
65+
currentMessageFirstAppear = Date.now();
66+
}
67+
} catch (err) {
68+
if (err.name !== "StaleElementReferenceError") throw err;
6169
}
62-
6370
return false;
6471
},
6572
600000,
@@ -82,7 +89,10 @@ export default class AppManipulationService {
8289
await this.elementHelperService.findAndClickElementByTag(
8390
`device-running-badge-${runningDeviceName}`
8491
);
85-
await this.driver.sleep(1000);
92+
await this.driver.actions().sendKeys(Key.ESCAPE).perform();
93+
await this.elementHelperService.findAndClickElementByTag(
94+
"radon-bottom-bar-device-select-dropdown-trigger"
95+
);
8696
await this.elementHelperService.findAndClickElementByTag(
8797
`device-${runningDeviceName}`
8898
);

packages/vscode-extension-tester/services/managingDevicesService.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ export default class ManagingDevicesService {
8787
async addNewDevice(newDeviceName) {
8888
await this.openDeviceCreationModal();
8989
await this.fillDeviceCreationForm(newDeviceName);
90-
9190
await this.elementHelperService.findAndClickElementByTag(
9291
"creating-device-form-confirmation-button"
9392
);

packages/vscode-extension-tester/ui-tests/07-radonTools.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,24 @@ safeDescribe("7 - Radon tools tests", () => {
404404
await managingDevicesService.switchToDevice(deviceName2);
405405
await appManipulationService.waitForAppToLoad();
406406

407+
await driver.wait(async () => {
408+
appWebsocket = get().appWebsocket;
409+
return appWebsocket != null;
410+
}, 5000);
411+
412+
await appManipulationService.hideExpoOverlay(appWebsocket);
413+
407414
await radonSettingsService.rotateDevice("landscape-left");
408415

416+
await driver.wait(async () => {
417+
const orientation =
418+
await appManipulationService.sendMessageAndWaitForResponse(
419+
appWebsocket,
420+
"getOrientation"
421+
);
422+
return orientation.value === "landscape";
423+
}, 5000);
424+
409425
await managingDevicesService.switchToDevice(deviceName1);
410426

411427
await testIfInspectElementAppearsInCorrectPlace();

packages/vscode-extension-tester/ui-tests/08-deviceSettings.test.js

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { execSync } from "child_process";
2+
import * as fs from "fs";
3+
import { assert } from "chai";
14
import { WebView, By, Key } from "vscode-extension-tester";
25
import initServices from "../services/index.js";
36
import { getAppWebsocket } from "../server/webSocketServer.js";
@@ -8,6 +11,10 @@ import { get } from "./setupTest.js";
811

912
const rotationSequence = "1010110010101110010010111011100100100111";
1013

14+
const raw = fs.readFileSync("./data/react-native-app/package.json");
15+
const data = JSON.parse(raw);
16+
const IS_APP_WITH_ADDITIONAL_LIBS = data.name.includes("AdditionalLibs");
17+
1118
safeDescribe("8 - Device Settings", () => {
1219
let driver,
1320
appWebsocket,
@@ -31,8 +38,6 @@ safeDescribe("8 - Device Settings", () => {
3138

3239
await managingDevicesService.prepareDevices();
3340

34-
await appManipulationService.waitForAppToLoad();
35-
3641
view = new WebView();
3742
await view.switchBack();
3843
});
@@ -324,4 +329,124 @@ safeDescribe("8 - Device Settings", () => {
324329
return appState.value === "background";
325330
}, 5000);
326331
});
332+
333+
const locationsToTest = [
334+
{ lattitude: 1, longitude: 1 },
335+
{ lattitude: -1, longitude: -1 },
336+
{ lattitude: 0, longitude: 0 },
337+
];
338+
let permissionGranted = false;
339+
340+
for (const actualLocation of locationsToTest) {
341+
itIf(
342+
!getConfiguration().IS_ANDROID && IS_APP_WITH_ADDITIONAL_LIBS,
343+
`Should change location to (${actualLocation.lattitude}, ${actualLocation.longitude})`,
344+
async () => {
345+
if (!permissionGranted) {
346+
execSync(
347+
"xcrun simctl --set ~/Library/Caches/com.swmansion.radon-ide/Devices/iOS privacy booted grant location org.reactjs.native.example.reactNative81AdditionalLibs"
348+
);
349+
350+
await appManipulationService.restartDevice();
351+
await appManipulationService.waitForAppToLoad();
352+
353+
await driver.sleep(3000);
354+
await driver.wait(async () => {
355+
appWebsocket = get().appWebsocket;
356+
return appWebsocket != null;
357+
}, 5000);
358+
permissionGranted = true;
359+
}
360+
361+
await appManipulationService.hideExpoOverlay(appWebsocket);
362+
363+
radonViewsService.openRadonDeviceSettingsMenu();
364+
await elementHelperService.findAndClickElementByTag(
365+
"device-settings-location"
366+
);
367+
const locationInput =
368+
await elementHelperService.findAndWaitForElementByTag(
369+
"coordinates-input"
370+
);
371+
await locationInput.clear();
372+
await driver.sleep(1000);
373+
await locationInput.sendKeys(
374+
`${actualLocation.lattitude} ${actualLocation.longitude}`,
375+
Key.ENTER
376+
);
377+
378+
await elementHelperService.findAndClickElementByTag(
379+
"modal-close-button"
380+
);
381+
await driver.wait(async () => {
382+
try {
383+
const location =
384+
await appManipulationService.sendMessageAndWaitForResponse(
385+
appWebsocket,
386+
"getLocation"
387+
);
388+
assert.approximately(
389+
location.value.latitude,
390+
actualLocation.lattitude,
391+
0.1
392+
);
393+
assert.approximately(
394+
location.value.longitude,
395+
actualLocation.longitude,
396+
0.1
397+
);
398+
return true;
399+
} catch {
400+
return false;
401+
}
402+
}, 10000);
403+
}
404+
);
405+
}
406+
407+
itIf(
408+
!getConfiguration().IS_ANDROID && IS_APP_WITH_ADDITIONAL_LIBS,
409+
"change location",
410+
async () => {
411+
radonViewsService.openRadonDeviceSettingsMenu();
412+
await elementHelperService.findAndClickElementByTag(
413+
"device-settings-localization"
414+
);
415+
const input = await elementHelperService.findAndClickElementByTag(
416+
"localization-search-input"
417+
);
418+
await input.sendKeys("Spanish", Key.ENTER);
419+
await elementHelperService.findAndClickElementByTag(
420+
"localization-tile-es_es"
421+
);
422+
await elementHelperService.findAndClickElementByTag(
423+
"confirm-localization-change-button"
424+
);
425+
426+
await elementHelperService.findAndWaitForElementByTag("startup-message");
427+
428+
await appManipulationService.waitForAppToLoad();
429+
430+
await driver.wait(async () => {
431+
appWebsocket = get().appWebsocket;
432+
return appWebsocket != null;
433+
}, 5000);
434+
435+
await driver.wait(async () => {
436+
try {
437+
const localization =
438+
await appManipulationService.sendMessageAndWaitForResponse(
439+
appWebsocket,
440+
"getLocalization"
441+
);
442+
assert.equal(localization.value.countryCode.toLowerCase(), "es");
443+
assert.equal(localization.value.languageTag.toLowerCase(), "es-es");
444+
assert.equal(localization.value.languageCode.toLowerCase(), "es");
445+
return true;
446+
} catch {
447+
return false;
448+
}
449+
}, 10000);
450+
}
451+
);
327452
});

0 commit comments

Comments
 (0)