Skip to content

Commit

Permalink
Electron tests in CI (#63)
Browse files Browse the repository at this point in the history
* Fix and simplify electron test

* add electron tests

* add CI electron tests

* rollback pnpm mistake

* rollback pnpm mistake

* fix browser tests

* fix electron tests
  • Loading branch information
leordev committed Nov 7, 2023
1 parent 5638d10 commit f306fd3
Show file tree
Hide file tree
Showing 9 changed files with 889 additions and 43 deletions.
93 changes: 90 additions & 3 deletions .github/workflows/tests-runner.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Tests Runner
name: Bundling Tests

on:
push:
Expand Down Expand Up @@ -52,7 +52,6 @@ jobs:
if: ${{ github.event.inputs.web5ApiVersion }}
run: |
pnpm i -w @web5/api@${{ github.event.inputs.web5ApiVersion }}
cat package.json
- name: 🧪 Run Web5 tests
run: pnpm test:web5
Expand Down Expand Up @@ -88,7 +87,6 @@ jobs:
if: ${{ github.event.inputs.dwnVersion }}
run: |
pnpm i -w @tbd54566975/dwn-sdk-js@${{ github.event.inputs.dwnVersion }}
cat package.json
- name: 🧪 Run DWN tests
run: pnpm test:dwn
Expand All @@ -115,6 +113,18 @@ jobs:
- name: Install Yarn dependencies
run: yarn --frozen-lockfile --prefer-offline

- name: 🔃 Update Web5 Version
if: ${{ github.event.inputs.web5ApiVersion }}
run: |
yarn add @web5/api@${{ github.event.inputs.web5ApiVersion }}
cat package.json
- name: 🔃 Update dwn-sdk-js Version
if: ${{ github.event.inputs.dwnVersion }}
run: |
yarn add @tbd54566975/dwn-sdk-js@${{ github.event.inputs.dwnVersion }}
cat package.json
- name: Install macOS dependencies
run: |
brew tap wix/brew
Expand Down Expand Up @@ -187,20 +197,97 @@ jobs:

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: 20

- name: Install pnpm
run: npm install -g pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: 🔃 Update Web5 Version
if: ${{ github.event.inputs.web5ApiVersion }}
run: |
pnpm i -w @web5/api@${{ github.event.inputs.web5ApiVersion }}
cat package.json
- name: 🔃 Update dwn-sdk-js Version
if: ${{ github.event.inputs.dwnVersion }}
run: |
pnpm i -w @tbd54566975/dwn-sdk-js@${{ github.event.inputs.dwnVersion }}
cat package.json
- name: Install Playwright Browsers
run: pnpm playwright install --with-deps

- name: Run browser tests
run: TEST_PARAMS="--project=${{ matrix.browser }} --trace=on" pnpm test:browser

- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30

test-electron:
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]

runs-on: ${{ matrix.os }}

defaults:
run:
working-directory: ./tests/electron-vite

steps:
- name: Checkout repository
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

- name: Setup Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version: 18
cache-dependency-path: ./tests/electron-vite/yarn.lock

- name: Install Yarn dependencies
run: yarn --frozen-lockfile --prefer-offline
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1

- name: 🔃 Update Web5 Version
if: ${{ github.event.inputs.web5ApiVersion }}
run: |
yarn add @web5/api@${{ github.event.inputs.web5ApiVersion }}
cat package.json
- name: 🔃 Update dwn-sdk-js Version
if: ${{ github.event.inputs.dwnVersion }}
run: |
yarn add @tbd54566975/dwn-sdk-js@${{ github.event.inputs.dwnVersion }}
cat package.json
- name: Build electron app
run: yarn build

- name: Run electron tests
run: yarn test --trace=on
if: matrix.os != 'ubuntu-latest'

- name: Run electron tests (xvfb)
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test --trace=on
if: matrix.os == 'ubuntu-latest'

- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: tests/electron-vite/playwright-report/
retention-days: 30
1 change: 1 addition & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default defineConfig({
reporter: [["html"], ["list"]],
testDir: "./",
testMatch: "**/*.spec.js",
testIgnore: "tests/electron-vite/**",
projects: [
{
name: "desktop-safari",
Expand Down
42 changes: 42 additions & 0 deletions tests/electron-vite/electron-test.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { test, expect, _electron as electron } from '@playwright/test'

const SCREENSHOT_FOLDER = './playwright-report/screenshots'

test.describe('App Test Results', () => {
let app
let page

test.beforeAll(async () => {
app = await electron.launch({ args: ['.', '--no-sandbox'] })
page = await app.firstWindow()
await page.screenshot({ path: `${SCREENSHOT_FOLDER}/initial-load.png` })
})

test('main app should not present dwn error', async () => {
const dwnError = await app.evaluate(async ({ app }) => app.getDwnError())
console.error({ dwnError })
expect(dwnError).toBeUndefined()
})

test('main app should not present web5 error', async () => {
const web5Error = await app.evaluate(async ({ app }) => app.getWeb5Error())
console.error({ web5Error })
expect(web5Error).toBeUndefined()
})

test('should display Web5 results with success', async () => {
await page.waitForSelector('#web5-results')
const web5ResultsText = await page.textContent('#web5-results')
await page.screenshot({ path: `${SCREENSHOT_FOLDER}/web5-loaded.png` })
const web5Results = JSON.parse(web5ResultsText)
expect(web5Results.success).toBe(true)
})

test('should display Dwn results with success', async () => {
await page.waitForSelector('#dwn-results')
const dwnResultsText = await page.textContent('#dwn-results')
await page.screenshot({ path: `${SCREENSHOT_FOLDER}/dwn-loaded.png` })
const dwnResults = JSON.parse(dwnResultsText)
expect(dwnResults.success).toBe(true)
})
})
5 changes: 4 additions & 1 deletion tests/electron-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"postinstall": "electron-builder install-app-deps",
"build:win": "npm run build && electron-builder --win --config",
"build:mac": "npm run build && electron-builder --mac --config",
"build:linux": "npm run build && electron-builder --linux --config"
"build:linux": "npm run build && electron-builder --linux --config",
"test": "playwright test"
},
"dependencies": {
"@electron-toolkit/preload": "^2.0.0",
Expand All @@ -29,11 +30,13 @@
"@electron-toolkit/eslint-config-prettier": "^1.0.1",
"@electron-toolkit/eslint-config-ts": "^1.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@playwright/test": "^1.39.0",
"@types/node": "^18.17.5",
"electron": "^25.6.0",
"electron-builder": "^24.6.3",
"electron-vite": "^1.0.27",
"eslint": "^8.47.0",
"node-stdlib-browser": "^1.2.0",
"prettier": "^3.0.2",
"typescript": "^5.1.6",
"vite": "^4.4.9",
Expand Down
30 changes: 30 additions & 0 deletions tests/electron-vite/playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export default {
reporter: [['html'], ['list']],
testDir: './',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 15_000
},
/* 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,
testMatch: '**/*.spec.js',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry'
}
}
59 changes: 42 additions & 17 deletions tests/electron-vite/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ function createWindow(): void {
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
app.whenReady().then(async () => {
// Set app user model id for windows
electronApp.setAppUserModelId('com.electron')

await initDwn()
await initWeb5()

// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
Expand All @@ -56,9 +59,6 @@ app.whenReady().then(() => {
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

initDwn()
initWeb5()
})

// Quit when all windows are closed, except on macOS. There, it's common
Expand Down Expand Up @@ -90,21 +90,46 @@ import '../../../util/node-polyfill.js'
import checkWeb5 from '../../../util/web5-test.js'
import checkDwn from '../../../util/dwn-test.js'

let web5Error
let dwnError
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const customApp = app as any

async function initWeb5(): Promise<void> {
await checkWeb5(Web5)
try {
await checkWeb5(Web5)
} catch (error) {
web5Error = error
}
}

export function getWeb5Error(): Error {
return web5Error
}

customApp.getWeb5Error = getWeb5Error

async function initDwn(): Promise<void> {
await checkDwn(
Dwn,
DataStream,
DidKeyResolver,
Jws,
RecordsWrite,
RecordsRead,
RecordsDelete,
MessageStoreLevel,
DataStoreLevel,
EventLogLevel
)
try {
await checkDwn(
Dwn,
DataStream,
DidKeyResolver,
Jws,
RecordsWrite,
RecordsRead,
RecordsDelete,
MessageStoreLevel,
DataStoreLevel,
EventLogLevel
)
} catch (error) {
dwnError = error
}
}

export function getDwnError(): Error {
return dwnError
}

customApp.getDwnError = getDwnError
13 changes: 9 additions & 4 deletions tests/electron-vite/src/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<title>Electron</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta content="script-src 'self' blob:" http-equiv="Content-Security-Policy">
<meta content="script-src 'self' blob:" http-equiv="Content-Security-Policy" />

<link href="./assets/styles.css" type="text/css" rel="stylesheet" />
</head>
Expand Down Expand Up @@ -42,10 +42,15 @@ <h2 class="hero-text">You've successfully created an Electron project with TypeS
</div>

<div class="results">
<div id="web5-results"></div>
<div id="dwn-results"></div>
<div>
<h2>Web5 Results</h2>
<div id="web5-results"></div>
</div>
<div>
<h2>DWN Results</h2>
<div id="dwn-results"></div>
</div>
</div>

</div>

<script type="module" src="./src/renderer.ts"></script>
Expand Down
12 changes: 6 additions & 6 deletions tests/electron-vite/src/renderer/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
MessageStoreLevel
} from '@tbd54566975/dwn-sdk-js'

import checkWeb5 from '../../../../util/web5-test.js'
import checkDwn from '../../../../util/dwn-test.js'
import browserCheck from '../../../../util/browser-check.js'
const { checkWeb5, checkDwn } = browserCheck

if (typeof window !== 'undefined') {
window.Buffer = Buffer
Expand All @@ -30,12 +30,12 @@ export function init(): void {
}

async function initWeb5(): Promise<void> {
await checkWeb5(Web5)
replaceText('#web5-results', 'Web5 renderer is ready!')
const result = await checkWeb5(Web5)
replaceText('#web5-results', result)
}

async function initDwn(): Promise<void> {
await checkDwn(
const result = await checkDwn(
Dwn,
DataStream,
DidKeyResolver,
Expand All @@ -47,7 +47,7 @@ async function initDwn(): Promise<void> {
DataStoreLevel,
EventLogLevel
)
replaceText('#dwn-results', 'Dwn renderer is ready!')
replaceText('#dwn-results', result)
}

function loadVersionsInfo(): void {
Expand Down
Loading

0 comments on commit f306fd3

Please sign in to comment.