Skip to content

Commit 223f79a

Browse files
authored
Merge pull request #4694 from usebruno/feature/playwright
Improvements in Playwright setup and added tests for running bruno-testbench
2 parents 5dc6f67 + a006fe8 commit 223f79a

File tree

12 files changed

+324
-85
lines changed

12 files changed

+324
-85
lines changed

.github/workflows/playwright.yml

Lines changed: 0 additions & 44 deletions
This file was deleted.

.github/workflows/tests.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,43 @@ jobs:
9191
uses: EnricoMi/publish-unit-test-result-action@v2
9292
if: always()
9393
with:
94+
check_name: CLI Test Results
9495
files: packages/bruno-tests/collection/junit.xml
9596
comment_mode: always
97+
e2e-test:
98+
name: Playwright E2E Tests
99+
timeout-minutes: 60
100+
runs-on: ubuntu-24.04
101+
steps:
102+
- uses: actions/checkout@v4
103+
- uses: actions/setup-node@v4
104+
with:
105+
node-version: v22.11.x
106+
- name: Install dependencies
107+
run: |
108+
sudo apt-get update
109+
sudo apt-get --no-install-recommends install -y \
110+
libglib2.0-0 libnss3 libdbus-1-3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libgtk-3-0 libasound2t64 \
111+
xvfb
112+
npm ci --legacy-peer-deps
113+
sudo chown root /home/runner/work/bruno/bruno/node_modules/electron/dist/chrome-sandbox
114+
sudo chmod 4755 /home/runner/work/bruno/bruno/node_modules/electron/dist/chrome-sandbox
115+
116+
- name: Build libraries
117+
run: |
118+
npm run build:graphql-docs
119+
npm run build:bruno-query
120+
npm run build:bruno-common
121+
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
122+
npm run build:bruno-converters
123+
npm run build:bruno-requests
124+
125+
- name: Run Playwright tests
126+
run: |
127+
xvfb-run npm run test:e2e
128+
- uses: actions/upload-artifact@v4
129+
if: ${{ !cancelled() }}
130+
with:
131+
name: playwright-report
132+
path: playwright-report/
133+
retention-days: 30

contributing.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,13 @@ npm run dev
9999
```
100100

101101
#### Customize Electron `userData` path
102-
If `ELECTRON_APP_NAME` env-variable is present and its development mode, then the `appName` and `userData` path is modified accordingly.
102+
If `ELECTRON_USER_DATA_PATH` env-variable is present and its development mode, then `userData` path is modified accordingly.
103103

104104
e.g.
105105
```sh
106-
ELECTRON_APP_NAME=bruno-dev npm run dev:electron
106+
ELECTRON_USER_DATA_PATH=$(realpath ~/Desktop/bruno-test) npm run dev:electron
107107
```
108-
109-
> This doesn't change the name of the window or the names in lot of other places, only the name used by Electron internally.
108+
This will create a `bruno-test` folder on your Desktop and use it as the `userData` path.
110109

111110
### Troubleshooting
112111

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test, expect } from '../../playwright';
2+
3+
test('Check if the logo on top left is visible', async ({ page }) => {
4+
await expect(page.getByRole('button', { name: 'bruno' })).toBeVisible();
5+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { test, expect } from '../../playwright';
2+
3+
test('Create new collection and add a simple HTTP request', async ({ page, createTmpDir }) => {
4+
await page.getByLabel('Create Collection').click();
5+
await page.getByLabel('Name').click();
6+
await page.getByLabel('Name').fill('test-collection');
7+
await page.getByLabel('Name').press('Tab');
8+
await page.getByLabel('Location').fill(await createTmpDir('test-collection'));
9+
await page.getByRole('button', { name: 'Create', exact: true }).click();
10+
await page.getByText('test-collection').click();
11+
await page.getByLabel('Safe ModeBETA').check();
12+
await page.getByRole('button', { name: 'Save' }).click();
13+
await page.locator('#create-new-tab').getByRole('img').click();
14+
await page.getByPlaceholder('Request Name').fill('r1');
15+
await page.getByPlaceholder('Request URL').click();
16+
await page.getByPlaceholder('Request URL').fill('http://localhost:8081');
17+
await page.getByRole('button', { name: 'Create' }).click();
18+
await page.locator('pre').filter({ hasText: 'http://localhost:' }).click();
19+
await page.locator('textarea').fill('/ping');
20+
await page.locator('#send-request').getByRole('img').nth(2).click();
21+
22+
await expect(page.getByRole('main')).toContainText('200 OK');
23+
24+
await page.getByRole('tab', { name: 'GET r1' }).locator('circle').click();
25+
await page.getByRole('button', { name: 'Save', exact: true }).click();
26+
await page.getByText('GETr1').click();
27+
await page.getByRole('button', { name: 'Clear response' }).click();
28+
await page.locator('body').press('ControlOrMeta+Enter');
29+
30+
await expect(page.getByRole('main')).toContainText('200 OK');
31+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"maximized": true,
3+
"lastOpenedCollections": ["{{projectRoot}}/packages/bruno-tests/collection"]
4+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { test, expect } from '../../playwright';
2+
3+
test.describe.parallel('Run Testbench Requests', () => {
4+
test('Run bruno-testbench in Developer Mode', async ({ pageWithUserData: page }) => {
5+
test.setTimeout(2 * 60 * 1000);
6+
7+
await page.getByText('bruno-testbench').click();
8+
await page.getByLabel('Developer Mode(use only if').check();
9+
await page.getByRole('button', { name: 'Save' }).click();
10+
await page.locator('.environment-selector').nth(1).click();
11+
await page.locator('.dropdown-item').getByText('Prod').click();
12+
await page.locator('.collection-actions').hover();
13+
await page.locator('.collection-actions .icon').click();
14+
await page.getByText('Run', { exact: true }).click();
15+
await page.getByRole('button', { name: 'Run Collection' }).click();
16+
await page.getByRole('button', { name: 'Run Again' }).waitFor({ timeout: 2 * 60 * 1000 });
17+
18+
const result = await page.getByText('Total Requests: ').innerText();
19+
const [totalRequests, passed, failed, skipped] = result
20+
.match(/Total Requests: (\d+), Passed: (\d+), Failed: (\d+), Skipped: (\d+)/)
21+
.slice(1);
22+
23+
await expect(parseInt(failed)).toBe(0);
24+
await expect(parseInt(passed)).toBe(parseInt(totalRequests) - parseInt(skipped) - 1);
25+
});
26+
27+
test.fixme('Run bruno-testbench in Safe Mode', async ({ pageWithUserData: page }) => {
28+
test.setTimeout(2 * 60 * 1000);
29+
30+
await page.getByText('bruno-testbench').click();
31+
await page.getByLabel('Safe ModeBETA').check();
32+
await page.getByRole('button', { name: 'Save' }).click();
33+
await page.locator('.environment-selector').nth(1).click();
34+
await page.locator('.dropdown-item').getByText('Prod').click();
35+
await page.locator('.collection-actions').hover();
36+
await page.locator('.collection-actions .icon').click();
37+
await page.getByText('Run', { exact: true }).click();
38+
await page.getByRole('button', { name: 'Run Collection' }).click();
39+
await page.getByRole('button', { name: 'Run Again' }).waitFor({ timeout: 2 * 60 * 1000 });
40+
41+
const result = await page.getByText('Total Requests: ').innerText();
42+
const [totalRequests, passed, failed, skipped] = result
43+
.match(/Total Requests: (\d+), Passed: (\d+), Failed: (\d+), Skipped: (\d+)/)
44+
.slice(1);
45+
46+
await expect(parseInt(failed)).toBe(0);
47+
await expect(parseInt(passed)).toBe(parseInt(totalRequests) - parseInt(skipped) - 1);
48+
});
49+
});

e2e-tests/test-app-start.spec.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/bruno-electron/src/index.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,11 @@ const { format } = require('url');
1414
const { BrowserWindow, app, session, Menu, ipcMain } = require('electron');
1515
const { setContentSecurityPolicy } = require('electron-util');
1616

17-
if (isDev && process.env.ELECTRON_APP_NAME) {
18-
const appName = process.env.ELECTRON_APP_NAME;
19-
const userDataPath = path.join(app.getPath("appData"), appName);
17+
if (isDev && process.env.ELECTRON_USER_DATA_PATH) {
18+
console.debug("`ELECTRON_USER_DATA_PATH` found, modifying `userData` path: \n"
19+
+ `\t${app.getPath("userData")} -> ${process.env.ELECTRON_USER_DATA_PATH}`);
2020

21-
console.log("`ELECTRON_APP_NAME` found, overriding `appName` and `userData` path: \n"
22-
+ `\t${app.getName()} -> ${appName}\n`
23-
+ `\t${app.getPath("userData")} -> ${userDataPath}`);
24-
25-
app.setName(appName);
26-
app.setPath("userData", userDataPath);
21+
app.setPath('userData', process.env.ELECTRON_USER_DATA_PATH);
2722
}
2823

2924
const menuTemplate = require('./app/menu-template');

playwright.config.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { defineConfig, devices } from '@playwright/test';
22

3-
const reporter: string[][string] = [['list'], ['html']];
3+
const reporter: any[] = [['list'], ['html']];
44

55
if (process.env.CI) {
6-
reporter.push(["github"]);
6+
reporter.push(['github']);
77
}
88

9-
109
export default defineConfig({
1110
testDir: './e2e-tests',
1211
fullyParallel: false,
1312
forbidOnly: !!process.env.CI,
1413
retries: process.env.CI ? 1 : 0,
1514
workers: process.env.CI ? undefined : 1,
1615
reporter,
16+
1717
use: {
18-
trace: 'on-first-retry'
18+
trace: process.env.CI ? 'on-first-retry' : 'on'
1919
},
2020

2121
projects: [
@@ -24,9 +24,16 @@ export default defineConfig({
2424
}
2525
],
2626

27-
webServer: {
28-
command: 'npm run dev:web',
29-
url: 'http://localhost:3000',
30-
reuseExistingServer: !process.env.CI
31-
}
27+
webServer: [
28+
{
29+
command: 'npm run dev:web',
30+
url: 'http://localhost:3000',
31+
reuseExistingServer: !process.env.CI
32+
},
33+
{
34+
command: 'npm start --workspace=packages/bruno-tests',
35+
url: 'http://localhost:8081/ping',
36+
reuseExistingServer: !process.env.CI
37+
}
38+
]
3239
});

playwright/electron.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ exports.startApp = async () => {
77
const app = await electron.launch({ args: [electronAppPath] });
88
const context = await app.context();
99

10-
app.process().stdout.on('data', (data) => console.log(data.toString()));
11-
app.process().stderr.on('data', (error) => console.error(error.toString()));
10+
app.process().stdout.on('data', (data) => {
11+
process.stdout.write(data.toString().replace(/^(?=.)/gm, '[Electron] |'));
12+
});
13+
app.process().stderr.on('data', (error) => {
14+
process.stderr.write(error.toString().replace(/^(?=.)/gm, '[Electron] |'));
15+
});
1216
return { app, context };
1317
};

0 commit comments

Comments
 (0)