mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
304 lines
12 KiB
TypeScript
304 lines
12 KiB
TypeScript
import path from 'path';
|
|
import fs from 'fs';
|
|
import { test, expect, closeElectronApp } from '../../playwright';
|
|
import {
|
|
createCollection,
|
|
openRequest,
|
|
selectRequestPaneTab,
|
|
waitForReadyPage
|
|
} from '../utils/page';
|
|
import { buildCommonLocators } from '../utils/page/locators';
|
|
|
|
const readSnapshot = (userDataPath: string) => {
|
|
const snapshotPath = path.join(userDataPath, 'ui-state-snapshot.json');
|
|
if (!fs.existsSync(snapshotPath)) return null;
|
|
return JSON.parse(fs.readFileSync(snapshotPath, 'utf-8'));
|
|
};
|
|
|
|
const findSnapshotRequestTab = (snapshot: any, requestName: string) => {
|
|
if (!snapshot || !Array.isArray(snapshot.collections)) {
|
|
return null;
|
|
}
|
|
|
|
for (const collection of snapshot.collections) {
|
|
if (!Array.isArray(collection?.tabs)) continue;
|
|
|
|
const tab = collection.tabs.find((candidate) => (
|
|
candidate?.accessor === 'pathname'
|
|
&& typeof candidate?.pathname === 'string'
|
|
&& candidate.pathname.includes(requestName)
|
|
));
|
|
|
|
if (tab) {
|
|
return tab;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
test.describe('Snapshot: Request Pane Interactivity', () => {
|
|
test('grpc request pane tab interactivity is restored after restart', async ({ launchElectronApp, createTmpDir }) => {
|
|
const userDataPath = await createTmpDir('snap-grpc-interactivity');
|
|
const colPath = await createTmpDir('col');
|
|
|
|
const app = await launchElectronApp({ userDataPath });
|
|
const page = await waitForReadyPage(app);
|
|
|
|
await test.step('Create collection and gRPC request', async () => {
|
|
await createCollection(page, 'TestCol', colPath);
|
|
|
|
const locators = buildCommonLocators(page);
|
|
await locators.sidebar.collection('TestCol').hover();
|
|
await locators.actions.collectionActions('TestCol').click();
|
|
await locators.dropdown.item('New Request').click();
|
|
|
|
await page.getByTestId('grpc-request').click();
|
|
await page.getByTestId('request-name').fill('ReqGrpc');
|
|
await page.getByTestId('new-request-url').locator('.CodeMirror').click();
|
|
await page.keyboard.type('grpc://localhost:50051');
|
|
await locators.modal.button('Create').click();
|
|
|
|
await openRequest(page, 'TestCol', 'ReqGrpc', { persist: true });
|
|
await selectRequestPaneTab(page, 'Metadata');
|
|
});
|
|
|
|
await test.step('Close and restart app', async () => {
|
|
await page.waitForTimeout(2000);
|
|
await closeElectronApp(app);
|
|
});
|
|
|
|
await test.step('Verify gRPC pane tabs remain interactive', async () => {
|
|
const app2 = await launchElectronApp({ userDataPath });
|
|
const page2 = await waitForReadyPage(app2);
|
|
|
|
const locators = buildCommonLocators(page2);
|
|
await expect(locators.tabs.requestTab('ReqGrpc')).toBeVisible({ timeout: 15000 });
|
|
await locators.tabs.requestTab('ReqGrpc').click({ force: true });
|
|
|
|
await selectRequestPaneTab(page2, 'Metadata');
|
|
await selectRequestPaneTab(page2, 'Auth');
|
|
await selectRequestPaneTab(page2, 'Docs');
|
|
await selectRequestPaneTab(page2, 'Message');
|
|
|
|
await closeElectronApp(app2);
|
|
});
|
|
});
|
|
|
|
test('websocket request pane tab interactivity is restored after restart', async ({ launchElectronApp, createTmpDir }) => {
|
|
const userDataPath = await createTmpDir('snap-ws-interactivity');
|
|
const colPath = await createTmpDir('col');
|
|
|
|
const app = await launchElectronApp({ userDataPath });
|
|
const page = await waitForReadyPage(app);
|
|
|
|
await test.step('Create collection and WebSocket request', async () => {
|
|
await createCollection(page, 'TestCol', colPath);
|
|
|
|
const locators = buildCommonLocators(page);
|
|
await locators.sidebar.collection('TestCol').hover();
|
|
await locators.actions.collectionActions('TestCol').click();
|
|
await locators.dropdown.item('New Request').click();
|
|
|
|
await page.getByTestId('ws-request').click();
|
|
await page.getByTestId('request-name').fill('ReqWs');
|
|
await page.getByTestId('new-request-url').locator('.CodeMirror').click();
|
|
await page.keyboard.type('ws://localhost:8080');
|
|
await locators.modal.button('Create').click();
|
|
|
|
await openRequest(page, 'TestCol', 'ReqWs', { persist: true });
|
|
await selectRequestPaneTab(page, 'Headers');
|
|
});
|
|
|
|
await test.step('Close and restart app', async () => {
|
|
await page.waitForTimeout(2000);
|
|
await closeElectronApp(app);
|
|
});
|
|
|
|
await test.step('Verify WebSocket pane tabs remain interactive', async () => {
|
|
const app2 = await launchElectronApp({ userDataPath });
|
|
const page2 = await waitForReadyPage(app2);
|
|
|
|
const locators = buildCommonLocators(page2);
|
|
await expect(locators.tabs.requestTab('ReqWs')).toBeVisible({ timeout: 15000 });
|
|
await locators.tabs.requestTab('ReqWs').click({ force: true });
|
|
|
|
await selectRequestPaneTab(page2, 'Headers');
|
|
await selectRequestPaneTab(page2, 'Auth');
|
|
await selectRequestPaneTab(page2, 'Settings');
|
|
await selectRequestPaneTab(page2, 'Docs');
|
|
await selectRequestPaneTab(page2, 'Message');
|
|
|
|
await closeElectronApp(app2);
|
|
});
|
|
});
|
|
|
|
test('grpc snapshot stores concrete type and body tab key', async ({ launchElectronApp, createTmpDir }) => {
|
|
const userDataPath = await createTmpDir('snap-grpc-snapshot-type-tab-key');
|
|
const colPath = await createTmpDir('col');
|
|
|
|
const app = await launchElectronApp({ userDataPath });
|
|
const page = await app.firstWindow();
|
|
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
await test.step('Create collection and gRPC request', async () => {
|
|
await createCollection(page, 'TestCol', colPath);
|
|
|
|
const locators = buildCommonLocators(page);
|
|
await locators.sidebar.collection('TestCol').hover();
|
|
await locators.actions.collectionActions('TestCol').click();
|
|
await locators.dropdown.item('New Request').click();
|
|
|
|
await page.getByTestId('grpc-request').click();
|
|
await page.getByTestId('request-name').fill('ReqGrpcSnapshot');
|
|
await page.getByTestId('new-request-url').locator('.CodeMirror').click();
|
|
await page.keyboard.type('grpc://localhost:50051');
|
|
await locators.modal.button('Create').click();
|
|
|
|
await openRequest(page, 'TestCol', 'ReqGrpcSnapshot', { persist: true });
|
|
await selectRequestPaneTab(page, 'Message');
|
|
});
|
|
|
|
await test.step('Close app and verify snapshot stores grpc-request/body', async () => {
|
|
await page.waitForTimeout(2000);
|
|
await closeElectronApp(app);
|
|
|
|
const snapshotPath = path.join(userDataPath, 'ui-state-snapshot.json');
|
|
await expect.poll(() => fs.existsSync(snapshotPath)).toBe(true);
|
|
|
|
const snapshot = readSnapshot(userDataPath);
|
|
const tab = findSnapshotRequestTab(snapshot, 'ReqGrpcSnapshot');
|
|
expect(tab).toBeTruthy();
|
|
expect(tab.type).toBe('grpc-request');
|
|
expect(tab.request?.tab).toBe('body');
|
|
});
|
|
|
|
await test.step('Verify restore opens Message tab and avoids 404', async () => {
|
|
const app2 = await launchElectronApp({ userDataPath });
|
|
const page2 = await app2.firstWindow();
|
|
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
const locators = buildCommonLocators(page2);
|
|
await expect(locators.tabs.requestTab('ReqGrpcSnapshot')).toBeVisible({ timeout: 15000 });
|
|
await locators.tabs.requestTab('ReqGrpcSnapshot').click({ force: true });
|
|
|
|
await expect(page2.getByTestId('responsive-tab-body')).toHaveAttribute('aria-selected', 'true');
|
|
await expect(page2.locator('text=404 | Not found')).not.toBeVisible();
|
|
|
|
await closeElectronApp(app2);
|
|
});
|
|
});
|
|
|
|
test('websocket snapshot stores concrete type and body tab key', async ({ launchElectronApp, createTmpDir }) => {
|
|
const userDataPath = await createTmpDir('snap-ws-snapshot-type-tab-key');
|
|
const colPath = await createTmpDir('col');
|
|
|
|
const app = await launchElectronApp({ userDataPath });
|
|
const page = await app.firstWindow();
|
|
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
await test.step('Create collection and WebSocket request', async () => {
|
|
await createCollection(page, 'TestCol', colPath);
|
|
|
|
const locators = buildCommonLocators(page);
|
|
await locators.sidebar.collection('TestCol').hover();
|
|
await locators.actions.collectionActions('TestCol').click();
|
|
await locators.dropdown.item('New Request').click();
|
|
|
|
await page.getByTestId('ws-request').click();
|
|
await page.getByTestId('request-name').fill('ReqWsSnapshot');
|
|
await page.getByTestId('new-request-url').locator('.CodeMirror').click();
|
|
await page.keyboard.type('ws://localhost:8080');
|
|
await locators.modal.button('Create').click();
|
|
|
|
await openRequest(page, 'TestCol', 'ReqWsSnapshot', { persist: true });
|
|
await selectRequestPaneTab(page, 'Message');
|
|
});
|
|
|
|
await test.step('Close app and verify snapshot stores ws-request/body', async () => {
|
|
await page.waitForTimeout(2000);
|
|
await closeElectronApp(app);
|
|
|
|
const snapshotPath = path.join(userDataPath, 'ui-state-snapshot.json');
|
|
await expect.poll(() => fs.existsSync(snapshotPath)).toBe(true);
|
|
|
|
const snapshot = readSnapshot(userDataPath);
|
|
const tab = findSnapshotRequestTab(snapshot, 'ReqWsSnapshot');
|
|
expect(tab).toBeTruthy();
|
|
expect(tab.type).toBe('ws-request');
|
|
expect(tab.request?.tab).toBe('body');
|
|
});
|
|
|
|
await test.step('Verify restore opens Message tab and avoids 404', async () => {
|
|
const app2 = await launchElectronApp({ userDataPath });
|
|
const page2 = await app2.firstWindow();
|
|
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
const locators = buildCommonLocators(page2);
|
|
await expect(locators.tabs.requestTab('ReqWsSnapshot')).toBeVisible({ timeout: 15000 });
|
|
await locators.tabs.requestTab('ReqWsSnapshot').click({ force: true });
|
|
|
|
await expect(page2.getByTestId('responsive-tab-body')).toHaveAttribute('aria-selected', 'true');
|
|
await expect(page2.locator('text=404 | Not found')).not.toBeVisible();
|
|
|
|
await closeElectronApp(app2);
|
|
});
|
|
});
|
|
|
|
test('graphql snapshot stores concrete type and query tab key', async ({ launchElectronApp, createTmpDir }) => {
|
|
const userDataPath = await createTmpDir('snap-graphql-snapshot-type-tab-key');
|
|
const colPath = await createTmpDir('col');
|
|
|
|
const app = await launchElectronApp({ userDataPath });
|
|
const page = await app.firstWindow();
|
|
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
await test.step('Create collection and GraphQL request', async () => {
|
|
await createCollection(page, 'TestCol', colPath);
|
|
|
|
const locators = buildCommonLocators(page);
|
|
await locators.sidebar.collection('TestCol').hover();
|
|
await locators.actions.collectionActions('TestCol').click();
|
|
await locators.dropdown.item('New Request').click();
|
|
|
|
await page.getByTestId('graphql-request').click();
|
|
await page.getByTestId('request-name').fill('ReqGraphSnapshot');
|
|
await page.getByTestId('new-request-url').locator('.CodeMirror').click();
|
|
await page.keyboard.type('https://echo.usebruno.com/graphql');
|
|
await locators.modal.button('Create').click();
|
|
|
|
await openRequest(page, 'TestCol', 'ReqGraphSnapshot', { persist: true });
|
|
await selectRequestPaneTab(page, 'Headers');
|
|
});
|
|
|
|
await test.step('Close app and verify snapshot stores graphql-request/headers', async () => {
|
|
await page.waitForTimeout(2000);
|
|
await closeElectronApp(app);
|
|
|
|
const snapshotPath = path.join(userDataPath, 'ui-state-snapshot.json');
|
|
await expect.poll(() => fs.existsSync(snapshotPath)).toBe(true);
|
|
|
|
const snapshot = readSnapshot(userDataPath);
|
|
const tab = findSnapshotRequestTab(snapshot, 'ReqGraphSnapshot');
|
|
expect(tab).toBeTruthy();
|
|
expect(tab.type).toBe('graphql-request');
|
|
expect(tab.request?.tab).toBe('headers');
|
|
});
|
|
|
|
await test.step('Verify restore opens Headers tab and avoids 404', async () => {
|
|
const app2 = await launchElectronApp({ userDataPath });
|
|
const page2 = await app2.firstWindow();
|
|
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
|
|
|
const locators = buildCommonLocators(page2);
|
|
await expect(locators.tabs.requestTab('ReqGraphSnapshot')).toBeVisible({ timeout: 15000 });
|
|
await locators.tabs.requestTab('ReqGraphSnapshot').click({ force: true });
|
|
|
|
await expect(page2.getByTestId('responsive-tab-headers')).toHaveAttribute('aria-selected', 'true');
|
|
await expect(page2.locator('text=404 | Not found')).not.toBeVisible();
|
|
|
|
await closeElectronApp(app2);
|
|
});
|
|
});
|
|
});
|