mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat(visionos): ui-mobile-base supporting xros plus improvements to window handling (#10478)
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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.');
|
||||
@@ -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.');
|
||||
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,6 +5,8 @@ export function test_platform() {
|
||||
let expectedPlatform;
|
||||
if (isAndroid) {
|
||||
expectedPlatform = 'Android';
|
||||
} else if (__VISIONOS__) {
|
||||
expectedPlatform = 'visionOS';
|
||||
} else {
|
||||
expectedPlatform = 'iOS';
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -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()) {
|
||||
@@ -519,7 +531,7 @@ export function runAll(testSelector?: string) {
|
||||
new TestInfo(function () {
|
||||
testsQueue = [];
|
||||
running = false;
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
TKUnit.runTests(testsQueue, 0);
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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';
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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> {
|
||||
@@ -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}`);
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ function _test_PageNavigation_EventSequence(withTransition: boolean) {
|
||||
? {
|
||||
name: 'slide',
|
||||
duration: 10,
|
||||
}
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
|
||||
@@ -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');
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
@@ -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';
|
||||
@@ -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`);
|
||||
}
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -63,89 +63,95 @@ function createTabItemsWithFrames(count: number) {
|
||||
}
|
||||
|
||||
export function test_frame_topmost_matches_selectedIndex() {
|
||||
const items = createTabItemsWithFrames(3);
|
||||
const tabView = new TabView();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
if (!__VISIONOS__) {
|
||||
// TODO: investigate TabView conditions on visionOS
|
||||
const items = createTabItemsWithFrames(3);
|
||||
const tabView = new TabView();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
tabView.androidOffscreenTabLimit = 0;
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab0 Frame0');
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab0 Frame0');
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[1].page], () => (tabView.selectedIndex = 1));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab1 Frame1');
|
||||
waitUntilNavigatedToMaxTimeout([items[1].page], () => (tabView.selectedIndex = 1));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab1 Frame1');
|
||||
}
|
||||
}
|
||||
|
||||
export function test_offset_zero_should_raise_same_events() {
|
||||
let actualEventsRaised = [];
|
||||
if (!__VISIONOS__) {
|
||||
// TODO: investigate cases where Application.resetRootView is called on visionOS
|
||||
let actualEventsRaised = [];
|
||||
|
||||
function resetActualEventsRaised() {
|
||||
for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
actualEventsRaised[i] = [];
|
||||
function resetActualEventsRaised() {
|
||||
for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
actualEventsRaised[i] = [];
|
||||
}
|
||||
}
|
||||
|
||||
function attachEventHandlers(i: number, item) {
|
||||
actualEventsRaised.push([]);
|
||||
|
||||
const page = item.page;
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
const frame = item.frame;
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
const items = createTabItemsWithFrames(3);
|
||||
|
||||
items.forEach((item, i) => {
|
||||
attachEventHandlers(i, item);
|
||||
});
|
||||
|
||||
const tabView = new TabView();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
|
||||
const expectedEventsRaisedAfterTabCreated = [['Tab0 Frame0 loaded', 'Tab0 Frame0 Page0 navigatingTo', 'Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 Page0 navigatedTo'], [], []];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
resetActualEventsRaised();
|
||||
waitUntilNavigatedToMaxTimeout([items[2].page], () => (tabView.selectedIndex = 2));
|
||||
|
||||
const expectedEventsRaisedAfterSelectThirdTab = [['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'], [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
resetActualEventsRaised();
|
||||
|
||||
waitUntilTabViewReady(items[0].page, () => (tabView.selectedIndex = 0));
|
||||
|
||||
const expectedEventsRaisedAfterReturnToFirstTab = [['Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 loaded'], [], ['Tab2 Frame2 Page2 unloaded', 'Tab2 Frame2 unloaded']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
}
|
||||
|
||||
function attachEventHandlers(i: number, item) {
|
||||
actualEventsRaised.push([]);
|
||||
|
||||
const page = item.page;
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
const frame = item.frame;
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
const items = createTabItemsWithFrames(3);
|
||||
|
||||
items.forEach((item, i) => {
|
||||
attachEventHandlers(i, item);
|
||||
});
|
||||
|
||||
const tabView = new TabView();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
|
||||
const expectedEventsRaisedAfterTabCreated = [['Tab0 Frame0 loaded', 'Tab0 Frame0 Page0 navigatingTo', 'Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 Page0 navigatedTo'], [], []];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
resetActualEventsRaised();
|
||||
waitUntilNavigatedToMaxTimeout([items[2].page], () => (tabView.selectedIndex = 2));
|
||||
|
||||
const expectedEventsRaisedAfterSelectThirdTab = [['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'], [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
resetActualEventsRaised();
|
||||
|
||||
waitUntilTabViewReady(items[0].page, () => (tabView.selectedIndex = 0));
|
||||
|
||||
const expectedEventsRaisedAfterReturnToFirstTab = [['Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 loaded'], [], ['Tab2 Frame2 Page2 unloaded', 'Tab2 Frame2 unloaded']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
}
|
||||
|
||||
export function test_android_default_offset_should_preload_1_tab_on_each_side() {
|
||||
|
||||
@@ -87,7 +87,7 @@ export var testSetTextUndefined = function () {
|
||||
};
|
||||
|
||||
// Supported for ios only.
|
||||
if (platform.Device.os === platform.platformNames.ios) {
|
||||
if (__APPLE__) {
|
||||
exports.test_set_color = function () {
|
||||
helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) {
|
||||
var textView = <textViewModule.TextView>views[0];
|
||||
|
||||
@@ -322,7 +322,7 @@ export function test_parse_ShouldParsePlatformSpecificProperties() {
|
||||
var p = <Page>Builder.parse("<Page><TextField ios:editable='False' android:editable='True' /></Page>");
|
||||
var tf = <TextField>p.content;
|
||||
|
||||
if (Device.os === platformNames.ios) {
|
||||
if (__APPLE__) {
|
||||
TKUnit.assertFalse(tf.editable, 'Expected result: false; Actual result: ' + tf.editable + '; type: ' + typeof tf.editable);
|
||||
} else {
|
||||
TKUnit.assertTrue(tf.editable, 'Expected result: true; Actual result: ' + tf.editable + '; type: ' + typeof tf.editable);
|
||||
@@ -331,7 +331,7 @@ export function test_parse_ShouldParsePlatformSpecificProperties() {
|
||||
|
||||
export function test_parse_ShouldParsePlatformSpecificComponents() {
|
||||
var p = <Page>Builder.parse('<Page><ios><TextField /></ios><android><Label /></android></Page>');
|
||||
if (Device.os === platformNames.ios) {
|
||||
if (__APPLE__) {
|
||||
TKUnit.assert(p.content instanceof TextField, 'Expected result: TextField; Actual result: ' + p.content);
|
||||
} else {
|
||||
TKUnit.assert(p.content instanceof Label, 'Expected result: Label; Actual result: ' + p.content);
|
||||
|
||||
Reference in New Issue
Block a user