mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-07 14:08:38 +00:00
* feat: enhance ScriptError with source context, code snippets, and navigation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: remove auto-commenting of untranslated pm commands during import Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: update CodeSnippet styles to use theme colors for error and warning highlights * fix: remove unused SCRIPT_TYPES import from network IPC module * refactor: remove unused functions and clean up source-context utility - Removed `getUnifiedScriptContext`, `getWarningSourceGroups`, and related helper functions from `source-context.js` to streamline the utility. - Updated tests in `source-context.spec.js` to reflect the removal of unused functions, ensuring only relevant tests for `findLineInSource` and `getScriptContext` remain. * refactor: simplify ScriptError component and update styles * refactor: streamline tab management in Script components * refactor: enhance tab management in ScriptError and add testsMetadata handling in prepare-request * refactor: improve error source identification in ScriptError component - Enhanced the logic for determining error source types by introducing separate checks for folder and collection files. - Updated the handling of folder file names to ensure accurate UID retrieval and labeling. - Streamlined the overall structure of the getErrorSourceInfo function for better readability and maintainability. * refactor: improve ScriptError component and enhance styling - Simplified the conditions for displaying the ScriptError component in ResponsePane. - Updated navigation logic in ScriptErrorCard to ensure proper handling of source information. - Adjusted styles in StyledWrapper to allow for visible overflow. - Enhanced ScriptErrorIcon to accept additional class names for better styling flexibility. - Minor layout adjustments in RunnerResults ResponsePane for improved UI consistency. * refactor: simplify test description for untranslated pm commands and consolidate error formatter imports * fixes * refactor: update focusedTab logic in Script components to use collection and folder UIDthe respective collection and folder UID instead of the activeTabUid. * feat: add buildErrorContext utility for enhanced error handling in network IPC - Introduced a new utility function `buildErrorContext` to construct detailed error context from script errors. - This function parses error locations, adjusts line numbers, and retrieves relevant source context, improving error reporting. - Removed the previous inline error handling logic from the network IPC module to streamline the codebase. * feat: added playwright test cases to test scriptError behavior * refactor: enhance ScriptError component and improve error handling - Updated labels for error source types in ScriptError to be more concise (e.g., "Request Script" to "Request"). - Improved navigation logic in ScriptErrorCard to ensure proper handling of navigable file paths. - Enhanced styling in StyledWrapper for better visual consistency and user experience. - Added tests to verify fallback behavior for missing error types and non-navigable file paths. - Refined utility functions for better context extraction from script errors. * refactor: normalize file paths for cross-platform compatibility in ScriptError component * refactor: improve file path handling in ScriptError component * refactor: enhance buildErrorContext for improved error handling * docs: add detailed comments to build-error-context for better understanding of error handling * refactor: enhance error block line detection in error formatter - Updated `findScriptBlockEndLine` and `findYmlScriptBlockEndLine` functions to return null for empty or missing blocks, improving accuracy in line detection. - Added comprehensive tests for both functions to ensure correct behavior across various scenarios, including handling of non-.bru and non-.yml files. * refactor: improve error handling and testing in ScriptError and buildErrorContext - Updated ScriptError component to streamline tab management by replacing focusTab with addTab for better request handling. - Enhanced buildErrorContext to return null for empty or missing script blocks in .bru and .yml files, ensuring accurate error reporting. - Added tests to validate behavior for empty script blocks and improved error context extraction in various scenarios. * test: add new tests for script error navigation and handling - Implemented tests for post-response file-path navigation to the Script tab and verification of active sub-tabs. - Added keyboard navigation tests to trigger file-path navigation using the Enter key. - Included a test for multiple error cards to ensure closing one does not affect others. - Enhanced runner tests to verify navigation to the Tests tab from script error results. * refactor: enhance CodeSnippet line rendering and remove unused source-context utilities * refactor: update locators in script-errors tests for improved readability and maintainability * test: enhance script-errors tests to verify error line content * review fixes * refactor: update RunnerResults component and enhance locators for improved testability * refactor: remove buildErrorContext and replace with formatErrorWithContextV2 - Deleted the buildErrorContext function and its associated tests. - Updated network IPC to utilize formatErrorWithContextV2 for improved error context handling. - Enhanced error reporting by ensuring structured error context is returned for desktop UI. * refactor: enhance tab components with data-testid attributes for improved testability - Added data-testid attributes to tab elements in CollectionSettings and FolderSettings components for better integration with testing frameworks. - Updated Tabs and ResponsiveTabs components to include data-testid attributes for tab triggers, enhancing the ability to select and verify tabs in tests. - Modified script-errors tests to utilize new locators for improved readability and maintainability. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
141 lines
5.9 KiB
JavaScript
141 lines
5.9 KiB
JavaScript
import '@testing-library/jest-dom';
|
|
import React from 'react';
|
|
import { render, screen } from '@testing-library/react';
|
|
import { ThemeProvider } from 'styled-components';
|
|
import CodeSnippet from './index';
|
|
|
|
const theme = {
|
|
font: { size: { xs: '0.75rem' } },
|
|
background: { elevated: '#f5f5f5' },
|
|
border: { border2: '#e0e0e0', radius: { base: '4px' } },
|
|
colors: { text: { danger: '#ef4444', warning: '#f59e0b', muted: '#999' } }
|
|
};
|
|
|
|
const renderWithTheme = (component) => {
|
|
return render(
|
|
<ThemeProvider theme={theme}>
|
|
{component}
|
|
</ThemeProvider>
|
|
);
|
|
};
|
|
|
|
const sampleLines = [
|
|
{ lineNumber: 3, content: 'const a = 1;', isHighlighted: false },
|
|
{ lineNumber: 4, content: 'undefinedVar.foo();', isHighlighted: true },
|
|
{ lineNumber: 5, content: 'const b = 2;', isHighlighted: false }
|
|
];
|
|
|
|
describe('CodeSnippet', () => {
|
|
it('should render nothing when lines is empty', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet lines={[]} />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('should render nothing when lines is null', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet lines={null} />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('should render all lines with line numbers', () => {
|
|
renderWithTheme(<CodeSnippet lines={sampleLines} />);
|
|
expect(screen.getByText('3')).toBeInTheDocument();
|
|
expect(screen.getByText('4')).toBeInTheDocument();
|
|
expect(screen.getByText('5')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should apply error highlight class by default', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet lines={sampleLines} variant="error" />);
|
|
const highlightedLine = container.querySelector('.highlighted-error');
|
|
expect(highlightedLine).toBeInTheDocument();
|
|
});
|
|
|
|
it('should apply warning highlight class when variant is warning', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet lines={sampleLines} variant="warning" />);
|
|
const highlightedLine = container.querySelector('.highlighted-warning');
|
|
expect(highlightedLine).toBeInTheDocument();
|
|
expect(container.querySelector('.highlighted-error')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should show > prefix on highlighted line for accessibility', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet lines={sampleLines} />);
|
|
const codeLineContents = container.querySelectorAll('.code-line-content');
|
|
// The highlighted line (index 1) should start with "> "
|
|
expect(codeLineContents[1].textContent).toContain('> ');
|
|
// Non-highlighted lines should not have ">"
|
|
expect(codeLineContents[0].textContent).not.toContain('>');
|
|
});
|
|
|
|
it('should also support isError property for backward compatibility', () => {
|
|
const linesWithIsError = [
|
|
{ lineNumber: 1, content: 'line 1', isError: false },
|
|
{ lineNumber: 2, content: 'error line', isError: true },
|
|
{ lineNumber: 3, content: 'line 3', isError: false }
|
|
];
|
|
const { container } = renderWithTheme(<CodeSnippet lines={linesWithIsError} />);
|
|
expect(container.querySelector('.highlighted-error')).toBeInTheDocument();
|
|
});
|
|
|
|
describe('hunks prop', () => {
|
|
const sampleHunks = [
|
|
{
|
|
hasSeparatorBefore: false,
|
|
lines: [
|
|
{ lineNumber: 1, content: 'const a = true;', isHighlighted: false },
|
|
{ lineNumber: 2, content: 'pm.vault.get();', isHighlighted: true },
|
|
{ lineNumber: 3, content: 'const b = false;', isHighlighted: false }
|
|
]
|
|
},
|
|
{
|
|
hasSeparatorBefore: true,
|
|
lines: [
|
|
{ lineNumber: 10, content: 'const x = null;', isHighlighted: false },
|
|
{ lineNumber: 11, content: 'pm.cookies.jar();', isHighlighted: true },
|
|
{ lineNumber: 12, content: 'const y = undefined;', isHighlighted: false }
|
|
]
|
|
}
|
|
];
|
|
|
|
it('should render all lines from all hunks', () => {
|
|
renderWithTheme(<CodeSnippet hunks={sampleHunks} variant="warning" />);
|
|
// line numbers
|
|
expect(screen.getByText('1')).toBeInTheDocument();
|
|
expect(screen.getByText('2')).toBeInTheDocument();
|
|
expect(screen.getByText('10')).toBeInTheDocument();
|
|
expect(screen.getByText('11')).toBeInTheDocument();
|
|
// content
|
|
expect(screen.getByText(/const a = true;/)).toBeInTheDocument();
|
|
expect(screen.getByText(/pm\.vault\.get\(\);/)).toBeInTheDocument();
|
|
expect(screen.getByText(/const x = null;/)).toBeInTheDocument();
|
|
expect(screen.getByText(/pm\.cookies\.jar\(\);/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('should render separator between hunks when hasSeparatorBefore is true', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet hunks={sampleHunks} variant="warning" />);
|
|
const separators = container.querySelectorAll('.code-line-separator');
|
|
expect(separators).toHaveLength(1);
|
|
// separator should appear between the two hunks, not before the first
|
|
const allRows = container.querySelectorAll('.code-line, .code-line-separator');
|
|
const separatorIndex = Array.from(allRows).findIndex((el) => el.classList.contains('code-line-separator'));
|
|
// first hunk has 3 lines (indices 0-2), separator should be at index 3
|
|
expect(separatorIndex).toBe(3);
|
|
});
|
|
|
|
it('should render the ellipsis character in separator', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet hunks={sampleHunks} variant="warning" />);
|
|
const separator = container.querySelector('.separator-content');
|
|
expect(separator.textContent).toBe('\u22EE');
|
|
});
|
|
|
|
it('should apply warning highlights within hunks', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet hunks={sampleHunks} variant="warning" />);
|
|
const highlighted = container.querySelectorAll('.highlighted-warning');
|
|
expect(highlighted).toHaveLength(2);
|
|
});
|
|
|
|
it('should render nothing when hunks is empty array', () => {
|
|
const { container } = renderWithTheme(<CodeSnippet hunks={[]} />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
});
|
|
});
|