From 7a3a6617d3a28459f1a7854ebf8445a9f7f93193 Mon Sep 17 00:00:00 2001 From: 4gray Date: Wed, 20 Nov 2024 23:58:31 +0100 Subject: [PATCH] refactor: update commands and clean up test configurations --- README.md | 2 +- e2e/basic.e2e.ts | 102 ++++---------------------------------- e2e/settings.e2e.ts | 99 +++++++++++++++--------------------- electron/api.ts | 7 ++- package.json | 16 ++---- playwright.config.ts | 39 ++++----------- src-tauri/tauri.conf.json | 4 +- tsconfig.spec.json | 2 +- 8 files changed, 71 insertions(+), 200 deletions(-) diff --git a/README.md b/README.md index a760e44c5..59afb20af 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ The Electron version of the application will open in a separate window, and the If you want to run only the angular app without electron, in this case you can use the command: ``` - $ npm run ng:serve + $ npm run serve ``` diff --git a/e2e/basic.e2e.ts b/e2e/basic.e2e.ts index 0f6c0c351..a87989c70 100644 --- a/e2e/basic.e2e.ts +++ b/e2e/basic.e2e.ts @@ -1,98 +1,14 @@ import { expect, test } from '@playwright/test'; -import { - BrowserContext, - ElectronApplication, - Page, - _electron as electron, -} from 'playwright'; -const PATH = require('path'); -const fs = require('fs'); -let app: ElectronApplication; -let page: Page; -let context: BrowserContext; +test('basic test', async ({ page }) => { + await page.goto('/'); -test.beforeAll(async () => { - app = await electron.launch({ - args: [PATH.join(__dirname, '../electron/main.js')], - env: { - e2e: 'true', - }, - }); + // Basic checks + expect(await page.title()).toBe('IPTVnator'); - context = app.context(); - await context.tracing.start({ screenshots: true, snapshots: true }); - - page = await app.firstWindow(); - const isMainWindow = (await page.title()) === 'IPTVnator'; - if (!isMainWindow) { - page = app.windows()[1]; - } - await page.waitForLoadState('domcontentloaded'); + // Upload playlist test + await page.getByTestId('add-playlist').click(); + await page.click('"Add via file upload"'); + await page.setInputFiles('input[type="file"]', './e2e/fixtures/test.m3u'); + await expect(page.getByTestId('channel-item')).toHaveCount(4); }); - -test.describe('Check Home Page', () => { - test('Launch electron app', async () => { - const windowState = await app.evaluate((electronProcess) => { - let mainWindow = electronProcess.BrowserWindow.getAllWindows()[0]; - const isMainWindow = mainWindow.title === 'IPTVnator'; - if (!isMainWindow) { - mainWindow = electronProcess.BrowserWindow.getAllWindows()[1]; - } - - return { - isVisible: mainWindow.isVisible(), - isDevToolsOpened: mainWindow.webContents.isDevToolsOpened(), - isCrashed: mainWindow.webContents.isCrashed(), - }; - }); - - expect(windowState.isVisible).toBeTruthy(); - expect(windowState.isDevToolsOpened).toBeFalsy(); - expect(windowState.isCrashed).toBeFalsy(); - expect(app.windows()).toHaveLength(2); - }); - - // eslint-disable-next-line no-empty-pattern - test('Check title of the application', async ({}, testInfo) => { - const title = await page.title(); - const screenshot = await page.screenshot({ - path: `./e2e/screenshots/home/${testInfo.title}.png`, - }); - await testInfo.attach('screenshot', { - body: screenshot, - contentType: 'image/png', - }); - expect(title).toBe('IPTVnator'); - }); -}); - -test.describe('Upload playlists', () => { - test('should upload m3u playlist via file upload', async () => { - await page.getByTestId('add-playlist').click(); - await page.click('"Add via file upload"'); - await page.setInputFiles( - 'input[type="file"]', - './e2e/fixtures/test.m3u' - ); - await expect(page.getByTestId('channel-item')).toHaveCount(4); - }); -}); - -test.afterAll(async () => { - deleteDbFile(); - await page.close(); - await app.close(); -}); - -function deleteDbFile() { - const pathToFile = './e2e/db/data.db'; - - try { - fs.unlink(pathToFile, () => { - console.log('db file was deleted'); - }); - } catch (error) { - console.log('db file not found'); - } -} diff --git a/e2e/settings.e2e.ts b/e2e/settings.e2e.ts index 7a2579901..94b976843 100644 --- a/e2e/settings.e2e.ts +++ b/e2e/settings.e2e.ts @@ -1,44 +1,31 @@ import { expect, test } from '@playwright/test'; -import { - BrowserContext, - ElectronApplication, - Page, - _electron as electron, -} from 'playwright'; -const PATH = require('path'); - -let app: ElectronApplication; -let page: Page; -let context: BrowserContext; - -test.beforeAll(async () => { - app = await electron.launch({ - args: [PATH.join(__dirname, '../electron/main.js')], - env: { - e2e: 'true', - }, - }); - - context = app.context(); - await context.tracing.start({ screenshots: true, snapshots: true }); - - page = await app.firstWindow(); - const isMainWindow = (await page.title()) === 'IPTVnator'; - if (!isMainWindow) { - page = app.windows()[1]; - } - await page.waitForLoadState('domcontentloaded'); -}); test.describe('Settings', () => { - test('Check settings page', async () => { - await page.getByTestId('open-settings').click(); + test.beforeEach(async ({ page }) => { + await page.goto('/'); + // Clear IndexedDB before each test + await page.evaluate(async () => { + const dbNames = (await window.indexedDB.databases()).map( + (db) => db.name + ); + dbNames.forEach((name) => + name !== undefined + ? window.indexedDB.deleteDatabase(name) + : null + ); + }); + }); + + test('Check settings page', async ({ page }) => { + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.getByTestId('settings-container')).toBeVisible(); await page.getByTestId('back-to-home').click(); }); - test('Change video player', async () => { - await page.getByTestId('open-settings').click(); + test('Change video player', async ({ page }) => { + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="VideoJs Player"')).toBeVisible(); await page.getByTestId('select-video-player').click(); @@ -46,55 +33,47 @@ test.describe('Settings', () => { await page.getByTestId('save-settings').click(); await page.getByTestId('back-to-home').click(); - await page.getByTestId('open-settings').click(); + + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="HTML5 Video Player"')).toBeVisible(); }); - test('Change app theme', async () => { + test('Change app theme', async ({ page }) => { + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="Light theme"')).toBeVisible(); await page.getByTestId('select-theme').click(); await page.getByTestId('DARK_THEME').click(); await page.getByTestId('save-settings').click(); await page.getByTestId('back-to-home').click(); - await page.getByTestId('open-settings').click(); + + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="Dark theme"')).toBeVisible(); }); - test('Change app language', async () => { + test('Change app language', async ({ page }) => { + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="English"')).toBeVisible(); await page.getByTestId('select-language').click(); await page.getByTestId('de').click(); await page.getByTestId('save-settings').click(); await page.getByTestId('back-to-home').click(); - await page.getByTestId('open-settings').click(); + await page.getByTestId('pwa-menu').click(); + await page.getByTestId('pwa-open-settings').click(); await expect(page.locator('text="Deutsch"')).toBeVisible(); }); -}); -test.beforeEach(async () => { - await page.evaluate(async () => { - const dbNames = (await window.indexedDB.databases()).map( - (db) => db.name - ); - dbNames.forEach((name) => - name !== undefined ? window.indexedDB.deleteDatabase(name) : null - ); + test.afterEach(async ({ page }, testInfo) => { + await page.screenshot({ + path: `./e2e/screenshots/settings/${testInfo.title}.png`, + }); }); }); - -// eslint-disable-next-line no-empty-pattern -test.afterEach(async ({}, testInfo) => { - await page.screenshot({ - path: `./e2e/screenshots/home/${testInfo.title}.png`, - }); -}); - -test.afterAll(async () => { - await page.close(); - await app.close(); -}); diff --git a/electron/api.ts b/electron/api.ts index f12b1373e..ff124e51f 100644 --- a/electron/api.ts +++ b/electron/api.ts @@ -187,7 +187,7 @@ export class Api { args.userAgent || 'localhost', args.referer || 'localhost' ); - } + } } ) .on(IS_PLAYLISTS_MIGRATION_POSSIBLE, (event) => { @@ -297,7 +297,7 @@ export class Api { .on(SETTINGS_UPDATE, (_event, arg) => { this.settings = arg; this.server.updateSettings(); - }) ; + }); // listeners for EPG events ipcMain @@ -420,7 +420,7 @@ export class Api { // Remove trailing slash from referer if it exists let originURL: string; if (referer?.endsWith('/')) { - originURL= referer.slice(0, -1); + originURL = referer.slice(0, -1); } session.defaultSession.webRequest.onBeforeSendHeaders( @@ -636,5 +636,4 @@ export class Api { } }); } - } diff --git a/package.json b/package.json index 1c6f4d400..90bc40c39 100644 --- a/package.json +++ b/package.json @@ -21,19 +21,14 @@ "main": "electron/main.js", "private": true, "scripts": { - "build:dev": "npm run build -- -c dev", - "build:prod": "npm run build -- -c production", - "build:web": "npm run build -- -c web", - "ng:build": "ng build -c production", - "ng:serve": "ng serve -c dev", - "ng:serve:web": "ng serve -c web -o", + "build:dev": "ng build -c dev", + "build:prod": "ng build -c production", + "build:web": "ng build -c web", + "serve": "ng serve -c dev", "test": "ng test", "test:watch": "ng test --watch", - "e2e": "npm run build:electron && npx playwright test --retries 3", + "e2e": "npm run build:prod && npx playwright test --ui", "e2e:ci": "npx playwright test --retries 3 --workers=1", - "e2e:debug": "npm run build:electron && PWDEBUG=1 npx playwright test -c playwright.config.ts e2e/ /", - "e2e:html-report": "npm run build:electron && npm run e2e -- --reporter=html", - "e2e:show-report": "npx playwright show-report", "version": "conventional-changelog -i CHANGELOG.md -p angular -s -r 0 && git add CHANGELOG.md", "lint": "ng lint", "build-pwa": "ng build -c production --base-href /iptvnator --deploy-url /iptvnator/", @@ -71,7 +66,6 @@ "iptv-playlist-parser": "github:4gray/iptv-playlist-parser", "lodash": "4.17.21", "moment": "2.30.1", - "nedb-promises": "6.0.3", "ngx-indexed-db": "19.0.0", "ngx-skeleton-loader": "9.0.0", "ngx-whats-new": "0.4.0", diff --git a/playwright.config.ts b/playwright.config.ts index ee835f20d..9a0c6852d 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,38 +1,21 @@ -import { devices, PlaywrightTestConfig } from '@playwright/test'; +import { defineConfig, devices } from '@playwright/test'; -const config: PlaywrightTestConfig = { +export default defineConfig({ testDir: './e2e', timeout: 45000, maxFailures: 2, testMatch: /.*\.e2e\.ts/, - projects: [ - { - name: 'chromium', - use: { - ...devices['Desktop Chrome'], - serviceWorkers: 'block', - }, - }, - /* { - name: 'firefox', - use: { - ...devices['Desktop Firefox'], - serviceWorkers: 'block', - }, - }, - { - name: 'webkit', - use: { - ...devices['Desktop Safari'], - serviceWorkers: 'block', - }, - }, */ - ], + webServer: { + command: 'npm run serve', + port: 4200, + reuseExistingServer: !process.env.CI, + timeout: 120000, + }, use: { + ...devices['Desktop Chrome'], + baseURL: 'http://localhost:4200', headless: false, screenshot: 'only-on-failure', testIdAttribute: 'data-test-id', }, -}; - -export default config; +}); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 18593098a..317df80b2 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -6,8 +6,8 @@ "build": { "frontendDist": "../dist", "devUrl": "http://localhost:4200", - "beforeDevCommand": "npm run ng:serve", - "beforeBuildCommand": "npm run ng:build" + "beforeDevCommand": "npm run serve", + "beforeBuildCommand": "npm run build:prod" }, "plugins": { "updater": { diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 411294031..363afa9a7 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "../out-tsc/spec", "baseUrl": "./", - "types": ["jest", "node", "electron"], + "types": ["jest", "node"], "experimentalDecorators": true, "emitDecoratorMetadata": true, "resolveJsonModule": true