Merge changes I5b9c227e,Iadfe6f81

* changes:
  add e2e test infrastracture (protractor-based)
  enable Angular production mode
This commit is contained in:
Kean Mariotti
2022-07-06 20:06:13 +00:00
committed by Android (Google) Code Review
14 changed files with 2818 additions and 113 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,16 @@
"name": "winscope-ng",
"version": "0.0.0",
"scripts": {
"start": "webpack serve --config webpack.config.dev.js --open --hot",
"build:kotlin": "npx kotlinc-js -source-map -source-map-embed-sources always -module-kind commonjs -output kotlin_build/flicker.js ../../../platform_testing/libraries/flicker/src/com/android/server/wm/traces/common",
"build:prod": "npm run build:kotlin && cross-env NODE_ENV=production webpack --progress",
"start": "cross-env NODE_ENV=development webpack serve --open --hot",
"test:unit": "cross-env NODE_ENV=development webpack --config webpack.config.spec.js && jasmine dist/bundle.spec.js",
"build:prod": "webpack --config webpack.config.prod.js --progress",
"build:unit": "webpack --config webpack.config.unit.spec.js",
"build:e2e": "npx tsc -p ./src/test/e2e",
"build:all": "npm run build:kotlin && npm run build:prod && npm run build:unit && npm run build:e2e",
"test:unit": "jasmine dist/unit.spec/bundle.js",
"test:component": "npx karma start",
"test:all": "npm run test:unit && npm run test:component"
"test:e2e": "npx protractor protractor.config.js",
"test:all": "npm run test:unit && npm run test:component && npm run test:e2e"
},
"private": true,
"dependencies": {
@@ -21,7 +25,6 @@
"@angular/platform-browser-dynamic": "^14.0.0",
"@angular/router": "^14.0.0",
"angular2-template-loader": "^0.6.2",
"cross-env": "^7.0.3",
"html-loader": "^3.1.0",
"html-webpack-inline-source-plugin": "^1.0.0-beta.2",
"html-webpack-plugin": "^5.5.0",
@@ -48,6 +51,7 @@
"karma-chrome-launcher": "~3.1.0",
"karma-jasmine": "~5.0.0",
"karma-sourcemap-loader": "^0.3.8",
"karma-webpack": "^5.0.0"
"karma-webpack": "^5.0.0",
"protractor": "^7.0.0"
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Note:
// Chrome driver must match the system's Chrome browser version.
// Use this command to update to the specified Chrome driver version:
// node node_modules/.bin/webdriver-manager update -- versions.chrome=103.0.5060.53
exports.config = {
specs: ["dist/e2e.spec/e2e/*.spec.js"],
directConnect: true,
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ["--headless", "--disable-gpu", "--window-size=1280x1024"]
}
},
chromeDriver: "./node_modules/webdriver-manager/selenium/chromedriver_103.0.5060.53",
// allow specifying the file protocol within browser.get(...)
onPrepare: function() {
browser.ignoreSynchronization = true;
browser.waitForAngular();
browser.sleep(500);
browser.resetUrl = "file:///";
}
};

View File

@@ -13,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const environment = (process.env.NODE_ENV || 'development').trim();
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {AppModule} from "./app/app.module";
if (environment === 'development') {
module.exports = require('./webpack.config.dev');
} else {
module.exports = require('./webpack.config.prod');
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

View File

@@ -13,23 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {enableProdMode} from "@angular/core";
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {AppModule} from "./app/app.module";
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
//TODO: implement production mode switch
//enableProdMode();
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

View File

@@ -0,0 +1,30 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "../../../dist/e2e.spec",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es6",
"module": "commonjs",
"resolveJsonModule": true,
},
"include": ["."],
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {browser, element, by} from 'protractor';
import {TestUtils} from '../test_utils';
describe("winscope", () => {
beforeAll(() => {
browser.get("file://" + TestUtils.getProductionIndexHtmlPath());
}),
it("processes trace and renders view", () => {
const inputfile = element(by.css("input[type=\"file\"]"));
inputfile.sendKeys(TestUtils.getFixturePath("trace_WindowManager.pb"));
const windowManagerViewerTitle = element(by.css(".viewer-window-manager .title"));
expect(windowManagerViewerTitle.getText()).toContain("Window Manager");
});
});

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {browser, element, by} from 'protractor';
import {TestUtils} from "../test_utils"
describe("winscope", () => {
beforeAll(() => {
browser.get("file://" + TestUtils.getProductionIndexHtmlPath());
}),
it("has title", () => {
const title = element(by.css("#title"));
expect(title.getText()).toContain("Winscope");
})
});

View File

@@ -13,15 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs';
import path from 'path';
const fs = require("fs");
const path = require("path");
class TestUtils {
static loadFixture(filename: string): Uint8Array {
const fullPath = path.resolve(__dirname, path.join("../src/test/fixtures", filename));
const data = fs.readFileSync(fullPath);
const fullPath = path.resolve(__dirname, path.join("../../src/test/fixtures", filename));
const data = fs.readFileSync(TestUtils.getFixturePath(filename));
return new Uint8Array(data);
}
static getFixturePath(filename: string): string {
return path.join(TestUtils.getProjectRootPath(), "src/test/fixtures", filename);
}
static getProductionIndexHtmlPath(): string {
return path.join(TestUtils.getProjectRootPath(), "dist/prod/index.html");
}
static getProjectRootPath(): string {
return path.join(__dirname, "../..");
}
};
export {TestUtils};

View File

@@ -27,6 +27,7 @@
"resolveJsonModule": true,
},
"include": ["src"],
"exclude": ["src/test/e2e"],
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,

View File

@@ -17,11 +17,6 @@ const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
polyfills: "./src/polyfills.ts",
app: "./src/main.ts"
},
resolve: {
extensions: [".ts", ".js"],
modules: [

View File

@@ -18,6 +18,10 @@ const configCommon = require('./webpack.config.common');
const configDev = {
mode: 'development',
entry: {
polyfills: "./src/polyfills.ts",
app: "./src/main.dev.ts"
},
devtool: "source-map",
};

View File

@@ -21,8 +21,12 @@ const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin
const configProd = {
mode: 'production',
entry: {
polyfills: "./src/polyfills.ts",
app: "./src/main.prod.ts"
},
output: {
path: path.resolve(__dirname, 'dist'),
path: path.resolve(__dirname, 'dist/prod'),
publicPath: '/',
filename: 'js/[name].[hash].js',
chunkFilename: 'js/[name].[id].[hash].chunk.js',

View File

@@ -18,18 +18,22 @@ const glob = require('glob');
let config = require('./webpack.config.common');
config["mode"] = "development";
const allTestFiles = [
...glob.sync('./src/**/*.spec.js'),
...glob.sync('./src/**/*.spec.ts')
]
const unitTestFiles = allTestFiles.filter(file => !file.match(".*component\.spec\.(js|ts)$"))
const unitTestFiles = allTestFiles
.filter(file => !file.match(".*component\.spec\.(js|ts)$"))
.filter(file => !file.match(".*e2e.*"))
config["entry"] = {
tests: unitTestFiles,
};
config["output"] = {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.spec.js',
path: path.resolve(__dirname, 'dist/unit.spec'),
filename: 'bundle.js',
};
config["target"] = "node";