mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-01 00:24:08 +00:00
fix: example-request tab collision (#7989)
* fix: prevent response-example tabs from hijacking request sidebar selection * fix: add selectors for examples with index * test: better locator * fix: duplicate name collision * fix: refactor sidebar example handling functions for better clarity and reusability * chore: cr comments
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { test, expect, closeElectronApp, type Page } from '../../playwright';
|
||||
import {
|
||||
createCollection,
|
||||
createExampleFromSidebar,
|
||||
createRequest,
|
||||
openExampleFromSidebar,
|
||||
openRequest
|
||||
} from '../utils/page';
|
||||
import { buildCommonLocators } from '../utils/page/locators';
|
||||
@@ -77,4 +79,117 @@ test.describe('Snapshot: Sidebar-Tab Restoration', () => {
|
||||
await closeElectronApp(app2);
|
||||
});
|
||||
});
|
||||
|
||||
test('when request and example are open, last active request restores as active after restart', async ({ launchElectronApp, createTmpDir }) => {
|
||||
const userDataPath = await createTmpDir('snap-sidebar-request-active-over-example');
|
||||
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 request, create example, then make request last active', async () => {
|
||||
await createCollection(page, 'TestCol', colPath);
|
||||
await createRequest(page, 'ReqAlpha', 'TestCol', { url: 'https://echo.usebruno.com', method: 'GET' });
|
||||
await openRequest(page, 'TestCol', 'ReqAlpha', { persist: true });
|
||||
|
||||
await createExampleFromSidebar(page, 'ReqAlpha', 'Example One');
|
||||
await expect(page.getByTestId('response-example-title')).toHaveText('ReqAlpha / Example One');
|
||||
|
||||
await openRequest(page, 'TestCol', 'ReqAlpha', { persist: true });
|
||||
|
||||
const locators = buildCommonLocators(page);
|
||||
await expect(locators.tabs.activeRequestTab()).toContainText('ReqAlpha');
|
||||
});
|
||||
|
||||
await test.step('Close and restart app', async () => {
|
||||
await page.waitForTimeout(2000);
|
||||
await closeElectronApp(app);
|
||||
});
|
||||
|
||||
await test.step('Verify request restores as active and request click does not focus example', 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.activeRequestTab()).toContainText('ReqAlpha', { timeout: 15000 });
|
||||
|
||||
await openRequest(page2, 'TestCol', 'ReqAlpha', { persist: true });
|
||||
await expect(locators.tabs.requestTab('ReqAlpha')).toHaveCount(1);
|
||||
await expect(page2.getByTestId('response-example-title')).not.toBeVisible();
|
||||
|
||||
await closeElectronApp(app2);
|
||||
});
|
||||
});
|
||||
|
||||
test('when last active tab is an example, it restores as active after restart', async ({ launchElectronApp, createTmpDir }) => {
|
||||
const userDataPath = await createTmpDir('snap-sidebar-example-active-restore');
|
||||
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 request and example, then make example active', async () => {
|
||||
await createCollection(page, 'TestCol', colPath);
|
||||
await createRequest(page, 'ReqAlpha', 'TestCol', { url: 'https://echo.usebruno.com', method: 'GET' });
|
||||
await openRequest(page, 'TestCol', 'ReqAlpha', { persist: true });
|
||||
|
||||
await createExampleFromSidebar(page, 'ReqAlpha', 'Example One');
|
||||
await openExampleFromSidebar(page, 'ReqAlpha', 'Example One');
|
||||
await expect(page.getByTestId('response-example-title')).toHaveText('ReqAlpha / Example One');
|
||||
});
|
||||
|
||||
await test.step('Close and restart app', async () => {
|
||||
await page.waitForTimeout(2000);
|
||||
await closeElectronApp(app);
|
||||
});
|
||||
|
||||
await test.step('Verify example restores as active', async () => {
|
||||
const app2 = await launchElectronApp({ userDataPath });
|
||||
const page2 = await app2.firstWindow();
|
||||
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page2.getByTestId('response-example-title')).toHaveText('ReqAlpha / Example One', { timeout: 15000 });
|
||||
|
||||
await closeElectronApp(app2);
|
||||
});
|
||||
});
|
||||
|
||||
test('when duplicate example names exist, snapshot restores the same active example by index', async ({ launchElectronApp, createTmpDir }) => {
|
||||
const userDataPath = await createTmpDir('snap-sidebar-duplicate-example-restore');
|
||||
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 request and two examples with duplicate names, then activate second', async () => {
|
||||
await createCollection(page, 'TestCol', colPath);
|
||||
await createRequest(page, 'ReqAlpha', 'TestCol', { url: 'https://echo.usebruno.com', method: 'GET' });
|
||||
await openRequest(page, 'TestCol', 'ReqAlpha', { persist: true });
|
||||
|
||||
await createExampleFromSidebar(page, 'ReqAlpha', 'DupExample', 'first-desc');
|
||||
await createExampleFromSidebar(page, 'ReqAlpha', 'DupExample', 'second-desc');
|
||||
await openExampleFromSidebar(page, 'ReqAlpha', 'DupExample', 1);
|
||||
await expect(page.getByTestId('response-example-description')).toHaveText('second-desc');
|
||||
});
|
||||
|
||||
await test.step('Close and restart app', async () => {
|
||||
await page.waitForTimeout(2000);
|
||||
await closeElectronApp(app);
|
||||
});
|
||||
|
||||
await test.step('Verify second duplicate example restores as active', async () => {
|
||||
const app2 = await launchElectronApp({ userDataPath });
|
||||
const page2 = await app2.firstWindow();
|
||||
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page2.getByTestId('response-example-title')).toHaveText('ReqAlpha / DupExample', { timeout: 15000 });
|
||||
await expect(page2.getByTestId('response-example-description')).toHaveText('second-desc');
|
||||
|
||||
await closeElectronApp(app2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1198,6 +1198,41 @@ const sendAndWaitForResponse = async (page: Page) => {
|
||||
});
|
||||
};
|
||||
|
||||
const createExampleFromSidebar = async (page: Page, requestName: string, exampleName: string, description: string = '') => {
|
||||
const requestRow = page.locator('.collection-item-name').filter({ hasText: requestName }).first();
|
||||
|
||||
await requestRow.hover();
|
||||
await requestRow.locator('..').locator('.menu-icon').click({ force: true });
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Example' }).click();
|
||||
|
||||
const exampleInput = page.getByTestId('create-example-name-input');
|
||||
await expect(exampleInput).toBeVisible();
|
||||
await exampleInput.clear();
|
||||
await exampleInput.fill(exampleName);
|
||||
const descriptionInput = page.getByTestId('create-example-description-input');
|
||||
await descriptionInput.clear();
|
||||
await descriptionInput.fill(description);
|
||||
await page.getByRole('button', { name: 'Create Example' }).click();
|
||||
await expect(page.locator('text=Create Response Example')).not.toBeAttached();
|
||||
};
|
||||
|
||||
const openExampleFromSidebar = async (page: Page, requestName: string, exampleName: string, index: number = 0) => {
|
||||
const requestRow = page.locator('.collection-item-name').filter({ hasText: requestName }).first();
|
||||
const requestBranch = requestRow.locator('..');
|
||||
const exampleRow = requestBranch
|
||||
.locator('.collection-item-name')
|
||||
.filter({ has: page.locator('.example-icon') })
|
||||
.getByText(exampleName, { exact: true })
|
||||
.nth(index);
|
||||
|
||||
if (!(await exampleRow.isVisible())) {
|
||||
await requestRow.getByTestId('request-item-chevron').click();
|
||||
}
|
||||
|
||||
await expect(exampleRow).toBeVisible();
|
||||
await exampleRow.click();
|
||||
};
|
||||
|
||||
export {
|
||||
closeAllCollections,
|
||||
openCollection,
|
||||
@@ -1243,7 +1278,9 @@ export {
|
||||
addPostResponseScript,
|
||||
addTestScript,
|
||||
sendAndWaitForErrorCard,
|
||||
sendAndWaitForResponse
|
||||
sendAndWaitForResponse,
|
||||
createExampleFromSidebar,
|
||||
openExampleFromSidebar
|
||||
};
|
||||
|
||||
export type { SandboxMode, EnvironmentType, EnvironmentVariable, ImportCollectionOptions, CreateRequestOptions, CreateUntitledRequestOptions, CreateTransientRequestOptions, AssertionInput };
|
||||
|
||||
Reference in New Issue
Block a user