test(e2e): add modal-navigation app tests (#5445)

* test(e2e): modal-navigation app webpack support

* test(e2e): add modal-navigation app smoke test

* chore(e2e): tslint disable next line

* chore(e2e): modal-navigation app compilation

* refactor(e2e): modal-nabivation app pages

* test(e2e): add app root modal frame tests

* test(e2e): add app root modal frame background tests

* refactor(e2e): app root modal frame tests

* test(e2e): add tab root modal frame tests

* refactor(e2e): modal frame tests

* test(e2e): add modal page tests

* docs(e2e): add scenarios

* refactor(e2e): modal-navigation app tests

* test(e2e): turn on/off "Don't keep activities"

* test(e2e): delete no background tests

* test(e2e): add modal tab tests

* refactor(e2e): quit driver after all tests

* refactor(e2e): config files

* fix(e2e): tab root tests

* refactor(e2e): skip tab root tests until fix app

* chore(e2e): config files
This commit is contained in:
Vasil Chimev
2018-03-13 09:06:12 +02:00
committed by GitHub
parent 1cbb1e8d0d
commit e1a1d643c8
30 changed files with 1108 additions and 53 deletions

6
.gitignore vendored
View File

@@ -52,7 +52,11 @@ apps/hooks/
apps/node_modules/
e2e/**/platforms
!e2e/**/webpack.config.js
e2e/**/reports/
e2e/**/*.trace/
e2e/**/test-results.xml
package-lock.json
.nsbuildinfo
.nsbuildinfo

View File

@@ -20,7 +20,6 @@ Managing dependencies:
- `tns-platform-declarations`
- `tns-core-modules`
- `e2e` depends on:
- `tns-platform-declarations`
- `tns-core-modules`
- `tests` depends on:
- `tns-platform-declarations`
@@ -43,7 +42,7 @@ Install devDependencies:
npm install
```
Run `setup` script. This will [`npm link`](https://docs.npmjs.com/cli/link) the `tns-core-modules` and `tns-core-modules-declarations` dependencies inside the `tests`, `apps` and `e2e` projects.
Run `setup` script. This will [`npm link`](https://docs.npmjs.com/cli/link) the `tns-core-modules` and `tns-core-modules-declarations` dependencies inside the `tests` and `apps` projects.
```bash
npm run setup
@@ -69,7 +68,7 @@ The modules have `typescript` as a devDependency so you should also be able to u
./node_modules/.bin/tsc
```
You can compile the TypeScript files in the `tns-core-modules`, `tns-platform-declarations`, `apps`, `e2e` and `tests` at once at the root of the repo:
You can compile the TypeScript files in the `tns-core-modules`, `tns-platform-declarations`, `apps` and `tests` at once at the root of the repo:
```bash
npm run tsc

View File

@@ -4,7 +4,48 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Tests on Android",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u",
"tdd",
"--timeout",
"999999",
"--colors",
// "${workspaceFolder}/test",
"--opts",
"./e2e/config/mocha.opts",
"--runType",
"android23",
"--reuseDevice",
"--verbose"
],
"internalConsoleOptions": "openOnSessionStart"
},
{
"type": "node",
"request": "launch",
"name": "Launch Tests on iOS",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u",
"tdd",
"--timeout",
"999999",
"--colors",
// "${workspaceFolder}/test",
"--opts",
"./e2e/config/mocha.opts",
"--runType",
"sim.iPhoneX.iOS112",
"--reuseDevice",
"--verbose"
],
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "Launch on iOS",
"type": "nativescript",
@@ -25,7 +66,6 @@
"platform": "ios",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"stopOnEntry": true,
"tnsArgs": [
"--syncAllFiles"
],
@@ -51,7 +91,6 @@
"platform": "android",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"stopOnEntry": true,
"tnsArgs": [
"--syncAllFiles"
],

View File

@@ -0,0 +1,62 @@
Execute Tests
=============
Android:
```
npm run e2e -- --runType android23 --reuseDevice
```
iOS:
```
npm run e2e -- --runType sim.iPhoneX.iOS112 --reuseDevice
```
Scenarios
=============
ROOT FRAME:
1. [Done] Show modal dialog with frame
1. Navigate to modal second page within modal dialog
1. Go back
2. Show nested modal dialog
2. Close nested modal dialog
3. Show nested modal dialog with frame
3. Close nested modal dialog
4. Close modal dialog
2. [Done] Show modal dialog
1. Show nested modal dialog
1. Close nested modal dialog
2. Show nested modal dialog with frame
2. Close nested modal dialog
3. Close modal dialog
3. [Done] Show modal tabview
1. Navigate to second page within tab item frame
1. Go back
2. Show nested modal dialog
2. Close nested modal dialog
3. Show nested modal dialog with frame
3. Close nested modal dialog
4. Close modal dialog
4. Navigate to second page within root frame
1. Show modal dialog with frame
1. Navigate to second page within modal dialog
1. Go back
2. Show nested modal dialog
2. Close nested modal dialog
3. Show nested modal dialog with frame
3. Close nested modal dialog
4. Close modal dialog
2. Show modal dialog
1. Show nested modal dialog
1. Close nested modal dialog
2. Show nested modal dialog with frame
2. Close nested modal dialog
3. Close modal dialog
3. Go back
ROOT TABVIEW:
[Same as above]

View File

@@ -1,3 +1,4 @@
import "./bundle-config";
import * as application from "tns-core-modules/application";
application.run({ moduleName: "app-root" });

View File

@@ -0,0 +1,9 @@
if ((<any>global).TNS_WEBPACK) {
// Register tns-core-modules UI framework modules
require("bundle-entry-points");
// Register application modules
// This will register each `root`, `page`, `fragment` postfixed xml, css, js, ts, scss file in the app/ folder
const context = (<any>require).context("~/", true, /(root|page|fragment)\.(xml|css|js|ts|scss|less|sass)$/);
global.registerWebpackModules(context);
}

View File

@@ -56,6 +56,6 @@ export function onNavigate(args: EventData) {
}
export function onRootViewChange() {
let rootView: View = application.getRootView();
rootView.typeName === "Frame" ? application._resetRootView({moduleName: "tab-root"}) : application._resetRootView({moduleName: "app-root"});
let rootView = application.getRootView();
rootView instanceof Frame ? application._resetRootView({moduleName: "tab-root"}) : application._resetRootView({moduleName: "app-root"});
}

View File

@@ -5,10 +5,10 @@
navigatedFrom="onNavigatedFrom">
<ActionBar class="action-bar">
<Label class="action-bar-title" text="Nested Modal"></Label>
<Label class="action-bar-title" text="Modal Nested"></Label>
</ActionBar>
<StackLayout backgroundColor="darkBlue">
<Button text="Close Modal" tap="closeModal" />
<Button text="Close Modal Nested" tap="closeModal" />
</StackLayout>
</Page>

View File

@@ -39,15 +39,6 @@ export function closeModal(args: EventData) {
(args.object as View).closeModal();
}
export function showNestedModalPage(args: EventData) {
const view = args.object as View;
view.showModal("modal-nested/modal-nested-page",
"nested-context",
() => console.log("modal page nested closed"),
false);
}
export function showNestedModalFrame(args: EventData) {
const view = args.object as View;
@@ -60,6 +51,15 @@ export function showNestedModalFrame(args: EventData) {
false);
}
export function showNestedModalPage(args: EventData) {
const view = args.object as View;
view.showModal("modal-nested/modal-nested-page",
"nested-context",
() => console.log("modal page nested closed"),
false);
}
export function onNavigate(args: EventData) {
const view = args.object as View;
const page = view.page as Page;

View File

@@ -10,8 +10,8 @@
<StackLayout backgroundColor="maroon">
<Button text="Navigate To Second Page" tap="onNavigate" visibility="{{ navigationVisibility }}" />
<Button text="Show Nested Modal Page" tap="showNestedModalPage" />
<Button text="Show Nested Modal Page With Frame" tap="showNestedModalFrame" />
<Button text="Show Nested Modal Page" tap="showNestedModalPage" />
<Button text="Close Modal" tap="closeModal" />
</StackLayout>
</Page>

View File

@@ -0,0 +1,9 @@
require("application");
if (!global["__snapshot"]) {
// In case snapshot generation is enabled these modules will get into the bundle
// but will not be required/evaluated.
// The snapshot webpack plugin will add them to the tns-java-classes.js bundle file.
// This way, they will be evaluated on app start as early as possible.
require("ui/frame");
require("ui/frame/activity");
}

View File

@@ -0,0 +1,4 @@
// There is a bug in angular: https://github.com/angular/angular-cli/pull/8589/files
// Legendary stuff, its webpack plugin pretty much doesn't work with empty TypeScript files in v1.8.3
// tslint:disable-next-line:no-unused-expression
void 0;

View File

@@ -0,0 +1,10 @@
// Snapshot the ~/app.css and the theme
const application = require("application");
require("ui/styling/style-scope");
const appCssContext = require.context("~/", false, /^\.\/app\.(css|scss|less|sass)$/);
global.registerWebpackModules(appCssContext);
application.loadAppCss();
require("./vendor-platform");
require("bundle-entry-points");

View File

@@ -0,0 +1,118 @@
{
"android19": {
"platformName": "Android",
"platformVersion": "4.4",
"deviceName": "Emulator-Api19-Default",
"avd": "Emulator-Api19-Default",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android21": {
"platformName": "Android",
"platformVersion": "5.0",
"deviceName": "Emulator-Api21-Default",
"avd": "Emulator-Api21-Default",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android23": {
"platformName": "Android",
"platformVersion": "6.0",
"deviceName": "Emulator-Api23-Default",
"avd": "Emulator-Api23-Default",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android24": {
"platformName": "Android",
"platformVersion": "7.0",
"deviceName": "Emulator-Api24-Default",
"avd": "Emulator-Api24-Default",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android25": {
"platformName": "Android",
"platformVersion": "7.1",
"deviceName": "Emulator-Api25-Google",
"avd": "Emulator-Api25-Google",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android26": {
"platformName": "Android",
"platformVersion": "8.0",
"deviceName": "Emulator-Api26-Google",
"avd": "Emulator-Api26-Google",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"android27": {
"platformName": "Android",
"platformVersion": "8.1",
"deviceName": "Emulator-Api27-Google",
"avd": "Emulator-Api27-Google",
"lt": 60000,
"appActivity": "com.tns.NativeScriptActivity",
"newCommandTimeout": 720,
"noReset": true,
"fullReset": false,
"app": ""
},
"sim.iPhone7.iOS110": {
"platformName": "iOS",
"platformVersion": "11.2",
"deviceName": "iPhone 7 110",
"noReset": true,
"fullReset": false,
"app": ""
},
"sim.iPhone8.iOS110": {
"platformName": "iOS",
"platformVersion": "11.0",
"deviceName": "iPhone 8 110",
"noReset": true,
"fullReset": false,
"app": ""
},
"sim.iPhoneX.iOS110": {
"platformName": "iOS",
"platformVersion": "11.0",
"deviceName": "iPhone X",
"noReset": true,
"fullReset": false,
"app": ""
},
"sim.iPhoneX.iOS112": {
"platformName": "iOS",
"platformVersion": "11.2",
"deviceName": "iPhone X",
"noReset": true,
"fullReset": false,
"app": ""
}
}

View File

@@ -0,0 +1,4 @@
--timeout 80000
--recursive e2e
--reporter mocha-multi
--reporter-options spec=-,mocha-junit-reporter=test-results.xml

View File

@@ -0,0 +1,58 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe("app root modal frame background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
// should load app root
await screen.loadedHome();
});
beforeEach(async function () {
await screen.loadModalFrame();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal page with frame in background", async () => {
await modalFrameBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});

View File

@@ -0,0 +1,50 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalPageBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe("app root modal page background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
// should load app root
await screen.loadedHome();
});
beforeEach(async function () {
await screen.loadModalPage();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal page in background", async () => {
await modalPageBackground(driver, screen, false);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen, false);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen, false);
});
});

View File

@@ -0,0 +1,64 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
modalTabViewBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground,
testSecondItemBackground
} from "../shared.e2e-spec"
describe("app root modal tab view background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
// should load app root
await screen.loadedHome();
});
beforeEach(async function () {
await screen.loadModalTabView();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal tab view in background", async () => {
await modalTabViewBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen);
});
it("should navigate to second item, run in background, navigate back to first item", async () => {
await testSecondItemBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});

View File

@@ -0,0 +1,58 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe.skip("tab root modal frame background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
await screen.setTabRootView();
});
beforeEach(async function () {
await screen.loadModalFrame();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
await screen.setTabRootView();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal page with frame in background", async () => {
await modalFrameBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});

View File

@@ -0,0 +1,50 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalPageBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe.skip("tab root modal page background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
await screen.setTabRootView();
});
beforeEach(async function () {
await screen.loadModalPage();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
await screen.setTabRootView();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal page in background", async () => {
await modalPageBackground(driver, screen, false);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen, false);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen, false);
});
});

View File

@@ -0,0 +1,64 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
modalTabViewBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground,
testSecondItemBackground
} from "../shared.e2e-spec"
describe.skip("tab root modal tab view background scenarios", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
await screen.setTabRootView();
});
beforeEach(async function () {
await screen.loadModalTabView();
});
afterEach(async function () {
if (this.currentTest.state === "failed") {
await driver.logPageSource(this.currentTest.title);
await driver.logScreenshot(this.currentTest.title);
await driver.resetApp();
await screen.setTabRootView();
}
});
after(async () => {
// should close page with frame
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal tab view in background", async () => {
await modalTabViewBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
it("should show nested modal page with frame, run in background, close", async () => {
await testNestedModalFrameBackground(driver, screen);
});
it("should show nested modal page, run in background, close", async () => {
await testNestedModalPageBackground(driver, screen);
});
it("should navigate to second item, run in background, navigate back to first item", async () => {
await testSecondItemBackground(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});

View File

@@ -0,0 +1,192 @@
import { AppiumDriver } from "nativescript-dev-appium";
import { assert } from "chai";
const home = "Home"
const first = "First"
const modal = "Modal";
const modalFirst = "Modal First";
const modalSecond = "Modal Second";
const modalNested = "Modal Nested";
const modalFrame = "Show Modal Page With Frame";
const modalPage = "Show Modal Page";
const modalTabView = "Show Modal TabView";
const navToSecondPage = "Navigate To Second Page";
const rootView = "Change Root View";
const showNestedModalFrame = "Show Nested Modal Page With Frame";
const showNestedModalPage = "Show Nested Modal Page";
const closeModalNested = "Close Modal Nested";
const closeModal = "Close Modal";
const goBack = "Go Back";
export class Screen {
private _driver: AppiumDriver
constructor(driver: AppiumDriver) {
this._driver = driver;
}
loadedHome = async () => {
const lblHome = await this._driver.findElementByText(home);
assert.isTrue(await lblHome.isDisplayed());
console.log(home + " loaded!");
}
changeRootView = async () => {
const btnChangeRootView = await this._driver.findElementByText(rootView);
await btnChangeRootView.tap();
}
loadedTabRootView = async () => {
const tabFirst = await this._driver.findElementByText(first);
assert.isTrue(await tabFirst.isDisplayed());
console.log("Tab root view loaded!");
}
setTabRootView = async () => {
// should load tab root
await this.loadedHome();
try {
await this.loadedTabRootView();
} catch (err) {
await this.changeRootView();
await this.loadedTabRootView();
}
}
showModalFrame = async () => {
const btnModalFrame = await this._driver.findElementByText(modalFrame);
await btnModalFrame.tap();
}
loadedModalFrame = async () => {
const lblModal = await this._driver.findElementByText(modal);
assert.isTrue(await lblModal.isDisplayed());
console.log(modal + " loaded!");
}
showModalPage = async () => {
const btnModalPage = await this._driver.findElementByText(modalPage);
await btnModalPage.tap();
}
loadedModalPage = async () => {
const btnShowNestedModalPage = await this._driver.findElementByText(showNestedModalPage);
assert.isTrue(await btnShowNestedModalPage.isDisplayed());
console.log("Modal Page loaded!");
}
showModalTabView = async () => {
const btnModalTabView = await this._driver.findElementByText(modalTabView);
await btnModalTabView.tap();
}
loadedModalTabView = async () => {
const itemModalFirst = await this._driver.findElementByText(modalFirst);
assert.isTrue(await itemModalFirst.isDisplayed());
console.log("Modal TabView loaded!");
}
navigateToSecondPage = async () => {
const btnNavToSecondPage = await this._driver.findElementByText(navToSecondPage);
await btnNavToSecondPage.tap();
}
navigateToFirstItem = async () => {
const itemModalFirst = await this._driver.findElementByText(modalFirst);
await itemModalFirst.tap();
}
navigateToSecondItem = async () => {
const itemModalSecond = await this._driver.findElementByText(modalSecond);
await itemModalSecond.tap();
}
loadedSecondPage = async () => {
const lblModalSecond = await this._driver.findElementByText(modalSecond);
assert.isTrue(await lblModalSecond.isDisplayed());
console.log(modalSecond + " loaded!");
}
loadedFirstItem = async () => {
const lblModal = await this._driver.findElementByText(modal);
assert.isTrue(await lblModal.isDisplayed());
console.log("First Item loaded!");
}
loadedSecondItem = async () => {
const btnGoBack = await this._driver.findElementByText(goBack);
assert.isTrue(await btnGoBack.isDisplayed());
console.log("Second Item loaded!");
}
goBackFromSecondPage = async () => {
const btnGoBackFromSecondPage = await this._driver.findElementByText(goBack);
await btnGoBackFromSecondPage.tap();
}
showNestedModalFrame = async () => {
const btnShowNestedModalFrame = await this._driver.findElementByText(showNestedModalFrame);
await btnShowNestedModalFrame.tap();
}
loadedNestedModalFrame = async () => {
const lblModalNested = await this._driver.findElementByText(modalNested);
assert.isTrue(await lblModalNested.isDisplayed());
console.log(modalNested + " loaded!");
}
closeModalNested = async () => {
const btnCloseNestedModal = await this._driver.findElementByText(closeModalNested);
await btnCloseNestedModal.tap();
}
showNestedModalPage = async () => {
const btnShowNestedModalPage = await this._driver.findElementByText(showNestedModalPage);
await btnShowNestedModalPage.tap();
}
loadedNestedModalPage = async () => {
const btnCloseModalNested = await this._driver.findElementByText(closeModalNested);
assert.isTrue(await btnCloseModalNested.isDisplayed());
console.log(closeModalNested + " loaded!");
}
closeModal = async () => {
const btnCloseModal = await this._driver.findElementByText(closeModal);
await btnCloseModal.tap();
}
loadModalFrame = async () => {
try {
await this.loadedModalFrame();
} catch (err) {
// should show modal page with frame
await this.showModalFrame();
await this.loadedModalFrame();
}
}
loadModalPage = async () => {
try {
await this.loadedModalPage();
} catch (err) {
// should show modal page
await this.showModalPage();
await this.loadedModalPage();
}
}
loadModalTabView = async () => {
try {
await this.loadedModalTabView();
} catch (err) {
// should show modal tab view with frame
await this.showModalTabView();
await this.loadedModalTabView();
}
}
}

View File

@@ -0,0 +1,15 @@
import { AppiumDriver, createDriver, startServer, stopServer } from "nativescript-dev-appium";
let driver: AppiumDriver;
before("start server", async () => {
await startServer();
driver = await createDriver();
await driver.setDontKeepActivities(true);
});
after("stop server", async () => {
await driver.setDontKeepActivities(false);
await driver.quit();
await stopServer();
});

View File

@@ -0,0 +1,63 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "./screen"
const time = 1;
export async function modalFrameBackground(driver: AppiumDriver, screen: Screen) {
await driver.backgroundApp(time);
await screen.loadedModalFrame();
}
export async function testSecondPageBackground(driver: AppiumDriver, screen: Screen) {
await screen.navigateToSecondPage();
await screen.loadedSecondPage();
await driver.backgroundApp(time);
await screen.loadedSecondPage();
await screen.goBackFromSecondPage();
await screen.loadedModalFrame();
}
export async function testNestedModalFrameBackground(driver: AppiumDriver, screen: Screen, isInFrame: boolean = true) {
await screen.showNestedModalFrame();
await screen.loadedNestedModalFrame();
await driver.backgroundApp(time);
await screen.loadedNestedModalFrame();
await screen.closeModalNested();
isInFrame ? await screen.loadedModalFrame() : await screen.loadedModalPage();
}
export async function testNestedModalPageBackground(driver: AppiumDriver, screen: Screen, isInFrame: boolean = true) {
await screen.showNestedModalPage();
await screen.loadedNestedModalPage();
await driver.backgroundApp(time);
await screen.loadedNestedModalPage();
await screen.closeModalNested();
isInFrame ? await screen.loadedModalFrame() : await screen.loadedModalPage();
}
export async function modalPageBackground(driver: AppiumDriver, screen: Screen, isInFrame: boolean = true) {
await driver.backgroundApp(time);
isInFrame ? await screen.loadedModalFrame() : await screen.loadedModalPage();
}
export async function modalTabViewBackground(driver: AppiumDriver, screen: Screen) {
await driver.backgroundApp(time);
await screen.loadedModalTabView();
}
export async function testSecondItemBackground(driver: AppiumDriver, screen: Screen) {
await screen.navigateToSecondItem();
await screen.loadedSecondItem();
await driver.backgroundApp(time);
await screen.loadedSecondItem();
await screen.navigateToFirstItem();
await screen.loadedFirstItem();
}

View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"importHelpers": false,
"sourceMap": true,
"types": [
"node",
"mocha",
"chai"
],
"lib": [
"es2015",
"dom"
]
}
}

View File

@@ -1,28 +1,44 @@
{
"description": "NativeScript Application",
"license": "SEE LICENSE IN <your-license-filename>",
"readme": "NativeScript Application",
"repository": "<fill-your-repository-here>",
"nativescript": {
"id": "org.nativescript.modalnavigation",
"tns-ios": {
"version": "3.4.1"
},
"tns-android": {
"version": "3.4.1"
}
},
"dependencies": {
"nativescript-theme-core": "~1.0.4",
"tns-core-modules": "*"
},
"devDependencies": {
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"babylon": "6.18.0",
"lazy": "1.0.11",
"nativescript-dev-typescript": "~0.6.0",
"tns-platform-declarations": "*",
"typescript": "~2.4.2"
}
"description": "NativeScript Application",
"license": "SEE LICENSE IN <your-license-filename>",
"readme": "NativeScript Application",
"repository": "<fill-your-repository-here>",
"nativescript": {
"id": "org.nativescript.modalnavigation",
"tns-ios": {
"version": "next"
},
"tns-android": {
"version": "next"
}
},
"dependencies": {
"nativescript-theme-core": "~1.0.4",
"tns-core-modules": "next"
},
"devDependencies": {
"awesome-typescript-loader": "~3.1.3",
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"babylon": "6.18.0",
"copy-webpack-plugin": "~4.3.0",
"css-loader": "~0.28.7",
"extract-text-webpack-plugin": "~3.0.2",
"lazy": "1.0.11",
"nativescript-dev-appium": "next",
"nativescript-dev-typescript": "next",
"nativescript-dev-webpack": "next",
"nativescript-worker-loader": "~0.8.1",
"raw-loader": "~0.5.1",
"resolve-url-loader": "~2.2.1",
"typescript": "~2.4.2",
"uglifyjs-webpack-plugin": "~1.1.6",
"webpack": "~3.10.0",
"webpack-bundle-analyzer": "^2.9.1",
"webpack-sources": "~1.1.0"
},
"scripts": {
"e2e": "tsc -p e2e && mocha --opts ./e2e/config/mocha.opts",
"e2e-watch": "tsc -p e2e --watch"
}
}

View File

@@ -15,11 +15,15 @@
"*": [
"./node_modules/tns-core-modules/*",
"./node_modules/*"
],
"~/*": [
"app/*"
]
}
},
"exclude": [
"node_modules",
"platforms"
"platforms",
"e2e"
]
}
}

View File

@@ -0,0 +1,143 @@
const { resolve, join } = require("path");
const webpack = require("webpack");
const nsWebpack = require("nativescript-dev-webpack");
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = env => {
const platform = env && (env.android && "android" || env.ios && "ios");
if (!platform) {
throw new Error("You need to provide a target platform!");
}
const platforms = ["ios", "android"];
const { snapshot, uglify, report } = env;
const config = {
context: resolve("./app"),
target: nativescriptTarget,
entry: {
bundle: `./${nsWebpack.getEntryModule()}`,
vendor: "./vendor"
},
output: {
pathinfo: true,
// Default destination inside platforms/<platform>/...
path: resolve(nsWebpack.getAppPath(platform)),
libraryTarget: "commonjs2",
filename: "[name].js",
},
resolve: {
extensions: [".ts", ".js", ".scss", ".css"],
// Resolve {N} system modules from tns-core-modules
modules: [
"node_modules/tns-core-modules",
"node_modules",
],
alias: {
'~': resolve("./app")
},
// don't resolve symlinks to symlinked modules
symlinks: false
},
resolveLoader: {
// don't resolve symlinks to symlinked loaders
symlinks: false
},
node: {
// Disable node shims that conflict with NativeScript
"http": false,
"timers": false,
"setImmediate": false,
"fs": "empty",
},
module: {
rules: [
{ test: /\.(html|xml)$/, use: "raw-loader" },
{
test: /\.css$/,
use: { loader: "css-loader", options: { minimize: false, url: false } }
},
{
test: /\.scss$/,
use: [
{ loader: "css-loader", options: { minimize: false, url: false } },
"sass-loader"
]
},
{ test: /\.ts$/, use: "awesome-typescript-loader" }
]
},
plugins: [
// Vendor libs go to the vendor.js chunk
new webpack.optimize.CommonsChunkPlugin({
name: ["vendor"],
}),
// Define useful constants like TNS_WEBPACK
new webpack.DefinePlugin({
"global.TNS_WEBPACK": "true",
}),
// Copy assets to out dir. Add your own globs as needed.
new CopyWebpackPlugin([
{ from: "App_Resources/**" },
{ from: "fonts/**" },
{ from: "**/*.jpg" },
{ from: "**/*.png" },
{ from: "**/*.xml" },
]),
// Generate a bundle starter script and activate it in package.json
new nsWebpack.GenerateBundleStarterPlugin([
"./vendor",
"./bundle",
]),
// Support for web workers since v3.2
new NativeScriptWorkerPlugin(),
new nsWebpack.PlatformFSPlugin({
platform,
platforms,
// ignore: ["App_Resources"]
}),
// Does IPC communication with the {N} CLI to notify events when running in watch mode.
new nsWebpack.WatchStateLoggerPlugin(),
],
};
if (report) {
// Generate report files for bundles content
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: "static",
openAnalyzer: false,
generateStatsFile: true,
reportFilename: join(__dirname, "report", `report.html`),
statsFilename: join(__dirname, "report", `stats.json`),
}));
}
if (snapshot) {
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
chunk: "vendor",
projectRoot: __dirname,
webpackConfig: config,
targetArchs: ["arm", "arm64", "ia32"],
tnsJavaClassesOptions: { packages: ["tns-core-modules" ] },
useLibs: false
}));
}
if (uglify) {
config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));
// Work around an Android issue by setting compress = false
const compress = platform !== "android";
config.plugins.push(new UglifyJsPlugin({
uglifyOptions: {
mangle: { reserved: nsWebpack.uglifyMangleExcludes },
compress,
}
}));
}
return config;
};

View File

@@ -46,10 +46,11 @@
"typescript": "^2.6.1"
},
"scripts": {
"setup": "npm run dev-link-tns-platform-declarations && npm run dev-link-tns-core-modules && npm run dev-link-tests && npm run dev-link-apps && npm run dev-link-e2e-modal",
"setup": "npm run dev-link-tns-platform-declarations && npm run dev-link-tns-core-modules && npm run dev-link-tests && npm run dev-link-apps",
"tsc": "node --max_old_space_size=4096 ./node_modules/typescript/bin/tsc",
"ci": "tsc && npm run tslint && npm run ci-apps && npm run ci-tests",
"ci": "tsc && npm run tslint && npm run ci-apps && npm run ci-e2e && npm run ci-tests",
"ci-apps": "cd apps && npm i ../tns-core-modules ../tns-platform-declarations --save",
"ci-e2e": "cd e2e && cd modal-navigation && npm i ../../tns-core-modules ../../tns-platform-declarations --save",
"ci-tests": "cd tests && npm i ../tns-core-modules ../tns-platform-declarations --save",
"unit-test": "tsc -p tsconfig.unit-tests.json && mocha --opts unit-tests/mocha.opts",
"unit-test-watch": "mocha-typescript-watch -p tsconfig.unit-tests.json --opts unit-tests/mocha.opts",

View File

@@ -12,8 +12,7 @@
"apps/node_modules",
"apps/package/",
"apps/platforms",
"e2e/node_modules",
"e2e/platforms",
"e2e/",
"node_modules/",
"package/",
"bin",