From b8011d20d73320b588c041a56e62829925a6d28f Mon Sep 17 00:00:00 2001 From: an-lee Date: Mon, 12 Feb 2024 10:42:25 +0800 Subject: [PATCH] Test: add e2e tests (#297) * add e2e test * add whisper & ffmpeg command validate test * remove tests-examples --- .github/workflows/playwright.yml | 28 ++++++++++++ .gitignore | 7 ++- enjoy/e2e/main.spec.ts | 73 ++++++++++++++++++++++++++++++++ enjoy/package.json | 3 ++ enjoy/playwright.config.ts | 47 ++++++++++++++++++++ package.json | 1 + yarn.lock | 67 ++++++++++++++++++++++++++++- 7 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 enjoy/e2e/main.spec.ts create mode 100644 enjoy/playwright.config.ts diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 000000000..c6790e036 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,28 @@ +name: Playwright Tests +on: workflow_dispatch +jobs: + test: + timeout-minutes: 60 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-11, macos-12, macos-13, macos-latest, windows-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + - name: Install dependencies + run: npm install -g yarn && yarn + # - name: Install Playwright Browsers + # run: yarn playwright install --with-deps + - name: Package + run: yarn package:enjoy + - name: Run Playwright tests + run: yarn test:enjoy + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 284c3c053..2b47a8b0e 100644 --- a/.gitignore +++ b/.gitignore @@ -109,4 +109,9 @@ package-lock.json !.yarn/versions # sketch file excluded. -*.sketch* \ No newline at end of file +*.sketch* + +*/test-results/ +*/playwright-report/ +*/blob-report/ +*/playwright/.cache/ diff --git a/enjoy/e2e/main.spec.ts b/enjoy/e2e/main.spec.ts new file mode 100644 index 000000000..a74fc266e --- /dev/null +++ b/enjoy/e2e/main.spec.ts @@ -0,0 +1,73 @@ +import { expect, test } from "@playwright/test"; +import { + clickMenuItemById, + findLatestBuild, + ipcMainCallFirstListener, + ipcRendererCallFirstListener, + parseElectronApp, + ipcMainInvokeHandler, + ipcRendererInvoke, +} from "electron-playwright-helpers"; +import { ElectronApplication, Page, _electron as electron } from "playwright"; + +declare global { + interface Window { + __ENJOY_APP__: any; + } +} + +let electronApp: ElectronApplication; + +test.beforeAll(async () => { + // find the latest build in the out directory + const latestBuild = findLatestBuild(); + // parse the directory and find paths and other info + const appInfo = parseElectronApp(latestBuild); + // set the CI environment variable to true + process.env.CI = "e2e"; + electronApp = await electron.launch({ + args: [appInfo.main], + executablePath: appInfo.executable, + }); + electronApp.on("window", async (page) => { + const filename = page.url()?.split("/").pop(); + console.log(`Window opened: ${filename}`); + + // capture errors + page.on("pageerror", (error) => { + console.error(error); + }); + // capture console messages + page.on("console", (msg) => { + console.log(msg.text()); + }); + }); +}); + +test.afterAll(async () => { + await electronApp.close(); +}); + +let page: Page; + +test("renders the first page", async () => { + page = await electronApp.firstWindow(); + const title = await page.title(); + expect(title).toBe("Enjoy"); +}); + +test("validate whisper command", async () => { + page = await electronApp.firstWindow(); + const res = await page.evaluate(() => { + return window.__ENJOY_APP__.whisper.check(); + }); + expect(res.success).toBeTruthy(); +}); + +test("valid ffmpeg command", async () => { + page = await electronApp.firstWindow(); + const res = await page.evaluate(() => { + return window.__ENJOY_APP__.ffmpeg.check(); + }); + expect(res).toBeTruthy(); +}); diff --git a/enjoy/package.json b/enjoy/package.json index 0dc95d65b..f3473c54d 100644 --- a/enjoy/package.json +++ b/enjoy/package.json @@ -13,6 +13,7 @@ "make": "rimraf .vite && electron-forge make", "publish": "rimraf .vite && electron-forge publish", "lint": "eslint --ext .ts,.tsx .", + "test": "playwright test", "create-migration": "zx ./src/main/db/create-migration.mjs" }, "keywords": [], @@ -30,6 +31,7 @@ "@electron-forge/plugin-auto-unpack-natives": "^7.2.0", "@electron-forge/plugin-vite": "^7.2.0", "@electron-forge/publisher-github": "^7.2.0", + "@playwright/test": "^1.41.2", "@tailwindcss/typography": "^0.5.10", "@types/autosize": "^4.0.3", "@types/command-exists": "^1.2.3", @@ -48,6 +50,7 @@ "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.17", "electron": "^28.2.0", + "electron-playwright-helpers": "^1.7.0", "eslint": "^8.56.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", diff --git a/enjoy/playwright.config.ts b/enjoy/playwright.config.ts new file mode 100644 index 000000000..765b7864c --- /dev/null +++ b/enjoy/playwright.config.ts @@ -0,0 +1,47 @@ +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./e2e", + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: "html", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + // projects: [ + // { + // name: "chromium", + // use: { ...devices["Desktop Chrome"] }, + // }, + // ], + + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'npm run start', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); diff --git a/package.json b/package.json index d48dbcc7d..17681a4e8 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "dev:enjoy": "yarn workspace enjoy dev", "start:enjoy": "yarn workspace enjoy start", + "test:enjoy": "yarn workspace enjoy test", "package:enjoy": "yarn workspace enjoy package", "make:enjoy": "yarn workspace enjoy make", "publish:enjoy": "yarn workspace enjoy publish", diff --git a/yarn.lock b/yarn.lock index 4af9e846a..3e1b16bad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -651,7 +651,7 @@ __metadata: languageName: node linkType: hard -"@electron/asar@npm:^3.2.1, @electron/asar@npm:^3.2.7": +"@electron/asar@npm:^3.2.1, @electron/asar@npm:^3.2.4, @electron/asar@npm:^3.2.7": version: 3.2.8 resolution: "@electron/asar@npm:3.2.8" dependencies: @@ -2227,6 +2227,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.41.2": + version: 1.41.2 + resolution: "@playwright/test@npm:1.41.2" + dependencies: + playwright: "npm:1.41.2" + bin: + playwright: cli.js + checksum: 10c0/071fe307e7e46f550e8608ce3c2c207b7cfbda37b39f3dcbe3875eaa18e79f2a768a5795a8cfe21df9361ec63594de0359f5542dd3a3a7f6625300a98452a344 + languageName: node + linkType: hard + "@radix-ui/number@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/number@npm:1.0.1" @@ -5921,6 +5932,15 @@ __metadata: languageName: node linkType: hard +"electron-playwright-helpers@npm:^1.7.0": + version: 1.7.0 + resolution: "electron-playwright-helpers@npm:1.7.0" + dependencies: + "@electron/asar": "npm:^3.2.4" + checksum: 10c0/5f2de8f29675b1af9da0396f9f2728830974d5189a53ef83fbbb483e9e6cbbc3fa66f669ee51b3480a34e25452c1b93f7d16139ebde4d1f56507e58ebb57862d + languageName: node + linkType: hard + "electron-settings@npm:^4.0.2": version: 4.0.2 resolution: "electron-settings@npm:4.0.2" @@ -6053,6 +6073,7 @@ __metadata: "@hookform/resolvers": "npm:^3.3.4" "@langchain/google-genai": "npm:^0.0.8" "@mozilla/readability": "npm:^0.5.0" + "@playwright/test": "npm:^1.41.2" "@radix-ui/react-accordion": "npm:^1.1.2" "@radix-ui/react-alert-dialog": "npm:^1.0.5" "@radix-ui/react-aspect-ratio": "npm:^1.0.3" @@ -6110,6 +6131,7 @@ __metadata: decamelize-keys: "npm:^2.0.1" electron: "npm:^28.2.0" electron-log: "npm:^5.1.1" + electron-playwright-helpers: "npm:^1.7.0" electron-settings: "npm:^4.0.2" electron-squirrel-startup: "npm:^1.0.0" eslint: "npm:^8.56.0" @@ -7221,6 +7243,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -7231,6 +7263,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -10908,6 +10949,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.41.2": + version: 1.41.2 + resolution: "playwright-core@npm:1.41.2" + bin: + playwright-core: cli.js + checksum: 10c0/1e80a24b0e93dd5aa643fb926d23c055f2c1a0a1e711c0d798edcfd8c3e46a6716d4ca59d72ed076191e6c713d09a0f14387d96e60f5221abd4ff65aef1ac3b3 + languageName: node + linkType: hard + +"playwright@npm:1.41.2": + version: 1.41.2 + resolution: "playwright@npm:1.41.2" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.41.2" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/1b487387c1bc003291a9dbd098e8e3c6a31efbb4d7a2ce4f2bf9d5e7f9fbf4a406352ab70e5266eab9a2a858bd42d8955343ea30c0286c3912e81984aa0220a3 + languageName: node + linkType: hard + "plist@npm:^3.0.0, plist@npm:^3.0.5, plist@npm:^3.1.0": version: 3.1.0 resolution: "plist@npm:3.1.0"