mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00

* chore: move tns-core-modules to nativescript-core * chore: preparing compat generate script * chore: add missing definitions * chore: no need for http-request to be private * chore: packages chore * test: generate tests for tns-core-modules * chore: add anroid module for consistency * chore: add .npmignore * chore: added privateModulesWhitelist * chore(webpack): added bundle-entry-points * chore: scripts * chore: tests changed to use @ns/core * test: add scoped-packages test project * test: fix types * test: update test project * chore: build scripts * chore: update build script * chore: npm scripts cleanup * chore: make the compat pgk work with old wp config * test: generate diff friendly tests * chore: create barrel exports * chore: move files after rebase * chore: typedoc config * chore: compat mode * chore: review of barrels * chore: remove tns-core-modules import after rebase * chore: dev workflow setup * chore: update developer-workflow * docs: experiment with API extractor * chore: api-extractor and barrel exports * chore: api-extractor configs * chore: generate d.ts rollup with api-extractor * refactor: move methods inside Frame * chore: fic tests to use Frame static methods * refactor: create Builder class * refactor: use Builder class in tests * refactor: include Style in ui barrel * chore: separate compat build script * chore: fix tslint errors * chore: update NATIVESCRIPT_CORE_ARGS * chore: fix compat pack * chore: fix ui-test-app build with linked modules * chore: Application, ApplicationSettings, Connectivity and Http * chore: export Trace, Profiling and Utils * refactor: Static create methods for ImageSource * chore: fix deprecated usages of ImageSource * chore: move Span and FormattedString to ui * chore: add events-args and ImageSource to index files * chore: check for CLI >= 6.2 when building for IOS * chore: update travis build * chore: copy Pod file to compat package * chore: update error msg ui-tests-app * refactor: Apply suggestions from code review Co-Authored-By: Martin Yankov <m.i.yankov@gmail.com> * chore: typings and refs * chore: add missing d.ts files for public API * chore: adress code review FB * chore: update api-report * chore: dev-workflow for other apps * chore: api update * chore: update api-report
284 lines
9.0 KiB
TypeScript
284 lines
9.0 KiB
TypeScript
import * as TKUnit from "../../tk-unit";
|
|
import * as helper from "../../ui-helper";
|
|
import { Label } from "@nativescript/core/ui/label";
|
|
import { StackLayout } from "@nativescript/core/ui/layouts/stack-layout";
|
|
import { Frame } from "@nativescript/core/ui/frame";
|
|
import { Page } from "@nativescript/core/ui/page";
|
|
import { ListView, ItemEventData } from "@nativescript/core/ui/list-view";
|
|
import { BottomNavigation, TabContentItem, TabStrip, TabStripItem } from "@nativescript/core/ui/bottom-navigation";
|
|
import { Button } from "@nativescript/core/ui/button";
|
|
|
|
var ASYNC = 2;
|
|
|
|
function _createBottomNavigation(): BottomNavigation {
|
|
var tabView = new BottomNavigation();
|
|
tabView.id = "BottomNavigation";
|
|
|
|
return tabView;
|
|
}
|
|
|
|
function _createContentItems(count: number): Array<TabContentItem> {
|
|
const items = new Array<TabContentItem>();
|
|
for (let i = 0; i < count; i++) {
|
|
const label = new Label();
|
|
label.text = "Tab " + i;
|
|
const tabEntry = new TabContentItem();
|
|
tabEntry.content = label;
|
|
items.push(tabEntry);
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
function _createTabStrip(count: number): TabStrip {
|
|
const items = new Array<TabStripItem>();
|
|
for (let i = 0; i < count; i++) {
|
|
let tabStripEntry = new TabStripItem();
|
|
tabStripEntry.title = "Tab " + i;
|
|
items.push(tabStripEntry);
|
|
}
|
|
|
|
const tabStrip = new TabStrip();
|
|
tabStrip.items = items;
|
|
|
|
return tabStrip;
|
|
}
|
|
|
|
function _createListView(): ListView {
|
|
var listView = new ListView();
|
|
listView.id = "ListView";
|
|
var items = Array.apply(null, Array(10)).map(function (_, i) { return i; });
|
|
|
|
listView.on(ListView.itemLoadingEvent, function (args: ItemEventData) {
|
|
var button = <Button>args.view;
|
|
if (!button) {
|
|
button = new Button();
|
|
button.on(Button.tapEvent, _clickHandlerFactory(args.index));
|
|
args.view = button;
|
|
}
|
|
|
|
button.text = "Button" + args.index;
|
|
button.id = button.text;
|
|
});
|
|
|
|
listView.items = items;
|
|
|
|
return listView;
|
|
}
|
|
|
|
function _clickHandlerFactory(index: number) {
|
|
return function () {
|
|
var pageFactory = function (): Page {
|
|
var detailsLabel = new Label();
|
|
detailsLabel.text = "Details Page " + index;
|
|
var detailsPage = new Page();
|
|
detailsPage.id = "details-page";
|
|
detailsPage.content = detailsLabel;
|
|
|
|
return detailsPage;
|
|
};
|
|
|
|
helper.navigateWithHistory(pageFactory);
|
|
};
|
|
}
|
|
|
|
function _createFrameView(): Frame {
|
|
const frame = new Frame();
|
|
frame.navigate({ create: () => new Page() });
|
|
|
|
return frame;
|
|
}
|
|
|
|
export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
|
|
// https://github.com/NativeScript/NativeScript/issues/6490
|
|
const topFrame = Frame.topmost();
|
|
|
|
let tabViewPage: Page;
|
|
let tabView: BottomNavigation;
|
|
|
|
const pageFactory = function (): Page {
|
|
tabView = _createBottomNavigation();
|
|
let items = Array<TabContentItem>();
|
|
let tabViewitem = new TabContentItem();
|
|
// tabViewitem.title = "Item1";
|
|
tabViewitem.content = _createFrameView();
|
|
items.push(tabViewitem);
|
|
|
|
let tabViewitem2 = new TabContentItem();
|
|
// tabViewitem2.title = "Item2";
|
|
tabViewitem2.content = _createFrameView();
|
|
items.push(tabViewitem2);
|
|
|
|
tabView.items = items;
|
|
tabView.tabStrip = _createTabStrip(2);
|
|
|
|
tabViewPage = new Page();
|
|
tabViewPage.id = "tab-view-page";
|
|
tabViewPage.content = tabView;
|
|
|
|
return tabViewPage;
|
|
};
|
|
|
|
helper.waitUntilNavigatedFrom(() => topFrame.navigate(pageFactory), topFrame);
|
|
|
|
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
|
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
|
|
|
// navigate to a different page
|
|
helper.waitUntilNavigatedFrom(() => topFrame.navigate({ create: () => new Page(), animated: false }), topFrame);
|
|
|
|
// navigate back to the page that hold the tabview with nested frames
|
|
topFrame.goBack();
|
|
|
|
// make sure the app did not crash
|
|
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty());
|
|
}
|
|
|
|
export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithAListViewTheListViewIsThere() {
|
|
var topFrame = Frame.topmost();
|
|
|
|
let tabViewPage: Page;
|
|
let tabView: BottomNavigation;
|
|
|
|
let pageFactory = function (): Page {
|
|
tabView = _createBottomNavigation();
|
|
let items = Array<TabContentItem>();
|
|
let tabViewitem = new TabContentItem();
|
|
// tabViewitem.title = "List";
|
|
tabViewitem.content = _createListView();
|
|
items.push(tabViewitem);
|
|
|
|
let label = new Label();
|
|
label.text = "About";
|
|
let aboutLayout = new StackLayout();
|
|
aboutLayout.id = "AboutLayout";
|
|
aboutLayout.addChild(label);
|
|
tabViewitem = new TabContentItem();
|
|
// tabViewitem.title = "About";
|
|
tabViewitem.content = aboutLayout;
|
|
items.push(tabViewitem);
|
|
|
|
tabView.items = items;
|
|
tabView.tabStrip = _createTabStrip(2);
|
|
|
|
tabViewPage = new Page();
|
|
tabViewPage.id = "tab-view-page";
|
|
tabViewPage.content = tabView;
|
|
|
|
return tabViewPage;
|
|
};
|
|
|
|
let rootPage = helper.getCurrentPage();
|
|
|
|
helper.navigateWithHistory(pageFactory);
|
|
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
|
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
|
|
|
// This will navigate to a details page. The wait is inside the method.
|
|
_clickTheFirstButtonInTheListViewNatively(tabView);
|
|
|
|
Frame.goBack();
|
|
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty()); //() => topFrame.currentPage === tabViewPage);
|
|
|
|
Frame.goBack();
|
|
|
|
TKUnit.waitUntilReady(() => topFrame.currentPage === rootPage);
|
|
|
|
TKUnit.assert(tabView.items[0].content instanceof ListView, "ListView should be created when navigating back to the main page.");
|
|
}
|
|
|
|
function tabViewIsFullyLoaded(tabView: BottomNavigation): boolean {
|
|
if (!tabView.isLoaded) {
|
|
return false;
|
|
}
|
|
|
|
const i = tabView.selectedIndex;
|
|
if (i >= 0 && !tabView.items[i].isLoaded) {
|
|
return false;
|
|
}
|
|
|
|
if (tabView.android) {
|
|
const bottomNavigationBar = (<org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar);
|
|
if (bottomNavigationBar.getItemCount() === 0) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
|
|
let topFrame = Frame.topmost();
|
|
let rootPage = helper.getCurrentPage();
|
|
|
|
let itemCount = 2;
|
|
let loadedEventsCount = [0, 0];
|
|
let unloadedEventsCount = [0, 0];
|
|
|
|
const tabView = _createBottomNavigation();
|
|
tabView.items = _createContentItems(itemCount);
|
|
tabView.tabStrip = _createTabStrip(itemCount);
|
|
|
|
function createLoadedFor(tabIndex: number) {
|
|
return function () {
|
|
loadedEventsCount[tabIndex] = loadedEventsCount[tabIndex] + 1;
|
|
};
|
|
}
|
|
|
|
function createUnloadedFor(tabIndex: number) {
|
|
return function () {
|
|
unloadedEventsCount[tabIndex] = unloadedEventsCount[tabIndex] + 1;
|
|
};
|
|
}
|
|
|
|
tabView.items.forEach((item, i) => {
|
|
item.content.on("loaded", createLoadedFor(i));
|
|
item.content.on("unloaded", createUnloadedFor(i));
|
|
});
|
|
|
|
const tabViewPage = new Page();
|
|
helper.navigateWithHistory(() => {
|
|
tabViewPage.content = tabView;
|
|
|
|
return tabViewPage;
|
|
});
|
|
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView), ASYNC);
|
|
|
|
const detailsPage = new Page();
|
|
helper.navigateWithHistory(() => detailsPage);
|
|
TKUnit.assertEqual(topFrame.currentPage, detailsPage);
|
|
|
|
helper.goBack();
|
|
TKUnit.assertEqual(topFrame.currentPage, tabViewPage);
|
|
|
|
for (let i = 0; i < itemCount; i++) {
|
|
tabView.items[i].content.off("loaded");
|
|
tabView.items[i].content.off("unloaded");
|
|
}
|
|
|
|
helper.goBack();
|
|
TKUnit.assertEqual(topFrame.currentPage, rootPage);
|
|
|
|
topFrame.currentPage.id = null;
|
|
|
|
TKUnit.arrayAssert(loadedEventsCount, [2, 0]);
|
|
TKUnit.arrayAssert(unloadedEventsCount, [1, 0]);
|
|
}
|
|
|
|
function _clickTheFirstButtonInTheListViewNatively(tabView: BottomNavigation) {
|
|
if (tabView.android) {
|
|
const androidListView = <android.widget.ListView>tabView.items[0].content.nativeView;
|
|
// var viewPager: android.support.v4.view.ViewPager = (<any>tabView)._viewPager;
|
|
// var androidListView = <android.widget.ListView>viewPager.getChildAt(0);
|
|
var stackLayout = <org.nativescript.widgets.StackLayout>androidListView.getChildAt(0);
|
|
var button = <android.widget.Button>stackLayout.getChildAt(0);
|
|
button.performClick();
|
|
}
|
|
else {
|
|
const tableView = <UITableView>tabView.ios.selectedViewController.view.subviews[0];
|
|
const cell = <UITableViewCell>tableView.cellForRowAtIndexPath(NSIndexPath.indexPathForItemInSection(0, 0));
|
|
const btn = <UIButton>cell.contentView.subviews[0];
|
|
btn.sendActionsForControlEvents(UIControlEvents.TouchUpInside);
|
|
}
|
|
}
|