diff --git a/.gitignore b/.gitignore
index dbbd6a8a3..d912d0587 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ package-lock.json
# Appium files
e2e/**/*.trace/
e2e/**/test-results.xml
+e2e/**/e2e/resources/
# Webpack configuration files
webpack.config.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b9d8e7a75..9f8449330 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,37 @@
+
+## [6.0.4](https://github.com/NativeScript/NativeScript/compare/6.0.3...6.0.4) (2019-07-30)
+
+
+### Bug Fixes
+
+* **ios:** 'ui/tabs' not found for element 'Tabs'
+
+
+
+## [6.0.3](https://github.com/NativeScript/NativeScript/compare/6.0.2...6.0.3) (2019-07-29)
+
+
+### Bug Fixes
+
+* **ios:** move material design dependency to podfile ([#7592](https://github.com/NativeScript/NativeScript/issues/7592)) ([291e3b4](https://github.com/NativeScript/NativeScript/commit/291e3b4))
+
+
+
+
+## [6.0.2](https://github.com/NativeScript/NativeScript/compare/6.0.0...6.0.2) (2019-07-26)
+
+
+### Bug Fixes
+
+* **android:** remove wait for doubletap if no gesture recognizer ([#7584](https://github.com/NativeScript/NativeScript/issues/7584)) ([9fd5ddc](https://github.com/NativeScript/NativeScript/commit/9fd5ddc))
+* **bottom-navigation:** crash when tab selected with no item ([#7527](https://github.com/NativeScript/NativeScript/issues/7527)) ([46c17ca](https://github.com/NativeScript/NativeScript/commit/46c17ca))
+* **tabs:** tab bar not visible when nested in layout ([#7544](https://github.com/NativeScript/NativeScript/issues/7544)) ([f00b370](https://github.com/NativeScript/NativeScript/commit/f00b370))
+* **tabs-android:** wrong tabStripItem selected ([#7522](https://github.com/NativeScript/NativeScript/issues/7522)) ([ca22ba9](https://github.com/NativeScript/NativeScript/commit/ca22ba9))
+* **tabs-ios:** crash when setting tabStripItems through items property ([#7548](https://github.com/NativeScript/NativeScript/issues/7548)) ([4511c76](https://github.com/NativeScript/NativeScript/commit/4511c76))
+* **tabs-ios:** unable to return to tab after tab with nested frame visited ([#7574](https://github.com/NativeScript/NativeScript/issues/7574)) ([490cab0](https://github.com/NativeScript/NativeScript/commit/490cab0))
+
+
+
# [6.0.0](https://github.com/NativeScript/NativeScript/compare/5.4.2...6.0.0) (2019-06-28)
diff --git a/e2e/nested-frame-navigation/app/app.ts b/e2e/nested-frame-navigation/app/app.ts
index e0ef2193e..0c5afc47e 100644
--- a/e2e/nested-frame-navigation/app/app.ts
+++ b/e2e/nested-frame-navigation/app/app.ts
@@ -1,5 +1,3 @@
import * as application from "tns-core-modules/application";
application.run({ moduleName: "app-root" });
-// application.run({ moduleName: "tab-root" });
-// application.run({ moduleName: "layout-root" });
diff --git a/e2e/nested-frame-navigation/app/bottom-navigation-page/bottom-navigation-page.xml b/e2e/nested-frame-navigation/app/bottom-navigation-page/bottom-navigation-page.xml
index 407ca4aee..b467699b8 100644
--- a/e2e/nested-frame-navigation/app/bottom-navigation-page/bottom-navigation-page.xml
+++ b/e2e/nested-frame-navigation/app/bottom-navigation-page/bottom-navigation-page.xml
@@ -1,7 +1,7 @@
-
+
@@ -16,9 +16,9 @@
-
-
-
+
+
+
diff --git a/e2e/nested-frame-navigation/app/bottom-navigation-root/bottom-navigation-root.xml b/e2e/nested-frame-navigation/app/bottom-navigation-root/bottom-navigation-root.xml
index ecc8c8c2e..04920a131 100644
--- a/e2e/nested-frame-navigation/app/bottom-navigation-root/bottom-navigation-root.xml
+++ b/e2e/nested-frame-navigation/app/bottom-navigation-root/bottom-navigation-root.xml
@@ -1,14 +1,14 @@
-
+
-
-
+
+
-
+
diff --git a/e2e/nested-frame-navigation/app/tab-page/tab-bottom-page.xml b/e2e/nested-frame-navigation/app/tab-page/tab-bottom-page.xml
index 6d1cbd174..fe95ecd11 100644
--- a/e2e/nested-frame-navigation/app/tab-page/tab-bottom-page.xml
+++ b/e2e/nested-frame-navigation/app/tab-page/tab-bottom-page.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/e2e/nested-frame-navigation/app/tab-page/tab-top-page.xml b/e2e/nested-frame-navigation/app/tab-page/tab-top-page.xml
index 28b6a690d..479e24b8b 100644
--- a/e2e/nested-frame-navigation/app/tab-page/tab-top-page.xml
+++ b/e2e/nested-frame-navigation/app/tab-page/tab-top-page.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/e2e/nested-frame-navigation/app/tabs-page/tabs-bottom-page.xml b/e2e/nested-frame-navigation/app/tabs-page/tabs-bottom-page.xml
index 8daf6eb26..5e49cedca 100644
--- a/e2e/nested-frame-navigation/app/tabs-page/tabs-bottom-page.xml
+++ b/e2e/nested-frame-navigation/app/tabs-page/tabs-bottom-page.xml
@@ -1,7 +1,7 @@
-
+
@@ -16,9 +16,9 @@
-
-
-
+
+
+
diff --git a/e2e/nested-frame-navigation/app/tabs-page/tabs-top-page.xml b/e2e/nested-frame-navigation/app/tabs-page/tabs-top-page.xml
index e8b74511c..773558598 100644
--- a/e2e/nested-frame-navigation/app/tabs-page/tabs-top-page.xml
+++ b/e2e/nested-frame-navigation/app/tabs-page/tabs-top-page.xml
@@ -1,7 +1,7 @@
-
+
@@ -16,9 +16,9 @@
-
-
-
+
+
+
diff --git a/e2e/nested-frame-navigation/app/tabs-root/tabs-bottom-root.xml b/e2e/nested-frame-navigation/app/tabs-root/tabs-bottom-root.xml
index a4ce50327..481c4b2be 100644
--- a/e2e/nested-frame-navigation/app/tabs-root/tabs-bottom-root.xml
+++ b/e2e/nested-frame-navigation/app/tabs-root/tabs-bottom-root.xml
@@ -1,14 +1,14 @@
-
+
-
-
+
+
-
+
diff --git a/e2e/nested-frame-navigation/app/tabs-root/tabs-top-root.xml b/e2e/nested-frame-navigation/app/tabs-root/tabs-top-root.xml
index e6e81603d..9a95cc512 100644
--- a/e2e/nested-frame-navigation/app/tabs-root/tabs-top-root.xml
+++ b/e2e/nested-frame-navigation/app/tabs-root/tabs-top-root.xml
@@ -1,9 +1,9 @@
-
+
-
+
-
-
+
+
diff --git a/e2e/nested-frame-navigation/e2e/bottom-navigation-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/bottom-navigation-root.e2e-spec.ts
new file mode 100644
index 000000000..c3aadbd93
--- /dev/null
+++ b/e2e/nested-frame-navigation/e2e/bottom-navigation-root.e2e-spec.ts
@@ -0,0 +1,180 @@
+import { AppiumDriver, createDriver, logWarn, nsCapabilities } from "nativescript-dev-appium";
+
+import { Screen, playersData, teamsData } from "./screen";
+import * as shared from "./shared.e2e-spec";
+import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
+
+const roots = ["BottomNavigation"];
+
+const rootType = "bottom-navigation-root";
+describe(rootType, async function () {
+ let driver: AppiumDriver;
+ let screen: Screen;
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`====== ${rootType} ========`);
+ driver = await createDriver();
+ screen = new Screen(driver);
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(true);
+ }
+
+ driver.defaultWaitTime = 8000;
+ });
+
+ after(async function () {
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(false);
+ }
+ await driver.quit();
+ console.log("Quit driver!");
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ }
+ });
+
+ for (let index = 0; index < roots.length; index++) {
+ const root = roots[index];
+ describe(`${rootType}-${root}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ });
+
+ for (let index = 0; index < transitions.length; index++) {
+ const transition = transitions[index];
+
+ const playerOne = playersData[`playerOne${transition}`];
+ const playerTwo = playersData[`playerTwo${transition}`];
+ const teamOne = teamsData[`teamOne${transition}`];
+ const teamTwo = teamsData[`teamTwo${transition}`];
+
+ describe(`${rootType}-${root}-transition-${transition}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+
+ if (transition === "Flip" &&
+ driver.isAndroid && parseInt(driver.platformVersion) === 19) {
+ // TODO: known issue https://github.com/NativeScript/NativeScript/issues/6798
+ console.log("skipping flip transition tests on api level 19");
+ this.skip();
+ }
+ });
+
+ it("loaded home page", async function () {
+ await screen.loadedHome();
+ });
+
+ it(`loaded ${root} root with frames`, async function () {
+ await screen[`navigateTo${root}RootWithFrames`]();
+ await screen[`loaded${root}RootWithFrames`]();
+ });
+
+ it("loaded players list", async function () {
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and go back twice", async function () {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+
+ await shared.testPlayerNavigatedBack(screen, driver);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+ await shared.testPlayerNavigatedBack(screen, driver);
+ });
+
+ it("toggle teams tab", async function () {
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamOne.name); // wait for teams list
+ }
+ });
+
+ it("loaded teams list", async function () {
+ await screen.loadedTeamsList();
+ });
+
+ it("mix player and team list actions and go back", async function () {
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await screen.loadedPlayersList();
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (driver.isIOS) {
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+ }
+
+ await screen.toggleTeamsTab();
+
+ if (driver.isIOS) {
+ // TODO: run in background from appium breaks the test. Investigate the issue, once with the app and with appium
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamOne.name); // wait for teams list
+ }
+ }
+
+ await screen.loadedTeamsList();
+
+ await shared.testTeamNavigated(teamTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamTwo.name); // wait for team
+ }
+
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ await screen.goBackToTeamsList();
+ await screen.loadedTeamsList();
+
+ await screen.togglePlayersTab();
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded home page again", async function () {
+ await screen.resetToHome();
+ await screen.loadedHome();
+ });
+ });
+ }
+ });
+ }
+});
diff --git a/e2e/nested-frame-navigation/e2e/frame-bottom-navigation-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/frame-bottom-navigation-root.e2e-spec.ts
new file mode 100644
index 000000000..2a832fae5
--- /dev/null
+++ b/e2e/nested-frame-navigation/e2e/frame-bottom-navigation-root.e2e-spec.ts
@@ -0,0 +1,264 @@
+import { AppiumDriver, createDriver, logWarn, nsCapabilities } from "nativescript-dev-appium";
+
+import { Screen, playersData, somePage, teamsData, driverDefaultWaitTime, Item } from "./screen";
+import * as shared from "./shared.e2e-spec";
+import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
+
+const roots = ["BottomNavigation"];
+
+const rootType = "frame-bottom-navigation-root";
+describe(rootType, async function () {
+ let driver: AppiumDriver;
+ let screen: Screen;
+
+ before(async () => {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`====== ${rootType} ========`);
+ driver = await createDriver();
+ screen = new Screen(driver);
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(true);
+ }
+
+ driver.defaultWaitTime = driverDefaultWaitTime;
+ });
+
+ after(async () => {
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(false);
+ }
+ await driver.quit();
+ console.log("Quit driver!");
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ }
+ });
+
+ for (let index = 0; index < roots.length; index++) {
+ const root = roots[index];
+
+ describe(`${rootType}-${root} scenarios:`, async function () {
+ logWarn(`===== Root: ${root}`);
+ for (let trIndex = 0; trIndex < transitions.length; trIndex++) {
+ const transition = transitions[trIndex];
+ const playerOne: Item = playersData[`playerOne${transition}`];
+ const playerTwo: Item = playersData[`playerTwo${transition}`];
+ const teamOne: Item = teamsData[`teamOne${transition}`];
+ const teamTwo: Item = teamsData[`teamTwo${transition}`];
+
+ describe(`${rootType}-${root}-transition-${transition}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`========= ${root}-${transition} =========`);
+
+ if (transition === "Flip" &&
+ driver.isAndroid && parseInt(driver.platformVersion) === 19) {
+ // TODO: known issue https://github.com/NativeScript/NativeScript/issues/6798
+ console.log("skipping flip transition tests on api level 19");
+ this.skip();
+ }
+ });
+
+ it("loaded home page", async () => {
+ await screen.loadedHome();
+ });
+
+ it(`loaded frame ${root} root with nested frames`, async () => {
+ await screen[`navigateToPage${root}WithFrames`]();
+ await screen[`loadedPage${root}WithFrames`]();
+ });
+
+ it("loaded players list", async () => {
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and go back twice", async () => {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await shared.testPlayerNavigatedBack(screen, driver);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+ await shared.testPlayerNavigatedBack(screen, driver);
+ });
+
+ it("navigate parent frame and go back", async () => {
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and navigate parent frame and go back", async () => {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("toggle teams tab", async () => {
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamOne.name); // wait for team
+ }
+ });
+
+ it("loaded teams list", async () => {
+ await screen.loadedTeamsList();
+ });
+
+ it("mix player and team list actions and go back", async () => {
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerOne.name); // wait for players list
+ }
+
+ await screen.loadedPlayersList();
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ if (appSuspendResume) {
+ // This sleeps prevent test to fail
+ await driver.sleep(1000);
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamOne.name); // wait for teams list
+ }
+
+ await screen.loadedTeamsList();
+
+ await shared.testTeamNavigated(teamTwo, screen);
+
+ if (appSuspendResume) {
+ await screen.loadedElement(teamTwo.name); // wait for team
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamTwo.name); // wait for team
+ }
+
+ await screen.loadedTeamDetails(teamTwo);
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ if (appSuspendResume) {
+ await screen.loadedElement(teamTwo.name); // wait for team
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamTwo.name); // wait for team
+ }
+
+ await screen.loadedTeamDetails(teamTwo);
+
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ await screen.goBackToTeamsList();
+ await screen.loadedTeamsList();
+
+ await screen.togglePlayersTab();
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded home page again", async () => {
+ await screen[`goBackFrom${root}Page`]();
+ await screen.loadedHome();
+ });
+ });
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/e2e/nested-frame-navigation/e2e/frame-tab-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/frame-tab-root.e2e-spec.ts
index 00339c262..287567919 100644
--- a/e2e/nested-frame-navigation/e2e/frame-tab-root.e2e-spec.ts
+++ b/e2e/nested-frame-navigation/e2e/frame-tab-root.e2e-spec.ts
@@ -4,8 +4,8 @@ import { Screen, playersData, somePage, teamsData, driverDefaultWaitTime, Item }
import * as shared from "./shared.e2e-spec";
import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
-// NOTE: TabTop is Android only scenario (for iOS we will essentially execute 2x TabBottom)
-const roots = ["TabTop", "TabBottom"];
+// NOTE: TabViewTop is Android only scenario (for iOS we will essentially execute 2x TabViewBottom)
+const roots = ["TabViewTop", "TabViewBottom"];
const rootType = "frame-tab-root";
describe(rootType, async function () {
diff --git a/e2e/nested-frame-navigation/e2e/frame-tabs-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/frame-tabs-root.e2e-spec.ts
new file mode 100644
index 000000000..c945ce48c
--- /dev/null
+++ b/e2e/nested-frame-navigation/e2e/frame-tabs-root.e2e-spec.ts
@@ -0,0 +1,264 @@
+import { AppiumDriver, createDriver, logWarn, nsCapabilities } from "nativescript-dev-appium";
+
+import { Screen, playersData, somePage, teamsData, driverDefaultWaitTime, Item } from "./screen";
+import * as shared from "./shared.e2e-spec";
+import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
+
+const roots = ["TabsTop", "TabsBottom"];
+
+const rootType = "frame-tabs-root";
+describe(rootType, async function () {
+ let driver: AppiumDriver;
+ let screen: Screen;
+
+ before(async () => {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`====== ${rootType} ========`);
+ driver = await createDriver();
+ screen = new Screen(driver);
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(true);
+ }
+
+ driver.defaultWaitTime = driverDefaultWaitTime;
+ });
+
+ after(async () => {
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(false);
+ }
+ await driver.quit();
+ console.log("Quit driver!");
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ }
+ });
+
+ for (let index = 0; index < roots.length; index++) {
+ const root = roots[index];
+
+ describe(`${rootType}-${root} scenarios:`, async function () {
+ logWarn(`===== Root: ${root}`);
+ for (let trIndex = 0; trIndex < transitions.length; trIndex++) {
+ const transition = transitions[trIndex];
+ const playerOne: Item = playersData[`playerOne${transition}`];
+ const playerTwo: Item = playersData[`playerTwo${transition}`];
+ const teamOne: Item = teamsData[`teamOne${transition}`];
+ const teamTwo: Item = teamsData[`teamTwo${transition}`];
+
+ describe(`${rootType}-${root}-transition-${transition}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`========= ${root}-${transition} =========`);
+
+ if (transition === "Flip" &&
+ driver.isAndroid && parseInt(driver.platformVersion) === 19) {
+ // TODO: known issue https://github.com/NativeScript/NativeScript/issues/6798
+ console.log("skipping flip transition tests on api level 19");
+ this.skip();
+ }
+ });
+
+ it("loaded home page", async () => {
+ await screen.loadedHome();
+ });
+
+ it(`loaded frame ${root} root with nested frames`, async () => {
+ await screen[`navigateToPage${root}WithFrames`]();
+ await screen[`loadedPage${root}WithFrames`]();
+ });
+
+ it("loaded players list", async () => {
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and go back twice", async () => {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await shared.testPlayerNavigatedBack(screen, driver);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+ await shared.testPlayerNavigatedBack(screen, driver);
+ });
+
+ it("navigate parent frame and go back", async () => {
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and navigate parent frame and go back", async () => {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("toggle teams tab", async () => {
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamOne.name); // wait for team
+ }
+ });
+
+ it("loaded teams list", async () => {
+ await screen.loadedTeamsList();
+ });
+
+ it("mix player and team list actions and go back", async () => {
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerOne.name); // wait for players list
+ }
+
+ await screen.loadedPlayersList();
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ if (appSuspendResume) {
+ // This sleeps prevent test to fail
+ await driver.sleep(1000);
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamOne.name); // wait for teams list
+ }
+
+ await screen.loadedTeamsList();
+
+ await shared.testTeamNavigated(teamTwo, screen);
+
+ if (appSuspendResume) {
+ await screen.loadedElement(teamTwo.name); // wait for team
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamTwo.name); // wait for team
+ }
+
+ await screen.loadedTeamDetails(teamTwo);
+
+ await shared[`testSomePageNavigated${transition}`](screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(somePage); // wait for some page
+ }
+
+ if (driver.isAndroid) {
+ await driver.navBack();
+ } else {
+ await screen.goBackFromSomePage();
+ }
+
+ if (appSuspendResume) {
+ await screen.loadedElement(teamTwo.name); // wait for team
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(teamTwo.name); // wait for team
+ }
+
+ await screen.loadedTeamDetails(teamTwo);
+
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await screen.loadedElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ await screen.goBackToTeamsList();
+ await screen.loadedTeamsList();
+
+ await screen.togglePlayersTab();
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded home page again", async () => {
+ await screen[`goBackFrom${root}Page`]();
+ await screen.loadedHome();
+ });
+ });
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/e2e/nested-frame-navigation/e2e/screen.ts b/e2e/nested-frame-navigation/e2e/screen.ts
index f847b3273..842d939f1 100644
--- a/e2e/nested-frame-navigation/e2e/screen.ts
+++ b/e2e/nested-frame-navigation/e2e/screen.ts
@@ -6,18 +6,30 @@ const layoutWithMultiFrame = "Layout w/ multi frame";
const pageWithFrame = "Page w/ frame";
const pageWithFrameNonDefaultTransition = "Frame to NestedFrame (non-default transition)";
const pageWithMultiFrame = "Page w/ multi frame";
-const pageTabTopWithFrames = "Page w/ tabview (top)";
-const pageTabBottomWithFrames = "Page w/ tabview (bottom)";
+const pageTabViewTopWithFrames = "Page w/ tabview (top)";
+const pageTabViewBottomWithFrames = "Page w/ tabview (bottom)";
const tabTopRootWithFrames = "Root tabview (top)";
const tabBottomRootWithFrames = "Root tabview (bottom)";
+const pageTabsTopWithFrames = "Page w/ tabs (top)";
+const pageTabsBottomWithFrames = "Page w/ tabs (bottom)";
+const pageBottomNavigationWithFrames = "Page w/ bottom navigation";
+const tabsTopRootWithFrames = "Root tabs (top)";
+const tabsBottomRootWithFrames = "Root tabs (bottom)";
+const bottomNavigationRootWithFrames = "Root bottom navigation";
const layoutHome = "layout home page";
const layoutHomeSecondary = "layout home secondary page";
const frameHome = "frame home page";
const frameHomeSecondary = "multi frame home page";
const tabViewTopHome = "tabview top page";
const tabViewBottomHome = "tabview bottom page";
-const tabViewRootTopHome = "tabview root top home";
-const tabViewRootBottomHome = "tabview root bottom home";
+const tabViewTopRootHome = "tabview root top home";
+const tabViewBottomRootHome = "tabview root bottom home";
+const tabsTopHome = "tabs top page";
+const tabsBottomHome = "tabs bottom page";
+const tabsTopRootHome = "tabs root top home";
+const tabsBottomRootHome = "tabs root bottom home";
+const bottomNavigationHome = "bottom navigation page";
+const bottomNavigationRootHome = "bottom navigation root home";
const navigateToStillOtherPageSlide = "navigate to still other page (slide transition)";
const navigateToSomePageDefault = "navigate to some page (default transition)";
const navigateToSomePageNone = "navigate to some page (no transition)";
@@ -29,14 +41,20 @@ const navigateToOtherPageSlide = "navigate to other page (slide transition)";
const navigateToOtherPageFlip = "navigate to other page (flip transition)";
const players = "Players";
const teams = "Teams";
+const playersTab = "playersTabNavigation";
+const teamsTab = "teamsTabNavigation";
+const dummyTab = "dummyTabNavigation";
const playerBack = "playerBack";
const stillOtherPageBack = "stillOtherPageBack";
const somePageBack = "somePageBack";
const otherPageBack = "otherPageBack";
const teamBack = "teamBack";
const frameHomeBack = "frameHomeBack";
-const tabTopBack = "tabTopBack";
-const tabBottomBack = "tabBottomBack";
+const tabViewTopBack = "tabViewTopBack";
+const tabViewBottomBack = "tabViewBottomBack";
+const tabsTopBack = "tabsTopBack";
+const tabsBottomBack = "tabsBottomBack";
+const bottomNavigationBack = "bottomNavigationBack";
const resetApp = "reset app";
export const driverDefaultWaitTime = 10000;
@@ -165,22 +183,46 @@ export class Screen {
await this.navigateToPage(pageWithMultiFrame);
}
- navigateToPageTabTopWithFrames = async () => {
- await this.navigateToPage(pageTabTopWithFrames);
+ navigateToPageTabViewTopWithFrames = async () => {
+ await this.navigateToPage(pageTabViewTopWithFrames);
}
- navigateToPageTabBottomWithFrames = async () => {
- await this.navigateToPage(pageTabBottomWithFrames);
+ navigateToPageTabViewBottomWithFrames = async () => {
+ await this.navigateToPage(pageTabViewBottomWithFrames);
}
- navigateToTabTopRootWithFrames = async () => {
+ navigateToTabViewTopRootWithFrames = async () => {
await this.navigateToPage(tabTopRootWithFrames);
}
- navigateToTabBottomRootWithFrames = async () => {
+ navigateToTabViewBottomRootWithFrames = async () => {
await this.navigateToPage(tabBottomRootWithFrames);
}
+ navigateToPageTabsTopWithFrames = async () => {
+ await this.navigateToPage(pageTabsTopWithFrames);
+ }
+
+ navigateToPageTabsBottomWithFrames = async () => {
+ await this.navigateToPage(pageTabsBottomWithFrames);
+ }
+
+ navigateToPageBottomNavigationWithFrames = async () => {
+ await this.navigateToPage(pageBottomNavigationWithFrames);
+ }
+
+ navigateToTabsTopRootWithFrames = async () => {
+ await this.navigateToPage(tabsTopRootWithFrames);
+ }
+
+ navigateToTabsBottomRootWithFrames = async () => {
+ await this.navigateToPage(tabsBottomRootWithFrames);
+ }
+
+ navigateToBottomNavigationRootWithFrames = async () => {
+ await this.navigateToPage(bottomNavigationRootWithFrames);
+ }
+
navigateToStillOtherPageSlide = async () => {
await this.navigateToPage(navigateToStillOtherPageSlide);
}
@@ -256,22 +298,34 @@ export class Screen {
await this.goBack(frameHomeBack);
}
- goBackFromTabTopPage = async () => {
- await this.goBack(tabTopBack);
+ goBackFromTabViewTopPage = async () => {
+ await this.goBack(tabViewTopBack);
}
- goBackFromTabBottomPage = async () => {
- await this.goBack(tabBottomBack);
+ goBackFromTabViewBottomPage = async () => {
+ await this.goBack(tabViewBottomBack);
+ }
+
+ goBackFromTabsTopPage = async () => {
+ await this.goBack(tabsTopBack);
+ }
+
+ goBackFromTabsBottomPage = async () => {
+ await this.goBack(tabsBottomBack);
+ }
+
+ goBackFromBottomNavigationPage = async () => {
+ await this.goBack(bottomNavigationBack);
}
togglePlayersTab = async () => {
- const lblPlayers = await this._driver.waitForElement(players);
+ const lblPlayers = await this._driver.waitForElement(playersTab);
logInfo(`====== Navigate to "${players}"`);
await lblPlayers.tap();
}
toggleTeamsTab = async () => {
- const lblTeams = await this._driver.waitForElement(teams);
+ const lblTeams = await this._driver.waitForElement(teamsTab);
logInfo(`====== Navigate to "${teams}"`);
await lblTeams.tap();
}
@@ -299,20 +353,44 @@ export class Screen {
await this.loadedPage(frameHomeSecondary);
}
- loadedPageTabTopWithFrames = async () => {
+ loadedPageTabViewTopWithFrames = async () => {
await this.loadedPage(tabViewTopHome);
}
- loadedPageTabBottomWithFrames = async () => {
+ loadedPageTabViewBottomWithFrames = async () => {
await this.loadedPage(tabViewBottomHome);
}
- loadedTabTopRootWithFrames = async () => {
- await this.loadedPage(tabViewRootTopHome);
+ loadedTabViewTopRootWithFrames = async () => {
+ await this.loadedPage(tabViewTopRootHome);
}
- loadedTabBottomRootWithFrames = async () => {
- await this.loadedPage(tabViewRootBottomHome);
+ loadedTabViewBottomRootWithFrames = async () => {
+ await this.loadedPage(tabViewBottomRootHome);
+ }
+
+ loadedPageTabsTopWithFrames = async () => {
+ await this.loadedPage(tabsTopHome);
+ }
+
+ loadedPageTabsBottomWithFrames = async () => {
+ await this.loadedPage(tabsBottomHome);
+ }
+
+ loadedPageBottomNavigationWithFrames = async () => {
+ await this.loadedPage(bottomNavigationHome);
+ }
+
+ loadedTabsTopRootWithFrames = async () => {
+ await this.loadedPage(tabsTopRootHome);
+ }
+
+ loadedTabsBottomRootWithFrames = async () => {
+ await this.loadedPage(tabsBottomRootHome);
+ }
+
+ loadedBottomNavigationRootWithFrames = async () => {
+ await this.loadedPage(bottomNavigationRootHome);
}
loadedStillOtherPage = async () => {
diff --git a/e2e/nested-frame-navigation/e2e/tab-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/tab-root.e2e-spec.ts
index e6b1af1ee..fe198bbde 100644
--- a/e2e/nested-frame-navigation/e2e/tab-root.e2e-spec.ts
+++ b/e2e/nested-frame-navigation/e2e/tab-root.e2e-spec.ts
@@ -4,8 +4,8 @@ import { Screen, playersData, teamsData } from "./screen";
import * as shared from "./shared.e2e-spec";
import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
-// NOTE: TabTop is Android only scenario (for iOS we will essentially execute 2x TabBottom)
-const roots = ["TabTop", "TabBottom"];
+// NOTE: TabViewTop is Android only scenario (for iOS we will essentially execute 2x TabViewBottom)
+const roots = ["TabViewTop", "TabViewBottom"];
const rootType = "tab-root";
describe(rootType, async function () {
diff --git a/e2e/nested-frame-navigation/e2e/tabs-root.e2e-spec.ts b/e2e/nested-frame-navigation/e2e/tabs-root.e2e-spec.ts
new file mode 100644
index 000000000..61982d38a
--- /dev/null
+++ b/e2e/nested-frame-navigation/e2e/tabs-root.e2e-spec.ts
@@ -0,0 +1,180 @@
+import { AppiumDriver, createDriver, logWarn, nsCapabilities } from "nativescript-dev-appium";
+
+import { Screen, playersData, teamsData } from "./screen";
+import * as shared from "./shared.e2e-spec";
+import { suspendTime, appSuspendResume, dontKeepActivities, transitions } from "./config";
+
+const roots = ["TabsTop", "TabsBottom"];
+
+const rootType = "tabs-root";
+describe(rootType, async function () {
+ let driver: AppiumDriver;
+ let screen: Screen;
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ logWarn(`====== ${rootType} ========`);
+ driver = await createDriver();
+ screen = new Screen(driver);
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(true);
+ }
+
+ driver.defaultWaitTime = 8000;
+ });
+
+ after(async function () {
+ if (dontKeepActivities) {
+ await driver.setDontKeepActivities(false);
+ }
+ await driver.quit();
+ console.log("Quit driver!");
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ }
+ });
+
+ for (let index = 0; index < roots.length; index++) {
+ const root = roots[index];
+ describe(`${rootType}-${root}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ });
+
+ for (let index = 0; index < transitions.length; index++) {
+ const transition = transitions[index];
+
+ const playerOne = playersData[`playerOne${transition}`];
+ const playerTwo = playersData[`playerTwo${transition}`];
+ const teamOne = teamsData[`teamOne${transition}`];
+ const teamTwo = teamsData[`teamTwo${transition}`];
+
+ describe(`${rootType}-${root}-transition-${transition}-scenarios:`, async function () {
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+
+ if (transition === "Flip" &&
+ driver.isAndroid && parseInt(driver.platformVersion) === 19) {
+ // TODO: known issue https://github.com/NativeScript/NativeScript/issues/6798
+ console.log("skipping flip transition tests on api level 19");
+ this.skip();
+ }
+ });
+
+ it("loaded home page", async function () {
+ await screen.loadedHome();
+ });
+
+ it(`loaded ${root} root with frames`, async function () {
+ await screen[`navigateTo${root}RootWithFrames`]();
+ await screen[`loaded${root}RootWithFrames`]();
+ });
+
+ it("loaded players list", async function () {
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded player details and go back twice", async function () {
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+
+ await shared.testPlayerNavigatedBack(screen, driver);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+ await shared.testPlayerNavigatedBack(screen, driver);
+ });
+
+ it("toggle teams tab", async function () {
+ await screen.toggleTeamsTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamOne.name); // wait for teams list
+ }
+ });
+
+ it("loaded teams list", async function () {
+ await screen.loadedTeamsList();
+ });
+
+ it("mix player and team list actions and go back", async function () {
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerOne.name); // wait for players list
+ }
+
+ await screen.loadedPlayersList();
+
+ await shared.testPlayerNavigated(playerTwo, screen);
+
+ if (driver.isIOS) {
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+ }
+
+ await screen.toggleTeamsTab();
+
+ if (driver.isIOS) {
+ // TODO: run in background from appium breaks the test. Investigate the issue, once with the app and with appium
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamOne.name); // wait for teams list
+ }
+ }
+
+ await screen.loadedTeamsList();
+
+ await shared.testTeamNavigated(teamTwo, screen);
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(teamTwo.name); // wait for team
+ }
+
+ await screen.togglePlayersTab();
+
+ if (appSuspendResume) {
+ await driver.backgroundApp(suspendTime);
+ await driver.waitForElement(playerTwo.name); // wait for player
+ }
+
+ await screen.loadedPlayerDetails(playerTwo);
+
+ await screen.toggleTeamsTab();
+
+ await screen.goBackToTeamsList();
+ await screen.loadedTeamsList();
+
+ await screen.togglePlayersTab();
+
+ await screen.goBackToPlayersList();
+ await screen.loadedPlayersList();
+ });
+
+ it("loaded home page again", async function () {
+ await screen.resetToHome();
+ await screen.loadedHome();
+ });
+ });
+ }
+ });
+ }
+});
diff --git a/e2e/ui-tests-app/README.md b/e2e/ui-tests-app/README.md
index 3230d0df0..f2c0277b8 100644
--- a/e2e/ui-tests-app/README.md
+++ b/e2e/ui-tests-app/README.md
@@ -1,17 +1,21 @@
***e2e tests execution***
1. Local setup
- - install appium and all requirments related to how to use `nativescript-dev-appium` plugin
+ - install appium and all requirments related to `nativescript-dev-appium` plugin usage
- download images:
- ```npm run load-images Emulator-Api23-Default```
+ ```npm run load-images Emulator-Api23-Default "iPhone X 12"```
or load multiple folders:
- ``` npm run load-images Emulator-Api23-Default Emulator-Google-Api28```
+ ``` npm run load-images Emulator-Api23-Default Emulator-Google-Api28 "iPhone X 12"```
- This command will download https://github.com/NativeScript/functional-tests-images/tree/master/uitestsapp and sparse all passed directories [emulator-name|simulator-name] [emulator-name|simulator-name] [emulator-name|simulator-name]
- - name your device so that it matches folder name, respectively api level and density of emulators.
+ or load all folders:
+
+ ``` npm run load-images all```
+
+ This command will download https://github.com/NativeScript/functional-tests-images/tree/master/uitestsapp and sparse all passed directories [emulator-name|simulator-name]
+ - rename/ create your device so that it matches folder name, respectively api level and density of emulators.
You can also use scripts:
@@ -19,7 +23,7 @@
If you need to download system image and create emulator use:
- `npm run update-emulators -u`
+ `npm run update-emulators -- --update-system-images`
2. Test execution
- Run test compilation in separate terminal and don't kill it.
@@ -31,8 +35,8 @@
3. Debug test.
- Run:
- `npm run test-debug [android|ios]`
-in separate console and don't kill it. This command will start appium server and driver and use the installed app on the device but it will not execute tests.
+ `npm run e2e-debug [android|ios]`
+run in separate console and don't kill it. This command will start appium server and driver and use the installed app on the device but it will not execute tests.
- Go to vs code debugging and use a config like:
```
@@ -48,13 +52,15 @@ in separate console and don't kill it. This command will start appium server and
"--opts",
"../config/mocha.opts",
"--attachToDebug",
+ "--grpe",
+ "button"
],
"internalConsoleOptions": "openOnSessionStart"
}
***mocha options***
-mocha opt file is plased in "../config/mocha.opts".
+mocha opt file is located at "../config/mocha.opts".
--timeout 999999
--recursive e2e
@@ -63,4 +69,8 @@ mocha opt file is plased in "../config/mocha.opts".
--exit
-- grep particular suites: "--grep=tabs-tab(s-\\w+)-suite"
\ No newline at end of file
+***grep particular suit or test***
+
+` npm run e2e ios -- --grep=tabs-tab(s-\\w+)-suite`
+
+
diff --git a/e2e/ui-tests-app/app/action-bar/action-item-position-page.xml b/e2e/ui-tests-app/app/action-bar/action-item-position-page.xml
index 8272a576d..2c3af2caa 100644
--- a/e2e/ui-tests-app/app/action-bar/action-item-position-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/action-item-position-page.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/action-view-page.xml b/e2e/ui-tests-app/app/action-bar/action-view-page.xml
index 1b7bdd152..a48732c58 100644
--- a/e2e/ui-tests-app/app/action-bar/action-view-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/action-view-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/all-page.xml b/e2e/ui-tests-app/app/action-bar/all-page.xml
index c85946305..d9cccc775 100644
--- a/e2e/ui-tests-app/app/action-bar/all-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/all-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/background-css-page.xml b/e2e/ui-tests-app/app/action-bar/background-css-page.xml
index 317736b57..9930234a0 100644
--- a/e2e/ui-tests-app/app/action-bar/background-css-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/background-css-page.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/background-page.xml b/e2e/ui-tests-app/app/action-bar/background-page.xml
index c03793a64..60a17817f 100644
--- a/e2e/ui-tests-app/app/action-bar/background-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/background-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/clean-page.xml b/e2e/ui-tests-app/app/action-bar/clean-page.xml
index 4319ac687..1eb0a61fc 100644
--- a/e2e/ui-tests-app/app/action-bar/clean-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/clean-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/color-page.xml b/e2e/ui-tests-app/app/action-bar/color-page.xml
index 1224561be..0f999e833 100644
--- a/e2e/ui-tests-app/app/action-bar/color-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/color-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/flat-layout-page.xml b/e2e/ui-tests-app/app/action-bar/flat-layout-page.xml
index f7f64f965..95cfa7838 100644
--- a/e2e/ui-tests-app/app/action-bar/flat-layout-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/flat-layout-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/flat-page.xml b/e2e/ui-tests-app/app/action-bar/flat-page.xml
index caefbf7af..73d403de6 100644
--- a/e2e/ui-tests-app/app/action-bar/flat-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/flat-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/flat-scrollview-page.xml b/e2e/ui-tests-app/app/action-bar/flat-scrollview-page.xml
index 7617e5db9..425af1098 100644
--- a/e2e/ui-tests-app/app/action-bar/flat-scrollview-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/flat-scrollview-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/flat-tab-opaque-bar-page.xml b/e2e/ui-tests-app/app/action-bar/flat-tab-opaque-bar-page.xml
index 8314ca617..04030e71e 100644
--- a/e2e/ui-tests-app/app/action-bar/flat-tab-opaque-bar-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/flat-tab-opaque-bar-page.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/flat-tab-page.xml b/e2e/ui-tests-app/app/action-bar/flat-tab-page.xml
index fc177b441..d6f4967ab 100644
--- a/e2e/ui-tests-app/app/action-bar/flat-tab-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/flat-tab-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/font-icons-page.xml b/e2e/ui-tests-app/app/action-bar/font-icons-page.xml
index c9539b0c1..7ba4b9d22 100644
--- a/e2e/ui-tests-app/app/action-bar/font-icons-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/font-icons-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/icons-page.xml b/e2e/ui-tests-app/app/action-bar/icons-page.xml
index cde351035..7c4739b56 100644
--- a/e2e/ui-tests-app/app/action-bar/icons-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/icons-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/local-icons-page.xml b/e2e/ui-tests-app/app/action-bar/local-icons-page.xml
index a0e14c181..5583b4eae 100644
--- a/e2e/ui-tests-app/app/action-bar/local-icons-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/local-icons-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/modal-page-hidden-action-bar-page.xml b/e2e/ui-tests-app/app/action-bar/modal-page-hidden-action-bar-page.xml
index 31268c7c5..ee583a569 100644
--- a/e2e/ui-tests-app/app/action-bar/modal-page-hidden-action-bar-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/modal-page-hidden-action-bar-page.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/modal-test-hidden-action-bar-page.xml b/e2e/ui-tests-app/app/action-bar/modal-test-hidden-action-bar-page.xml
index 868e6fa5f..cf2952521 100644
--- a/e2e/ui-tests-app/app/action-bar/modal-test-hidden-action-bar-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/modal-test-hidden-action-bar-page.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/modal-test-with-action-bar-page.xml b/e2e/ui-tests-app/app/action-bar/modal-test-with-action-bar-page.xml
index 43fc81092..7aee9937a 100644
--- a/e2e/ui-tests-app/app/action-bar/modal-test-with-action-bar-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/modal-test-with-action-bar-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/system-icons-page.xml b/e2e/ui-tests-app/app/action-bar/system-icons-page.xml
index 23a723395..3fdb934f0 100644
--- a/e2e/ui-tests-app/app/action-bar/system-icons-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/system-icons-page.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/e2e/ui-tests-app/app/action-bar/transparent-bg-css-page.xml b/e2e/ui-tests-app/app/action-bar/transparent-bg-css-page.xml
index 42f6c9eb7..d95d8cd73 100644
--- a/e2e/ui-tests-app/app/action-bar/transparent-bg-css-page.xml
+++ b/e2e/ui-tests-app/app/action-bar/transparent-bg-css-page.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/e2e/ui-tests-app/app/tabs/main-page.ts b/e2e/ui-tests-app/app/tabs/main-page.ts
index 65d381991..17acc66e8 100644
--- a/e2e/ui-tests-app/app/tabs/main-page.ts
+++ b/e2e/ui-tests-app/app/tabs/main-page.ts
@@ -27,6 +27,8 @@ export function loadExamples() {
examples.set("tabs-position", "tabs/tabs-position-page");
examples.set("tabs-binding", "tabs/tabs-binding-page");
examples.set("font-icons", "tabs/font-icons-page");
+ examples.set("nested-layout", "tabs/nested-layout-page");
+ examples.set("nested-bottom-navigation", "tabs/nested-bottom-navigation-page");
return examples;
}
diff --git a/e2e/ui-tests-app/app/tabs/nested-bottom-navigation-page.xml b/e2e/ui-tests-app/app/tabs/nested-bottom-navigation-page.xml
new file mode 100644
index 000000000..c2e750418
--- /dev/null
+++ b/e2e/ui-tests-app/app/tabs/nested-bottom-navigation-page.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/nested-layout-page.xml b/e2e/ui-tests-app/app/tabs/nested-layout-page.xml
new file mode 100644
index 000000000..922365fe3
--- /dev/null
+++ b/e2e/ui-tests-app/app/tabs/nested-layout-page.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/ui-tests-app/app/tabs/tabs-page.xml b/e2e/ui-tests-app/app/tabs/tabs-page.xml
index e16c9aa92..865a806fa 100644
--- a/e2e/ui-tests-app/app/tabs/tabs-page.xml
+++ b/e2e/ui-tests-app/app/tabs/tabs-page.xml
@@ -3,87 +3,34 @@
-
-
-
-
-
-
+
+
-
-
-
-
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/e2e/ui-tests-app/e2e/helpers/image-helper.ts b/e2e/ui-tests-app/e2e/helpers/image-helper.ts
index aeee5e43e..530e9e0dc 100644
--- a/e2e/ui-tests-app/e2e/helpers/image-helper.ts
+++ b/e2e/ui-tests-app/e2e/helpers/image-helper.ts
@@ -1,6 +1,14 @@
export const setImageName = (suite: string, spec: string, testsName: string) => {
- const testName = `${suite}-${spec}-${testsName.replace(suite, "").replace(spec, "")}`.replace(/(\-+)/ig, "-").replace(/(\_+)/ig, "_");
+ let testName = testsName
+ .replace(suite, "")
+ .replace(spec, "");
+ testName = `${suite}-${spec}-${testName}`
+ .replace("should", "-")
+ .replace(/\s+/g, "-")
+ .replace(/\_+/ig, "_")
+ .replace(/[!$%^&*()+|~=`{}\[\]:";'<>?,.\/]/g, "")
+ .replace(/\-+/g, "-");
return testName;
};
\ No newline at end of file
diff --git a/e2e/ui-tests-app/e2e/helpers/navigation-helper.ts b/e2e/ui-tests-app/e2e/helpers/navigation-helper.ts
index ecf6ca396..d93ce7322 100644
--- a/e2e/ui-tests-app/e2e/helpers/navigation-helper.ts
+++ b/e2e/ui-tests-app/e2e/helpers/navigation-helper.ts
@@ -107,9 +107,10 @@ export class NavigationHelper {
const endPoint = {};
if (this._driver.isIOS) {
+ const rect = this._driver.getScreenActualViewPort();
startPoint.x = 5;
- startPoint.y = this._driver.nsCapabilities.device.viewportRect.y / this._driver.nsCapabilities.device.config.density;
- endPoint.x = (this._driver.nsCapabilities.device.viewportRect.width / this._driver.nsCapabilities.device.config.density) - 5;
+ startPoint.y = rect.y;
+ endPoint.x = (rect.width / this._driver.nsCapabilities.device.deviceScreenDensity) - 5;
endPoint.y = startPoint.y;
await this._driver.swipe(startPoint, endPoint);
diff --git a/e2e/ui-tests-app/e2e/resources/images/uitestsapp b/e2e/ui-tests-app/e2e/resources/images/uitestsapp
deleted file mode 120000
index 2ae4132a5..000000000
--- a/e2e/ui-tests-app/e2e/resources/images/uitestsapp
+++ /dev/null
@@ -1 +0,0 @@
-/Users/tsenov/git/nativescript/e2e/ui-tests-app/../../../functional-tests-images/uitestsapp
\ No newline at end of file
diff --git a/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-base-page.ts b/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-base-page.ts
new file mode 100644
index 000000000..a84ee85eb
--- /dev/null
+++ b/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-base-page.ts
@@ -0,0 +1,13 @@
+import { AppiumDriver } from "nativescript-dev-appium";
+import { PageObjectBaseModel } from "../../page-object-base-model";
+
+export class ActionBarBasePage extends PageObjectBaseModel {
+ private readonly automationText: string = "actionBar";
+ constructor(_driver: AppiumDriver) {
+ super(_driver, ["action-bar"]);
+ }
+
+ get actionBar() {
+ return this._driver.waitForElement(this.automationText);
+ }
+}
\ No newline at end of file
diff --git a/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-tests.e2e-spec.ts b/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-tests.e2e-spec.ts
new file mode 100644
index 000000000..37a399514
--- /dev/null
+++ b/e2e/ui-tests-app/e2e/suites/action-bar/action-bar-tests.e2e-spec.ts
@@ -0,0 +1,307 @@
+import { nsCapabilities, createDriver, AppiumDriver, SearchOptions, logError } from "nativescript-dev-appium";
+import { ActionBarBasePage } from "./action-bar-base-page";
+import { assert } from "chai";
+import { setImageName } from "../../helpers/image-helper";
+// import { unlinkSync, existsSync } from "fs";
+
+const suite = "action-bar";
+const testNamePrefix = `${suite}: `;
+
+describe(`${suite}-suite`, async function () {
+ let driver: AppiumDriver;
+ let actionBarBasePage: ActionBarBasePage;
+
+ before(async function () {
+ nsCapabilities.testReporter.context = this;
+ driver = await createDriver();
+ await driver.restartApp();
+ actionBarBasePage = new ActionBarBasePage(driver);
+ await actionBarBasePage.initSuite();
+ });
+
+ after(async function () {
+ await actionBarBasePage.endSuite();
+ });
+
+ beforeEach(async function () {
+ driver.imageHelper.testName = setImageName(suite, "", this.currentTest.title);
+ driver.imageHelper.options = {
+ donNotAppendActualSuffixOnIntialImageCapture: true
+ };
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ // await driver.resetApp();
+ // await actionBarBasePage.initSuite();
+ }
+ });
+
+ const btnGoToClearPageTap = async () => {
+ await clickOnElement("go to cleared page");
+ };
+
+ const btnGoToPrevPageTap = async () => {
+ await clickOnElement("go to previous page");
+ };
+
+ const btnTap = async () => {
+ await clickOnElement("Tap");
+ };
+
+ const clickOnElement = async (automationText: string) => {
+ const el = await driver.waitForElement(automationText);
+ if (el === null) {
+ logError(`Element ${automationText} not found!`);
+ assert.isTrue(false, `Element ${automationText} should be visible`);
+ }
+ await el.click();
+ };
+
+ it(`${testNamePrefix}"actBG", set background color`, async function () {
+ await actionBarBasePage.navigateToSample("actBG");
+ await driver.imageHelper.compareScreen();
+
+ await btnGoToClearPageTap();
+ await driver.imageHelper.compareScreen();
+
+ await btnGoToPrevPageTap();
+ await driver.imageHelper.compareScreen();
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"actBGCss", issue-516`, async function () {
+ await actionBarBasePage.navigateToSample("actBGCss");
+ const imageNameRed = setImageName(suite, "", `${testNamePrefix} should navigate to "actBGCss" issue-516-red`);
+ const imageNameTrans = setImageName(suite, "", `${testNamePrefix} should navigate to "actBGCss" issue-516-trans`);
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar, { imageName: imageNameRed, keepOriginalImageName: true });
+ await btnGoToClearPageTap();
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar, { imageName: imageNameTrans, keepOriginalImageName: true });
+
+ await btnGoToPrevPageTap();
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar, { imageName: imageNameRed, keepOriginalImageName: true });
+
+ await btnGoToClearPageTap();
+ await (await driver.waitForElement("ITEM")).click();
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar, { imageName: imageNameRed, keepOriginalImageName: true });
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"actColor", should set text color`, async function () {
+ await actionBarBasePage.navigateToSample("actColor");
+ const result = await driver.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix}"actIcons"`, async function () {
+ await actionBarBasePage.navigateToSample("actIcons");
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix}"actLocalIcons"`, async function () {
+ await actionBarBasePage.navigateToSample("actLocalIcons");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("undefined");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("alwaysTemplate");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("undefined");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("automatic");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"actResIcons"`, async function () {
+ await actionBarBasePage.navigateToSample("actResIcons");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("undefined");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("alwaysTemplate");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("undefined");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+
+ await clickOnElement("automatic");
+ await driver.imageHelper.compareElement(await actionBarBasePage.actionBar);
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix} should navigate to actStyle`, async function () {
+ await actionBarBasePage.navigateToSample("actStyle");
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} should "go to cleared page"`, async function () {
+ await btnGoToClearPageTap();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} should "go to previous page"`, async function () {
+ await btnGoToPrevPageTap();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} click on "ITEM" and navigate to clean page`, async function () {
+ await (await driver.waitForElement("ITEM")).click();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} click on "ITEM" and navigate to action bar style initial page`, async function () {
+ await (await driver.waitForElement("ITEM")).click();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar, `${suite}-navigate-to-actStyle`);
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} should navigate to "actView"`, async function () {
+ await actionBarBasePage.navigateToSample("actView");
+ const result = await driver.compareElement(await actionBarBasePage.actionBar);
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} should navigate with "Green" button`, async function () {
+ await (await driver.waitForElement("Green")).click();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar, setImageName(suite, ``, `${testNamePrefix} should "go to cleared page"`));
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix} should navigate back with "BACK"`, async function () {
+ await driver.navBack();
+ const result = await driver.compareElement(await actionBarBasePage.actionBar, setImageName(suite, "", `${testNamePrefix} should navigate to "actView"`));
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(result);
+ });
+
+ it(`${testNamePrefix}"actionItemPosition",should change item position`, async function () {
+ await actionBarBasePage.navigateToSample("actionItemPosition");
+ await driver.imageHelper.compareScreen();
+
+ await btnTap();
+ await driver.imageHelper.compareScreen();
+
+ await btnTap();
+ await driver.imageHelper.compareScreen();
+
+ await btnTap();
+ await driver.imageHelper.compareScreen();
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"actTransparentBgCss", page background color as actBackground color`, async function () {
+ await actionBarBasePage.navigateToSample("actTransparentBgCss");
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("go to cleared page")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("ITEM")).click();
+ await driver.imageHelper.compareScreen();
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix} should navigate to "modalShownActBar" nav back with "Go Back"`, async function () {
+ await actionBarBasePage.navigateToSample("modalShownActBar");
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Open Modal")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Close")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Go Back")).click();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix} should navigate to "modalHiddenActBar" nav back with "Go Back"`, async function () {
+ await actionBarBasePage.navigateToSample("modalHiddenActBar");
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Open Modal")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Change text")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Close")).click();
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("Go Back")).click();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"flat", change`, async function () {
+ await actionBarBasePage.navigateToSample("flat");
+ await driver.imageHelper.compareScreen();
+
+ await (await driver.waitForElement("change flat property")).click();
+ await driver.imageHelper.compareScreen();
+
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}flat-layout"`, async function () {
+ await actionBarBasePage.navigateToSample("flat-layout");
+ await driver.imageHelper.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}flat-scrollview`, async function () {
+ await actionBarBasePage.navigateToSample("flat-scrollview");
+ await driver.imageHelper.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}"flat-tab"`, async function () {
+ await actionBarBasePage.navigateToSample("flat-tab");
+ await driver.imageHelper.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ // BUG
+ it(`${testNamePrefix}flat-opaque-bar`, async function () {
+ this.skip();
+ await actionBarBasePage.navigateToSample("flat-tab-opaque-bar");
+ await driver.imageHelper.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+
+ it(`${testNamePrefix}font-icons`, async function () {
+ await actionBarBasePage.navigateToSample("font-icons");
+ await driver.imageHelper.compareScreen();
+ await actionBarBasePage.navigateBackToSuitMainPage();
+ assert.isTrue(driver.imageHelper.hasImageComparisonPassed());
+ });
+});
\ No newline at end of file
diff --git a/e2e/ui-tests-app/e2e/suites/button/background/button-background-page.ts b/e2e/ui-tests-app/e2e/suites/button/background/button-background-page.ts
index ede3d634f..b93b6d45a 100644
--- a/e2e/ui-tests-app/e2e/suites/button/background/button-background-page.ts
+++ b/e2e/ui-tests-app/e2e/suites/button/background/button-background-page.ts
@@ -8,7 +8,6 @@ export class ButtonBackgroundPage extends PageObjectBaseModel {
constructor(_driver: AppiumDriver) {
super(_driver, ["button", "background"], ElementCacheStrategy.none);
- this._driver.imageHelper.options.toleranceType = ImageOptions.percent;
}
public viewGroupLocator() {
diff --git a/e2e/ui-tests-app/e2e/suites/button/background/button-background.e2e-spec.ts b/e2e/ui-tests-app/e2e/suites/button/background/button-background.e2e-spec.ts
index 1938ede8a..eecb234cd 100644
--- a/e2e/ui-tests-app/e2e/suites/button/background/button-background.e2e-spec.ts
+++ b/e2e/ui-tests-app/e2e/suites/button/background/button-background.e2e-spec.ts
@@ -17,7 +17,6 @@ describe(`${imagePrefix}-suite`, () => {
await driver.restartApp();
backgroundPage = new ButtonBackgroundPage(driver);
await backgroundPage.initSuite();
- driver.imageHelper.options.donNotAppendActualSuffixOnIntialImageCapture = true;
});
after(async function () {
diff --git a/e2e/ui-tests-app/e2e/suites/tab-navigation/bottom-navigation/bottom-navigation-css-properties.e2e-spec.ts b/e2e/ui-tests-app/e2e/suites/tab-navigation/bottom-navigation/bottom-navigation-css-properties.e2e-spec.ts
index e863057fd..1bcd4fd0e 100644
--- a/e2e/ui-tests-app/e2e/suites/tab-navigation/bottom-navigation/bottom-navigation-css-properties.e2e-spec.ts
+++ b/e2e/ui-tests-app/e2e/suites/tab-navigation/bottom-navigation/bottom-navigation-css-properties.e2e-spec.ts
@@ -1,7 +1,6 @@
import { nsCapabilities, createDriver, AppiumDriver, Direction } from "nativescript-dev-appium";
import { BottomNavigationBasePage } from "./bottom-navigation-base-page";
import { Platform } from "mobile-devices-controller";
-import { ElementCacheStrategy } from "../../../helpers/navigation-helper";
import { setImageName } from "../../../helpers/image-helper";
import { assert } from "chai";
@@ -22,6 +21,7 @@ describe(`${imagePrefix}-suite`, async function () {
];
before(async function () {
+ this.skip();
nsCapabilities.testReporter.context = this;
driver = await createDriver();
await driver.restartApp();
@@ -30,10 +30,12 @@ describe(`${imagePrefix}-suite`, async function () {
});
after(async function () {
+ this.skip();
await bottomNavigationBasePage.endSuite();
});
afterEach(async function () {
+ this.skip();
if (this.currentTest.state === "failed") {
await driver.logTestArtifacts(this.currentTest.title);
await driver.restartApp();
diff --git a/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-navigation-base-page.ts b/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-navigation-base-page.ts
index 1e798c28f..ab8c76102 100644
--- a/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-navigation-base-page.ts
+++ b/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-navigation-base-page.ts
@@ -1,7 +1,6 @@
import { AppiumDriver, Point, IRectangle, UIElement, logInfo, logWarn } from "nativescript-dev-appium";
import { PageObjectBaseModel } from "../../page-object-base-model";
import { ElementCacheStrategy } from "../../helpers/navigation-helper";
-import { ImageOptions } from "nativescript-dev-appium/lib/image-options";
export abstract class TabNavigationBasePage extends PageObjectBaseModel {
protected bottomNavigatioinTabRect: IRectangle;
diff --git a/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-view/issues-from-git.ts b/e2e/ui-tests-app/e2e/suites/tab-navigation/tab-view/issues-from-git.ts
deleted file mode 100644
index e69de29bb..000000000
diff --git a/e2e/ui-tests-app/e2e/suites/tab-navigation/tabs/tabs-tests.e2e-spec.ts b/e2e/ui-tests-app/e2e/suites/tab-navigation/tabs/tabs-tests.e2e-spec.ts
index aa3aafc86..a889586b3 100644
--- a/e2e/ui-tests-app/e2e/suites/tab-navigation/tabs/tabs-tests.e2e-spec.ts
+++ b/e2e/ui-tests-app/e2e/suites/tab-navigation/tabs/tabs-tests.e2e-spec.ts
@@ -25,9 +25,6 @@ describe(`${imagePrefix}-suite`, async function () {
beforeEach(async function () {
driver.imageHelper.testName = setImageName(suite, spec, this.currentTest.title);
- driver.imageHelper.options = {
- donNotAppendActualSuffixOnIntialImageCapture: true
- };
});
afterEach(async function () {
diff --git a/gruntfile.js b/gruntfile.js
index 9411b6f8a..a436548aa 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -237,7 +237,7 @@ module.exports = function (grunt) {
},
platformsFiles: {
expand: true,
- src: "tns-core-modules/platforms/**/*.*",
+ src: "tns-core-modules/platforms/**/*",
dest: localCfg.outDir + "/"
},
apps: {
diff --git a/tests/app/ui/tabs/tabs-navigation-tests.ts b/tests/app/ui/tabs/tabs-navigation-tests.ts
index d06b06331..8489663d1 100644
--- a/tests/app/ui/tabs/tabs-navigation-tests.ts
+++ b/tests/app/ui/tabs/tabs-navigation-tests.ts
@@ -10,7 +10,7 @@ import { Button } from "tns-core-modules/ui/button";
var ASYNC = 2;
-function _createBottomNavigation(): Tabs {
+function _createTabsNavigation(): Tabs {
var tabView = new Tabs();
tabView.id = "BottomNavigation";
@@ -97,7 +97,7 @@ export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
let tabView: Tabs;
const pageFactory = function (): Page {
- tabView = _createBottomNavigation();
+ tabView = _createTabsNavigation();
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "Item1";
@@ -141,7 +141,7 @@ export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithALis
let tabView: Tabs;
let pageFactory = function (): Page {
- tabView = _createBottomNavigation();
+ tabView = _createTabsNavigation();
let items = Array();
let tabViewitem = new TabContentItem();
// tabViewitem.title = "List";
@@ -215,7 +215,7 @@ export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
let loadedEventsCount = [0, 0];
let unloadedEventsCount = [0, 0];
- const tabView = _createBottomNavigation();
+ const tabView = _createTabsNavigation();
tabView.items = _createContentItems(itemCount);
tabView.tabStrip = _createTabStrip(itemCount);
diff --git a/tns-core-modules-widgets/.gitignore b/tns-core-modules-widgets/.gitignore
index 4fbddfeda..f29a91f50 100644
--- a/tns-core-modules-widgets/.gitignore
+++ b/tns-core-modules-widgets/.gitignore
@@ -46,7 +46,6 @@ local.properties
ios/TNSWidgets/TNSWidgets.xcodeproj/project.xcworkspace/xcuserdata/
ios/TNSWidgets/TNSWidgets.xcodeproj/xcuserdata/
ios/TNSWidgets/DerivedData/
-ios/TNSWidgets/Pods/
xcuserdata/
android/widgets/bin
diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
index 113ac9d5f..be7970d42 100644
--- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
+++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java
@@ -170,7 +170,9 @@ class TabStrip extends LinearLayout {
}
@Override
- protected void onDraw(Canvas canvas) {
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
final int height = getHeight();
final int childCount = getChildCount();
final TabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
diff --git a/tns-core-modules-widgets/build.ios.sh b/tns-core-modules-widgets/build.ios.sh
index 66342487b..79736026c 100755
--- a/tns-core-modules-widgets/build.ios.sh
+++ b/tns-core-modules-widgets/build.ios.sh
@@ -16,9 +16,6 @@ cd ios
cd ..
echo "Copy ios/TNSWidgets/build/*.framework dist/package/platforms/ios"
-cp -R ios/TNSWidgets/build/MaterialComponents.framework dist/package/platforms/ios
-cp -R ios/TNSWidgets/build/MDFInternationalization.framework dist/package/platforms/ios
-cp -R ios/TNSWidgets/build/Pods_TNSWidgets.framework dist/package/platforms/ios
cp -R ios/TNSWidgets/build/TNSWidgets.framework dist/package/platforms/ios
cp ios/TNSWidgets/build/*.framework.dSYM.zip dist/package/platforms/ios
diff --git a/tns-core-modules-widgets/ios/TNSWidgets/Podfile b/tns-core-modules-widgets/ios/TNSWidgets/Podfile
deleted file mode 100644
index 01b809d3e..000000000
--- a/tns-core-modules-widgets/ios/TNSWidgets/Podfile
+++ /dev/null
@@ -1,6 +0,0 @@
-platform :ios, '10.0'
-use_frameworks!
-
-target 'TNSWidgets' do
- pod 'MaterialComponents/Tabs', '84.4.0'
-end
\ No newline at end of file
diff --git a/tns-core-modules-widgets/ios/TNSWidgets/Podfile.lock b/tns-core-modules-widgets/ios/TNSWidgets/Podfile.lock
deleted file mode 100644
index 80f479d86..000000000
--- a/tns-core-modules-widgets/ios/TNSWidgets/Podfile.lock
+++ /dev/null
@@ -1,39 +0,0 @@
-PODS:
- - MaterialComponents/AnimationTiming (84.4.0)
- - MaterialComponents/Ink (84.4.0):
- - MaterialComponents/private/Math
- - MaterialComponents/Palettes (84.4.0)
- - MaterialComponents/private/Application (84.4.0)
- - MaterialComponents/private/Math (84.4.0)
- - MaterialComponents/ShadowElevations (84.4.0)
- - MaterialComponents/ShadowLayer (84.4.0):
- - MaterialComponents/ShadowElevations
- - MaterialComponents/Tabs (84.4.0):
- - MaterialComponents/AnimationTiming
- - MaterialComponents/Ink
- - MaterialComponents/Palettes
- - MaterialComponents/private/Math
- - MaterialComponents/ShadowElevations
- - MaterialComponents/ShadowLayer
- - MaterialComponents/Typography
- - MDFInternationalization
- - MaterialComponents/Typography (84.4.0):
- - MaterialComponents/private/Application
- - MaterialComponents/private/Math
- - MDFInternationalization (2.0.0)
-
-DEPENDENCIES:
- - MaterialComponents/Tabs (= 84.4.0)
-
-SPEC REPOS:
- https://github.com/cocoapods/specs.git:
- - MaterialComponents
- - MDFInternationalization
-
-SPEC CHECKSUMS:
- MaterialComponents: e31f67324695bb1b537e5eccaee62db07ac3d06b
- MDFInternationalization: 010097556d6b09d2c4ea38e0820ea6d37be6a314
-
-PODFILE CHECKSUM: cf8c5f11be5a664a1b63632768c1ac024bf37a30
-
-COCOAPODS: 1.5.3
diff --git a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj b/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj
index d23fc8ecc..05f34d003 100644
--- a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj
+++ b/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcodeproj/project.pbxproj
@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
- 3E944C4C61C317F04FCA72D5 /* Pods_TNSWidgets.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9DA784D6AE838F6BE65AB7D /* Pods_TNSWidgets.framework */; };
8B7321CF1D097ECD00884AC6 /* TNSLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7321CD1D097ECD00884AC6 /* TNSLabel.h */; settings = {ATTRIBUTES = (Public, ); }; };
8B7321D01D097ECD00884AC6 /* TNSLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7321CE1D097ECD00884AC6 /* TNSLabel.m */; };
B8E76F52212C2DA2009CFCE2 /* NSObject+Swizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = B8E76F50212C2DA2009CFCE2 /* NSObject+Swizzling.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -36,7 +35,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 0CA2D2E3500594F250B7E5AD /* Pods-TNSWidgets.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TNSWidgets.release.xcconfig"; path = "Pods/Target Support Files/Pods-TNSWidgets/Pods-TNSWidgets.release.xcconfig"; sourceTree = ""; };
8B7321CD1D097ECD00884AC6 /* TNSLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNSLabel.h; sourceTree = ""; };
8B7321CE1D097ECD00884AC6 /* TNSLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNSLabel.m; sourceTree = ""; };
B8E76F50212C2DA2009CFCE2 /* NSObject+Swizzling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+Swizzling.h"; sourceTree = ""; };
@@ -45,8 +43,6 @@
B8E76F59212C2F4E009CFCE2 /* UIView+PropertyBag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+PropertyBag.m"; sourceTree = ""; };
B8E76F5C212C3134009CFCE2 /* UIView+PassThroughParent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+PassThroughParent.h"; sourceTree = ""; };
B8E76F5D212C3134009CFCE2 /* UIView+PassThroughParent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+PassThroughParent.m"; sourceTree = ""; };
- BA714249C33720A4C73F2D73 /* Pods-TNSWidgets.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TNSWidgets.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TNSWidgets/Pods-TNSWidgets.debug.xcconfig"; sourceTree = ""; };
- C9DA784D6AE838F6BE65AB7D /* Pods_TNSWidgets.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TNSWidgets.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F915D3531EC9EF5E00071914 /* TNSProcess.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TNSProcess.m; path = ../TNSProcess.m; sourceTree = ""; };
F915D3541EC9EF5E00071914 /* TNSProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TNSProcess.h; path = ../TNSProcess.h; sourceTree = ""; };
F98F5CAF1CD0EFEA00978308 /* TNSWidgets.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TNSWidgets.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -64,7 +60,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 3E944C4C61C317F04FCA72D5 /* Pods_TNSWidgets.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -79,31 +74,12 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 23F4E40A96EF6D33AE4654D3 /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- C9DA784D6AE838F6BE65AB7D /* Pods_TNSWidgets.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 50D824CFC5BFEB60164D83B1 /* Pods */ = {
- isa = PBXGroup;
- children = (
- BA714249C33720A4C73F2D73 /* Pods-TNSWidgets.debug.xcconfig */,
- 0CA2D2E3500594F250B7E5AD /* Pods-TNSWidgets.release.xcconfig */,
- );
- name = Pods;
- sourceTree = "";
- };
F98F5CA51CD0EFEA00978308 = {
isa = PBXGroup;
children = (
F98F5CB11CD0EFEA00978308 /* TNSWidgets */,
F98F5CBD1CD0EFEA00978308 /* TNSWidgetsTests */,
F98F5CB01CD0EFEA00978308 /* Products */,
- 50D824CFC5BFEB60164D83B1 /* Pods */,
- 23F4E40A96EF6D33AE4654D3 /* Frameworks */,
);
sourceTree = "";
};
@@ -170,7 +146,6 @@
isa = PBXNativeTarget;
buildConfigurationList = F98F5CC31CD0EFEA00978308 /* Build configuration list for PBXNativeTarget "TNSWidgets" */;
buildPhases = (
- A19DC6B35DC47BC836BB21AE /* [CP] Check Pods Manifest.lock */,
F98F5CAA1CD0EFEA00978308 /* Sources */,
F98F5CAB1CD0EFEA00978308 /* Frameworks */,
F98F5CAC1CD0EFEA00978308 /* Headers */,
@@ -255,31 +230,6 @@
};
/* End PBXResourcesBuildPhase section */
-/* Begin PBXShellScriptBuildPhase section */
- A19DC6B35DC47BC836BB21AE /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-TNSWidgets-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
-/* End PBXShellScriptBuildPhase section */
-
/* Begin PBXSourcesBuildPhase section */
F98F5CAA1CD0EFEA00978308 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -403,7 +353,6 @@
};
F98F5CC41CD0EFEA00978308 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BA714249C33720A4C73F2D73 /* Pods-TNSWidgets.debug.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -420,7 +369,6 @@
};
F98F5CC51CD0EFEA00978308 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 0CA2D2E3500594F250B7E5AD /* Pods-TNSWidgets.release.xcconfig */;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
diff --git a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/contents.xcworkspacedata b/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 219395415..000000000
--- a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
diff --git a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d981003..000000000
--- a/tns-core-modules-widgets/ios/TNSWidgets/TNSWidgets.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/tns-core-modules-widgets/ios/build.sh b/tns-core-modules-widgets/ios/build.sh
index 6273ea297..af6a21e49 100755
--- a/tns-core-modules-widgets/ios/build.sh
+++ b/tns-core-modules-widgets/ios/build.sh
@@ -3,17 +3,11 @@
echo "Set exit on simple errors"
set -e
-(
- echo "update pods"
- cd TNSWidgets
- pod install
-)
-
echo "Build for iphonesimulator"
-xcodebuild -workspace TNSWidgets/TNSWidgets.xcworkspace -scheme TNSWidgets -sdk iphonesimulator -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build -quiet
+xcodebuild -project TNSWidgets/TNSWidgets.xcodeproj -scheme TNSWidgets -sdk iphonesimulator -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build -quiet
echo "Build for iphoneos"
-xcodebuild -workspace TNSWidgets/TNSWidgets.xcworkspace -scheme TNSWidgets -sdk iphoneos -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -quiet
+xcodebuild -project TNSWidgets/TNSWidgets.xcodeproj -scheme TNSWidgets -sdk iphoneos -configuration Release clean build BUILD_DIR=$(PWD)/TNSWidgets/build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -quiet
function buildFatFramework() {
FRAMEWORK_NAME=$1
@@ -50,6 +44,3 @@ function buildFatFramework() {
}
buildFatFramework TNSWidgets .
-buildFatFramework Pods_TNSWidgets .
-buildFatFramework MDFInternationalization MDFInternationalization
-buildFatFramework MaterialComponents MaterialComponents
diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json
index 078302d0f..91325f896 100644
--- a/tns-core-modules/package.json
+++ b/tns-core-modules/package.json
@@ -26,7 +26,7 @@
"license": "Apache-2.0",
"typings": "tns-core-modules.d.ts",
"dependencies": {
- "tns-core-modules-widgets": "6.0.1",
+ "tns-core-modules-widgets": "next",
"tslib": "^1.9.3"
},
"devDependencies": {
diff --git a/tns-core-modules/platforms/ios/Podfile b/tns-core-modules/platforms/ios/Podfile
new file mode 100644
index 000000000..c1b2f02b7
--- /dev/null
+++ b/tns-core-modules/platforms/ios/Podfile
@@ -0,0 +1 @@
+pod 'MaterialComponents/Tabs', '~> 84.4'
\ No newline at end of file
diff --git a/tns-core-modules/ui/gestures/gestures.android.ts b/tns-core-modules/ui/gestures/gestures.android.ts
index 89330e4e2..019e3935e 100644
--- a/tns-core-modules/ui/gestures/gestures.android.ts
+++ b/tns-core-modules/ui/gestures/gestures.android.ts
@@ -68,13 +68,20 @@ function initializeTapAndDoubleTapGestureListener() {
}
private _handleSingleTap(motionEvent: android.view.MotionEvent): void {
- this._tapTimeoutId = timer.setTimeout(() => {
+ if (this._target.getGestureObservers(GestureTypes.doubleTap)) {
+ this._tapTimeoutId = timer.setTimeout(() => {
+ if (this._type & GestureTypes.tap) {
+ const args = _getArgs(GestureTypes.tap, this._target, motionEvent);
+ _executeCallback(this._observer, args);
+ }
+ timer.clearTimeout(this._tapTimeoutId);
+ }, TapAndDoubleTapGestureListenerImpl.DoubleTapTimeout);
+ } else {
if (this._type & GestureTypes.tap) {
const args = _getArgs(GestureTypes.tap, this._target, motionEvent);
_executeCallback(this._observer, args);
}
- timer.clearTimeout(this._tapTimeoutId);
- }, TapAndDoubleTapGestureListenerImpl.DoubleTapTimeout);
+ }
}
private _handleDoubleTap(motionEvent: android.view.MotionEvent): void {
diff --git a/tns-core-modules/ui/tabs/tabs.ios.ts b/tns-core-modules/ui/tabs/tabs.ios.ts
index 979d93e41..f85baf621 100644
--- a/tns-core-modules/ui/tabs/tabs.ios.ts
+++ b/tns-core-modules/ui/tabs/tabs.ios.ts
@@ -111,14 +111,23 @@ class UIPageViewControllerImpl extends UIPageViewController {
public viewDidLayoutSubviews(): void {
super.viewDidLayoutSubviews();
-
const owner = this._owner.get();
+ if (!owner) {
+ return;
+ }
+
const tabsPosition = owner.tabsPosition;
+ const parent = owner.parent;
let tabBarTop = this.view.safeAreaInsets.top;
let tabBarHeight = this.tabBar.frame.size.height;
let scrollViewTop = this.tabBar.frame.size.height;
- let scrollViewHeight = this.view.bounds.size.height - this.tabBar.frame.size.height + this.view.safeAreaInsets.bottom;
+ let scrollViewHeight = this.view.bounds.size.height - this.tabBar.frame.size.height;
+
+ if (parent) {
+ // TODO: Figure out a better way to handle ViewController nesting/Safe Area nesting
+ tabBarTop = Math.max(this.view.safeAreaInsets.top, owner.parent.nativeView.safeAreaInsets.top);
+ }
if (tabsPosition === "bottom") {
tabBarTop = this.view.frame.size.height - this.tabBar.frame.size.height - this.view.safeAreaInsets.bottom;
@@ -126,45 +135,7 @@ class UIPageViewControllerImpl extends UIPageViewController {
scrollViewHeight = this.view.frame.size.height - this.view.safeAreaInsets.bottom;
}
- this.tabBar.frame = CGRectMake(this.view.safeAreaInsets.left, tabBarTop, this.tabBar.frame.size.width, tabBarHeight); //this.view.safeAreaLayoutGuide.layoutFrame;
- // this.additionalSafeAreaInsets = new UIEdgeInsets({ top: this.tabBar.frame.size.height, left: 0, bottom: 0, right: 0 });
- // const tabBar = MDCTabBar.alloc().initWithFrame(this.view.safeAreaLayoutGuide.layoutFrame);
-
- // tabBar.items = >NSArray.alloc().initWithArray([
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // ]);
-
- // tabBar.itemAppearance = MDCTabBarItemAppearance.Titles;
- // tabBar.tintColor = UIColor.greenColor;
- // tabBar.barTintColor = UIColor.yellowColor;
- // tabBar.setTitleColorForState(UIColor.blackColor, MDCTabBarItemState.Normal);
- // tabBar.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleBottomMargin;
- // tabBar.sizeToFit();
- // this.view.addSubview(tabBar);
-
- // this.view.bringSubviewToFront(tabBar);
-
- // const tabBar = MDCTabBar.alloc().initWithFrame(this.view.bounds);
- // tabBar.items = >NSArray.alloc().initWithArray([
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0),
- // UITabBarItem.alloc().initWithTitleImageTag("Test", null, 0)
- // ]);
-
- // tabBar.itemAppearance = MDCTabBarItemAppearance.Titles;
- // tabBar.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleBottomMargin;
- // tabBar.sizeToFit();
- // this.view.addSubview(tabBar);
+ this.tabBar.frame = CGRectMake(this.view.safeAreaInsets.left, tabBarTop, this.tabBar.frame.size.width, tabBarHeight);
const subViews: NSArray = this.view.subviews;
let scrollView: UIScrollView = null;
@@ -192,47 +163,6 @@ class UIPageViewControllerImpl extends UIPageViewController {
scrollView.frame = CGRectMake(this.view.safeAreaInsets.left, scrollViewTop, this.view.bounds.size.width, scrollViewHeight); //this.view.bounds;
}
-
- // if (mdcBar) {
- // mdcBar.frame = this.view.bounds;
- // }
-
- // const owner = this.owner.get();
- // if (owner) {
- // if (majorVersion >= 11) {
- // // Handle nested UILayoutViewController safe area application.
- // // Currently, UILayoutViewController can be nested only in a TabView.
- // // The TabView itself is handled by the OS, so we check the TabView's parent (usually a Page, but can be a Layout).
- // const tabViewItem = owner.parent;
- // const tabView = tabViewItem && tabViewItem.parent;
- // let parent = tabView && tabView.parent;
-
- // // Handle Angular scenario where TabView is in a ProxyViewContainer
- // // It is possible to wrap components in ProxyViewContainers indefinitely
- // // Not using instanceof ProxyViewContainer to avoid circular dependency
- // // TODO: Try moving UILayoutViewController out of view module
- // while (parent && !parent.nativeViewProtected) {
- // parent = parent.parent;
- // }
-
- // if (parent) {
- // const parentPageInsetsTop = parent.nativeViewProtected.safeAreaInsets.top;
- // const currentInsetsTop = this.view.safeAreaInsets.top;
- // const additionalInsetsTop = Math.max(parentPageInsetsTop - currentInsetsTop, 0);
-
- // const parentPageInsetsBottom = parent.nativeViewProtected.safeAreaInsets.bottom;
- // const currentInsetsBottom = this.view.safeAreaInsets.bottom;
- // const additionalInsetsBottom = Math.max(parentPageInsetsBottom - currentInsetsBottom, 0);
-
- // if (additionalInsetsTop > 0 || additionalInsetsBottom > 0) {
- // const additionalInsets = new UIEdgeInsets({ top: additionalInsetsTop, left: 0, bottom: additionalInsetsBottom, right: 0 });
- // this.additionalSafeAreaInsets = additionalInsets;
- // }
- // }
- // }
-
- // layoutView(this, owner);
- // }
}
}
@@ -269,7 +199,8 @@ class UIPageViewControllerDataSourceImpl extends NSObject implements UIPageViewC
// prevViewController = owner.getViewController(prevItem);
// }
- (prevItem).canBeLoaded = true;
+ owner._setCanBeLoaded(selectedIndex);
+ owner._loadUnloadTabItems(selectedIndex);
return prevViewController;
}
@@ -295,7 +226,8 @@ class UIPageViewControllerDataSourceImpl extends NSObject implements UIPageViewC
// nextViewController = owner.getViewController(nextItem);
// }
- (nextItem).canBeLoaded = true;
+ owner._setCanBeLoaded(selectedIndex);
+ owner._loadUnloadTabItems(selectedIndex);
// nextItem.loadView(nextItem.view);
return nextViewController;
@@ -590,6 +522,11 @@ export class Tabs extends TabsBase {
this._ios.dataSource = this._dataSource;
this._ios.delegate = this._delegate;
+
+ if (!this.tabBarItems) {
+ const tabStripItems = this.tabStrip ? this.tabStrip.items : null;
+ this.setTabStripItems(tabStripItems);
+ }
}
public onUnloaded() {
@@ -670,7 +607,6 @@ export class Tabs extends TabsBase {
toLoad.forEach(index => {
const item = items[index];
if (this.isLoaded && items[index]) {
- (item).canBeLoaded = true;
item.loadView(item.view);
}
});
@@ -770,6 +706,18 @@ export class Tabs extends TabsBase {
return newController;
}
+ public _setCanBeLoaded(index: number) {
+ const items = this.items;
+ const lastIndex = items.length - 1;
+ const offsideItems = this.offscreenTabLimit;
+
+ iterateIndexRange(index, offsideItems, lastIndex, (i) => {
+ if (items[i]) {
+ (items[i]).canBeLoaded = true;
+ }
+ });
+ }
+
private setViewControllers(items: TabContentItem[]) {
const length = items ? items.length : 0;
if (length === 0) {
@@ -836,6 +784,10 @@ export class Tabs extends TabsBase {
}
public setTabStripItems(items: Array) {
+ if (!this.tabStrip || !items) {
+ return;
+ }
+
const tabBarItems = [];
items.forEach((item: TabStripItem, i) => {
@@ -1024,7 +976,6 @@ export class Tabs extends TabsBase {
// if (traceEnabled()) {
// traceWrite("TabView._onSelectedIndexPropertyChangedSetNativeValue(" + value + ")", traceCategories.Debug);
// }
- const that = this;
if (value > -1) {
const item = this.items[value];
@@ -1047,7 +998,9 @@ export class Tabs extends TabsBase {
this._currentNativeSelectedIndex = value;
this.viewController.setViewControllersDirectionAnimatedCompletion(controllers, navigationDirection, true, (finished: boolean) => {
if (finished) {
- that._canSelectItem = true;
+ this._canSelectItem = true;
+ this._setCanBeLoaded(value);
+ this._loadUnloadTabItems(value);
}
});
diff --git a/tns-core-modules/utils/utils.ios.ts b/tns-core-modules/utils/utils.ios.ts
index 303352d51..335497660 100644
--- a/tns-core-modules/utils/utils.ios.ts
+++ b/tns-core-modules/utils/utils.ios.ts
@@ -89,20 +89,9 @@ export module ios {
export const MajorVersion = NSString.stringWithString(UIDevice.currentDevice.systemVersion).intValue;
export function openFile(filePath: string): boolean {
- try {
- const appPath = getCurrentAppPath();
- const path = filePath.replace("~", appPath);
+ console.log("utils.ios.openFile() is deprecated; use utils.openFile() instead");
- const controller = UIDocumentInteractionController.interactionControllerWithURL(NSURL.fileURLWithPath(path));
- controller.delegate = new UIDocumentInteractionControllerDelegateImpl();
-
- return controller.presentPreviewAnimated(true);
- }
- catch (e) {
- traceWrite("Error in openFile", traceCategories.Error, traceMessageType.error);
- }
-
- return false;
+ return openFileAtRootModule(filePath);
}
export function getCurrentAppPath(): string {
@@ -146,6 +135,26 @@ export module ios {
}
+export function openFile(filePath: string): boolean {
+ try {
+ const appPath = ios.getCurrentAppPath();
+ const path = filePath.replace("~", appPath);
+
+ const controller = UIDocumentInteractionController.interactionControllerWithURL(NSURL.fileURLWithPath(path));
+ controller.delegate = new UIDocumentInteractionControllerDelegateImpl();
+
+ return controller.presentPreviewAnimated(true);
+ }
+ catch (e) {
+ traceWrite("Error in openFile", traceCategories.Error, traceMessageType.error);
+ }
+
+ return false;
+}
+
+// Need this so that we can use this function inside the ios module (avoid name clashing).
+const openFileAtRootModule = openFile;
+
export function GC() {
__collect();
}