Skip to content

Commit 01d537b

Browse files
authored
feat(visionos): ui-mobile-base supporting xros plus improvements to window handling (#10478)
1 parent 9ca4902 commit 01d537b

File tree

242 files changed

+8637
-2078
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

242 files changed

+8637
-2078
lines changed

apps/automated/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core"
1212
},
1313
"devDependencies": {
14-
"@nativescript/android": "~8.6.0",
15-
"@nativescript/ios": "~8.6.0",
14+
"@nativescript/android": "rc",
15+
"@nativescript/ios": "rc",
16+
"@nativescript/visionos": "rc",
1617
"@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz",
1718
"circular-dependency-plugin": "^5.2.2",
18-
"typescript": "~5.2.0"
19+
"typescript": "~5.4.0"
1920
},
2021
"gitHead": "c06800e52ee1a184ea2dffd12a6702aaa43be4e3",
2122
"readme": "NativeScript Application"

apps/automated/project.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
"platform": "ios"
2929
}
3030
},
31+
"vision": {
32+
"executor": "@nativescript/nx:build",
33+
"inputs": ["default", "^production"],
34+
"outputs": [],
35+
"options": {
36+
"noHmr": true,
37+
"debug": false,
38+
"platform": "vision"
39+
}
40+
},
3141
"android": {
3242
"executor": "@nativescript/nx:build",
3343
"inputs": ["default", "^production"],

apps/automated/src/application/application-tests-common.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ if (isAndroid) {
1111
export function testInitialized() {
1212
if (Device.os === platformNames.android) {
1313
TKUnit.assert(Application.android, 'Application module not properly intialized');
14-
} else if (Device.os === platformNames.ios) {
14+
} else if (__APPLE__) {
1515
TKUnit.assert(Application.ios, 'Application module not properly intialized');
1616
}
1717
}
1818

1919
export function testDisplayedEvent() {
20+
if (__VISIONOS__) {
21+
return;
22+
}
2023
// global.isDisplayedEventFired flag is set in app.ts application.displayedEvent handler
2124
TKUnit.assert(global.isDisplayedEventFired, 'application.displayedEvent not fired');
2225
}

apps/automated/src/application/application-tests.ios.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function testIOSApplicationInitialized() {
4646
TKUnit.assert(Application.ios.nativeApp, 'iOS nativeApp not initialized.');
4747
TKUnit.assert(Application.ios.orientation(), 'iOS orientation not initialized.');
4848

49-
if (Utils.ios.MajorVersion <= 11) {
49+
if (!__VISIONOS__ && Utils.SDK_VERSION <= 11) {
5050
TKUnit.assertNull(Application.ios.systemAppearance(), 'iOS system appearance should be `null` on iOS <= 11.');
5151
} else {
5252
TKUnit.assert(Application.ios.systemAppearance(), 'iOS system appearance not initialized.');
@@ -57,7 +57,7 @@ export function testIOSApplicationInitialized() {
5757
}
5858

5959
export function testSystemAppearance() {
60-
if (Utils.ios.MajorVersion <= 11) {
60+
if (!__VISIONOS__ && Utils.SDK_VERSION <= 11) {
6161
TKUnit.assertNull(Application.ios.systemAppearance(), 'System appearance should be `null` on iOS <= 11.');
6262
} else {
6363
TKUnit.assert(Application.ios.systemAppearance(), 'System appearance not initialized.');

apps/automated/src/file-system/file-system-tests.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export var testFileReadWriteBinary = function () {
207207
error = e;
208208
});
209209
TKUnit.assertNull(error);
210-
if (Device.os === platformNames.ios) {
210+
if (__APPLE__) {
211211
TKUnit.assertTrue(source.isEqualToData(destination));
212212
} else {
213213
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
@@ -235,7 +235,7 @@ export var testFileReadWriteBinaryAsync = function () {
235235
// Succeded in writing the file
236236
destinationFile.read().then(
237237
function (destination) {
238-
if (Device.os === platformNames.ios) {
238+
if (__APPLE__) {
239239
TKUnit.assertTrue(source.isEqualToData(destination));
240240
} else {
241241
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
@@ -306,14 +306,16 @@ function _testIOSSpecificKnownFolder(knownFolderName: string) {
306306
}
307307

308308
export var testIOSSpecificKnownFolders = function () {
309-
_testIOSSpecificKnownFolder('library');
310-
_testIOSSpecificKnownFolder('developer');
311-
_testIOSSpecificKnownFolder('desktop');
312-
_testIOSSpecificKnownFolder('downloads');
313-
_testIOSSpecificKnownFolder('movies');
314-
_testIOSSpecificKnownFolder('music');
315-
_testIOSSpecificKnownFolder('pictures');
316-
_testIOSSpecificKnownFolder('sharedPublic');
309+
if (__IOS__) {
310+
_testIOSSpecificKnownFolder('library');
311+
_testIOSSpecificKnownFolder('developer');
312+
_testIOSSpecificKnownFolder('desktop');
313+
_testIOSSpecificKnownFolder('downloads');
314+
_testIOSSpecificKnownFolder('movies');
315+
_testIOSSpecificKnownFolder('music');
316+
_testIOSSpecificKnownFolder('pictures');
317+
_testIOSSpecificKnownFolder('sharedPublic');
318+
}
317319
};
318320

319321
export var testGetEntities = function () {

apps/automated/src/navigation/transition-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function test_Transitions() {
3232
});
3333

3434
var transitions;
35-
if (Device.os === platformNames.ios) {
35+
if (__APPLE__) {
3636
transitions = ['curl'];
3737
} else {
3838
const _sdkVersion = parseInt(Device.sdkVersion);

apps/automated/src/platform/platform-tests.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ export function test_platform() {
55
let expectedPlatform;
66
if (isAndroid) {
77
expectedPlatform = 'Android';
8+
} else if (__VISIONOS__) {
9+
expectedPlatform = 'visionOS';
810
} else {
911
expectedPlatform = 'iOS';
1012
}

apps/automated/src/test-runner.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import * as TKUnit from './tk-unit';
33
import './ui-test';
44

5-
import { isIOS, isAndroid, Application, Device, platformNames, Trace, Button, Frame, StackLayout, Page, TextView, Utils } from '@nativescript/core';
5+
import { isIOS, isAndroid, Application, Device, platformNames, Trace, Button, Frame, StackLayout, Page, TextView, Utils, Color } from '@nativescript/core';
66
Frame.defaultAnimatedNavigation = false;
77

88
export function isRunningOnEmulator(): boolean {
@@ -16,7 +16,7 @@ export function isRunningOnEmulator(): boolean {
1616
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('sdk') > -1 ||
1717
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('emulator') > -1
1818
); // VS Emulator
19-
} else if (Device.os === platformNames.ios) {
19+
} else if (__APPLE__) {
2020
return __dirname.search('Simulator') > -1;
2121
}
2222
}
@@ -218,8 +218,8 @@ allTests['PROGRESS'] = progressTests;
218218
import * as placeholderTests from './ui/placeholder/placeholder-tests';
219219
allTests['PLACEHOLDER'] = placeholderTests;
220220

221-
// import * as pageTests from './ui/page/page-tests';
222-
// allTests['PAGE'] = pageTests;
221+
import * as pageTests from './ui/page/page-tests';
222+
allTests['PAGE'] = pageTests;
223223

224224
import * as listViewTests from './ui/list-view/list-view-tests';
225225
allTests['LISTVIEW'] = listViewTests;
@@ -245,6 +245,7 @@ allTests['DATE-PICKER'] = datePickerTests;
245245
import * as timePickerTests from './ui/time-picker/time-picker-tests';
246246
allTests['TIME-PICKER'] = timePickerTests;
247247

248+
// TODO: followup on 3 assertions here -
248249
// import * as webViewTests from './ui/web-view/web-view-tests';
249250
// allTests['WEB-VIEW'] = webViewTests;
250251

@@ -397,12 +398,23 @@ function showReportPage(finalMessage: string) {
397398
messageContainer.text = finalMessage;
398399
stack.addChild(messageContainer);
399400

401+
if (__VISIONOS__) {
402+
// just helps make the results screen more clear on Vision Pro
403+
btn.style.fontSize = 22;
404+
stack.style.padding = 20;
405+
stack.style.marginTop = 20;
406+
messageContainer.style.fontSize = 22;
407+
messageContainer.style.color = new Color('#fff');
408+
}
409+
400410
Frame.topmost().navigate({
401411
create: () => {
402412
const page = new Page();
403413
page.content = stack;
404414
messageContainer.focus();
405-
page.style.fontSize = 11;
415+
if (!__VISIONOS__) {
416+
page.style.fontSize = 11;
417+
}
406418
if (isAndroid) {
407419
page.on('navigatedTo', () => {
408420
messageContainer.focus();
@@ -473,7 +485,7 @@ export function runAll(testSelector?: string) {
473485
new TestInfo(() => {
474486
running = true;
475487
startTime = TKUnit.time();
476-
})
488+
}),
477489
);
478490
for (const name in allTests) {
479491
if (singleModuleName && singleModuleName !== name.toLowerCase()) {
@@ -519,7 +531,7 @@ export function runAll(testSelector?: string) {
519531
new TestInfo(function () {
520532
testsQueue = [];
521533
running = false;
522-
})
534+
}),
523535
);
524536

525537
TKUnit.runTests(testsQueue, 0);

apps/automated/src/ui/activity-indicator/activity-indicator-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function test_set_TNS_value_updates_native_value() {
4949
}
5050

5151
// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
52-
if (platform.Device.os === platform.platformNames.ios) {
52+
if (__APPLE__) {
5353
exports.test_set_color = function () {
5454
var ai = new activityIndicatorModule.ActivityIndicator();
5555
ai.color = new color.Color('red');

apps/automated/src/ui/label/label-tests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import * as fs from '@nativescript/core/file-system';
1616

1717
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
1818
import { GridLayout } from '@nativescript/core/ui/layouts/grid-layout';
19-
import { isIOS, isAndroid } from '@nativescript/core/platform';
19+
import { isIOS, isAndroid, isApple } from '@nativescript/core/platform';
2020
import { Label } from '@nativescript/core/ui/label';
2121
import { LayoutBase } from '@nativescript/core/ui/layouts/layout-base';
2222
import * as helper from '../../ui-helper';
@@ -606,7 +606,7 @@ export class LabelTest extends testModule.UITest<LabelModule.Label> {
606606
}
607607

608608
private requestLayoutFixture(expectRequestLayout: boolean, initialValue: string, setup: (label: Label) => LayoutBase): void {
609-
if (!isIOS) {
609+
if (!isApple) {
610610
return;
611611
}
612612

apps/automated/src/ui/layouts/safe-area-tests.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as view from '@nativescript/core/ui/core/view';
33
import * as testModule from '../../ui-test';
44
import * as platform from '@nativescript/core/platform';
55
import * as helper from '../../ui-helper';
6-
import { Builder, Page, Label, GridLayout } from '@nativescript/core';
6+
import { Builder, Page, Label, GridLayout, Utils } from '@nativescript/core';
77
import { dipToDp, left, top, right, bottom, height, width, equal, closeEnough, lessOrCloseEnough, greaterOrCloseEnough, isLeftAlignedWith, isRightAlignedWith, isTopAlignedWith, isBottomAlignedWith, isLeftWith, isAboveWith, isRightWith, isBelowWith } from './layout-tests-helper';
88

99
export class SafeAreaTests extends testModule.UITest<any> {
@@ -84,10 +84,10 @@ export class SafeAreaTests extends testModule.UITest<any> {
8484
}
8585

8686
private layout_insets_top_action_bar_hidden_test(layout: view.View) {
87-
const app = UIApplication.sharedApplication;
87+
const keyWindow = Utils.ios.getWindow();
8888
// const statusBarHeight = round(dipToDp(app.statusBarFrame.size.height));
8989
// use window inset instead of status bar frame as that's unreliable on iOS 16+
90-
const topInset = round(dipToDp(app.keyWindow.safeAreaInsets.top));
90+
const topInset = round(dipToDp(keyWindow ? keyWindow.safeAreaInsets.top : UIApplication.sharedApplication.keyWindow.safeAreaInsets.top));
9191

9292
const insets = layout.getSafeAreaInsets();
9393
equal(insets.top, topInset, `${layout}.topInset - actual:${insets.top}; expected: ${topInset}`);

apps/automated/src/ui/page/modal-tab-root.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function onShownModally(args: ShownModallyData) {
1313
TKUnit.assertEqual(hostFrame.currentPage.modal, tabView, 'hostFrame.currentPage.modal should be equal to the tabView instance on tabView.shownModally event handler.');
1414

1515
// shownModally raised after page.NavigatedTo on iOS
16-
if (isIOS) {
16+
if (__APPLE__) {
1717
args.closeCallback('return value');
1818
}
1919
}

apps/automated/src/ui/page/page-tests-common.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function _test_PageNavigation_EventSequence(withTransition: boolean) {
174174
? {
175175
name: 'slide',
176176
duration: 10,
177-
}
177+
}
178178
: undefined,
179179
};
180180

@@ -370,7 +370,7 @@ export function test_page_backgroundColor() {
370370
helper.navigate(factory);
371371

372372
if (isIOS) {
373-
const backgroundColor = Utils.ios.MajorVersion <= 12 || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
373+
const backgroundColor = (!__VISIONOS__ && Utils.ios.MajorVersion <= 12) || !UIColor.systemBackgroundColor ? UIColor.whiteColor : UIColor.systemBackgroundColor;
374374
TKUnit.assertEqual(page.nativeView.backgroundColor, backgroundColor, 'page backgroundColor is wrong');
375375
} else {
376376
const whiteColor = new Color('white');
@@ -1219,6 +1219,10 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalTabView()
12191219
return masterPage;
12201220
};
12211221

1222+
if (__ANDROID__) {
1223+
// revisit
1224+
return;
1225+
}
12221226
TKUnit.assertEqual(Frame._stack().length, 1, 'Single host frame should be instantiated at this point!');
12231227

12241228
helper.navigate(masterPageFactory);

apps/automated/src/ui/progress/progress-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function test_set_value_greater_than_max_should_set_value_to_max() {
5757
}
5858

5959
// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
60-
if (platform.Device.os === platform.platformNames.ios) {
60+
if (__APPLE__) {
6161
exports.test_set_color = function () {
6262
var progress = new progressModule.Progress();
6363
progress.color = new color.Color('red');

apps/automated/src/ui/root-view/root-view-tests.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ export function test_custom_component_rootview_layout_updates() {
3838
}
3939

4040
export function test_tabview_rootview_css_applied() {
41+
if (__VISIONOS__) {
42+
// TODO: investigate resetRootView cases with visionOS setup
43+
return;
44+
}
4145
var entry = {
4246
moduleName: 'ui/root-view/root-modules/tabview-root',
4347
};

apps/automated/src/ui/styling/root-views-css-classes-tests.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const ROOT_CSS_CLASS = 'ns-root';
99
const MODAL_CSS_CLASS = 'ns-modal';
1010
const ANDROID_PLATFORM_CSS_CLASS = 'ns-android';
1111
const IOS_PLATFORM_CSS_CLASS = 'ns-ios';
12+
const VISIONOS_PLATFORM_CSS_CLASS = 'ns-visionos';
1213
const PHONE_DEVICE_TYPE_CSS_CLASS = 'ns-phone';
1314
const TABLET_DEVICE_TYPE_CSS_CLASS = 'ns-tablet';
1415
const PORTRAIT_ORIENTATION_CSS_CLASS = 'ns-portrait';
@@ -41,7 +42,8 @@ function _test_platform_css_class(rootView: View, shouldSetClassName: boolean) {
4142
TKUnit.assertTrue(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is missing`);
4243
TKUnit.assertFalse(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is present`);
4344
} else {
44-
TKUnit.assertTrue(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is missing`);
45+
const cssClass = __VISIONOS__ ? VISIONOS_PLATFORM_CSS_CLASS : IOS_PLATFORM_CSS_CLASS;
46+
TKUnit.assertTrue(cssClasses.has(cssClass), `${cssClass} CSS class is missing`);
4547
TKUnit.assertFalse(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is present`);
4648
}
4749

@@ -113,7 +115,7 @@ function _test_system_appearance_css_class(rootView: View, shouldSetClassName: b
113115
} else {
114116
systemAppearance = Application.ios.systemAppearance;
115117
}
116-
if (isIOS && Utils.ios.MajorVersion <= 12) {
118+
if (isIOS && !__VISIONOS__ && Utils.SDK_VERSION <= 12) {
117119
TKUnit.assertFalse(cssClasses.has(DARK_SYSTEM_APPEARANCE_CSS_CLASS), `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`);
118120
TKUnit.assertFalse(cssClasses.has(LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`);
119121
} else if (systemAppearance === 'dark') {

apps/automated/src/ui/switch/switch-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function test_default_native_values() {
4242
}
4343

4444
// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
45-
if (platform.Device.os === platform.platformNames.ios) {
45+
if (__APPLE__) {
4646
exports.test_set_color = function () {
4747
var mySwitch = new switchModule.Switch();
4848
mySwitch.color = new Color('red');

0 commit comments

Comments
 (0)