Files
bruno/tests/snapshots/environment/shared-collection-workspace-environment.spec.ts
Sid b1f08b5131 fix(snapshot): active workspace restoration from snapshot (#8392)
* feat(workspaces): implement active workspace restoration from snapshot

- Added a new action to restore the active workspace from a snapshot.
- Integrated workspace restoration into IPC events for improved user experience.
- Refactored workspace loading logic to prioritize valid workspaces and handle invalid paths.
- Introduced utility functions for workspace path validation and normalization.
- Added tests to ensure correct functionality of workspace restoration and validation logic.

* feat(snapshot): refactor snapshot serialization and add environment preservation logic

- Moved snapshot serialization logic to a new file for better organization.
- Implemented environment preservation for collections during snapshot serialization.
- Added utility functions to handle collection environment checks and serialization.
- Introduced tests to validate the new serialization behavior and environment preservation.
- Enhanced existing tests to cover edge cases for unmounted collections and environment persistence.

* Add tests for missing and invalid environment files

* feat(snapshot): refactor devTools normalization and add saveToken to IPC handler

* refactor(snapshot): remove saveToken from IPC handler for renderer:snapshot:save

* feat(snapshot): implement collection deduplication logic in SnapshotManager and add corresponding tests

* feat(snapshot): enhance workspace-specific environment handling for shared collections

* feat(snapshot): remove sourceWorkspacePathname from snapshot serialization and related tests

* feat(snapshot): remove sourceWorkspacePathname from SnapshotManager and add tests for shared collection environment restoration

* feat(snapshot): refactor collection deduplication tests and enhance snapshot seeding utility

* feat(snapshot): enhance workspace path normalization and improve snapshot environment tests

---------

Co-authored-by: engineering-bruno <engineering@usebruno.com>
2026-07-04 17:38:41 +05:30

107 lines
4.8 KiB
TypeScript

import path from 'path';
import fs from 'fs';
import { test, expect, closeElectronApp } from '../../../playwright';
import {
createRequest,
createEnvironment,
selectEnvironment,
openRequest,
openWorkspaceFromDialog,
waitForReadyPage,
openCollection
} from '../../utils/page';
const buildWorkspaceYml = (workspaceName: string, collectionPath: string) => [
'opencollection: 1.0.0',
'info:',
` name: ${workspaceName}`,
' type: workspace',
'collections:',
' - name: SharedCol',
` path: ${collectionPath.replace(/\\/g, '/')}`,
'specs: []',
'docs: \'\'',
''
].join('\n');
test.describe('Snapshot: Shared collection across workspaces restores its own environment', () => {
test('two workspaces sharing a collection each restore their own selected environment', async ({
launchElectronApp,
createTmpDir
}) => {
const userDataPath = await createTmpDir('snap-shared-col-env-userdata');
const workspaceAPath = await createTmpDir('snap-shared-col-env-ws-a');
const workspaceBPath = await createTmpDir('snap-shared-col-env-ws-b');
const sharedCollectionPath = await createTmpDir('snap-shared-col-env-collection');
fs.writeFileSync(path.join(sharedCollectionPath, 'bruno.json'), JSON.stringify({ version: '1', name: 'SharedCol', type: 'collection' }, null, 2));
fs.writeFileSync(path.join(workspaceAPath, 'workspace.yml'), buildWorkspaceYml('Workspace A', sharedCollectionPath));
fs.writeFileSync(path.join(workspaceBPath, 'workspace.yml'), buildWorkspaceYml('Workspace B', sharedCollectionPath));
const app = await launchElectronApp({ userDataPath });
const page = await waitForReadyPage(app);
await test.step('Open Workspace A, create request, and select env-a', async () => {
await openWorkspaceFromDialog(app, page, workspaceAPath);
await expect(page.getByTestId('workspace-name')).toHaveText('Workspace A', { timeout: 10000 });
await openCollection(page, 'SharedCol');
await createRequest(page, 'PingA', 'SharedCol', { url: 'https://echo.usebruno.com', method: 'GET' });
await openRequest(page, 'SharedCol', 'PingA', { persist: true });
await createEnvironment(page, 'env-a');
await selectEnvironment(page, 'env-a');
await expect(page.locator('.current-environment')).toContainText('env-a');
});
await test.step('Open Workspace B, select env-b for the same shared collection', async () => {
await openWorkspaceFromDialog(app, page, workspaceBPath);
await expect(page.getByTestId('workspace-name')).toHaveText('Workspace B', { timeout: 10000 });
await openCollection(page, 'SharedCol');
await openRequest(page, 'SharedCol', 'PingA');
await createEnvironment(page, 'env-b');
await selectEnvironment(page, 'env-b');
await expect(page.locator('.current-environment')).toContainText('env-b');
});
await test.step('Switch back to Workspace A and verify env-a is still selected', async () => {
await page.getByTestId('workspace-menu').click();
await page.locator('.workspace-item').filter({ hasText: 'Workspace A' }).click();
await expect(page.getByTestId('workspace-name')).toHaveText('Workspace A', { timeout: 10000 });
await openRequest(page, 'SharedCol', 'PingA');
await expect(page.locator('.current-environment')).toContainText('env-a', { timeout: 10000 });
});
await test.step('Switch to Workspace B again and verify env-b is still selected', async () => {
await page.getByTestId('workspace-menu').click();
await page.locator('.workspace-item').filter({ hasText: 'Workspace B' }).click();
await expect(page.getByTestId('workspace-name')).toHaveText('Workspace B', { timeout: 10000 });
await openRequest(page, 'SharedCol', 'PingA');
await expect(page.locator('.current-environment')).toContainText('env-b', { timeout: 10000 });
});
await test.step('Close and relaunch app: both workspaces still restore their own environment', async () => {
await page.waitForTimeout(2000);
await closeElectronApp(app);
const app2 = await launchElectronApp({ userDataPath });
const page2 = await waitForReadyPage(app2);
await expect(page2.getByTestId('workspace-name')).toHaveText('Workspace B', { timeout: 10000 });
await openRequest(page2, 'SharedCol', 'PingA');
await expect(page2.locator('.current-environment')).toContainText('env-b', { timeout: 10000 });
await page2.getByTestId('workspace-menu').click();
await page2.locator('.workspace-item').filter({ hasText: 'Workspace A' }).click();
await expect(page2.getByTestId('workspace-name')).toHaveText('Workspace A', { timeout: 10000 });
await openRequest(page2, 'SharedCol', 'PingA');
await expect(page2.locator('.current-environment')).toContainText('env-a', { timeout: 10000 });
await closeElectronApp(app2);
});
});
});