feat(CI): configure workflow for different OS

This commit is contained in:
Bijin A B
2026-03-21 13:57:06 +05:30
parent 9190de53ad
commit 8ad8aa2d2f
21 changed files with 341 additions and 164 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Force LF line endings for all text files
* text=auto eol=lf

View File

@@ -5,6 +5,10 @@ inputs:
description: 'Skip building libraries'
required: false
default: 'false'
shell:
description: 'Shell to use (bash, pwsh)'
required: false
default: 'bash'
runs:
using: 'composite'
steps:
@@ -16,12 +20,12 @@ runs:
cache-dependency-path: './package-lock.json'
- name: Install node dependencies
shell: bash
shell: ${{ inputs.shell }}
run: npm ci --legacy-peer-deps
- name: Build libraries
if: inputs.skip-build != 'true'
shell: bash
shell: ${{ inputs.shell }}
run: |
npm run build:graphql-docs
npm run build:bruno-query

View File

@@ -7,13 +7,13 @@ runs:
shell: bash
run: |
set -euo pipefail
xvfb-run npm run test:e2e:ssl
- name: Upload Playwright Report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report-linux
name: playwright-report-linux-ssl
path: playwright-report/
retention-days: 30

View File

@@ -12,6 +12,6 @@ runs:
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report-macos
name: playwright-report-macos-ssl
path: playwright-report/
retention-days: 30

View File

@@ -12,6 +12,6 @@ runs:
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report-windows
name: playwright-report-windows-ssl
path: playwright-report/
retention-days: 30

View File

@@ -1,20 +1,41 @@
name: 'Run CLI Tests'
description: 'Setup dependencies, start local testbench and run CLI tests'
inputs:
shell:
description: 'Shell to use (bash, pwsh)'
required: false
default: 'bash'
runs:
using: 'composite'
steps:
- name: Run Local Testbench
shell: bash
- name: Install Test Collection Dependencies
shell: ${{ inputs.shell }}
run: npm ci --prefix packages/bruno-tests/collection
- name: Run Local Testbench and CLI Tests
if: inputs.shell != 'pwsh'
shell: ${{ inputs.shell }}
run: |
npm start --workspace=packages/bruno-tests &
sleep 5
- name: Install Test Collection Dependencies
shell: bash
run: npm ci --prefix packages/bruno-tests/collection
- name: Run CLI Tests
shell: bash
run: |
cd packages/bruno-tests/collection
node ../../bruno-cli/bin/bru.js run --env Prod --output junit.xml --format junit --sandbox developer
- name: Run Local Testbench and CLI Tests - Windows
if: inputs.shell == 'pwsh'
shell: pwsh
run: |
$process = Start-Process "npm.cmd" `
-ArgumentList "start","--workspace=packages/bruno-tests" `
-NoNewWindow `
-PassThru
Start-Sleep -Seconds 5
if ($process.HasExited) {
Write-Error "Server exited early"
exit 1
}
cd packages/bruno-tests/collection
node ../../bruno-cli/bin/bru.js run --env Prod --output junit.xml --format junit --sandbox developer

View File

@@ -4,11 +4,15 @@ inputs:
os:
description: 'Operating system (ubuntu, macos, windows)'
default: 'ubuntu'
shell:
description: 'Shell to use (bash, pwsh)'
required: false
default: 'bash'
runs:
using: 'composite'
steps:
- name: Install Test Collection Dependencies
shell: bash
shell: ${{ inputs.shell }}
run: npm ci --prefix packages/bruno-tests/collection
- name: Run Playwright Tests (Ubuntu)
@@ -18,5 +22,5 @@ runs:
- name: Run Playwright Tests
if: inputs.os != 'ubuntu'
shell: bash
shell: ${{ inputs.shell }}
run: npm run test:e2e

View File

@@ -1,48 +1,53 @@
name: 'Run Unit Tests'
description: 'Setup dependencies and run unit tests for all packages'
inputs:
shell:
description: 'Shell to use (bash, pwsh)'
required: false
default: 'bash'
runs:
using: 'composite'
steps:
- name: Test Package bruno-js
shell: bash
run: npm run test --workspace=packages/bruno-js
shell: ${{ inputs.shell }}
run: npm run test:ci --workspace=packages/bruno-js
- name: Test Package bruno-cli
shell: bash
run: npm run test --workspace=packages/bruno-cli
shell: ${{ inputs.shell }}
run: npm run test:ci --workspace=packages/bruno-cli
- name: Test Package bruno-query
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-query
- name: Test Package bruno-lang
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-lang
- name: Test Package bruno-schema
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-schema
- name: Test Package bruno-app
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-app
- name: Test Package bruno-common
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-common
- name: Test Package bruno-converters
shell: bash
run: npm run test --workspace=packages/bruno-converters
shell: ${{ inputs.shell }}
run: npm run test:ci --workspace=packages/bruno-converters
- name: Test Package bruno-electron
shell: bash
run: npm run test --workspace=packages/bruno-electron
shell: ${{ inputs.shell }}
run: npm run test:ci --workspace=packages/bruno-electron
- name: Test Package bruno-requests
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-requests
- name: Test Package bruno-filestore
shell: bash
shell: ${{ inputs.shell }}
run: npm run test --workspace=packages/bruno-filestore

View File

@@ -1,91 +0,0 @@
name: SSL Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
tests-for-linux:
name: SSL Tests - Linux
timeout-minutes: 60
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Setup Feature Dependencies
uses: ./.github/actions/ssl/linux/setup-feature-specific-deps
- name: Setup CA Certificates
uses: ./.github/actions/ssl/linux/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/linux/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/linux/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/linux/run-ssl-e2e-tests
tests-for-macos:
name: SSL Tests - macOS
timeout-minutes: 60
runs-on: macos-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Setup Feature Dependencies
uses: ./.github/actions/ssl/macos/setup-feature-specific-deps
- name: Setup CA Certificates
uses: ./.github/actions/ssl/macos/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/macos/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/macos/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/macos/run-ssl-e2e-tests
tests-for-windows:
name: SSL Tests - Windows
timeout-minutes: 60
runs-on: windows-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Setup CA Certificates
uses: ./.github/actions/ssl/windows/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/windows/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/windows/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/windows/run-ssl-e2e-tests

View File

@@ -1,4 +1,4 @@
name: Tests
name: Linux Tests
on:
workflow_dispatch:
push:
@@ -8,7 +8,7 @@ on:
jobs:
unit-test:
name: Unit Tests
name: Unit Tests (Linux)
timeout-minutes: 60
runs-on: ubuntu-latest
permissions:
@@ -23,7 +23,7 @@ jobs:
uses: ./.github/actions/tests/run-unit-tests
cli-test:
name: CLI Tests
name: CLI Tests (Linux)
runs-on: ubuntu-latest
permissions:
checks: write
@@ -38,17 +38,9 @@ jobs:
- name: Run CLI Tests
uses: ./.github/actions/tests/run-cli-tests
- name: Publish Test Report
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
check_name: CLI Test Results
files: packages/bruno-tests/collection/junit.xml
comment_mode: always
e2e-test:
name: Playwright E2E Tests
timeout-minutes: 60
name: Playwright E2E Tests (Linux)
timeout-minutes: 90
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
@@ -77,6 +69,35 @@ jobs:
uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report
name: playwright-report-linux
path: playwright-report/
retention-days: 30
ssl-test:
name: SSL Tests (Linux)
timeout-minutes: 60
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Setup Feature Dependencies
uses: ./.github/actions/ssl/linux/setup-feature-specific-deps
- name: Setup CA Certificates
uses: ./.github/actions/ssl/linux/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/linux/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/linux/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/linux/run-ssl-e2e-tests

91
.github/workflows/tests-macos.yml vendored Normal file
View File

@@ -0,0 +1,91 @@
name: macOS Tests
on:
workflow_dispatch:
push:
branches: [main, 'release/v*']
pull_request:
branches: [main, 'release/v*']
jobs:
unit-test:
name: Unit Tests (macOS)
timeout-minutes: 60
runs-on: macos-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Run Unit Tests
uses: ./.github/actions/tests/run-unit-tests
cli-test:
name: CLI Tests (macOS)
runs-on: macos-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Run CLI Tests
uses: ./.github/actions/tests/run-cli-tests
e2e-test:
name: Playwright E2E Tests (macOS)
timeout-minutes: 90
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Run E2E Tests
uses: ./.github/actions/tests/run-e2e-tests
with:
os: macos
- name: Upload Playwright Report
uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report-macos
path: playwright-report/
retention-days: 30
ssl-test:
name: SSL Tests (macOS)
timeout-minutes: 60
runs-on: macos-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
- name: Setup Feature Dependencies
uses: ./.github/actions/ssl/macos/setup-feature-specific-deps
- name: Setup CA Certificates
uses: ./.github/actions/ssl/macos/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/macos/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/macos/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/macos/run-ssl-e2e-tests

101
.github/workflows/tests-windows.yml vendored Normal file
View File

@@ -0,0 +1,101 @@
name: Windows Tests
on:
workflow_dispatch:
push:
branches: [main, 'release/v*']
pull_request:
branches: [main, 'release/v*']
jobs:
unit-test:
name: Unit Tests (Windows)
timeout-minutes: 60
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
with:
shell: pwsh
- name: Run Unit Tests
uses: ./.github/actions/tests/run-unit-tests
with:
shell: pwsh
cli-test:
name: CLI Tests (Windows)
runs-on: windows-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
with:
shell: pwsh
- name: Run CLI Tests
uses: ./.github/actions/tests/run-cli-tests
with:
shell: pwsh
e2e-test:
name: Playwright E2E Tests (Windows)
timeout-minutes: 90
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
with:
shell: pwsh
- name: Run E2E Tests
uses: ./.github/actions/tests/run-e2e-tests
with:
os: windows
shell: pwsh
- name: Upload Playwright Report
uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report-windows
path: playwright-report/
retention-days: 30
ssl-test:
name: SSL Tests (Windows)
timeout-minutes: 60
runs-on: windows-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node Dependencies
uses: ./.github/actions/common/setup-node-deps
with:
shell: pwsh
- name: Setup CA Certificates
uses: ./.github/actions/ssl/windows/setup-ca-certs
- name: Run Basic SSL CLI Tests
uses: ./.github/actions/ssl/windows/run-basic-ssl-cli-tests
- name: Run Custom CA Certs CLI Tests
uses: ./.github/actions/ssl/windows/run-custom-ca-certs-cli-tests
- name: Run Custom CA Certs E2E Tests
uses: ./.github/actions/ssl/windows/run-ssl-e2e-tests

View File

@@ -36,7 +36,8 @@
"api-scripting"
],
"scripts": {
"test": "node --experimental-vm-modules $(npx which jest)"
"test": "node --experimental-vm-modules $(npx which jest)",
"test:ci": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js"
},
"files": [
"src",

View File

@@ -74,7 +74,8 @@ const builder = (yargs) => {
const isUrl = (str) => {
try {
return Boolean(new URL(str));
const url = new URL(str);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (error) {
return false;
}

View File

@@ -12,6 +12,7 @@
"scripts": {
"clean": "rimraf dist",
"test": "node --experimental-vm-modules $(npx which jest) --colors --collectCoverage",
"test:ci": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --colors --collectCoverage",
"prebuild": "npm run clean",
"build": "rollup -c",
"watch": "rollup -c -w",

View File

@@ -21,7 +21,8 @@
"dist:rpm": "electron-builder --linux rpm --config electron-builder-config.js",
"dist:snap": "electron-builder --linux snap --config electron-builder-config.js",
"pack": "electron-builder --dir",
"test": "node --experimental-vm-modules $(npx which jest)"
"test": "node --experimental-vm-modules $(npx which jest)",
"test:ci": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js"
},
"jest": {
"modulePaths": [

View File

@@ -9,6 +9,7 @@
],
"scripts": {
"test": "node --experimental-vm-modules $(npx which jest) --testPathIgnorePatterns test.js",
"test:ci": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --testPathIgnorePatterns test.js",
"sandbox:bundle-libraries": "node ./src/sandbox/bundle-libraries.js"
},
"dependencies": {

View File

@@ -21,18 +21,12 @@ script:pre-request {
tests {
const path = require('node:path');
test("path.join", function() {
expect(path.join('/foo', 'bar', 'baz')).to.equal('/foo/bar/baz');
expect(path.join('foo', 'bar', 'baz')).to.equal('foo/bar/baz');
});
test("path.resolve", function() {
const resolved = path.resolve('foo', 'bar');
expect(path.isAbsolute(resolved)).to.equal(true);
});
test("path.dirname and path.basename", function() {
expect(path.dirname('/foo/bar/baz.txt')).to.equal('/foo/bar');
expect(path.basename('/foo/bar/baz.txt')).to.equal('baz.txt');
expect(path.basename('/foo/bar/baz.txt', '.txt')).to.equal('baz');
});
@@ -45,17 +39,9 @@ tests {
test("path.parse and path.format", function() {
const parsed = path.parse('/foo/bar/baz.txt');
expect(parsed.root).to.equal('/');
expect(parsed.dir).to.equal('/foo/bar');
expect(parsed.base).to.equal('baz.txt');
expect(parsed.name).to.equal('baz');
expect(parsed.ext).to.equal('.txt');
expect(path.format(parsed)).to.equal('/foo/bar/baz.txt');
});
test("path.normalize", function() {
expect(path.normalize('/foo/bar//baz/../qux')).to.equal('/foo/bar/qux');
});
test("path.isAbsolute", function() {
@@ -63,10 +49,6 @@ tests {
expect(path.isAbsolute('foo/bar')).to.equal(false);
});
test("path.relative", function() {
expect(path.relative('/foo/bar', '/foo/baz')).to.equal('../baz');
});
test("path.sep and path.delimiter", function() {
expect(path.sep).to.be.a('string');
expect(path.delimiter).to.be.a('string');

View File

@@ -136,7 +136,10 @@ export const test = baseTest.extend<
if (srcPath) {
const tmpDir = await createTmpDir(path.basename(srcPath));
await fs.promises.cp(srcPath, tmpDir, { recursive: true });
await use(tmpDir);
// Normalize to forward slashes so the path is valid JSON when substituted
// into template files (e.g. preferences.json). Windows paths with backslashes
// produce invalid JSON escape sequences such as \U, \A, \T, etc.
await use(tmpDir.replace(/\\/g, '/'));
} else {
await use(null);
}
@@ -155,7 +158,7 @@ export const test = baseTest.extend<
if (initUserDataPath) {
const replacements: Record<string, string> = {
projectRoot: path.posix.join(__dirname, '..'),
projectRoot: path.join(__dirname, '..').replace(/\\/g, '/'),
...templateVars
};
@@ -163,7 +166,7 @@ export const test = baseTest.extend<
let content = await fs.promises.readFile(path.join(initUserDataPath, file), 'utf-8');
content = content.replace(/{{(\w+)}}/g, (_, key) => {
if (replacements[key]) {
return replacements[key];
return replacements[key].replace(/\\/g, '/');
} else {
throw new Error(`\tNo replacement for {{${key}}} in ${path.join(initUserDataPath, file)}`);
}

View File

@@ -12,9 +12,9 @@ function normalizeJunitReport(xmlContent: string): string {
// Replace execution times with fixed value
.replace(/time="[^"]*"/g, 'time="0.100"')
// Replace file paths with normalized path
.replace(/file="[^"]*\/[^"]*"/g, 'file="/mock/path/to/file.bru"')
.replace(/file="[^"]*[\\/][^"]*"/g, 'file="/mock/path/to/file.bru"')
// Replace test paths with normalized path
.replace(/classname="[^"]*\/[^"]*"/g, 'classname="/test/path/collection"');
.replace(/classname="[^"]*[\\/][^"]*"/g, 'classname="/test/path/collection"');
}
test.describe('Collection Run Report Tests', () => {

View File

@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<testsuites>
<testsuite name="Get User Info" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has slideshow property" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Slideshow has title" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="Get UUID" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="This test will fail" status="fail" classname="/test/path/collection" time="0.100">
<failure type="failure" message="expected 200 to equal 404"/>
</testcase>
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has uuid property" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="UUID is a string" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="Login Request" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response has json field" status="pass" classname="/test/path/collection" time="0.100"/>
<testcase name="Response json has username" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
<testsuite name="Logout Request" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
<testcase name="This test will also fail" status="fail" classname="/test/path/collection" time="0.100">
<failure type="failure" message="expected 200 to equal 500"/>
</testcase>
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
</testsuite>
</testsuites>