test(modal-navigation): add close modal, modal layout and root layout tests (#5680)

This commit is contained in:
Vasil Chimev
2018-04-20 14:29:28 +03:00
committed by GitHub
parent 4f5887b0ad
commit 0e1f19a76a
27 changed files with 453 additions and 377 deletions

1
e2e/modal-navigation/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.vscode/settings.json

View File

@@ -53,7 +53,7 @@
"platform": "ios",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"stopOnEntry": true,
"stopOnEntry": false,
"tnsArgs": [
"--syncAllFiles"
],
@@ -78,7 +78,7 @@
"platform": "android",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"stopOnEntry": true,
"stopOnEntry": false,
"tnsArgs": [
"--syncAllFiles"
],

View File

@@ -4,13 +4,13 @@ Execute Tests
Android:
```
npm run e2e -- --runType android23 --reuseDevice
npm run e2e -- --runType android23 # --devMode
```
iOS:
```
npm run e2e -- --runType sim.iPhoneX.iOS112 --reuseDevice
npm run e2e -- --runType sim.iPhoneX.iOS112 # --devMode
```
Scenarios
@@ -32,7 +32,15 @@ ROOT FRAME:
2. Show nested modal dialog with frame
2. Close nested modal dialog
3. Close modal dialog
3. [Done] Show modal tabview
3. [Done] Show modal layout
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
4. [Done] Show modal tabview
1. Navigate to second page within tab item frame
1. Go back
2. Show nested modal dialog
@@ -40,7 +48,7 @@ ROOT FRAME:
3. Show nested modal dialog with frame
3. Close nested modal dialog
4. Close modal dialog
4. Navigate to second page within root frame
5. Navigate to second page within root frame
1. Show modal dialog with frame
1. Navigate to second page within modal dialog
1. Go back
@@ -57,6 +65,10 @@ ROOT FRAME:
3. Close modal dialog
3. Go back
ROOT LAYOUT:
[Same as above]
ROOT TABVIEW:
[Same as above]

View File

@@ -5,7 +5,6 @@ import { View, EventData } from "tns-core-modules/ui/core/view";
import { Frame } from "tns-core-modules/ui/frame";
export function onNavigatingTo(args: NavigatedData) {
const page = <StackLayout>args.object;
console.log("home-page onNavigatingTo");
}
@@ -66,7 +65,10 @@ export function onModalTabView(args: EventData) {
export function onNavigate(args: EventData) {
const view = args.object as View;
const page = view.page as Page;
page.frame.navigate("second/second-page");
// In the layout root case for iOS, the page will be null
if (page) {
page.frame.navigate("second/second-page");
}
}
export function onFrameRootViewReset() {

View File

@@ -1,3 +1,3 @@
<GridLayout>
<Frame defaultPage="home/home-page" />
</GridLayout>
</GridLayout>

View File

@@ -0,0 +1,10 @@
export {
onModalFrame,
onModalPage,
onModalLayout,
onModalTabView,
onNavigate,
onFrameRootViewReset,
onTabRootViewReset,
onLayoutRootViewReset
} from "./home/home-page";

View File

@@ -0,0 +1,11 @@
<StackLayout>
<Label text="Home" horizontalAlignment="center" />
<Button text="Show Modal Page With Frame" tap="onModalFrame" />
<Button text="Show Modal Page" tap="onModalPage" />
<Button text="Show Modal Layout" tap="onModalLayout" />
<Button text="Show Modal TabView" tap="onModalTabView" />
<Button text="Navigate To Second Page" tap="onNavigate" />
<Button text="Reset Frame Root View" tap="onFrameRootViewReset" />
<Button text="Reset Tab Root View" tap="onTabRootViewReset" />
<Button text="Reset Layout Root View" tap="onLayoutRootViewReset" />
</StackLayout>

View File

@@ -1,4 +1,4 @@
<GridLayout backgroundColor="green" showingModally="onShowingModally" loaded="onLoaded"
<GridLayout showingModally="onShowingModally" loaded="onLoaded"
navigatingTo="onNavigatingTo"
navigatingFrom="onNavigatingFrom"
navigatedTo="onNavigatedTo"

View File

@@ -1,4 +1,4 @@
<Page backgroundColor="yellow"
<Page backgroundColor="blue"
navigatingTo="onNavigatingTo"
navigatingFrom="onNavigatingFrom"
navigatedTo="onNavigatedTo"
@@ -8,7 +8,7 @@
<Label class="action-bar-title" text="Modal Nested"></Label>
</ActionBar>
<StackLayout backgroundColor="darkBlue">
<StackLayout backgroundColor="lightBlue">
<Button text="Close Modal Nested" tap="closeModal" />
</StackLayout>
</Page>

View File

@@ -24,3 +24,7 @@ export function onGoBack(args: EventData) {
const page = view.page as Page;
page.frame.goBack();
}
export function onCloseModal(args: EventData) {
(args.object as View).closeModal();
}

View File

@@ -11,5 +11,6 @@
<StackLayout>
<Button text="Go Back" tap="onGoBack" />
<Button text="Close Modal" tap="onCloseModal" />
</StackLayout>
</Page>

View File

@@ -8,7 +8,7 @@
<Label class="action-bar-title" text="Modal"></Label>
</ActionBar>
<StackLayout backgroundColor="maroon">
<StackLayout backgroundColor="lightGreen">
<Button text="Navigate To Second Page" tap="onNavigate" visibility="{{ navigationVisibility }}" />
<Button text="Show Nested Modal Page With Frame" tap="showNestedModalFrame" />
<Button text="Show Nested Modal Page" tap="showNestedModalPage" />

View File

@@ -114,5 +114,13 @@
"noReset": true,
"fullReset": false,
"app": ""
},
"sim.iPhoneX.iOS113": {
"platformName": "iOS",
"platformVersion": "11.3",
"deviceName": "iPhone X",
"noReset": true,
"fullReset": false,
"app": ""
}
}
}

View File

@@ -1,58 +0,0 @@
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

@@ -1,50 +0,0 @@
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

@@ -1,64 +0,0 @@
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

@@ -1,58 +0,0 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe("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

@@ -1,50 +0,0 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalPageBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "../shared.e2e-spec"
describe("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

@@ -1,64 +0,0 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "../screen"
import { modalFrameBackground,
modalTabViewBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground,
testSecondItemBackground
} from "../shared.e2e-spec"
describe("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,72 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "./screen"
import {
roots,
modalFrameBackground,
testSecondPageBackground,
testSecondPageClose,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "./shared.e2e-spec"
describe("modal frame:", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
});
roots.forEach(root => {
describe(`${root} modal frame background scenarios:`, () => {
before(async () => {
await screen[root]();
});
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[root]();
}
});
after(async () => {
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, close", async () => {
await testSecondPageClose(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});
});
});

View File

@@ -0,0 +1,75 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "./screen"
import {
roots,
modalFrameBackground,
testSecondPageBackground,
testSecondPageClose,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "./shared.e2e-spec"
describe("modal layout:", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
});
roots.forEach(root => {
describe(`${root} modal layout background scenarios:`, () => {
before(async () => {
if (driver.isAndroid) {
await driver.resetApp();
}
await screen[root]();
});
beforeEach(async function () {
await screen.loadModalLayout();
});
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[root]();
}
});
after(async () => {
await screen.closeModal();
await screen.loadedHome();
});
it("should run modal layout 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, close", async () => {
await testSecondPageClose(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});
});
});

View File

@@ -0,0 +1,62 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "./screen"
import {
roots,
modalPageBackground,
testSecondPageBackground,
testNestedModalFrameBackground,
testNestedModalPageBackground
} from "./shared.e2e-spec"
describe("modal page:", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
});
roots.forEach(root => {
describe(`${root} modal page background scenarios:`, () => {
before(async () => {
if (driver.isAndroid) {
await driver.resetApp();
}
await screen[root]();
});
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[root]();
}
});
after(async () => {
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,81 @@
import { AppiumDriver, createDriver } from "nativescript-dev-appium";
import { Screen } from "./screen"
import {
roots,
modalFrameBackground,
modalTabViewBackground,
testSecondPageBackground,
testSecondPageClose,
testNestedModalFrameBackground,
testNestedModalPageBackground,
testSecondItemBackground
} from "./shared.e2e-spec"
describe("modal tab:", () => {
let driver: AppiumDriver;
let screen: Screen;
before(async () => {
driver = await createDriver();
screen = new Screen(driver);
});
roots.forEach(root => {
describe(`${root} modal tab view background scenarios:`, () => {
before(async () => {
if (driver.isAndroid) {
await driver.resetApp();
}
await screen[root]();
});
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[root]();
}
});
after(async () => {
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, close", async () => {
await testSecondPageClose(driver, screen);
});
it("should navigate to second page, run in background, go back", async () => {
await testSecondPageBackground(driver, screen);
});
});
});
});

View File

@@ -10,6 +10,7 @@ const modalNested = "Modal Nested";
const modalFrame = "Show Modal Page With Frame";
const modalPage = "Show Modal Page";
const modalLayout = "Show Modal Layout";
const modalTabView = "Show Modal TabView";
const navToSecondPage = "Navigate To Second Page";
const resetFrameRootView = "Reset Frame Root View";
@@ -38,26 +39,34 @@ export class Screen {
}
resetFrameRootView = async () => {
console.log("Setting frame root ...");
const btnResetFrameRootView = await this._driver.findElementByText(resetFrameRootView);
await btnResetFrameRootView.tap();
}
resetLayoutRootView = async () => {
console.log("Setting layout root ...");
const btnResetLayoutRootView = await this._driver.findElementByText(resetLayoutRootView);
await btnResetLayoutRootView.tap();
}
resetTabRootView = async () => {
const btnResetTabRootView = await this._driver.findElementByText(resetTabRootView);
await btnResetTabRootView.tap();
}
resetLayoutRootView = async () => {
const btnResetLayoutRootView = await this._driver.findElementByText(resetLayoutRootView);
await btnResetLayoutRootView.tap();
}
loadedTabRootView = async () => {
const tabFirst = await this._driver.findElementByText(first);
assert.isTrue(await tabFirst.isDisplayed());
console.log("Tab root view loaded!");
}
setFrameRootView = async () => {
// should load frame root, no need to verify it is loaded
await this.loadedHome();
await this.resetFrameRootView();
}
setTabRootView = async () => {
// should load tab root
await this.loadedHome();
@@ -69,6 +78,12 @@ export class Screen {
}
}
setLayoutRootView = async () => {
// should load layout root, no need to verify it is loaded
await this.loadedHome();
await this.resetLayoutRootView();
}
showModalFrame = async () => {
const btnModalFrame = await this._driver.findElementByText(modalFrame);
await btnModalFrame.tap();
@@ -91,6 +106,15 @@ export class Screen {
console.log("Modal Page loaded!");
}
showModalLayout = async () => {
const btnModalLayout = await this._driver.findElementByText(modalLayout);
await btnModalLayout.tap();
}
loadedModalLayout = async () => {
await this.loadedModalFrame();
}
showModalTabView = async () => {
const btnModalTabView = await this._driver.findElementByText(modalTabView);
await btnModalTabView.tap();
@@ -192,6 +216,16 @@ export class Screen {
}
}
loadModalLayout = async () => {
try {
await this.loadedModalLayout();
} catch (err) {
// should show modal layout
await this.showModalLayout();
await this.loadedModalLayout();
}
}
loadModalTabView = async () => {
try {
await this.loadedModalTabView();

View File

@@ -3,6 +3,8 @@ import { Screen } from "./screen"
const time = 1;
export const roots = ["setFrameRootView", "setLayoutRootView", "setTabRootView"];
export async function modalFrameBackground(driver: AppiumDriver, screen: Screen) {
await driver.backgroundApp(time);
await screen.loadedModalFrame();
@@ -19,6 +21,14 @@ export async function testSecondPageBackground(driver: AppiumDriver, screen: Scr
await screen.loadedModalFrame();
}
export async function testSecondPageClose(driver: AppiumDriver, screen: Screen) {
await screen.navigateToSecondPage();
await screen.loadedSecondPage();
await screen.closeModal();
await screen.loadedHome();
}
export async function testNestedModalFrameBackground(driver: AppiumDriver, screen: Screen, isInFrame: boolean = true) {
await screen.showNestedModalFrame();
await screen.loadedNestedModalFrame();

View File

@@ -38,7 +38,8 @@
"webpack-sources": "~1.1.0",
"@types/chai": "^4.0.2",
"@types/mocha": "^2.2.41",
"@types/node": "^7.0.5"
"@types/node": "^7.0.5",
"clean-webpack-plugin": "~0.1.19"
},
"scripts": {
"e2e": "tsc -p e2e && mocha --opts ./e2e/config/mocha.opts",

View File

@@ -1,8 +1,9 @@
const { resolve, join } = require("path");
const { relative, resolve, join } = require("path");
const webpack = require("webpack");
const nsWebpack = require("nativescript-dev-webpack");
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
@@ -13,20 +14,48 @@ module.exports = env => {
if (!platform) {
throw new Error("You need to provide a target platform!");
}
const platforms = ["ios", "android"];
const { snapshot, uglify, report } = env;
const projectRoot = __dirname;
// Default destination inside platforms/<platform>/...
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform));
const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS";
const {
// The 'appPath' and 'appResourcesPath' values are fetched from
// the nsconfig.json configuration file
// when bundling with `tns run android|ios --bundle`.
appPath = "app",
appResourcesPath = "app/App_Resources",
// Snapshot, uglify and report can be enabled by providing
// the `--env.snapshot`, `--env.uglify` or `--env.report` flags
// when running 'tns run android|ios'
snapshot,
uglify,
report,
} = env;
const appFullPath = resolve(projectRoot, appPath);
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
const config = {
context: resolve("./app"),
context: appFullPath,
watchOptions: {
ignored: [
appResourcesFullPath,
// Don't watch hidden files
"**/.*",
]
},
target: nativescriptTarget,
entry: {
bundle: `./${nsWebpack.getEntryModule()}`,
bundle: `./${nsWebpack.getEntryModule(appFullPath)}`,
vendor: "./vendor"
},
output: {
pathinfo: true,
// Default destination inside platforms/<platform>/...
path: resolve(nsWebpack.getAppPath(platform)),
path: dist,
libraryTarget: "commonjs2",
filename: "[name].js",
},
@@ -83,14 +112,23 @@ module.exports = env => {
new webpack.DefinePlugin({
"global.TNS_WEBPACK": "true",
}),
// Remove all files from the out dir.
new CleanWebpackPlugin([ `${dist}/**/*` ]),
// Copy native app resources to out dir.
new CopyWebpackPlugin([
{
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
context: projectRoot
},
]),
// Copy assets to out dir. Add your own globs as needed.
new CopyWebpackPlugin([
{ from: "App_Resources/**" },
{ from: "fonts/**" },
{ from: "**/*.jpg" },
{ from: "**/*.png" },
{ from: "**/*.xml" },
]),
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
// Generate a bundle starter script and activate it in package.json
new nsWebpack.GenerateBundleStarterPlugin([
"./vendor",
@@ -101,7 +139,6 @@ module.exports = env => {
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(),
@@ -113,14 +150,14 @@ module.exports = env => {
analyzerMode: "static",
openAnalyzer: false,
generateStatsFile: true,
reportFilename: join(__dirname, "report", `report.html`),
statsFilename: join(__dirname, "report", `stats.json`),
reportFilename: resolve(projectRoot, "report", `report.html`),
statsFilename: resolve(projectRoot, "report", `stats.json`),
}));
}
if (snapshot) {
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
chunk: "vendor",
projectRoot: __dirname,
projectRoot,
webpackConfig: config,
targetArchs: ["arm", "arm64", "ia32"],
tnsJavaClassesOptions: { packages: ["tns-core-modules" ] },
@@ -134,7 +171,6 @@ module.exports = env => {
const compress = platform !== "android";
config.plugins.push(new UglifyJsPlugin({
uglifyOptions: {
mangle: { reserved: nsWebpack.uglifyMangleExcludes },
compress,
}
}));