diff --git a/.vscode/launch.json b/.vscode/launch.json index 75e18bd2f..38041cb91 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -66,10 +66,8 @@ "platform": "android", "appRoot": "${workspaceRoot}/tests", "sourceMaps": true, + "stopOnEntry": true, "watch": true, - // "tnsArgs": [ - // "--debug-brk" - // ] }, // { // "name": "Test on Android", diff --git a/e2e/ui-tests-app/app/bottom-navigation/background-color-page.css b/e2e/ui-tests-app/app/bottom-navigation/background-color-page.css new file mode 100644 index 000000000..27ce526db --- /dev/null +++ b/e2e/ui-tests-app/app/bottom-navigation/background-color-page.css @@ -0,0 +1,7 @@ +BottomNavigation { + background-color: gold; +} + +TabStrip { + background-color: skyblue; +} \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/background-color-page.xml b/e2e/ui-tests-app/app/bottom-navigation/background-color-page.xml index a931de491..8c771d54f 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/background-color-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/background-color-page.xml @@ -3,7 +3,7 @@ - + @@ -11,13 +11,13 @@ - - diff --git a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml index b174dcfba..ea3ab58d7 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml @@ -4,20 +4,20 @@ - - + + - - + + - - + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts index 5301c28e9..199c5c566 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts +++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts @@ -1,7 +1,7 @@ import { BottomNavigation, SelectedIndexChangedEventData } from "tns-core-modules/ui/bottom-navigation"; export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) { - const bottomNav = args.object as BottomNavigation; + const bottomNav = args.object; const newItem = bottomNav.tabStrip.items[args.newIndex]; if (newItem) { diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml index 4b77e353a..014b9a249 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml @@ -1,4 +1,4 @@ - + diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-title-placement-page.xml b/e2e/ui-tests-app/app/bottom-navigation/icon-title-placement-page.xml index 36b74e3f0..d3b604304 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/icon-title-placement-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/icon-title-placement-page.xml @@ -11,19 +11,19 @@ - - - diff --git a/e2e/ui-tests-app/app/bottom-navigation/issue-5470-page.xml b/e2e/ui-tests-app/app/bottom-navigation/issue-5470-page.xml index c1f8d3785..c5993a4d8 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/issue-5470-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/issue-5470-page.xml @@ -23,5 +23,5 @@ - + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/background-color-page.css b/e2e/ui-tests-app/app/tabs/background-color-page.css new file mode 100644 index 000000000..6c53c0e65 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/background-color-page.css @@ -0,0 +1,7 @@ +Tabs { + background-color: gold; +} + +TabStrip { + background-color: skyblue; +} \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/background-color-page.xml b/e2e/ui-tests-app/app/tabs/background-color-page.xml index a931de491..12860bc43 100644 --- a/e2e/ui-tests-app/app/tabs/background-color-page.xml +++ b/e2e/ui-tests-app/app/tabs/background-color-page.xml @@ -1,24 +1,24 @@ - + - + - - + + - - + + - - + + - + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/color-page.xml b/e2e/ui-tests-app/app/tabs/color-page.xml index b174dcfba..a0dfb57aa 100644 --- a/e2e/ui-tests-app/app/tabs/color-page.xml +++ b/e2e/ui-tests-app/app/tabs/color-page.xml @@ -1,23 +1,23 @@ - + - + - - + + - - + + - - + + - + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/default-page.ts b/e2e/ui-tests-app/app/tabs/default-page.ts index 6ef17fcfa..50e5c8233 100644 --- a/e2e/ui-tests-app/app/tabs/default-page.ts +++ b/e2e/ui-tests-app/app/tabs/default-page.ts @@ -1,17 +1,17 @@ import { EventData } from "tns-core-modules/data/observable"; import { Page } from "tns-core-modules/ui/page"; -import { BottomNavigation } from "tns-core-modules/ui/bottom-navigation"; +import { Tabs } from "tns-core-modules/ui/tabs"; export function goToFirst(args: EventData) { const page = (args.object).page; - const bottomNav = page.getViewById("bottomNav"); + const tabsNav = page.getViewById("tabsNav"); - bottomNav.selectedIndex = 0; + tabsNav.selectedIndex = 0; } export function goToSecond(args: EventData) { const page = (args.object).page; - const bottomNav = page.getViewById("bottomNav"); + const tabsNav = page.getViewById("tabsNav"); - bottomNav.selectedIndex = 1; + tabsNav.selectedIndex = 1; } diff --git a/e2e/ui-tests-app/app/tabs/default-page.xml b/e2e/ui-tests-app/app/tabs/default-page.xml index 260450593..396478113 100644 --- a/e2e/ui-tests-app/app/tabs/default-page.xml +++ b/e2e/ui-tests-app/app/tabs/default-page.xml @@ -1,6 +1,6 @@ - + @@ -18,7 +18,7 @@ --> - + diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.ts b/e2e/ui-tests-app/app/tabs/icon-change-page.ts index 5301c28e9..1a466d6a6 100644 --- a/e2e/ui-tests-app/app/tabs/icon-change-page.ts +++ b/e2e/ui-tests-app/app/tabs/icon-change-page.ts @@ -1,14 +1,14 @@ -import { BottomNavigation, SelectedIndexChangedEventData } from "tns-core-modules/ui/bottom-navigation"; +import { Tabs, SelectedIndexChangedEventData } from "tns-core-modules/ui/tabs"; export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) { - const bottomNav = args.object as BottomNavigation; + const tabsNav = args.object; - const newItem = bottomNav.tabStrip.items[args.newIndex]; + const newItem = tabsNav.tabStrip.items[args.newIndex]; if (newItem) { newItem.iconSource = "res://icon"; } - const oldItem = bottomNav.tabStrip.items[args.oldIndex]; + const oldItem = tabsNav.tabStrip.items[args.oldIndex]; if (oldItem) { oldItem.iconSource = "res://testlogo"; } diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.xml b/e2e/ui-tests-app/app/tabs/icon-change-page.xml index 4b77e353a..e6ddb809f 100644 --- a/e2e/ui-tests-app/app/tabs/icon-change-page.xml +++ b/e2e/ui-tests-app/app/tabs/icon-change-page.xml @@ -1,8 +1,8 @@ - - + + - + @@ -19,5 +19,5 @@ + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/icon-title-placement-page.xml b/e2e/ui-tests-app/app/tabs/icon-title-placement-page.xml index 36b74e3f0..4caed0e7e 100644 --- a/e2e/ui-tests-app/app/tabs/icon-title-placement-page.xml +++ b/e2e/ui-tests-app/app/tabs/icon-title-placement-page.xml @@ -1,30 +1,30 @@ - + - + - - - + + + - - + + - - + + - - + + - + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/issue-5470-page.xml b/e2e/ui-tests-app/app/tabs/issue-5470-page.xml index c1f8d3785..a47f48d18 100644 --- a/e2e/ui-tests-app/app/tabs/issue-5470-page.xml +++ b/e2e/ui-tests-app/app/tabs/issue-5470-page.xml @@ -1,9 +1,9 @@ - + - + @@ -22,6 +22,6 @@ - - + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/main-page.ts b/e2e/ui-tests-app/app/tabs/main-page.ts index d34357eec..b7d492781 100644 --- a/e2e/ui-tests-app/app/tabs/main-page.ts +++ b/e2e/ui-tests-app/app/tabs/main-page.ts @@ -11,14 +11,14 @@ export function pageLoaded(args: EventData) { export function loadExamples() { const examples = new Map(); - examples.set("default", "tabs/default-page"); - examples.set("issue-5470", "tabs/issue-5470-page"); + examples.set("tabs", "tabs/tabs-page"); + examples.set("issue-5470", "tabs/issue-5470"); examples.set("background-color", "tabs/background-color-page"); - examples.set("color", "tabs/color-page"); - examples.set("icon-title-placement", "tabs/icon-title-placement-page"); - examples.set("icon-change", "tabs/icon-change-page"); - examples.set("swipe-enabled", "tabs/swipe-enabled-page"); - examples.set("tabs-position", "tabs/tabs-position-page"); + examples.set("color", "tabs/color"); + examples.set("icon-title-placement", "tabs/icon-title-placement"); + examples.set("icon-change", "tabs/icon-change"); + examples.set("swipe-enabled", "tabs/swipe-enabled"); + examples.set("tabs-position", "tabs/tabs-position"); return examples; } diff --git a/e2e/ui-tests-app/app/tabs/tabs-page.ts b/e2e/ui-tests-app/app/tabs/tabs-page.ts new file mode 100644 index 000000000..50e5c8233 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/tabs-page.ts @@ -0,0 +1,17 @@ +import { EventData } from "tns-core-modules/data/observable"; +import { Page } from "tns-core-modules/ui/page"; +import { Tabs } from "tns-core-modules/ui/tabs"; + +export function goToFirst(args: EventData) { + const page = (args.object).page; + const tabsNav = page.getViewById("tabsNav"); + + tabsNav.selectedIndex = 0; +} + +export function goToSecond(args: EventData) { + const page = (args.object).page; + const tabsNav = page.getViewById("tabsNav"); + + tabsNav.selectedIndex = 1; +} diff --git a/e2e/ui-tests-app/app/tabs/tabs-page.xml b/e2e/ui-tests-app/app/tabs/tabs-page.xml new file mode 100644 index 000000000..396478113 --- /dev/null +++ b/e2e/ui-tests-app/app/tabs/tabs-page.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/tests/app/app-new-page.css b/tests/app/livesync/app-new-page.css similarity index 100% rename from tests/app/app-new-page.css rename to tests/app/livesync/app-new-page.css diff --git a/tests/app/app-new-sass-page.scss b/tests/app/livesync/app-new-scss-page.scss similarity index 100% rename from tests/app/app-new-sass-page.scss rename to tests/app/livesync/app-new-scss-page.scss diff --git a/tests/app/application-page.css b/tests/app/livesync/application-page.css similarity index 100% rename from tests/app/application-page.css rename to tests/app/livesync/application-page.css diff --git a/tests/app/button-page.css b/tests/app/livesync/button-css-page.css similarity index 100% rename from tests/app/button-page.css rename to tests/app/livesync/button-css-page.css diff --git a/tests/app/livesync/button-scss-page.scss b/tests/app/livesync/button-scss-page.scss new file mode 100644 index 000000000..1f811bb24 --- /dev/null +++ b/tests/app/livesync/button-scss-page.scss @@ -0,0 +1,3 @@ +Button { + color: green; +} \ No newline at end of file diff --git a/tests/app/livesync/livesync-button-page.scss b/tests/app/livesync/livesync-button-page.scss index 3b012936e..e69de29bb 100644 --- a/tests/app/livesync/livesync-button-page.scss +++ b/tests/app/livesync/livesync-button-page.scss @@ -1,3 +0,0 @@ -Button { - color: cyan; -} \ No newline at end of file diff --git a/tests/app/livesync/livesync-tests.ts b/tests/app/livesync/livesync-tests.ts index 04d54584c..7bf950f90 100644 --- a/tests/app/livesync/livesync-tests.ts +++ b/tests/app/livesync/livesync-tests.ts @@ -3,40 +3,57 @@ import * as TKUnit from "../tk-unit"; import * as app from "tns-core-modules/application/application"; import * as frame from "tns-core-modules/ui/frame"; -import * as fs from "tns-core-modules/file-system"; import { Color } from "tns-core-modules/color"; import { createViewFromEntry } from "tns-core-modules/ui/builder"; import { Page } from "tns-core-modules/ui/page"; import { Frame } from "tns-core-modules/ui/frame"; -const appCssFileName = "/application-page.css"; -const appNewCssFileName = "app-new-page.css"; -const appNewScssFileName = "app-new-sass-page.css"; -const buttonCssFileName = "/button-page.css"; +const LIVESYNC_FOLDER = "livesync/"; -const buttonPageModuleName = "livesync/livesync-button-page"; -const buttonHtmlPageFileName = "./livesync/livesync-button-page.html"; -const buttonXmlPageFileName = "./livesync/livesync-button-page.xml"; -const buttonJsPageFileName = "./livesync/livesync-button-page.js"; -const buttonTsPageFileName = "./livesync/livesync-button-page.ts"; -const buttonScssPageFileName = "./livesync/livesync-button-page.scss"; -const labelPageModuleName = "livesync/livesync-label-page"; +const appCssFileName = `${LIVESYNC_FOLDER}application-page.css`; +const appNewCssFileName = `${LIVESYNC_FOLDER}app-new-page.css`; +// `.scss` module registers in webpack as `.css` +// https://github.com/NativeScript/NativeScript/blob/5.4.2/tns-core-modules/globals/globals.ts#L32-L33 +const appNewScssFileNameAsCss = `${LIVESYNC_FOLDER}app-new-scss-page.css`; +const appNewScssFileName = `${LIVESYNC_FOLDER}app-new-scss-page.scss`; + +const buttonCssModuleName = `${LIVESYNC_FOLDER}button-css-page`; +const buttonScssModuleName = `${LIVESYNC_FOLDER}button-scss-page`; +const buttonCssFileName = `${LIVESYNC_FOLDER}button-css-page.css`; +const buttonScssFileName = `${LIVESYNC_FOLDER}button-scss-page.scss`; + +const buttonPageModuleName = `${LIVESYNC_FOLDER}livesync-button-page`; +const buttonHtmlPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.html`; +const buttonXmlPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.xml`; +const buttonJsPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.js`; +const buttonTsPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.ts`; +const buttonScssPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.scss`; +const labelPageModuleName = `${LIVESYNC_FOLDER}livesync-label-page`; const green = new Color("green"); +export function setUp() { + const labelPage = createViewFromEntry(({ moduleName: labelPageModuleName })); + helper.navigate(() => labelPage); +} + +export function tearDown() { + app.setCssFileName(appCssFileName); +} + export function test_onLiveSync_ModuleContext_AppStyle_AppNewCss() { - _test_onLiveSync_ModuleContext_AppStyle(appNewCssFileName); + _test_onLiveSync_ModuleContext_AppStyle(appNewCssFileName, appNewCssFileName); } export function test_onLiveSync_ModuleContext_AppStyle_AppNewScss() { - _test_onLiveSync_ModuleContext_AppStyle(appNewScssFileName); + _test_onLiveSync_ModuleContext_AppStyle(appNewScssFileNameAsCss, appNewScssFileName); } -export function test_onLiveSync_ModuleContext_ContextUndefined() { +export function test_onLiveSync_ModuleContext_Undefined() { _test_onLiveSync_ModuleContext({ type: undefined, path: undefined }); } -export function test_onLiveSync_ModuleContext_ModuleUndefined() { +export function test_onLiveSync_ModuleContext_PathUndefined() { _test_onLiveSync_ModuleContext({ type: "script", path: undefined }); } @@ -49,7 +66,11 @@ export function test_onLiveSync_ModuleContext_Script_TsFile() { } export function test_onLiveSync_ModuleContext_Style_CssFile() { - _test_onLiveSync_ModuleContext_TypeStyle({ type: "style", path: fs.knownFolders.currentApp().path + buttonCssFileName }); + _test_onLiveSync_ModuleContext_TypeStyle(buttonCssModuleName, buttonCssFileName); +} + +export function test_onLiveSync_ModuleContext_Style_ScssFile() { + _test_onLiveSync_ModuleContext_TypeStyle(buttonScssModuleName, buttonScssFileName); } export function test_onLiveSync_ModuleContext_Markup_HtmlFile() { @@ -60,14 +81,14 @@ export function test_onLiveSync_ModuleContext_Markup_XmlFile() { _test_onLiveSync_ModuleReplace({ type: "markup", path: buttonXmlPageFileName }); } -export function test_onLiveSync_ModuleContext_Markup_Script_XmlFile() { +export function test_onLiveSync_ModuleContext_MarkupXml_ScriptTs_Files() { _test_onLiveSync_ModuleReplace_Multiple([ { type: "script", path: buttonTsPageFileName }, { type: "markup", path: buttonXmlPageFileName } ]); } -export function test_onLiveSync_ModuleContext_Markup_Script_Style_XmlFile() { +export function test_onLiveSync_ModuleContext_MarkupXml_ScriptTs_StyleScss_Files() { _test_onLiveSync_ModuleReplace_Multiple([ { type: "script", path: buttonTsPageFileName }, { type: "markup", path: buttonXmlPageFileName }, @@ -75,14 +96,14 @@ export function test_onLiveSync_ModuleContext_Markup_Script_Style_XmlFile() { ]); } -export function test_onLiveSync_ModuleContext_Markup_Script_HtmlFile() { +export function test_onLiveSync_ModuleContext_MarkupHtml_ScriptTs_Files() { _test_onLiveSync_ModuleReplace_Multiple([ { type: "script", path: buttonTsPageFileName }, { type: "markup", path: buttonHtmlPageFileName } ]); } -export function test_onLiveSync_ModuleContext_Markup_Script_Style_HtmlFile() { +export function test_onLiveSync_ModuleContext_MarkupHtml_ScriptTs_StyleScss_Files() { _test_onLiveSync_ModuleReplace_Multiple([ { type: "script", path: buttonTsPageFileName }, { type: "markup", path: buttonHtmlPageFileName }, @@ -90,23 +111,14 @@ export function test_onLiveSync_ModuleContext_Markup_Script_Style_HtmlFile() { ]); } -export function setUp() { - const labelPage = createViewFromEntry(({ moduleName: labelPageModuleName })); - helper.navigate(() => labelPage); -} - -export function tearDown() { - app.setCssFileName(fs.knownFolders.currentApp().path + appCssFileName); -} - -function _test_onLiveSync_ModuleContext_AppStyle(styleFileName: string) { +function _test_onLiveSync_ModuleContext_AppStyle(appStyleFileName: string, livesyncStyleFileName: string) { const pageBeforeNavigation = helper.getCurrentPage(); const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); helper.navigateWithHistory(() => buttonPage); - app.setCssFileName(fs.knownFolders.currentApp().path + "/" + styleFileName); + app.setCssFileName(appStyleFileName); const pageBeforeLiveSync = helper.getCurrentPage(); - global.__onLiveSync({ type: "style", path: fs.knownFolders.currentApp().path + "/" + styleFileName }); + livesync({ type: "style", path: livesyncStyleFileName }); const pageAfterLiveSync = helper.getCurrentPage(); TKUnit.waitUntilReady(() => pageAfterLiveSync.getViewById("button").style.color.toString() === green.toString()); @@ -121,10 +133,10 @@ function _test_onLiveSync_ModuleContext_AppStyle(styleFileName: string) { TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); } -function _test_onLiveSync_ModuleContext(context: { type, path }) { +function _test_onLiveSync_ModuleContext(context: ModuleContext) { const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); helper.navigateWithHistory(() => buttonPage); - global.__onLiveSync({ type: context.type, path: context.path }); + livesync({ type: context.type, path: context.path }); TKUnit.waitUntilReady(() => !!frame.topmost()); const topmostFrame = frame.topmost(); @@ -132,12 +144,12 @@ function _test_onLiveSync_ModuleContext(context: { type, path }) { TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded); } -function _test_onLiveSync_ModuleReplace(context: { type, path }) { +function _test_onLiveSync_ModuleReplace(context: ModuleContext) { const pageBeforeNavigation = helper.getCurrentPage(); const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); helper.navigateWithHistory(() => buttonPage); - global.__onLiveSync({ type: context.type, path: context.path }); + livesync({ type: context.type, path: context.path }); const topmostFrame = frame.topmost(); waitUntilLivesyncComplete(topmostFrame); TKUnit.assertTrue(topmostFrame.currentPage.getViewById("button").isLoaded, "Button page is NOT loaded!"); @@ -151,37 +163,15 @@ function _test_onLiveSync_ModuleReplace(context: { type, path }) { TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, "Pages are different!"); } -function _test_onLiveSync_ModuleReplace_Multiple(context: { type: string, path: string }[]) { - const pageBeforeNavigation = helper.getCurrentPage(); - const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); - helper.navigateWithHistory(() => buttonPage); - - context.forEach(item => { - global.__onLiveSync(item); - }); - - const topmostFrame = frame.topmost(); - waitUntilLivesyncComplete(topmostFrame); - TKUnit.assertTrue(topmostFrame.currentPage.getViewById("button").isLoaded, "Button page is NOT loaded!"); - TKUnit.assertEqual(topmostFrame.backStack.length, 1, "Backstack is clean!"); - TKUnit.assertTrue(topmostFrame.canGoBack(), "Can NOT go back!"); - - helper.goBack(); - const pageAfterBackNavigation = helper.getCurrentPage(); - TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded, "Label page is NOT loaded!"); - TKUnit.assertEqual(topmostFrame.backStack.length, 0, "Backstack is NOT clean!"); - TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, "Pages are different!"); -} - -function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) { +function _test_onLiveSync_ModuleContext_TypeStyle(styleModuleName: string, livesyncStyleFileName: string) { const pageBeforeNavigation = helper.getCurrentPage(); const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); helper.navigateWithHistory(() => buttonPage); const pageBeforeLiveSync = helper.getCurrentPage(); - pageBeforeLiveSync._moduleName = "button-page"; + pageBeforeLiveSync._moduleName = styleModuleName; - global.__onLiveSync({ type: context.type, path: context.path }); + livesync({ type: "style", path: livesyncStyleFileName }); const topmostFrame = frame.topmost(); waitUntilLivesyncComplete(topmostFrame); @@ -197,6 +187,33 @@ function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) { TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); } +function _test_onLiveSync_ModuleReplace_Multiple(context: ModuleContext[]) { + const pageBeforeNavigation = helper.getCurrentPage(); + const buttonPage = createViewFromEntry(({ moduleName: buttonPageModuleName })); + helper.navigateWithHistory(() => buttonPage); + + context.forEach(item => { + livesync(item); + }); + + const topmostFrame = frame.topmost(); + waitUntilLivesyncComplete(topmostFrame); + TKUnit.assertTrue(topmostFrame.currentPage.getViewById("button").isLoaded, "Button page is NOT loaded!"); + TKUnit.assertEqual(topmostFrame.backStack.length, 1, "Backstack is clean!"); + TKUnit.assertTrue(topmostFrame.canGoBack(), "Can NOT go back!"); + + helper.goBack(); + const pageAfterBackNavigation = helper.getCurrentPage(); + TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded, "Label page is NOT loaded!"); + TKUnit.assertEqual(topmostFrame.backStack.length, 0, "Backstack is NOT clean!"); + TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, "Pages are different!"); +} + +function livesync(context: ModuleContext) { + const ls = (global).__hmrSyncBackup || global.__onLiveSync; + ls(context); +} + function waitUntilLivesyncComplete(frame: Frame) { TKUnit.waitUntilReady(() => frame.navigationQueueIsEmpty()); } diff --git a/tests/app/test-runner.ts b/tests/app/test-runner.ts index 53fd98d5e..a1ff7bc6e 100644 --- a/tests/app/test-runner.ts +++ b/tests/app/test-runner.ts @@ -280,9 +280,8 @@ allTests["SEARCH-BAR"] = searchBarTests; import * as navigationTests from "./navigation/navigation-tests"; allTests["NAVIGATION"] = navigationTests; -// TODO: These test should be run with --no-hrm -// import * as livesyncTests from "./livesync/livesync-tests"; -// allTests["LIVESYNC"] = livesyncTests; +import * as livesyncTests from "./livesync/livesync-tests"; +allTests["LIVESYNC"] = livesyncTests; import * as tabViewRootTests from "./ui/tab-view/tab-view-root-tests"; allTests["TAB-VIEW-ROOT"] = tabViewRootTests; diff --git a/tests/package.json b/tests/package.json index 8b771cfc8..b1a3a76c6 100644 --- a/tests/package.json +++ b/tests/package.json @@ -5,7 +5,7 @@ "version": "next" }, "tns-ios": { - "version": "6.0.0-2019-06-13-141312-01" + "version": "next" } }, "main": "app.js", diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index b6a823cee..11d7d7ce6 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -5,7 +5,7 @@ import { TabContentItem } from "../tab-navigation-base/tab-content-item"; // Requires import { TabNavigationBase, itemsProperty, selectedIndexProperty, tabStripProperty } from "../tab-navigation-base/tab-navigation-base"; -import { CSSType } from "../core/view"; +import { CSSType, Color } from "../core/view"; import { Frame } from "../frame"; import { RESOURCE_PREFIX, ad, layout } from "../../utils/utils"; import { fromFileOrResource } from "../../image-source"; @@ -352,6 +352,11 @@ export class BottomNavigation extends TabNavigationBase { }); this._bottomNavigationBar.setItems(tabItems); + this.tabStrip.setNativeView(this._bottomNavigationBar); + this.tabStrip.items.forEach((item, i, arr) => { + const tv = this._bottomNavigationBar.getTextViewForItemAt(i); + item.setNativeView(tv); + }); } } @@ -359,6 +364,18 @@ export class BottomNavigation extends TabNavigationBase { this._bottomNavigationBar.updateItemAt(index, spec); } + public getTabBarBackgroundColor(): android.graphics.drawable.Drawable { + return this._bottomNavigationBar.getBackground(); + } + + public setTabBarBackgroundColor(value: android.graphics.drawable.Drawable | Color): void { + if (value instanceof Color) { + this._bottomNavigationBar.setBackgroundColor(value.android); + } else { + this._bottomNavigationBar.setBackground(tryCloneDrawable(value, this.nativeViewProtected.getResources)); + } + } + [selectedIndexProperty.setNative](value: number) { // const smoothScroll = false; @@ -383,3 +400,14 @@ export class BottomNavigation extends TabNavigationBase { this.setAdapterItems([]); } } + +function tryCloneDrawable(value: android.graphics.drawable.Drawable, resources: android.content.res.Resources): android.graphics.drawable.Drawable { + if (value) { + const constantState = value.getConstantState(); + if (constantState) { + return constantState.newDrawable(resources); + } + } + + return value; +} diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts index c46f61a2f..c24dbb48f 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts @@ -277,6 +277,14 @@ export class BottomNavigation extends TabNavigationBase { super.onSelectedIndexChanged(oldIndex, newIndex); } + public getTabBarBackgroundColor(): UIColor { + return this._ios.tabBar.barTintColor; + } + + public setTabBarBackgroundColor(value: UIColor | Color): void { + this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value; + } + public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { const width = layout.getMeasureSpecSize(widthMeasureSpec); const widthMode = layout.getMeasureSpecMode(widthMeasureSpec); @@ -384,6 +392,10 @@ export class BottomNavigation extends TabNavigationBase { const controllers = NSMutableArray.alloc().initWithCapacity(length); const states = getTitleAttributesForStates(this); + if (this.tabStrip) { + this.tabStrip.setNativeView(this._ios.tabBar); + } + items.forEach((item, i) => { const controller = this.getViewController(item); @@ -401,6 +413,7 @@ export class BottomNavigation extends TabNavigationBase { applyStatesToItem(tabBarItem, states); controller.tabBarItem = tabBarItem; + tabStripItem.setNativeView(tabBarItem); } controllers.addObject(controller); diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts index c98ef710f..30642fb96 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts @@ -82,6 +82,18 @@ export class TabNavigationBase extends View { * Method is intended to be overridden by inheritors and used as "protected" */ onSelectedIndexChanged(oldIndex: number, newIndex: number): void; + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + getTabBarBackgroundColor(): any + + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarBackgroundColor(value: any): void } export const itemsProperty: Property; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts index de86890cf..b85c6f944 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts @@ -34,9 +34,10 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti } this.items.push(value); this._addView(value); - selectedIndexProperty.coerce(this); + // selectedIndexProperty.coerce(this); } else if (name === "TabStrip") { this.tabStrip = value; + this._addView(value); } } @@ -59,6 +60,11 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti callback(item); }); } + + const tabStrip = this.tabStrip; + if (tabStrip) { + callback(tabStrip); + } } public eachChildView(callback: (child: View) => boolean) { @@ -102,6 +108,15 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti // to be overridden in platform specific files this.notify({ eventName: TabNavigationBase.selectedIndexChangedEvent, object: this, oldIndex, newIndex }); } + + public getTabBarBackgroundColor(): any { + // overridden by inheritors + return null; + } + + public setTabBarBackgroundColor(value: any): void { + // overridden by inheritors + } } export interface TabNavigationBase { diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.d.ts index f6a043a1c..d6b5dc041 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.d.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.d.ts @@ -3,13 +3,15 @@ * @module "ui/tab-navigation/tab-strip" */ /** */ -import { ViewBase, Property } from "../../core/view"; +import { View, Property } from "../../core/view"; +import { Color } from "../../../color"; import { TabStripItem } from "../tab-strip-item"; /** * Represents a tab strip. */ -export class TabStrip extends ViewBase { +export class TabStrip extends View { + /** * Gets or sets the items of the tab strip. */ diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts index 2be31d8b5..9146370da 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts @@ -1,15 +1,17 @@ -// Types +// Types import { TabStrip as TabStripDefinition } from "."; import { TabStripItem } from "../tab-strip-item"; +import { TabNavigationBase } from "../tab-navigation-base"; +import { Color } from "../../../color"; import { AddArrayFromBuilder, AddChildFromBuilder } from "../../core/view"; // Requires -import { ViewBase, Property, CSSType } from "../../core/view"; +import { View, Property, CSSType, backgroundColorProperty, backgroundInternalProperty } from "../../core/view"; export const traceCategory = "TabView"; @CSSType("TabStrip") -export class TabStrip extends ViewBase implements TabStripDefinition, AddChildFromBuilder, AddArrayFromBuilder { +export class TabStrip extends View implements TabStripDefinition, AddChildFromBuilder, AddArrayFromBuilder { public items: TabStripItem[]; public iosIconRenderingMode: "automatic" | "alwaysOriginal" | "alwaysTemplate"; @@ -29,7 +31,25 @@ export class TabStrip extends ViewBase implements TabStripDefinition, AddChildFr // selectedIndexProperty.coerce(this); } } -} + + [backgroundColorProperty.getDefault](): Color { + const parent = this.parent; + + return parent && parent.getTabBarBackgroundColor(); + } + [backgroundColorProperty.setNative](value: Color) { + const parent = this.parent; + + return parent && parent.setTabBarBackgroundColor(value); + } + + [backgroundInternalProperty.getDefault](): any { + return null; + } + [backgroundInternalProperty.setNative](value: any) { + // disable the background CSS properties + } +} export const iosIconRenderingModeProperty = new Property({ name: "iosIconRenderingMode", defaultValue: "automatic" }); iosIconRenderingModeProperty.register(TabStrip); diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index 84c886231..d521b0b47 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -7,6 +7,7 @@ import { TabStripItem } from "../tab-navigation-base/tab-strip-item"; import { selectedIndexProperty, itemsProperty, tabStripProperty } from "../tab-navigation-base/tab-navigation-base"; import { TabsBase, swipeEnabledProperty, offscreenTabLimitProperty } from "./tabs-common"; import { Frame } from "../frame"; +import { Color } from "../core/view"; import { fromFileOrResource } from "../../image-source"; import { RESOURCE_PREFIX, ad, layout } from "../../utils/utils"; import * as application from "../../application"; @@ -529,6 +530,7 @@ export class Tabs extends TabsBase { const tabLayout = this._tabLayout; tabLayout.setItems(tabItems, this._viewPager); + this.tabStrip.setNativeView(tabLayout); items.forEach((item, i, arr) => { const tv = tabLayout.getTextViewForItemAt(i); item.setNativeView(tv); @@ -569,6 +571,18 @@ export class Tabs extends TabsBase { this._tabLayout.updateItemAt(index, spec); } + public getTabBarBackgroundColor(): android.graphics.drawable.Drawable { + return this._tabLayout.getBackground(); + } + + public setTabBarBackgroundColor(value: android.graphics.drawable.Drawable | Color): void { + if (value instanceof Color) { + this._tabLayout.setBackgroundColor(value.android); + } else { + this._tabLayout.setBackground(tryCloneDrawable(value, this.nativeViewProtected.getResources)); + } + } + [selectedIndexProperty.setNative](value: number) { const smoothScroll = true; @@ -610,3 +624,14 @@ export class Tabs extends TabsBase { this._viewPager.setOffscreenPageLimit(value); } } + +function tryCloneDrawable(value: android.graphics.drawable.Drawable, resources: android.content.res.Resources): android.graphics.drawable.Drawable { + if (value) { + const constantState = value.getConstantState(); + if (constantState) { + return constantState.newDrawable(resources); + } + } + + return value; +} diff --git a/tns-core-modules/ui/tabs/tabs.ios.ts b/tns-core-modules/ui/tabs/tabs.ios.ts index 1fbffb373..eb245cc5e 100644 --- a/tns-core-modules/ui/tabs/tabs.ios.ts +++ b/tns-core-modules/ui/tabs/tabs.ios.ts @@ -8,6 +8,7 @@ import { selectedIndexProperty, itemsProperty, tabStripProperty } from "../tab-n import { TabsBase, swipeEnabledProperty } from "./tabs-common"; import { Frame } from "../frame"; import { ios as iosView, View } from "../core/view"; +import { Color } from "../../color"; import { /*ios as iosUtils,*/ layout } from "../../utils/utils"; // import { device } from "../../platform"; import { fromFileOrResource } from "../../image-source"; @@ -845,11 +846,13 @@ export class Tabs extends TabsBase { items.forEach((item: TabStripItem, i, arr) => { const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(item.title, null, 0); tabBarItems.push(tabBarItem); + item.setNativeView(tabBarItem); }); this.tabBarItems = tabBarItems; if (this.viewController && this.viewController.tabBar) { this.viewController.tabBar.items = NSArray.arrayWithArray(tabBarItems); + this.tabStrip.setNativeView(this.viewController.tabBar); } // tabBar.items = >NSArray.alloc().initWithArray([ @@ -934,6 +937,14 @@ export class Tabs extends TabsBase { // this._updateIOSTabBarColorsAndFonts(); // } + public getTabBarBackgroundColor(): UIColor { + return this._ios.tabBar.barTintColor; + } + + public setTabBarBackgroundColor(value: UIColor | Color): void { + this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value; + } + [selectedIndexProperty.setNative](value: number) { // TODO // if (traceEnabled()) {