chore: repo wide lint fixes

This commit is contained in:
Bijin A B
2025-12-03 09:44:50 +05:30
parent 4a38f2d49f
commit 62cf4139d7
460 changed files with 6921 additions and 7052 deletions

View File

@@ -37,4 +37,4 @@ test.describe('Create collection', () => {
// Verify the response
await expect(page.getByRole('main')).toContainText('200 OK');
});
});
});

View File

@@ -51,7 +51,7 @@ test.describe('Tag persistence', () => {
// Move the request-3 request to just above request-1 within the same collection
const r3Request = page.locator('.collection-item-name').filter({ hasText: 'request-3' });
const r1Request = page.locator('.collection-item-name').filter({ hasText: 'request-1' });
await expect(r3Request).toBeVisible();
await expect(r1Request).toBeVisible();
@@ -100,7 +100,7 @@ test.describe('Tag persistence', () => {
await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).hover();
await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').getByText('New Request').click()
await page.locator('.dropdown-item').getByText('New Request').click();
await page.getByRole('textbox', { name: 'Request Name' }).fill('request-1');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
@@ -110,7 +110,7 @@ test.describe('Tag persistence', () => {
.filter({ hasText: 'folder-1' }).hover();
await page.locator('.collection-item-name')
.filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').getByText('New Request').click()
await page.locator('.dropdown-item').getByText('New Request').click();
await page.getByRole('textbox', { name: 'Request Name' }).fill('request-2');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
@@ -145,12 +145,12 @@ test.describe('Tag persistence', () => {
await page.getByRole('textbox', { name: 'Request Name' }).fill('request-3');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
// Drag and drop request-2 request to folder-2 folder
const r2Request = page.locator('.collection-item-name').filter({ hasText: 'request-2' });
const f2Folder = page.locator('.collection-item-name').filter({ hasText: 'folder-2' });
await r2Request.dragTo(f2Folder);
// Verify the requests are still in the collection and request-2 is now in folder-2 folder
await expect(page.locator('.collection-item-name').filter({ hasText: 'request-2' })).toBeVisible();
await expect(page.locator('.collection-item-name').filter({ hasText: 'folder-2' })).toBeVisible();

View File

@@ -23,7 +23,7 @@ test('should handle corrupted passkey and still display saved cookie list', asyn
await page1.getByRole('button', { name: 'Save' }).click();
await expect(page1.getByText('example.com')).toBeVisible();
await app1.close();
// 2. Corrupt the encryptedPasskey in cookies.json

View File

@@ -70,8 +70,8 @@ test.describe('Multiline Variables - Write Test', () => {
await expect(page.locator('.response-status-code')).toContainText('200');
// verify multiline JSON variable resolution in response
const expectedBody =
'{\n "user": {\n "name": "John Doe",\n "email": "john@example.com",\n "preferences": {\n "theme": "dark",\n "notifications": true\n }\n },\n "metadata": {\n "created": "2025-09-03",\n "version": "1.0"\n }\n}';
const expectedBody
= '{\n "user": {\n "name": "John Doe",\n "email": "john@example.com",\n "preferences": {\n "theme": "dark",\n "notifications": true\n }\n },\n "metadata": {\n "created": "2025-09-03",\n "version": "1.0"\n }\n}';
await expect(page.locator('.response-pane')).toContainText(`"body": ${JSON.stringify(expectedBody)}`);
});

View File

@@ -4,22 +4,22 @@ test.describe('Notifications Modal', () => {
test('should open notifications modal when clicking bell icon and close with close button', async ({ page }) => {
// Get the notification bell icon in the status bar
const notificationBell = page.getByLabel('Check all Notifications');
// Click on the bell icon to open notifications
await notificationBell.click();
// Get modal elements
const notificationsModal = page.locator('.bruno-modal');
const modalCloseButton = notificationsModal.locator('div.bruno-modal-header div.close');
// Verify modal is visible and has the correct title
await expect(notificationsModal).toBeVisible();
await expect(notificationsModal.locator('.bruno-modal-header-title')).toContainText('NOTIFICATIONS');
// Click the close button
await modalCloseButton.click();
// Verify modal is closed
await expect(notificationsModal).not.toBeVisible();
});
});
});

View File

@@ -6,14 +6,14 @@ test.describe('Sidebar Toggle', () => {
const sidebar = page.locator('aside.sidebar');
const toggleButton = page.getByLabel('Toggle Sidebar');
const dragHandle = page.locator('.sidebar-drag-handle');
// Initial state - sidebar and drag handle should be visible
await expect(sidebar).toBeVisible();
await expect(dragHandle).toBeVisible();
// Click toggle to hide sidebar
await toggleButton.click();
// Wait for transition to complete and verify sidebar and drag handle are hidden
await expect(sidebar).not.toBeVisible();
await expect(dragHandle).not.toBeVisible();
@@ -21,10 +21,10 @@ test.describe('Sidebar Toggle', () => {
// Verify the sidebar has collapsed width
const sidebarBox = await sidebar.boundingBox();
expect(sidebarBox?.width).toBe(0);
// Click toggle again to show sidebar
await toggleButton.click();
// Wait for transition and verify sidebar and drag handle are visible again
await expect(sidebar).toBeVisible();
await expect(dragHandle).toBeVisible();
@@ -33,4 +33,4 @@ test.describe('Sidebar Toggle', () => {
const expandedSidebarBox = await sidebar.boundingBox();
expect(expandedSidebarBox?.width).toBeGreaterThan(0);
});
});
});

View File

@@ -7,30 +7,29 @@ const env = {
test.describe('Onboarding', () => {
test('should create sample collection on first launch', async ({ launchElectronApp, createTmpDir }) => {
// Use a fresh app instance to avoid contamination from previous tests
const userDataPath = await createTmpDir('onboarding-fresh');
const app = await launchElectronApp({ userDataPath, dotEnv: env });
const page = await app.firstWindow();
// Verify sample collection appears in sidebar
const sampleCollection = page.locator('#sidebar-collection-name').getByText('Sample API Collection');
await expect(sampleCollection).toBeVisible();
// Click on the sample collection to open it
await sampleCollection.click();
const modeSaveButton = page.getByRole('button', { name: 'Save' });
await expect(modeSaveButton).toBeVisible();
await modeSaveButton.click();
// Verify the sample request is visible and clickable
const request = page.locator('.collection-item-name').getByText('Get Users');
await expect(request).toBeVisible();
await request.click();
// Verify the URL is set correctly
await expect(page.locator('#request-url')).toContainText('https://jsonplaceholder.typicode.com/users');
// Clean up
await app.close();
});
@@ -40,7 +39,7 @@ test.describe('Onboarding', () => {
const userDataPath = await createTmpDir('duplicate-collections');
const app = await launchElectronApp({ userDataPath, dotEnv: env });
const page = await app.firstWindow();
// First launch - verify sample collection is created
const sampleCollection = page.locator('#sidebar-collection-name').getByText('Sample API Collection');
await expect(sampleCollection).toBeVisible();
@@ -48,12 +47,12 @@ test.describe('Onboarding', () => {
const modeSaveButton = page.getByRole('button', { name: 'Save' });
await expect(modeSaveButton).toBeVisible();
await modeSaveButton.click();
// Verify the sample request
const request = page.locator('.collection-item-name').getByText('Get Users');
await expect(request).toBeVisible();
await request.click();
// Verify the URL is set correctly
await expect(page.locator('#request-url')).toContainText('https://jsonplaceholder.typicode.com/users');
@@ -67,16 +66,16 @@ test.describe('Onboarding', () => {
// Verify only one sample collection exists
const sampleCollections = newPage.locator('#sidebar-collection-name').getByText('Sample API Collection');
await expect(sampleCollections).toHaveCount(1);
// Verify the collection still works after restart
await sampleCollections.click();
const request2 = newPage.locator('.collection-item-name').getByText('Get Users');
await expect(request2).toBeVisible();
await request2.click();
// Verify the URL is still correct after restart
await expect(newPage.locator('#request-url')).toContainText('https://jsonplaceholder.typicode.com/users');
// Clean up
await newApp.close();
});
@@ -85,29 +84,28 @@ test.describe('Onboarding', () => {
const userDataPath = await createTmpDir('first-launch');
const app = await launchElectronApp({ userDataPath, dotEnv: env });
const page = await app.firstWindow();
// First launch - sample collection should be created
const sampleCollection = page.locator('.collection-name').filter({ hasText: 'Sample API Collection' });
await expect(sampleCollection).toBeVisible();
// User closes the sample collection (hover on the collection and open context menu)
await sampleCollection.hover();
await sampleCollection.locator('.collection-actions .icon').click();
// Close the sample collection
const closeOption = page.locator('.dropdown-item').getByText('Close');
await expect(closeOption).toBeVisible();
await closeOption.click();
// Handle the confirmation dialog - click the 'Close' button to confirm
const confirmCloseButton = page.locator('.bruno-modal').getByRole('button', { name: 'Close' });
await expect(confirmCloseButton).toBeVisible();
await confirmCloseButton.click();
// Verify collection is closed (no longer visible in sidebar)
await expect(sampleCollection).not.toBeVisible();
// Restart app - sample collection should NOT be recreated
const newApp = await reuseOrLaunchElectronApp({ userDataPath, dotEnv: env });
const newPage = await newApp.firstWindow();
@@ -127,7 +125,7 @@ test.describe('Onboarding', () => {
// This test simulates old users who already have a collection opened
const brunoTestbench = page.locator('#sidebar-collection-name').getByText('bruno-testbench');
await expect(brunoTestbench).toBeVisible();
// Verify no sample collection was created since user already has collections
const sampleCollection = page.locator('#sidebar-collection-name').getByText('Sample API Collection');
await expect(sampleCollection).not.toBeVisible();

View File

@@ -1,27 +1,27 @@
import { test, expect } from '../../playwright';
test('Should verify all support links with correct URL in preference > Support tab', async ({ page }) => {
// Open Preferences
await page.getByLabel('Open Preferences').click();
// Go to Support tab
await page.getByRole('tab', { name: 'Support' }).click();
// Open Preferences
await page.getByLabel('Open Preferences').click();
// Verify all support links with correct URL
const locator_twitter = page.getByRole('link', { name: 'Twitter' });
expect(await locator_twitter.getAttribute('href')).toEqual('https://twitter.com/use_bruno');
// Go to Support tab
await page.getByRole('tab', { name: 'Support' }).click();
const locator_github = page.getByRole('link', { name: 'GitHub', exact: true });
expect(await locator_github.getAttribute('href')).toEqual('https://github.com/usebruno/bruno');
// Verify all support links with correct URL
const locator_twitter = page.getByRole('link', { name: 'Twitter' });
expect(await locator_twitter.getAttribute('href')).toEqual('https://twitter.com/use_bruno');
const locator_discord = page.getByRole('link', { name: 'Discord', exact: true });
expect(await locator_discord.getAttribute('href')).toEqual('https://discord.com/invite/KgcZUncpjq');
const locator_github = page.getByRole('link', { name: 'GitHub', exact: true });
expect(await locator_github.getAttribute('href')).toEqual('https://github.com/usebruno/bruno');
const locator_reportissues = page.getByRole('link', { name: 'Report Issues', exact: true });
expect(await locator_reportissues.getAttribute('href')).toEqual('https://github.com/usebruno/bruno/issues');
const locator_discord = page.getByRole('link', { name: 'Discord', exact: true });
expect(await locator_discord.getAttribute('href')).toEqual('https://discord.com/invite/KgcZUncpjq');
const locator_documentation = page.getByRole('link', { name: 'Documentation', exact: true });
expect(await locator_documentation.getAttribute('href')).toEqual('https://docs.usebruno.com');
const locator_reportissues = page.getByRole('link', { name: 'Report Issues', exact: true });
expect(await locator_reportissues.getAttribute('href')).toEqual('https://github.com/usebruno/bruno/issues');
const locator_documentation = page.getByRole('link', { name: 'Documentation', exact: true });
expect(await locator_documentation.getAttribute('href')).toEqual('https://docs.usebruno.com');
await page.locator('[data-test-id="modal-close-button"]').click();
});

View File

@@ -66,4 +66,4 @@ test.describe.parallel('Collection Run', () => {
await expect(failed).toBe(0);
await expect(passed).toBe(totalRequests - skipped - failed);
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe.serial('basic ssl success', () => {
skipped: 0
});
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe.serial('self signed rejected', () => {
skipped: 0
});
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe.serial('self signed success with validation disabled', () => {
skipped: 0
});
});
});
});

View File

@@ -11,10 +11,10 @@ function createCertsDir(certsDir) {
function generateCertificates(certsDir) {
execCommand('openssl version');
// Generate CA private key
execCommand('openssl genrsa -out ca-key.pem 4096', certsDir);
// Create CA configuration file with proper CA extensions and subject (LibreSSL/OpenSSL compatible)
const caConfigContent = `[req]
distinguished_name = req_distinguished_name
@@ -33,15 +33,15 @@ basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always`;
fs.writeFileSync(path.join(certsDir, 'ca.conf'), caConfigContent);
// Generate CA certificate with proper CA extensions using config file (no -subj needed)
execCommand('openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 -config ca.conf', certsDir);
// Generate server private key and CSR
execCommand('openssl genrsa -out localhost-key.pem 4096', certsDir);
// Create server CSR configuration file
const serverCsrConfigContent = `[req]
distinguished_name = req_distinguished_name
@@ -53,10 +53,10 @@ ST = Dev
L = Local
O = Local Dev
CN = localhost`;
fs.writeFileSync(path.join(certsDir, 'localhost-csr.conf'), serverCsrConfigContent);
execCommand('openssl req -new -key localhost-key.pem -out localhost.csr -config localhost-csr.conf', certsDir);
// Create server certificate configuration file (LibreSSL/OpenSSL compatible)
const serverConfigContent = `[req]
distinguished_name = req_distinguished_name
@@ -83,27 +83,27 @@ DNS.2 = localhost.localdomain
IP.1 = 127.0.0.1
IP.2 = ::1
IP.3 = ::ffff:127.0.0.1`;
fs.writeFileSync(path.join(certsDir, 'localhost.conf'), serverConfigContent);
execCommand('openssl x509 -req -in localhost.csr -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out localhost-cert.pem -days 730 -extensions v3_req -extfile localhost.conf', certsDir);
const platform = detectPlatform();
if (platform === 'windows') {
execCommand('openssl x509 -in ca-cert.pem -outform DER -out ca-cert.der', certsDir);
execCommand('openssl pkcs12 -export -out localhost.p12 -inkey localhost-key.pem -in localhost-cert.pem -certfile ca-cert.pem -password pass:', certsDir);
execCommand('openssl x509 -in localhost-cert.pem -outform DER -out localhost-cert.der', certsDir);
}
if (platform !== 'windows') {
execCommand('chmod 600 ca-key.pem localhost-key.pem', certsDir);
execCommand('chmod 644 ca-cert.pem localhost-cert.pem', certsDir);
}
['localhost.csr', 'localhost.conf', 'localhost-csr.conf', 'ca.conf', 'ca-cert.srl'].forEach(file => {
['localhost.csr', 'localhost.conf', 'localhost-csr.conf', 'ca.conf', 'ca-cert.srl'].forEach((file) => {
const filePath = path.join(certsDir, file);
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
});
// Validate certificate chain
validateCertificateChain(certsDir);
}
@@ -112,29 +112,29 @@ function validateCertificateChain(certsDir) {
try {
// Verify CA certificate is valid and has proper CA extensions
const caVerifyOutput = execCommandSilent('openssl x509 -in ca-cert.pem -text -noout', certsDir).toString();
if (!caVerifyOutput.includes('CA:TRUE')) {
throw new Error('CA certificate missing basicConstraints=CA:TRUE');
}
if (!caVerifyOutput.includes('Certificate Sign')) {
throw new Error('CA certificate missing keyCertSign in keyUsage');
}
// Verify server certificate is valid and signed by CA
const serverVerifyOutput = execCommandSilent('openssl x509 -in localhost-cert.pem -text -noout', certsDir).toString();
if (!serverVerifyOutput.includes('CA:FALSE')) {
throw new Error('Server certificate should have basicConstraints=CA:FALSE');
}
if (!serverVerifyOutput.includes('TLS Web Server Authentication')) {
throw new Error('Server certificate missing serverAuth in extendedKeyUsage');
}
// Verify certificate chain
execCommandSilent('openssl verify -CAfile ca-cert.pem localhost-cert.pem', certsDir);
console.log('✅ Certificate chain validation passed');
} catch (error) {
console.error('❌ Certificate validation failed:', error.message);
@@ -193,7 +193,7 @@ function verifyCertificates(certsDir) {
const platform = detectPlatform();
// Core PEM files required for all platforms
const requiredFiles = ['ca-cert.pem', 'ca-key.pem', 'localhost-cert.pem', 'localhost-key.pem'];
// Verify required PEM files exist
for (const file of requiredFiles) {
const filePath = path.join(certsDir, file);
@@ -201,7 +201,7 @@ function verifyCertificates(certsDir) {
throw new Error(`missing certificate file: ${file}`);
}
}
// Check Windows-specific files but don't require them (they're optional fallbacks)
if (platform === 'windows') {
const windowsFiles = ['ca-cert.der', 'localhost.p12', 'localhost-cert.der'];
@@ -222,4 +222,3 @@ module.exports = {
addCAToTruststore,
verifyCertificates
};

View File

@@ -2,18 +2,18 @@ const { execSync } = require('node:child_process');
const os = require('node:os');
function execCommand(command, cwd = process.cwd()) {
return execSync(command, {
cwd,
return execSync(command, {
cwd,
stdio: 'inherit',
timeout: 30000
timeout: 30000
});
}
function execCommandSilent(command, cwd = process.cwd()) {
return execSync(command, {
cwd,
return execSync(command, {
cwd,
stdio: 'pipe',
timeout: 30000
timeout: 30000
});
}
@@ -29,7 +29,7 @@ function detectPlatform() {
function killProcessOnPort(port) {
const platform = detectPlatform();
try {
switch (platform) {
case 'macos':
@@ -57,4 +57,4 @@ module.exports = {
execCommandSilent,
detectPlatform,
killProcessOnPort
};
};

View File

@@ -6,11 +6,11 @@ const https = require('node:https');
const { killProcessOnPort } = require('./helpers/platform');
function createServer(certsDir, port = 8090) {
const serverOptions = {
const serverOptions = {
key: fs.readFileSync(path.join(certsDir, 'localhost-key.pem')),
cert: fs.readFileSync(path.join(certsDir, 'localhost-cert.pem')),
ca: fs.readFileSync(path.join(certsDir, 'ca-cert.pem'))
}
};
const server = https.createServer(serverOptions, (req, res) => {
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
@@ -31,9 +31,9 @@ function createServer(certsDir, port = 8090) {
function shutdownServer(server, cleanup) {
const shutdown = (signal) => {
console.log(`🛑 Received ${signal}, shutting down`);
if (cleanup) cleanup();
if (server) {
server.close(() => process.exit(0));
} else {
@@ -56,11 +56,10 @@ async function startServer() {
console.log(`🌐 Creating server on port ${port}`);
const server = await createServer(certsDir, port);
shutdownServer(server, () => {
console.log('✨ Server cleanup completed');
});
} catch (error) {
console.error('❌ Server startup failed:', error.message);
process.exit(1);
@@ -71,4 +70,4 @@ if (require.main === module) {
startServer();
}
module.exports = { startServer };
module.exports = { startServer };

View File

@@ -13,7 +13,7 @@ const {
*/
async function setup() {
console.log('🔧 Setting up CA certificates for test server');
const certsDir = path.join(__dirname, '..', 'certs');
try {

View File

@@ -37,4 +37,4 @@ test.describe('custom invalid ca cert added to the config and keep default ca ce
skipped: 0
});
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe.serial('custom invalid ca cert added to the config and NO default
skipped: 0
});
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe('custom valid ca cert added to the config and keep default ca cert
skipped: 0
});
});
});
});

View File

@@ -37,4 +37,4 @@ test.describe('custom valid ca cert added to the config and NO default ca certs'
skipped: 0
});
});
});
});