Skip to content

Commit

Permalink
feat(visionos): ui-mobile-base supporting xros plus improvements to w…
Browse files Browse the repository at this point in the history
…indow handling (#10478)
  • Loading branch information
NathanWalker committed Apr 6, 2024
1 parent 9ca4902 commit 01d537b
Show file tree
Hide file tree
Showing 242 changed files with 8,637 additions and 2,078 deletions.
7 changes: 4 additions & 3 deletions apps/automated/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core"
},
"devDependencies": {
"@nativescript/android": "~8.6.0",
"@nativescript/ios": "~8.6.0",
"@nativescript/android": "rc",
"@nativescript/ios": "rc",
"@nativescript/visionos": "rc",
"@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz",
"circular-dependency-plugin": "^5.2.2",
"typescript": "~5.2.0"
"typescript": "~5.4.0"
},
"gitHead": "c06800e52ee1a184ea2dffd12a6702aaa43be4e3",
"readme": "NativeScript Application"
Expand Down
10 changes: 10 additions & 0 deletions apps/automated/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
"platform": "ios"
}
},
"vision": {
"executor": "@nativescript/nx:build",
"inputs": ["default", "^production"],
"outputs": [],
"options": {
"noHmr": true,
"debug": false,
"platform": "vision"
}
},
"android": {
"executor": "@nativescript/nx:build",
"inputs": ["default", "^production"],
Expand Down
5 changes: 4 additions & 1 deletion apps/automated/src/application/application-tests-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ if (isAndroid) {
export function testInitialized() {
if (Device.os === platformNames.android) {
TKUnit.assert(Application.android, 'Application module not properly intialized');
} else if (Device.os === platformNames.ios) {
} else if (__APPLE__) {
TKUnit.assert(Application.ios, 'Application module not properly intialized');
}
}

export function testDisplayedEvent() {
if (__VISIONOS__) {
return;
}
// global.isDisplayedEventFired flag is set in app.ts application.displayedEvent handler
TKUnit.assert(global.isDisplayedEventFired, 'application.displayedEvent not fired');
}
Expand Down
4 changes: 2 additions & 2 deletions apps/automated/src/application/application-tests.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function testIOSApplicationInitialized() {
TKUnit.assert(Application.ios.nativeApp, 'iOS nativeApp not initialized.');
TKUnit.assert(Application.ios.orientation(), 'iOS orientation not initialized.');

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

export function testSystemAppearance() {
if (Utils.ios.MajorVersion <= 11) {
if (!__VISIONOS__ && Utils.SDK_VERSION <= 11) {
TKUnit.assertNull(Application.ios.systemAppearance(), 'System appearance should be `null` on iOS <= 11.');
} else {
TKUnit.assert(Application.ios.systemAppearance(), 'System appearance not initialized.');
Expand Down
22 changes: 12 additions & 10 deletions apps/automated/src/file-system/file-system-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export var testFileReadWriteBinary = function () {
error = e;
});
TKUnit.assertNull(error);
if (Device.os === platformNames.ios) {
if (__APPLE__) {
TKUnit.assertTrue(source.isEqualToData(destination));
} else {
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
Expand Down Expand Up @@ -235,7 +235,7 @@ export var testFileReadWriteBinaryAsync = function () {
// Succeded in writing the file
destinationFile.read().then(
function (destination) {
if (Device.os === platformNames.ios) {
if (__APPLE__) {
TKUnit.assertTrue(source.isEqualToData(destination));
} else {
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
Expand Down Expand Up @@ -306,14 +306,16 @@ function _testIOSSpecificKnownFolder(knownFolderName: string) {
}

export var testIOSSpecificKnownFolders = function () {
_testIOSSpecificKnownFolder('library');
_testIOSSpecificKnownFolder('developer');
_testIOSSpecificKnownFolder('desktop');
_testIOSSpecificKnownFolder('downloads');
_testIOSSpecificKnownFolder('movies');
_testIOSSpecificKnownFolder('music');
_testIOSSpecificKnownFolder('pictures');
_testIOSSpecificKnownFolder('sharedPublic');
if (__IOS__) {
_testIOSSpecificKnownFolder('library');
_testIOSSpecificKnownFolder('developer');
_testIOSSpecificKnownFolder('desktop');
_testIOSSpecificKnownFolder('downloads');
_testIOSSpecificKnownFolder('movies');
_testIOSSpecificKnownFolder('music');
_testIOSSpecificKnownFolder('pictures');
_testIOSSpecificKnownFolder('sharedPublic');
}
};

export var testGetEntities = function () {
Expand Down
2 changes: 1 addition & 1 deletion apps/automated/src/navigation/transition-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function test_Transitions() {
});

var transitions;
if (Device.os === platformNames.ios) {
if (__APPLE__) {
transitions = ['curl'];
} else {
const _sdkVersion = parseInt(Device.sdkVersion);
Expand Down
2 changes: 2 additions & 0 deletions apps/automated/src/platform/platform-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export function test_platform() {
let expectedPlatform;
if (isAndroid) {
expectedPlatform = 'Android';
} else if (__VISIONOS__) {
expectedPlatform = 'visionOS';
} else {
expectedPlatform = 'iOS';
}
Expand Down
26 changes: 19 additions & 7 deletions apps/automated/src/test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as TKUnit from './tk-unit';
import './ui-test';

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

export function isRunningOnEmulator(): boolean {
Expand All @@ -16,7 +16,7 @@ export function isRunningOnEmulator(): boolean {
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('sdk') > -1 ||
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('emulator') > -1
); // VS Emulator
} else if (Device.os === platformNames.ios) {
} else if (__APPLE__) {
return __dirname.search('Simulator') > -1;
}
}
Expand Down Expand Up @@ -218,8 +218,8 @@ allTests['PROGRESS'] = progressTests;
import * as placeholderTests from './ui/placeholder/placeholder-tests';
allTests['PLACEHOLDER'] = placeholderTests;

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

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

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

Expand Down Expand Up @@ -397,12 +398,23 @@ function showReportPage(finalMessage: string) {
messageContainer.text = finalMessage;
stack.addChild(messageContainer);

if (__VISIONOS__) {
// just helps make the results screen more clear on Vision Pro
btn.style.fontSize = 22;
stack.style.padding = 20;
stack.style.marginTop = 20;
messageContainer.style.fontSize = 22;
messageContainer.style.color = new Color('#fff');
}

Frame.topmost().navigate({
create: () => {
const page = new Page();
page.content = stack;
messageContainer.focus();
page.style.fontSize = 11;
if (!__VISIONOS__) {
page.style.fontSize = 11;
}
if (isAndroid) {
page.on('navigatedTo', () => {
messageContainer.focus();
Expand Down Expand Up @@ -473,7 +485,7 @@ export function runAll(testSelector?: string) {
new TestInfo(() => {
running = true;
startTime = TKUnit.time();
})
}),
);
for (const name in allTests) {
if (singleModuleName && singleModuleName !== name.toLowerCase()) {
Expand Down Expand Up @@ -519,7 +531,7 @@ export function runAll(testSelector?: string) {
new TestInfo(function () {
testsQueue = [];
running = false;
})
}),
);

TKUnit.runTests(testsQueue, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function test_set_TNS_value_updates_native_value() {
}

// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
if (platform.Device.os === platform.platformNames.ios) {
if (__APPLE__) {
exports.test_set_color = function () {
var ai = new activityIndicatorModule.ActivityIndicator();
ai.color = new color.Color('red');
Expand Down
4 changes: 2 additions & 2 deletions apps/automated/src/ui/label/label-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as fs from '@nativescript/core/file-system';

import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
import { GridLayout } from '@nativescript/core/ui/layouts/grid-layout';
import { isIOS, isAndroid } from '@nativescript/core/platform';
import { isIOS, isAndroid, isApple } from '@nativescript/core/platform';
import { Label } from '@nativescript/core/ui/label';
import { LayoutBase } from '@nativescript/core/ui/layouts/layout-base';
import * as helper from '../../ui-helper';
Expand Down Expand Up @@ -606,7 +606,7 @@ export class LabelTest extends testModule.UITest<LabelModule.Label> {
}

private requestLayoutFixture(expectRequestLayout: boolean, initialValue: string, setup: (label: Label) => LayoutBase): void {
if (!isIOS) {
if (!isApple) {
return;
}

Expand Down
6 changes: 3 additions & 3 deletions apps/automated/src/ui/layouts/safe-area-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as view from '@nativescript/core/ui/core/view';
import * as testModule from '../../ui-test';
import * as platform from '@nativescript/core/platform';
import * as helper from '../../ui-helper';
import { Builder, Page, Label, GridLayout } from '@nativescript/core';
import { Builder, Page, Label, GridLayout, Utils } from '@nativescript/core';
import { dipToDp, left, top, right, bottom, height, width, equal, closeEnough, lessOrCloseEnough, greaterOrCloseEnough, isLeftAlignedWith, isRightAlignedWith, isTopAlignedWith, isBottomAlignedWith, isLeftWith, isAboveWith, isRightWith, isBelowWith } from './layout-tests-helper';

export class SafeAreaTests extends testModule.UITest<any> {
Expand Down Expand Up @@ -84,10 +84,10 @@ export class SafeAreaTests extends testModule.UITest<any> {
}

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

const insets = layout.getSafeAreaInsets();
equal(insets.top, topInset, `${layout}.topInset - actual:${insets.top}; expected: ${topInset}`);
Expand Down
2 changes: 1 addition & 1 deletion apps/automated/src/ui/page/modal-tab-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function onShownModally(args: ShownModallyData) {
TKUnit.assertEqual(hostFrame.currentPage.modal, tabView, 'hostFrame.currentPage.modal should be equal to the tabView instance on tabView.shownModally event handler.');

// shownModally raised after page.NavigatedTo on iOS
if (isIOS) {
if (__APPLE__) {
args.closeCallback('return value');
}
}
8 changes: 6 additions & 2 deletions apps/automated/src/ui/page/page-tests-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function _test_PageNavigation_EventSequence(withTransition: boolean) {
? {
name: 'slide',
duration: 10,
}
}
: undefined,
};

Expand Down Expand Up @@ -370,7 +370,7 @@ export function test_page_backgroundColor() {
helper.navigate(factory);

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

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

helper.navigate(masterPageFactory);
Expand Down
2 changes: 1 addition & 1 deletion apps/automated/src/ui/progress/progress-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function test_set_value_greater_than_max_should_set_value_to_max() {
}

// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
if (platform.Device.os === platform.platformNames.ios) {
if (__APPLE__) {
exports.test_set_color = function () {
var progress = new progressModule.Progress();
progress.color = new color.Color('red');
Expand Down
4 changes: 4 additions & 0 deletions apps/automated/src/ui/root-view/root-view-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export function test_custom_component_rootview_layout_updates() {
}

export function test_tabview_rootview_css_applied() {
if (__VISIONOS__) {
// TODO: investigate resetRootView cases with visionOS setup
return;
}
var entry = {
moduleName: 'ui/root-view/root-modules/tabview-root',
};
Expand Down
6 changes: 4 additions & 2 deletions apps/automated/src/ui/styling/root-views-css-classes-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const ROOT_CSS_CLASS = 'ns-root';
const MODAL_CSS_CLASS = 'ns-modal';
const ANDROID_PLATFORM_CSS_CLASS = 'ns-android';
const IOS_PLATFORM_CSS_CLASS = 'ns-ios';
const VISIONOS_PLATFORM_CSS_CLASS = 'ns-visionos';
const PHONE_DEVICE_TYPE_CSS_CLASS = 'ns-phone';
const TABLET_DEVICE_TYPE_CSS_CLASS = 'ns-tablet';
const PORTRAIT_ORIENTATION_CSS_CLASS = 'ns-portrait';
Expand Down Expand Up @@ -41,7 +42,8 @@ function _test_platform_css_class(rootView: View, shouldSetClassName: boolean) {
TKUnit.assertTrue(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is missing`);
TKUnit.assertFalse(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is present`);
} else {
TKUnit.assertTrue(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is missing`);
const cssClass = __VISIONOS__ ? VISIONOS_PLATFORM_CSS_CLASS : IOS_PLATFORM_CSS_CLASS;
TKUnit.assertTrue(cssClasses.has(cssClass), `${cssClass} CSS class is missing`);
TKUnit.assertFalse(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is present`);
}

Expand Down Expand Up @@ -113,7 +115,7 @@ function _test_system_appearance_css_class(rootView: View, shouldSetClassName: b
} else {
systemAppearance = Application.ios.systemAppearance;
}
if (isIOS && Utils.ios.MajorVersion <= 12) {
if (isIOS && !__VISIONOS__ && Utils.SDK_VERSION <= 12) {
TKUnit.assertFalse(cssClasses.has(DARK_SYSTEM_APPEARANCE_CSS_CLASS), `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`);
TKUnit.assertFalse(cssClasses.has(LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`);
} else if (systemAppearance === 'dark') {
Expand Down
2 changes: 1 addition & 1 deletion apps/automated/src/ui/switch/switch-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function test_default_native_values() {
}

// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
if (platform.Device.os === platform.platformNames.ios) {
if (__APPLE__) {
exports.test_set_color = function () {
var mySwitch = new switchModule.Switch();
mySwitch.color = new Color('red');
Expand Down
Loading

0 comments on commit 01d537b

Please sign in to comment.