From 20896fec0bbba096c951975d00d8dc4fbbcce851 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 12 May 2025 11:36:25 +0800 Subject: [PATCH 1/3] chore: bump version to 34 and electron@34 --- index.d.ts | 1 - package.json | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index d986466..8fe9b87 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,7 +3,6 @@ * * https://github.com/electron-modules/electron-windows */ - import type { BrowserWindow, BrowserWindowConstructorOptions } from 'electron' /** diff --git a/package.json b/package.json index 6fbc3b8..f4186fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron-windows", - "version": "18.5.0", + "version": "34.0.0", "description": "Manage multiple windows of Electron gracefully and provides powerful features.", "keywords": [ "electron", @@ -18,7 +18,7 @@ "url": "git://github.com/electron-modules/electron-windows.git" }, "dependencies": { - "electron": "18", + "electron": "34", "electron-window-state": "^5.0.3", "lodash": "4" }, From a35106fb60aee7f54457507a72407e2225a6fb9f Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 12 May 2025 11:36:51 +0800 Subject: [PATCH 2/3] fix: typo and demo app's `nodeIntegration` --- app/index.js | 3 ++- lib/electron-windows.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/index.js b/app/index.js index ede7b11..0d6af26 100644 --- a/app/index.js +++ b/app/index.js @@ -53,7 +53,8 @@ class App { browserWindow: { webPreferences: { enableRemoteModule: false, - nodeIntegration: false, + // `preload` uses Node's `fs` module, so `nodeIntegration` should be enabled. + nodeIntegration: true, webSecurity: true, webviewTag: true, preload: path.join(__dirname, 'renderer', 'preload.js'), diff --git a/lib/electron-windows.js b/lib/electron-windows.js index c185352..e6f1c43 100644 --- a/lib/electron-windows.js +++ b/lib/electron-windows.js @@ -62,7 +62,7 @@ class WindowsManager { if (storageKey) { window.stateFromStorage = stateFromStorage; window.storageKey = storageKey; - // register listner on BrowserWindow for window resize events, store state after window close + // register listener on BrowserWindow for window resize events, store state after window close stateFromStorage.manage(window); } return window; From 2a92c1cac922414206089acd7ff97c9a91f7d68e Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 12 May 2025 15:39:44 +0800 Subject: [PATCH 3/3] test: add e2e test with playwright --- .eslintrc.js | 6 ++- .github/workflows/playwright.yml | 28 ++++++++++ .gitignore | 8 ++- package.json | 8 ++- playwright.config.js | 22 ++++++++ test/e2e/electron-windows.e2e.test.js | 77 +++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 playwright.config.js create mode 100644 test/e2e/electron-windows.e2e.test.js diff --git a/.eslintrc.js b/.eslintrc.js index 8a31a55..f2b48dc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,9 +2,11 @@ module.exports = { extends: 'eslint-config-egg', - parser: 'babel-eslint', + // babel-eslint (deprecated) is now @babel/eslint-parser + parser: '@babel/eslint-parser', parserOptions: { ecmaVersion: 2018, + requireConfigFile: false, }, rules: { 'valid-jsdoc': 0, @@ -26,7 +28,7 @@ module.exports = { 'no-self-compare': 0, 'one-var': 0 }, - globals:{ + globals: { window: true, document: true, } diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 0000000..6e0bb30 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,28 @@ +name: E2E Tests +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] +jobs: + test: + timeout-minutes: 10 + strategy: + matrix: + os: [ macos-latest, windows-latest ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install dependencies + run: npm i + + - name: Install Playwright Browser + run: npx playwright install --with-deps chromium + + - name: Run Playwright tests + run: npm run test:e2e diff --git a/.gitignore b/.gitignore index 2626cff..50756c5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,10 @@ coverage file.txt *.gz *.sw* -*.un~ \ No newline at end of file +*.un~ + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/package.json b/package.json index f4186fd..8dbade8 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,13 @@ "lodash": "4" }, "devDependencies": { + "@babel/eslint-parser": "^7.27.1", + "@playwright/test": "^1.52.0", + "@types/node": "^22.15.17", "electron-json-storage-alt": "18", "eslint": "7", - "eslint-config-egg": "^5.1.1", - "eslint-plugin-mocha": "^4.11.0", + "eslint-config-egg": "12", + "eslint-plugin-mocha": "~10.0.0", "git-contributor": "*", "husky": "*", "mocha": "*", @@ -35,6 +38,7 @@ "scripts": { "dev": "electron ./start.js", "test": "nyc --reporter=lcov --reporter=text mocha", + "test:e2e": "npx playwright test", "lint": "eslint . --fix", "contributor": "git-contributor" }, diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 0000000..809f932 --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,22 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +const isCI = !!process.env.CI; + +module.exports = defineConfig({ + testDir: './test/e2e', + fullyParallel: false, + forbidOnly: isCI, + retries: 0, + workers: 1, + reporter: 'null', + use: { + trace: 'off', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], +}); diff --git a/test/e2e/electron-windows.e2e.test.js b/test/e2e/electron-windows.e2e.test.js new file mode 100644 index 0000000..b95a07b --- /dev/null +++ b/test/e2e/electron-windows.e2e.test.js @@ -0,0 +1,77 @@ +// @ts-check +import { test, expect, _electron as electron } from '@playwright/test'; +import { last as _last } from 'lodash'; +import * as path from 'path'; + +const wait = (ms = 2000) => new Promise((resolve) => setTimeout(resolve, ms)); + +/** + * Gets the last element of array. + * @template T + * @param {T[] | null | undefined} arr + * @returns {T} + */ +const last = (arr) => { + const lastElement = _last(arr); + expect(lastElement).not.toBeUndefined(); + // @ts-ignore + return lastElement; +}; + +test.describe('test/e2e/electron-windows.e2e.test.js', () => { + /** @type { import('@playwright/test').ElectronApplication } */ + let electronApp; + + test.beforeEach(async () => { + electronApp = await electron.launch({ args: ['start.js'], cwd: path.join(__dirname, '../..') }); + }); + + test('loadingView option is working', async () => { + const window = await electronApp.firstWindow(); + + expect(await window.title()).toBe('Loading'); + expect(window.url()).toMatch(/renderer\/loading\.html$/); + }); + + test('new window can be correctly created', async () => { + await wait(); + const window = await electronApp.firstWindow(); + await window.click('button#new'); + await wait(); + const windows = electronApp.windows(); + + expect(windows.length).toBeGreaterThan(1); + expect(last(windows).url()).toMatch(/renderer\/window\.html$/); + }); + + test('new online window can be correctly created', async () => { + await wait(); + const window = await electronApp.firstWindow(); + await window.click('button#new-online'); + await wait(); + const windows = electronApp.windows(); + + expect(windows.length).toBeGreaterThan(1); + expect(last(windows).url()).toMatch(/https(.+)?github\.com/); + }); + + test('window can be correctly closed', async () => { + await wait(); + const window = await electronApp.firstWindow(); + await window.click('button#new'); + await wait(); + const newWindow = last(electronApp.windows()); + await newWindow.click('button#close'); + await wait(); + const windows = electronApp.windows(); + + expect(windows).toHaveLength(1); + expect(await windows[0].title()).toBe('main'); + }); + + test.afterEach(async () => { + await electronApp?.close(); + // @ts-ignore + electronApp = null; + }); +});