From cc92febfd19bba01155f0f9884640bb7a57f18f2 Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Thu, 10 Apr 2025 17:32:18 +0200 Subject: [PATCH 1/8] add turnaround test --- .gitignore | 2 + bun.lock | 9 +++ package.json | 1 + playwright.config.ts | 61 ++++++++++++++++++ tests/menu-items-present.spec.ts | 11 ++++ tests/roundtrip-enc-dec.spec.ts | 103 +++++++++++++++++++++++++++++++ 6 files changed, 187 insertions(+) create mode 100644 playwright.config.ts create mode 100644 tests/menu-items-present.spec.ts create mode 100644 tests/roundtrip-enc-dec.spec.ts diff --git a/.gitignore b/.gitignore index b5a8dd9..327cf40 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ dist *.tgz local bundle +playwright-report +test-results # code coverage coverage diff --git a/bun.lock b/bun.lock index 525c487..fa76168 100644 --- a/bun.lock +++ b/bun.lock @@ -12,6 +12,7 @@ "@iconify/json": "^2.2.319", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.3.0", + "@playwright/test": "^1.51.1", "@types/alpinejs": "^3.13.11", "@types/bun": "latest", "typescript-eslint": "^8.28.0", @@ -79,6 +80,8 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@playwright/test": ["@playwright/test@1.51.1", "", { "dependencies": { "playwright": "1.51.1" }, "bin": { "playwright": "cli.js" } }, "sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q=="], + "@types/alpinejs": ["@types/alpinejs@3.13.11", "", {}, "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA=="], "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="], @@ -269,6 +272,8 @@ "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + "fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], @@ -389,6 +394,10 @@ "pkg-types": ["pkg-types@2.1.0", "", { "dependencies": { "confbox": "^0.2.1", "exsolve": "^1.0.1", "pathe": "^2.0.3" } }, "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A=="], + "playwright": ["playwright@1.51.1", "", { "dependencies": { "playwright-core": "1.51.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw=="], + + "playwright-core": ["playwright-core@1.51.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], diff --git a/package.json b/package.json index 85f5a04..cc3a6d6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@iconify/json": "^2.2.319", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.3.0", + "@playwright/test": "^1.51.1", "@types/alpinejs": "^3.13.11", "@types/bun": "latest", "typescript-eslint": "^8.28.0", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..fcec320 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,61 @@ +import { defineConfig, devices } from '@playwright/test'; + +const localDevUrl = 'http://localhost:8080'; +const teUrl = 'https://whisper.te.syncorix.com'; +const qaUrl = 'https://whisper.qa.syncorix.com'; +const liveUrl = 'https://whisper.syncorix.com'; + +export default defineConfig({ + testDir: './tests', + reporter: 'html', + projects: [ + { + name: 'dev - chromium', + use: { ...devices['Desktop Chrome'], channel: 'chromium', baseURL: localDevUrl }, + }, + { + name: 'dev - firefox', + use: { ...devices['Desktop Firefox'], baseURL: localDevUrl }, + }, + { + name: 'dev - webkit', + use: { ...devices['Desktop Safari'], baseURL: localDevUrl }, + }, + { + name: 'te - chromium', + use: { ...devices['Desktop Chrome'], channel: 'chromium', baseURL: teUrl }, + }, + { + name: 'te - firefox', + use: { ...devices['Desktop Firefox'], baseURL: teUrl }, + }, + { + name: 'te - webkit', + use: { ...devices['Desktop Safari'], baseURL: teUrl }, + }, + { + name: 'qa - chromium', + use: { ...devices['Desktop Chrome'], channel: 'chromium', baseURL: qaUrl }, + }, + { + name: 'qa - firefox', + use: { ...devices['Desktop Firefox'], baseURL: qaUrl }, + }, + { + name: 'qa - webkit', + use: { ...devices['Desktop Safari'], baseURL: qaUrl }, + }, + { + name: 'live - chromium', + use: { ...devices['Desktop Chrome'], channel: 'chromium', baseURL: liveUrl }, + }, + { + name: 'live - firefox', + use: { ...devices['Desktop Firefox'], baseURL: liveUrl }, + }, + { + name: 'live - webkit', + use: { ...devices['Desktop Safari'], baseURL: liveUrl }, + }, + ], +}); diff --git a/tests/menu-items-present.spec.ts b/tests/menu-items-present.spec.ts new file mode 100644 index 0000000..98b6a25 --- /dev/null +++ b/tests/menu-items-present.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +// Simple test for the expected menu items +test('test menu items are present', async ({ page }) => { + await page.goto('/'); + await expect(page.getByRole('list').getByRole('link', { name: 'Send' })).toBeVisible(); + await expect(page.getByRole('list').getByRole('link', { name: 'Receive' })).toBeVisible(); + await expect(page.getByRole('list').getByRole('link', { name: 'You' })).toBeVisible(); + await expect(page.getByRole('list').getByRole('link', { name: 'Info' })).toBeVisible(); + await expect(page.getByRole('list').getByRole('link', { name: 'to GitHub' })).toBeVisible(); +}); \ No newline at end of file diff --git a/tests/roundtrip-enc-dec.spec.ts b/tests/roundtrip-enc-dec.spec.ts new file mode 100644 index 0000000..40521c2 --- /dev/null +++ b/tests/roundtrip-enc-dec.spec.ts @@ -0,0 +1,103 @@ +import { test, expect } from '@playwright/test'; +import { Readable } from 'stream'; + +const publicKeyLabel = "__Playwright"; + +// a complete roundtrip test with encryption and decryption +test('test encrypt decrypt roundtrip', async ({ page }) => { + await page.goto('/'); + + // Fill in key label + await expect(page.getByRole('textbox', { name: 'Hint about your identity' })).toBeVisible(); + await page.getByRole('textbox', { name: 'Hint about your identity' }).click(); + await page.getByRole('textbox', { name: 'Hint about your identity' }).pressSequentially(publicKeyLabel); + + // Check and click OK button + await expect(page.getByRole('button', { name: 'Ok' })).toBeVisible(); + await page.getByRole('button', { name: 'Ok' }).click(); + + // Check and click download button + await expect(page.getByRole('link', { name: publicKeyLabel })).toBeVisible(); + const publicKeyDownloadPromise = page.waitForEvent('download'); + await page.getByRole('link', { name: publicKeyLabel }).click(); + const publicKeyDownload = await publicKeyDownloadPromise; + const publicKeyDownloadPath = await publicKeyDownload.path(); + console.log('Saved public key %s as %s.', publicKeyDownload.suggestedFilename(), publicKeyDownloadPath); + + // Goto Send page + await page.getByRole('list').getByRole('link', { name: 'Send' }).click(); + // Upload own public key as recipient + await expect(page.getByText('Drag & Drop your recipient')).toBeVisible(); + await page.locator('id=add-recipient-dropzone').locator('id=add-recipient-dropzone-input').setInputFiles(publicKeyDownloadPath); + // Check label + await expect(page.getByText(publicKeyLabel).nth(0)).toBeVisible(); + + // Upload file to be encrypted + await expect(page.locator('id=whisper-dropzone').getByText('Drag & Drop your file(s) to')).toBeVisible(); + await page.locator('id=whisper-dropzone').locator('id=whisper-dropzone-input').setInputFiles(publicKeyDownloadPath); + + // Perform encryption + await expect(page.getByText('Ready? Your data will be encrypted locally on your device and can only be')).toBeVisible(); + await expect(page.getByRole('link', { name: 'Go!' })).toBeVisible(); + await expect(page.getByRole('link', { name: 'Reset' })).toBeVisible(); + await page.getByRole('link', { name: 'Go!' }).click(); + + // Download the encrypted file + const cryptogramDownloadLinkName = toAbbreviatedFileName(publicKeyDownloadPath); + await expect(page.getByRole('heading', { name: 'Complete!' })).toBeVisible(); + await expect(page.getByRole('link', { name: cryptogramDownloadLinkName })).toBeVisible(); + await expect(page.getByRole('link', { name: 'Clear' })).toBeVisible(); + // Label from recipients should be hidden (1) but visible in dowload section (0) + await expect(page.getByRole('listitem').filter({ hasText: publicKeyLabel }).nth(0)).toBeVisible(); + await expect(page.getByRole('listitem').filter({ hasText: publicKeyLabel }).nth(1)).toBeHidden(); + + const cryptogramDownloadPromise = page.waitForEvent('download'); + await page.getByRole('link', { name: cryptogramDownloadLinkName }).click(); + const cryptogramDownload = await cryptogramDownloadPromise; + const cryptogramDownloadPath = await cryptogramDownload.path(); + console.log('Saved cryptogram %s as %s.', cryptogramDownload.suggestedFilename(), cryptogramDownloadPath); + + // Goto Receive page + await page.getByRole('list').getByRole('link', { name: 'Receive' }).click(); + await expect(page.getByRole('heading', { name: 'What have you received?' })).toBeVisible(); + + // Upload encrypted file + await expect(page.locator('id=whisper-received-dropzone').getByText('Drag & Drop your file(s) to')).toBeVisible(); + await page.locator('id=whisper-received-dropzone').locator('id=whisper-received-dropzone-input').setInputFiles(cryptogramDownloadPath); + + // Perform descryption + await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); + await expect(page.getByText('Ready? Your data will be decrypted locally on your device and is never')).toBeVisible(); + await expect(page.getByRole('link', { name: 'Go!' })).toBeVisible(); + await expect(page.getByRole('link', { name: 'Reset' })).toBeVisible(); + await page.getByRole('link', { name: 'Go!' }).click(); + await expect(page.getByRole('heading', { name: 'Complete!' })).toBeVisible(); + await expect(page.getByRole('link', { name: 'Clear' })).toBeVisible(); + + const decryptedDownloadLinkName = toAbbreviatedFileName(cryptogramDownloadPath); + const decryptedDownloadPromise = page.waitForEvent('download'); + await page.getByRole('link', { name: decryptedDownloadLinkName }).click(); + const decryptedDownload = await decryptedDownloadPromise; + const decryptedDownloadPath = await decryptedDownload.path(); + console.log('Saved decrypted file %s as %s.', decryptedDownload.suggestedFilename(), decryptedDownloadPath); + + // Since we used the keyfile as content, we can now check whether the decrypted file is the public key + const publicKeyDownloadContent = await publicKeyDownload.createReadStream().then(readFromStream); + const decryptedDownloadContent = await decryptedDownload.createReadStream().then(readFromStream); + expect(decryptedDownloadContent).toBe(publicKeyDownloadContent); +}); + +function toAbbreviatedFileName(path: string): string { + return path.split('/').findLast(() => true)?.slice(0, 8) + '...'; +} + +async function readFromStream(stream: Readable): Promise { + // Convert the stream into a string (file content) + let fileContent = ''; + stream.on('data', (chunk) => { + fileContent += chunk.toString(); // Append chunk as string + }); + + // Wait for stream to finish and return content when promise resolves + return new Promise((resolve) => stream.on('end', resolve)).then(() => fileContent); +} From 73fab143c1e2710deb5b1c1d8bfcd1b986cffeac Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:44:14 +0200 Subject: [PATCH 2/8] add doc --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 7fbb596..c3db673 100644 --- a/README.md +++ b/README.md @@ -85,3 +85,24 @@ Please note that usually bun src/index.html ``` should do the same but it compiled the jose lib without support for ```kty: 'EC``` for some reason. + +## Testing +A couple of functional UI tests across major browser engine is included in [tests/](tests/). To execute locally use one of the follwoing: +### Launch the Test UI + ```sh +bun playwright test --ui +``` +### Run tests against dev environment (localhost:8080) + ```sh +bun playwright test --project='dev*' +``` +### Run tests against hosted environments te, qa or live + ```sh +bun playwright test --project='*' +``` +### Run tests against all environments + ```sh +bun playwright test +``` + + See [test config](playwright.config.ts) for complete list of projects to execute and [Playwright](https://playwright.dev/) for doc From 463602c8e9c65b6c9f491bd83915e5b8fa9d4c93 Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:46:45 +0200 Subject: [PATCH 3/8] lint tests --- .github/workflows/build-and-deploy-workflow.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-and-deploy-workflow.yml b/.github/workflows/build-and-deploy-workflow.yml index d27f5e8..5c1d16a 100644 --- a/.github/workflows/build-and-deploy-workflow.yml +++ b/.github/workflows/build-and-deploy-workflow.yml @@ -48,6 +48,8 @@ jobs: run: bun install - name: lint sources run: bun run eslint src/ + - name: lint tests + run: bun run eslint tests/ - name: build code and icon css run: bun run build/build # https://pico.sh/pgs#-headers From 361c70e4e5f2d193a99ebd52bdec46d15d6c8d4f Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:47:50 +0200 Subject: [PATCH 4/8] lint build scripts, too --- .github/workflows/build-and-deploy-workflow.yml | 2 ++ build/build-iconify.ts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-deploy-workflow.yml b/.github/workflows/build-and-deploy-workflow.yml index 5c1d16a..ad5390f 100644 --- a/.github/workflows/build-and-deploy-workflow.yml +++ b/.github/workflows/build-and-deploy-workflow.yml @@ -50,6 +50,8 @@ jobs: run: bun run eslint src/ - name: lint tests run: bun run eslint tests/ + - name: lint build scripts + run: bun run eslint build/ - name: build code and icon css run: bun run build/build # https://pico.sh/pgs#-headers diff --git a/build/build-iconify.ts b/build/build-iconify.ts index d67f623..126466e 100644 --- a/build/build-iconify.ts +++ b/build/build-iconify.ts @@ -5,9 +5,9 @@ import { getIconsCSS } from '@iconify/utils'; import { locate } from '@iconify/json'; import { IconifyJSON } from '@iconify/types'; -const iconSetName: string = 'mdi'; +const iconSetName = 'mdi'; const targetFileName = 'src/css/' + iconSetName + '-icons.css' -const chosenIcons: Array = [ +const chosenIcons: string[] = [ 'account-circle-outline', 'call-made', 'call-received', From 06791b7a0f35c5d3f648f6520f05a42e6dd8391c Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 09:57:31 +0200 Subject: [PATCH 5/8] add e2e tests against hosted env to CI (might be too expensive) --- .github/workflows/build-and-deploy-workflow.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/build-and-deploy-workflow.yml b/.github/workflows/build-and-deploy-workflow.yml index ad5390f..9c9fdc0 100644 --- a/.github/workflows/build-and-deploy-workflow.yml +++ b/.github/workflows/build-and-deploy-workflow.yml @@ -99,6 +99,21 @@ jobs: retain: 'syncorix-whisper-build-te' # retention policy: num of recently updated projects to keep retain_num: 0 + e2e-tests-te: + runs-on: ubuntu-latest + name: Execute end to end tests (TE) + needs: deploy-to-pgs-te + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: install dependencies + run: bun install + - name: Install playwright + run: bun playwright install --with-deps + - name: Run tests + run: bun playwright test --project='te*' # Deploys the bundle build of the main branch to pgs-qa project # linked to whisper.qa.syncorix.com # See https://github.com/picosh/pgs-action From e744fb4d3a6c37adb07380b223fe8fa140015b23 Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 10:30:55 +0200 Subject: [PATCH 6/8] save test report --- .github/workflows/build-and-deploy-workflow.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-deploy-workflow.yml b/.github/workflows/build-and-deploy-workflow.yml index 9c9fdc0..4f1e04c 100644 --- a/.github/workflows/build-and-deploy-workflow.yml +++ b/.github/workflows/build-and-deploy-workflow.yml @@ -70,7 +70,7 @@ jobs: with: name: whisper-bundle path: bundle/ - # Deploys the bundle build of any non-main branch to pgs-te project + # Deploys the bundle build of any non-main branch to pgs-te project # linked to whisper.te.syncorix.com # See https://github.com/picosh/pgs-action deploy-to-pgs-te: @@ -110,10 +110,16 @@ jobs: bun-version: latest - name: install dependencies run: bun install - - name: Install playwright + - name: Install playwright (expensive :/) run: bun playwright install --with-deps - name: Run tests run: bun playwright test --project='te*' + - name: Upload test report + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ # Deploys the bundle build of the main branch to pgs-qa project # linked to whisper.qa.syncorix.com # See https://github.com/picosh/pgs-action From b094e5ee8599f4bc862cf8e2b620155a1f56b870 Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:04:34 +0200 Subject: [PATCH 7/8] add screenshots --- tests/roundtrip-enc-dec.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/roundtrip-enc-dec.spec.ts b/tests/roundtrip-enc-dec.spec.ts index 40521c2..6ae4cb2 100644 --- a/tests/roundtrip-enc-dec.spec.ts +++ b/tests/roundtrip-enc-dec.spec.ts @@ -4,7 +4,7 @@ import { Readable } from 'stream'; const publicKeyLabel = "__Playwright"; // a complete roundtrip test with encryption and decryption -test('test encrypt decrypt roundtrip', async ({ page }) => { +test('test encrypt decrypt roundtrip', async ({ page }, testInfo) => { await page.goto('/'); // Fill in key label @@ -23,6 +23,8 @@ test('test encrypt decrypt roundtrip', async ({ page }) => { const publicKeyDownload = await publicKeyDownloadPromise; const publicKeyDownloadPath = await publicKeyDownload.path(); console.log('Saved public key %s as %s.', publicKeyDownload.suggestedFilename(), publicKeyDownloadPath); + // Screenshot - looks nice in report + await page.screenshot().then(sc => testInfo.attach('Public key download', { body: sc, contentType: 'image/png' })); // Goto Send page await page.getByRole('list').getByRole('link', { name: 'Send' }).click(); @@ -56,6 +58,8 @@ test('test encrypt decrypt roundtrip', async ({ page }) => { const cryptogramDownload = await cryptogramDownloadPromise; const cryptogramDownloadPath = await cryptogramDownload.path(); console.log('Saved cryptogram %s as %s.', cryptogramDownload.suggestedFilename(), cryptogramDownloadPath); + // Screenshot - looks nice in report + await page.screenshot().then(sc => testInfo.attach('Encryption complete', { body: sc, contentType: 'image/png' })); // Goto Receive page await page.getByRole('list').getByRole('link', { name: 'Receive' }).click(); @@ -81,6 +85,9 @@ test('test encrypt decrypt roundtrip', async ({ page }) => { const decryptedDownloadPath = await decryptedDownload.path(); console.log('Saved decrypted file %s as %s.', decryptedDownload.suggestedFilename(), decryptedDownloadPath); + // Screenshot - looks nice in report + await page.screenshot().then(sc => testInfo.attach('Decryption complete', { body: sc, contentType: 'image/png' })); + // Since we used the keyfile as content, we can now check whether the decrypted file is the public key const publicKeyDownloadContent = await publicKeyDownload.createReadStream().then(readFromStream); const decryptedDownloadContent = await decryptedDownload.createReadStream().then(readFromStream); From 8e75923ae131976482f0bdde5b16bef6000f621a Mon Sep 17 00:00:00 2001 From: Simon Neumann <29802170+simaosimao@users.noreply.github.com> Date: Fri, 11 Apr 2025 11:07:59 +0200 Subject: [PATCH 8/8] add execution of e2e tests to qa and live --- .../workflows/build-and-deploy-workflow.yml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/build-and-deploy-workflow.yml b/.github/workflows/build-and-deploy-workflow.yml index 4f1e04c..9a30c7e 100644 --- a/.github/workflows/build-and-deploy-workflow.yml +++ b/.github/workflows/build-and-deploy-workflow.yml @@ -99,6 +99,7 @@ jobs: retain: 'syncorix-whisper-build-te' # retention policy: num of recently updated projects to keep retain_num: 0 + # Execute end-to-end tests against hosted environemt e2e-tests-te: runs-on: ubuntu-latest name: Execute end to end tests (TE) @@ -149,6 +150,28 @@ jobs: retain: 'syncorix-whisper-build-qa' # retention policy: num of recently updated projects to keep retain_num: 0 + # Execute end-to-end tests against hosted environemt + e2e-tests-qa: + runs-on: ubuntu-latest + name: Execute end to end tests (QA) + needs: deploy-to-pgs-qa + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: install dependencies + run: bun install + - name: Install playwright (expensive :/) + run: bun playwright install --with-deps + - name: Run tests + run: bun playwright test --project='qa*' + - name: Upload test report + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ # Deploys the bundle build of release tags to pgs-live project # linked to whisper.syncorix.com # See https://github.com/picosh/pgs-action @@ -178,3 +201,25 @@ jobs: retain: 'syncorix-whisper-build-live' # retention policy: num of recently updated projects to keep retain_num: 0 + # Execute end-to-end tests against hosted environemt + e2e-tests-live: + runs-on: ubuntu-latest + name: Execute end to end tests (LIVE) + needs: deploy-to-pgs-live + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: install dependencies + run: bun install + - name: Install playwright (expensive :/) + run: bun playwright install --with-deps + - name: Run tests + run: bun playwright test --project='live*' + - name: Upload test report + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/