Files
bruno/tests/request/description/read-request-description.spec.ts
Sid 0bba66a590 feat: variable descriptions (#8269)
* feat: add description column to various tables and enhance UI interactions
- Introduced a description column in Headers, VarsTable, and other components to allow multi-line descriptions.
- Added toggle buttons to show/hide the description column in relevant tables.
- Updated EditableTable component to support dynamic row addition with customizable labels.
- Enhanced UI for better user experience with consistent button styles and spacing adjustments.

* chore: resize fix handles

* fix: restrict column check for last index

* refactor: remove unwanted style and fix bottom padding of the last child in the table row

* tests: improve testability and fix impacted locators

* tests: fix locators for value fields

* fix: improve newline handling in description prefix

* fix: ts changes

* chore: remove redundant code and fix description roundtrip

* chore: remove redundant check

* tests(bru-lang): tests for description and annotation

* test: improve locators and tests

* tests: descriptions

* chore: re-add description setup

* fix: re-add description cols

* chore: fix the double click reset

* fix: account for hidden sidebar in request pane width calculation

* refactor: ui/ux fixes for data type toggle

* chore: inline common deps into bruno-lang and bruno-schema

* chore: tests

* chore: fix ux for descriptions

* fix: layout for environment vars table

* fix: ensure correct row selection for multipart file upload in tests

* feat: enhance UID assignment for request headers and variables in collections

* chore: simplify

* chore: update pkg

* chore: abstract the e2e utils

* chore: fix exports

* tests: fix locators for datatype vars

* fix: ux issue with secrets in environment table

* tests: update locators for collection headers and vars descriptions

* tests: update locators to use data attributes for datatype selectors

* chore: update default css width for actions column

* chore: remove tooltip for string type warnings

* fix: reduce name widths

* refactor: update annotation serialization to use single-quote delimiters for descriptions

* refactor(tests): simplify description formatting in jsonToEnv tests

* feat: add multiline description escaping and unescaping functions with tests

* refactor: clean up imports and improve multiline text block handling

* refactor: update locators to use new test IDs for environment variable editors

* refactor: streamline header input handling and improve environment variable row access

* refactor: update e2e-test job to support self-hosted runners

* refactor: update E2E test runner configuration to include e2e and macOS environments

---------

Co-authored-by: Pragadesh-45 <temporaryg7904@gmail.com>
2026-07-07 21:43:39 +05:30

151 lines
7.3 KiB
TypeScript

import { test, expect } from '../../../playwright';
import { openRequest, selectRequestPaneTab } from '../../utils/page';
const COLLECTION = 'req-description';
test.describe('Request Description - Read', () => {
test('reads descriptions from request headers in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'request-with-descriptions');
await selectRequestPaneTab(page, 'Headers');
const headersTable = page.getByTestId('request-headers-table');
const rows = headersTable.locator('tbody tr');
// row 0: X-Version — single-line description
const versionDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(versionDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line header desc');
// row 1: X-Multi — multiline description
const multiDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(multiDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Header line one');
await expect(multiDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Header line two');
// row 2: X-Plain — no description (editor is empty)
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
test('reads descriptions from request query params in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'request-with-descriptions');
await selectRequestPaneTab(page, 'Params');
const queryTable = page.getByTestId('query-params-table');
const rows = queryTable.locator('tbody tr');
// row 0: q — single-line description
const qDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(qDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line query desc');
// row 1: page — multiline description
const pageDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(pageDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Multi-line query desc line one');
await expect(pageDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Multi-line query desc line two');
// row 2: plain-query — no description
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
test('reads descriptions from multipart form fields in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'multipart-with-descriptions');
await selectRequestPaneTab(page, 'Body');
const multipartTable = page.getByTestId('multipart-form-table');
const rows = multipartTable.locator('tbody tr');
// row 0: username — single-line description
const usernameDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(usernameDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line field desc');
// row 1: email — multiline description
const emailDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(emailDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Multi-line field desc line one');
await expect(emailDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Multi-line field desc line two');
// row 2: plain-field — no description
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
test('reads descriptions from form-urlencoded fields in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'formurlencoded-with-descriptions');
await selectRequestPaneTab(page, 'Body');
const formTable = page.getByTestId('form-urlencoded-table');
const rows = formTable.locator('tbody tr');
// row 0: username — single-line description
const usernameDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(usernameDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line form desc');
// row 1: password — multiline description
const passwordDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(passwordDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Multi-line form desc line one');
await expect(passwordDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Multi-line form desc line two');
// row 2: plain-field — no description
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
test('reads descriptions from request vars in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'request-with-descriptions');
await selectRequestPaneTab(page, 'Vars');
const varsTable = page.getByTestId('request-vars-req');
const rows = varsTable.locator('tbody tr');
const apiKeyDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(apiKeyDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line var desc');
const baseUrlDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(baseUrlDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Multi-line var desc line one');
await expect(baseUrlDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Multi-line var desc line two');
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
test('reads descriptions from request assertions in a pre-existing .bru file', async ({
pageWithUserData: page
}) => {
test.setTimeout(30_000);
await openRequest(page, COLLECTION, 'request-with-descriptions');
await selectRequestPaneTab(page, 'Assert');
const assertionsTable = page.getByTestId('assertions-table');
const rows = assertionsTable.locator('tbody tr');
const statusDescEditor = rows.nth(0).getByTestId('column-description').locator('.CodeMirror');
await expect(statusDescEditor.locator('.CodeMirror-line').first()).toHaveText('Single-line assert desc');
const bodyDescEditor = rows.nth(1).getByTestId('column-description').locator('.CodeMirror');
await expect(bodyDescEditor.locator('.CodeMirror-line').nth(0)).toHaveText('Multi-line assert line one');
await expect(bodyDescEditor.locator('.CodeMirror-line').nth(1)).toHaveText('Multi-line assert line two');
const plainDescEditor = rows.nth(2).getByTestId('column-description').locator('.CodeMirror');
await expect(plainDescEditor.locator('.CodeMirror-line').first()).toHaveText('');
});
});