feat: angular upgrade - 13.3.2 => 14.2.3
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"es2020": true,
|
||||
"node": true
|
||||
},
|
||||
"plugins": ["@typescript-eslint", "import", "unicorn", "sonarjs"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:unicorn/recommended",
|
||||
"plugin:sonarjs/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/errors",
|
||||
@@ -15,8 +17,8 @@
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"extensions": [".js", ".jsx", ".ts", ".tsx"]
|
||||
"typescript": {
|
||||
"project": "workspaces/*/tsconfig.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -33,6 +35,7 @@
|
||||
{
|
||||
"ignoreRestArgs": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"unicorn/prefer-module": "off"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ Depending on your need, putting up [Electron](https://www.electronjs.org/) and [
|
||||
|
||||
### Main features :
|
||||
|
||||
- This project is based on last [Angular 13](https://angular.io/) version with required dependencies for [Electron 18](https://www.electronjs.org/).
|
||||
- This project is based on last [Angular 14](https://angular.io/) version with required dependencies for [Electron 18](https://www.electronjs.org/).
|
||||
- This project is also written in [Typescript 4](https://www.typescriptlang.org/) and includes test samples ([WebdriverIO](https://webdriver.io/) and [Jasmine](https://jasmine.github.io/)).
|
||||
- The app is runnable `on desktop` (with **live-reload** in `development mode`).
|
||||
- The app is also runnable `on browser` but **without Electron features**.
|
||||
@@ -83,6 +83,7 @@ npm start
|
||||
| `npm run install` | Install dependencies |
|
||||
| `npm run start` | Run the app on desktop (dev mode) |
|
||||
| `npm run start:angular-app` | Run the app on browser (dev mode) |
|
||||
| `npm run test:angular-e2e` | Run **angular** end-to-end tests |
|
||||
| `npm run test:electron-e2e` | Run **electron** end-to-end tests |
|
||||
| `npm run package` | Build and prepare application content |
|
||||
| `npm run make` | Generate platform distributables (./out) |
|
||||
|
||||
21379
package-lock.json
generated
21379
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@@ -9,7 +9,7 @@
|
||||
"main": ".webpack/main",
|
||||
"keywords": [
|
||||
"angular",
|
||||
"angular 13",
|
||||
"angular 14",
|
||||
"electron",
|
||||
"electron 18",
|
||||
"typescript",
|
||||
@@ -41,8 +41,8 @@
|
||||
"test:angular-e2e": "npm-run-all -p -r start start:angular-e2e",
|
||||
"start:angular-e2e": "wait-on http://localhost:4200 && cd workspaces/angular-app && npm run cypress:run",
|
||||
"test:electron-e2e": "npm run package && npm run test:electron-e2e:wdio-only",
|
||||
"test:electron-e2e:wdio-only": "cross-env X_NODE_ENV=e2e-test wdio run workspaces/electron-e2e/wdio.conf.ts --autoCompileOpts.tsNodeOpts.project=workspaces/electron-e2e/tsconfig.json",
|
||||
"clean": "shx rm -rf .webpack out allure-results node_modules workspaces/shared-lib/.dist workspaces/angular-app/node_modules workspaces/angular-app/.dist",
|
||||
"test:electron-e2e:wdio-only": "cross-env X_NODE_ENV=e2e-test wdio run workspaces/electron-e2e/webdriverio.config.ts --autoCompileOpts.tsNodeOpts.project=workspaces/electron-e2e/tsconfig.json",
|
||||
"clean": "shx rm -rf .webpack out allure-results package-lock.json node_modules workspaces/shared-lib/.dist workspaces/angular-app/node_modules workspaces/angular-app/.angular workspaces/angular-app/.dist",
|
||||
"prepare": "husky install",
|
||||
"postinstall": "husky install && shx rm -rf .git/hooks && shx ln -s ../.husky .git/hooks",
|
||||
"outdated-deps": "npm run outdated-deps:electron-app && npm run outdated-deps:angular-app && npm run outdated-deps:shared-lib",
|
||||
@@ -51,7 +51,7 @@
|
||||
"outdated-deps:shared-lib": "cd workspaces/shared-lib && npx ncu",
|
||||
"update-deps": "npm run update-deps:electron-app && npm run update-deps:angular-app && npm run update-deps:shared-lib",
|
||||
"update-deps:electron-app": "npx ncu -u",
|
||||
"update-deps:angular-app": "cd workspaces/angular-app && ng update @angular/cli @angular/core --force && npx ncu -u",
|
||||
"update-deps:angular-app": "cd workspaces/angular-app && ng update @angular/cli @angular/core --force && npx ncu -u && cd ../.. && npm run clean",
|
||||
"update-deps:shared-lib": "cd workspaces/shared-lib && npx ncu -u",
|
||||
"release:minor": "standard-version --release-as minor",
|
||||
"release:patch": "standard-version --release-as patch",
|
||||
@@ -128,10 +128,13 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.7.1",
|
||||
"electron": "^18.0.3",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint": "^8.23.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-sonarjs": "^0.15.0",
|
||||
"eslint-plugin-unicorn": "^43.0.2",
|
||||
"fork-ts-checker-webpack-plugin": "^7.2.3",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.3.7",
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
"with": "src/environments/environment.production.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
@@ -128,5 +128,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "angular-app"
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
18
workspaces/angular-app/cypress.config.ts
Normal file
18
workspaces/angular-app/cypress.config.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import configCypress from './cypress/plugins/index';
|
||||
|
||||
export default defineConfig({
|
||||
videosFolder: 'cypress/videos',
|
||||
screenshotsFolder: 'cypress/screenshots',
|
||||
fixturesFolder: 'cypress/fixtures',
|
||||
screenshotOnRunFailure: false,
|
||||
video: false,
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents(on, config) {
|
||||
return configCypress(on, config);
|
||||
},
|
||||
baseUrl: 'http://localhost:4200',
|
||||
},
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"integrationFolder": "cypress/integration",
|
||||
"supportFile": "cypress/support/index.ts",
|
||||
"videosFolder": "cypress/videos",
|
||||
"screenshotsFolder": "cypress/screenshots",
|
||||
"pluginsFile": "cypress/plugins/index.ts",
|
||||
"fixturesFolder": "cypress/fixtures",
|
||||
"baseUrl": "http://localhost:4200",
|
||||
"screenshotOnRunFailure": false,
|
||||
"video": false
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// Plugins enable you to tap into, modify, or extend the internal behavior of Cypress
|
||||
// For more info, visit https://on.cypress.io/plugins-api
|
||||
module.exports = (_on, _config) => {
|
||||
export default (
|
||||
_on: Cypress.PluginEvents,
|
||||
_config: Cypress.PluginConfigOptions
|
||||
): void => {
|
||||
// configure plugins here
|
||||
};
|
||||
|
||||
@@ -1,23 +1,6 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************
|
||||
// This example namespace declaration will help
|
||||
// with Intellisense and code completion in your
|
||||
// IDE or Text Editor.
|
||||
// ***********************************************
|
||||
// declare namespace Cypress {
|
||||
// interface Chainable<Subject = any> {
|
||||
// customCommand(param: any): typeof customCommand;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// function customCommand(param: any): void {
|
||||
// console.warn(param);
|
||||
// }
|
||||
//
|
||||
// NOTE: You can use it like so:
|
||||
// Cypress.Commands.add('customCommand', customCommand);
|
||||
//
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// This example commands.ts shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
@@ -28,16 +11,27 @@
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
//
|
||||
// declare global {
|
||||
// namespace Cypress {
|
||||
// interface Chainable {
|
||||
// login(email: string, password: string): Chainable<void>
|
||||
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* eslint-disable unicorn/prevent-abbreviations */
|
||||
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
@@ -13,5 +15,8 @@
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// When a command from ./commands is ready to use, import with `import './commands'` syntax
|
||||
// import './commands';
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
@@ -10,33 +10,33 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.3.2",
|
||||
"@angular/common": "~13.3.2",
|
||||
"@angular/compiler": "~13.3.2",
|
||||
"@angular/core": "~13.3.2",
|
||||
"@angular/forms": "~13.3.2",
|
||||
"@angular/platform-browser": "~13.3.2",
|
||||
"@angular/platform-browser-dynamic": "~13.3.2",
|
||||
"@angular/router": "~13.3.2",
|
||||
"@angular/animations": "^14.2.3",
|
||||
"@angular/common": "^14.2.3",
|
||||
"@angular/compiler": "^14.2.3",
|
||||
"@angular/core": "^14.2.3",
|
||||
"@angular/forms": "^14.2.3",
|
||||
"@angular/platform-browser": "^14.2.3",
|
||||
"@angular/platform-browser-dynamic": "^14.2.3",
|
||||
"@angular/router": "^14.2.3",
|
||||
"@ngx-translate/core": "^14.0.0",
|
||||
"@ngx-translate/http-loader": "^7.0.0",
|
||||
"electron": "^18.0.3",
|
||||
"rxjs": "~7.5.5",
|
||||
"tslib": "^2.3.1",
|
||||
"zone.js": "~0.11.5"
|
||||
"electron": "^20.2.0",
|
||||
"rxjs": "~7.5.6",
|
||||
"tslib": "^2.4.0",
|
||||
"zone.js": "~0.11.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~13.3.2",
|
||||
"@angular/cli": "~13.3.2",
|
||||
"@angular/compiler-cli": "~13.3.2",
|
||||
"@cypress/schematic": "^1.6.0",
|
||||
"@types/node": "^17.0.23",
|
||||
"cypress": "9.5.3",
|
||||
"karma": "~6.3.17",
|
||||
"@angular-devkit/build-angular": "^14.2.3",
|
||||
"@angular/cli": "^14.2.3",
|
||||
"@angular/compiler-cli": "^14.2.3",
|
||||
"@cypress/schematic": "^2.1.1",
|
||||
"@types/node": "^18.7.18",
|
||||
"cypress": "10.8.0",
|
||||
"karma": "~6.4.1",
|
||||
"karma-chrome-launcher": "~3.1.1",
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~4.0.2",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "^4.6.3"
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.0.0",
|
||||
"typescript": "^4.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MutiplesComponent } from './components/mutiples/mutiples.component';
|
||||
import { MultiplesComponent } from './components/multiples/multiples.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: MutiplesComponent,
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: MultiplesComponent,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule],
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { MutiplesComponent } from './components/mutiples/mutiples.component';
|
||||
import { MultiplesComponent } from './components/multiples/multiples.component';
|
||||
|
||||
// AoT requires an exported function for factories
|
||||
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||
@@ -14,7 +14,7 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent, MutiplesComponent],
|
||||
declarations: [AppComponent, MultiplesComponent],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#multiples {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 210px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-weight: 900;
|
||||
|
||||
.container {
|
||||
background-color: #d47800e0;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
> * {
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { MultiplesComponent } from './multiples.component';
|
||||
|
||||
describe('MultiplesComponent', () => {
|
||||
let component: MultiplesComponent;
|
||||
let fixture: ComponentFixture<MultiplesComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [MultiplesComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MultiplesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,17 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { FormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { WindowApiConst } from 'shared-lib';
|
||||
import { ElectronIpcService } from '../../services/electron-ipc.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mutiples',
|
||||
templateUrl: './mutiples.component.html',
|
||||
styleUrls: ['./mutiples.component.scss'],
|
||||
selector: 'app-multiples',
|
||||
templateUrl: './multiples.component.html',
|
||||
styleUrls: ['./multiples.component.scss'],
|
||||
})
|
||||
export class MutiplesComponent implements OnInit {
|
||||
timesTableForm = new FormGroup({
|
||||
input: new FormControl(Math.round(Math.random() * 100) % 10),
|
||||
export class MultiplesComponent implements OnInit {
|
||||
timesTableForm = new UntypedFormGroup({
|
||||
input: new FormControl<number>(Math.round(Math.random() * 100) % 10, {
|
||||
nonNullable: true,
|
||||
}),
|
||||
});
|
||||
|
||||
multiples: number[] = [];
|
||||
@@ -1,23 +0,0 @@
|
||||
#multiples {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 210px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-weight: 900;
|
||||
|
||||
.container {
|
||||
background-color: #d47800e0;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
> * {
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { MutiplesComponent } from './mutiples.component';
|
||||
|
||||
describe('MutiplesComponent', () => {
|
||||
let component: MutiplesComponent;
|
||||
let fixture: ComponentFixture<MutiplesComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MutiplesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MutiplesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -16,7 +16,7 @@ export class ElectronIpcService {
|
||||
}
|
||||
}
|
||||
|
||||
public receive<Out>(channel: string, func: (output: Out) => void): void {
|
||||
public receive<Out>(channel: string, callback: (output: Out) => void): void {
|
||||
if (this._api) {
|
||||
this._api.receive<Out>(channel, (output) => {
|
||||
console.log(`Received from main process channel [${channel}]`, output);
|
||||
@@ -25,7 +25,7 @@ export class ElectronIpcService {
|
||||
// doesn't recognize it needs to run change detection
|
||||
// Further details on SO : https://stackoverflow.com/a/49136353/11480016
|
||||
this.zone.run(() => {
|
||||
func(output);
|
||||
callback(output);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
production: true,
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// `ng build` replaces `environment.ts` with `environment.production.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
production: false,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,8 +5,10 @@ import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
// eslint-disable-next-line unicorn/prefer-top-level-await
|
||||
.catch((error) => console.error(error));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting,
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
import 'zone.js/testing';
|
||||
|
||||
declare const require: {
|
||||
context(
|
||||
@@ -29,4 +29,6 @@ getTestBed().initTestEnvironment(
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
for (const key of context.keys()) {
|
||||
context(key);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2017",
|
||||
"target": "es2020",
|
||||
"module": "es2020",
|
||||
"lib": ["es2018", "dom"]
|
||||
},
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as remoteMain from '@electron/remote/main';
|
||||
import { app, BrowserWindow, ipcMain, nativeImage } from 'electron';
|
||||
import * as path from 'path';
|
||||
import * as path from 'node:path';
|
||||
import { AbstractService } from '../services/abstract-service';
|
||||
import { MultiplesService } from '../services/multiples-service';
|
||||
import { Logger } from '../utils/logger';
|
||||
import * as remoteMain from '@electron/remote/main';
|
||||
|
||||
declare const global: Global;
|
||||
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string;
|
||||
@@ -44,17 +44,17 @@ export class Window {
|
||||
}
|
||||
|
||||
private loadIcon(): Electron.NativeImage | undefined {
|
||||
let iconObj = undefined;
|
||||
let iconObject;
|
||||
if (global.appConfig.isIconAvailable) {
|
||||
const iconPath = path.join(__dirname, 'icons/icon.png');
|
||||
Logger.debug('Icon Path', iconPath);
|
||||
iconObj = nativeImage.createFromPath(iconPath);
|
||||
iconObject = nativeImage.createFromPath(iconPath);
|
||||
// Change dock icon on MacOS
|
||||
if (iconObj && process.platform === 'darwin') {
|
||||
app.dock.setIcon(iconObj);
|
||||
if (iconObject && process.platform === 'darwin') {
|
||||
app.dock.setIcon(iconObject);
|
||||
}
|
||||
}
|
||||
return iconObj;
|
||||
return iconObject;
|
||||
}
|
||||
|
||||
private loadRenderer(): void {
|
||||
@@ -96,11 +96,11 @@ export class Window {
|
||||
private registerService<In, Out>(service: AbstractService<In, Out>) {
|
||||
ipcMain.on(
|
||||
service.receptionChannel(),
|
||||
async (event: Electron.IpcMainEvent, ...args: any[]) => {
|
||||
async (event: Electron.IpcMainEvent, ...parameters: any[]) => {
|
||||
// Handling input
|
||||
const input = args[0];
|
||||
const input = parameters[0];
|
||||
Logger.debug(`[${service.receptionChannel()}] =====> `, input);
|
||||
const output: Out = await service.process(input);
|
||||
const output: Out = service.process(input);
|
||||
|
||||
// Handling output
|
||||
if (service.sendingChannel()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import * as _ from 'lodash';
|
||||
import * as path from 'path';
|
||||
import _ from 'lodash';
|
||||
import * as path from 'node:path';
|
||||
import { AppConfig } from 'shared-lib';
|
||||
import { App } from './components/app';
|
||||
|
||||
@@ -14,14 +14,14 @@ declare global {
|
||||
}
|
||||
|
||||
// Load config
|
||||
const currentEnv = process.env.X_NODE_ENV || process.env.NODE_ENV;
|
||||
const currentEnvironment = process.env.X_NODE_ENV || process.env.NODE_ENV;
|
||||
const appConfigs = fs.readJsonSync(path.join(__dirname, 'config.json'));
|
||||
const defaultConf = appConfigs.development;
|
||||
const currentConf = appConfigs[currentEnv];
|
||||
const defaultConfig = appConfigs.development;
|
||||
const currentConfig = appConfigs[currentEnvironment];
|
||||
global.appConfig =
|
||||
currentEnv === 'development'
|
||||
? defaultConf
|
||||
: _.merge(defaultConf, currentConf);
|
||||
currentEnvironment === 'development'
|
||||
? defaultConfig
|
||||
: _.merge(defaultConfig, currentConfig);
|
||||
|
||||
// Launch app
|
||||
App.launch();
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
const NOT_IMPEMENTED_YET = 'Method not implemented yet.';
|
||||
export class AbstractService<In, Out> {
|
||||
receptionChannel(): string {
|
||||
throw new Error('Method not implemented yet.');
|
||||
throw new Error(NOT_IMPEMENTED_YET);
|
||||
}
|
||||
|
||||
sendingChannel(): string {
|
||||
throw new Error('Method not implemented yet.');
|
||||
throw new Error(NOT_IMPEMENTED_YET);
|
||||
}
|
||||
|
||||
process(_input: In): Out {
|
||||
throw new Error('Method not implemented yet.');
|
||||
throw new Error(NOT_IMPEMENTED_YET);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { app } from 'electron';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as os from 'node:os';
|
||||
import * as path from 'node:path';
|
||||
import * as winston from 'winston';
|
||||
|
||||
declare const global: Global;
|
||||
|
||||
@@ -11,11 +11,13 @@ const windowApi: WindowApi = {
|
||||
ipcRenderer.send(channel, input);
|
||||
}
|
||||
},
|
||||
receive: <Out>(channel: string, func: (output: Out) => void) => {
|
||||
receive: <Out>(channel: string, callback: (output: Out) => void) => {
|
||||
if (WindowApiConst.RECEIVING_SAFE_CHANNELS.includes(channel)) {
|
||||
// Deliberately strip event as it includes `sender`
|
||||
ipcRenderer.on(channel, (event: IpcRendererEvent, ...args: any[]) =>
|
||||
func(args[0])
|
||||
ipcRenderer.on(
|
||||
channel,
|
||||
(_event: IpcRendererEvent, ...parameters: any[]) =>
|
||||
callback(parameters[0])
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,7 +35,8 @@ describe('A simple test to check if app window is opened, visible and with expec
|
||||
// Checking there is one visible window
|
||||
// expect(await browser.).toEqual(true);
|
||||
// Please note that getWindowHandles() will return 2 if `dev tools` is opened.
|
||||
expect((await browser.getWindowHandles()).length).toEqual(1);
|
||||
const { length } = await browser.getWindowHandles();
|
||||
expect(length).toEqual(1);
|
||||
});
|
||||
|
||||
it('have expected title', async () => {
|
||||
@@ -10,10 +10,10 @@ describe('A simple test to check if a given input matches with computed multiple
|
||||
it(`display expected results on input (${number})`, async () => {
|
||||
await MultiplesPage.enterInput(number);
|
||||
const results = await MultiplesPage.results;
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const ntimes = 1 + i;
|
||||
for (const index of results.keys()) {
|
||||
const ntimes = 1 + index;
|
||||
const expected = `${number} * ${ntimes} = ${number * ntimes}`;
|
||||
expect(await results[i].getText()).toEqual(expected);
|
||||
expect(await results[index].getText()).toEqual(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Options } from '@wdio/types';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
// Path to local electron binary
|
||||
let electronPath = path.join(__dirname, '../../node_modules/.bin/electron');
|
||||
@@ -9,7 +9,7 @@ if (process.platform === 'win32') {
|
||||
|
||||
// Starting hook
|
||||
const waitUntilWindowLoaded = async () => {
|
||||
const timeout = 10000;
|
||||
const timeout = 10_000;
|
||||
await browser.waitUntil(async () => (await browser.isLoading()) === false, {
|
||||
timeout: timeout,
|
||||
timeoutMsg: `Expected app to be loaded in less than ${timeout}ms`,
|
||||
@@ -74,7 +74,7 @@ export const config: Options.Testrunner = {
|
||||
// then the current working directory is where your `package.json` resides, so `wdio`
|
||||
// will be called from there.
|
||||
//
|
||||
specs: ['./workspaces/electron-e2e/**/*.e2e-spec.ts'],
|
||||
specs: ['./workspaces/electron-e2e/**/*.spec.ts'],
|
||||
// Patterns to exclude.
|
||||
exclude: [
|
||||
// 'path/to/excluded/files'
|
||||
@@ -154,11 +154,11 @@ export const config: Options.Testrunner = {
|
||||
baseUrl: 'http://localhost',
|
||||
//
|
||||
// Default timeout for all waitFor* commands.
|
||||
waitforTimeout: 10000,
|
||||
waitforTimeout: 10_000,
|
||||
//
|
||||
// Default timeout in milliseconds for request
|
||||
// if browser driver or grid doesn't send response
|
||||
connectionRetryTimeout: 120000,
|
||||
connectionRetryTimeout: 120_000,
|
||||
//
|
||||
// Default request retries count
|
||||
connectionRetryCount: 3,
|
||||
@@ -195,7 +195,7 @@ export const config: Options.Testrunner = {
|
||||
// Options to be passed to Jasmine.
|
||||
jasmineOpts: {
|
||||
// Jasmine default timeout
|
||||
defaultTimeoutInterval: 60000,
|
||||
defaultTimeoutInterval: 60_000,
|
||||
//
|
||||
// The Jasmine framework allows interception of each assertion in order to log the state of the application
|
||||
// or website depending on the result. For example, it is pretty handy to take a screenshot every time
|
||||
@@ -1,17 +1,17 @@
|
||||
export class WindowApiConst {
|
||||
/** Channel used by the renderer process to send data to the main process */
|
||||
public static readonly MULTIPLES_INPUT = "getMultiplesInput";
|
||||
/** Channel used by the renderer process to send data to the main process */
|
||||
public static readonly MULTIPLES_INPUT = 'getMultiplesInput';
|
||||
|
||||
/** Channel used by the renderer process to receive data from the main process */
|
||||
public static readonly MULTIPLES_OUTPUT = "getMultiplesOutput";
|
||||
/** Channel used by the renderer process to receive data from the main process */
|
||||
public static readonly MULTIPLES_OUTPUT = 'getMultiplesOutput';
|
||||
|
||||
/** Whitelist of the safe channels to use when sending data to the main process */
|
||||
public static readonly SENDING_SAFE_CHANNELS = [
|
||||
WindowApiConst.MULTIPLES_INPUT,
|
||||
];
|
||||
/** Whitelist of the safe channels to use when sending data to the main process */
|
||||
public static readonly SENDING_SAFE_CHANNELS = [
|
||||
WindowApiConst.MULTIPLES_INPUT,
|
||||
];
|
||||
|
||||
/** Whitelist of the safe channels to use when receiving data from the main process */
|
||||
public static readonly RECEIVING_SAFE_CHANNELS = [
|
||||
WindowApiConst.MULTIPLES_OUTPUT,
|
||||
];
|
||||
/** Whitelist of the safe channels to use when receiving data from the main process */
|
||||
public static readonly RECEIVING_SAFE_CHANNELS = [
|
||||
WindowApiConst.MULTIPLES_OUTPUT,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export interface WindowApi {
|
||||
* @param channel used by the renderer to receive data and by the main to send them
|
||||
* @param func the callback function to execute when data are available
|
||||
*/
|
||||
receive<Out>(channel: string, func: (output: Out) => void): void;
|
||||
receive<Out>(channel: string, callback: (output: Out) => void): void;
|
||||
|
||||
/**
|
||||
* This method is used by the renderer process to send data to the main process
|
||||
|
||||
Reference in New Issue
Block a user