mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
fix: enhance error handling and context retrieval for script errors (#7537)
* refactor: enhance error handling and context retrieval for script errors - Updated the error formatter to utilize in-memory script content for error context, improving accuracy when users have unsaved changes. - Introduced a new utility function, `getSourceContextFromContent`, to extract context lines from in-memory scripts. - Enhanced tests to verify that draft script errors display the correct code context, ensuring users see the most relevant information during debugging. - Added new Playwright tests to validate error handling in draft states across pre-request, post-response, and test scripts. * refactor: enhance error context retrieval in error formatter - Updated `getSourceContext` to accept in-memory content, improving context extraction for unsaved changes. - Deprecated `getSourceContextFromContent` in favor of the new parameterized approach. - Adjusted related tests to ensure accurate context handling for draft script errors. * refactor: enhance error context handling for draft scripts * refactor: streamline script error tests and enhance utility functions - Consolidated helper functions for sending requests and waiting for responses into the actions module. - Introduced new utility functions for selecting script sub-tabs and editing CodeMirror editors. - Updated test cases to utilize the new utility functions, improving readability and maintainability. - Enhanced locators for better integration with testing frameworks. * refactor: improve script error context handling and utility functions - Introduced a new utility function to streamline the retrieval of script block start lines for .bru and .yml files. - Enhanced the error formatter to prioritize in-memory draft content when resolving error contexts, improving accuracy for unsaved changes. - Consolidated context extraction logic into a single function to reduce redundancy and improve maintainability. - Updated related tests to ensure accurate context handling for both draft and disk-based scripts. * refactor: add comments to clarify line index calculations in error formatter
This commit is contained in:
120
tests/script-errors/draft-script-errors.spec.ts
Normal file
120
tests/script-errors/draft-script-errors.spec.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { test, expect } from '../../playwright';
|
||||
import { buildScriptErrorLocators, buildCommonLocators } from '../utils/page/locators';
|
||||
import {
|
||||
openRequest,
|
||||
selectRequestPaneTab,
|
||||
selectScriptSubTab,
|
||||
editCodeMirrorEditor,
|
||||
sendAndWaitForErrorCard,
|
||||
sendAndWaitForResponse
|
||||
} from '../utils/page/actions';
|
||||
import { setSandboxMode } from '../utils/page/runner';
|
||||
|
||||
for (const mode of ['safe', 'developer'] as const) {
|
||||
test.describe.serial(`Draft Script Error Context [${mode} mode]`, () => {
|
||||
let scriptErrorLocators: ReturnType<typeof buildScriptErrorLocators>;
|
||||
let commonLocators: ReturnType<typeof buildCommonLocators>;
|
||||
|
||||
test.beforeAll(async ({ pageWithUserData: page }) => {
|
||||
scriptErrorLocators = buildScriptErrorLocators(page);
|
||||
commonLocators = buildCommonLocators(page);
|
||||
|
||||
await setSandboxMode(page, 'script-errors-test', mode);
|
||||
});
|
||||
|
||||
test('1. Draft pre-request error shows draft code in error context', async ({ pageWithUserData: page }) => {
|
||||
await test.step('Open draft-error-test request', async () => {
|
||||
await openRequest(page, 'script-errors-test', 'draft-error-test');
|
||||
});
|
||||
|
||||
await test.step('Navigate to Script > Pre Request tab and edit script', async () => {
|
||||
await selectScriptSubTab(page, 'pre-request');
|
||||
|
||||
await editCodeMirrorEditor(
|
||||
page,
|
||||
'pre-request-script-editor',
|
||||
'const draftOnlyVar = "draft";\ndraftOnlyUndefined();'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('Verify draft indicator is visible', async () => {
|
||||
await expect(commonLocators.tabs.draftIndicator()).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('Send request and wait for error card', async () => {
|
||||
await sendAndWaitForErrorCard(page);
|
||||
});
|
||||
|
||||
await test.step('Verify error card shows draft code, not saved code', async () => {
|
||||
const card = scriptErrorLocators.card();
|
||||
await expect(scriptErrorLocators.title(card)).toContainText('Pre-Request Script Error');
|
||||
await expect(scriptErrorLocators.errorLine(card)).toContainText('draftOnlyUndefined');
|
||||
await expect(scriptErrorLocators.errorLine(card)).not.toContainText('savedVar');
|
||||
});
|
||||
});
|
||||
|
||||
test('2. Draft post-response error shows draft code in error context', async ({ pageWithUserData: page }) => {
|
||||
await test.step('Open draft-postres-test request', async () => {
|
||||
await openRequest(page, 'script-errors-test', 'draft-postres-test');
|
||||
});
|
||||
|
||||
await test.step('Navigate to Script > Post Response tab and edit script', async () => {
|
||||
await selectScriptSubTab(page, 'post-response');
|
||||
|
||||
await editCodeMirrorEditor(
|
||||
page,
|
||||
'post-response-script-editor',
|
||||
'const postDraftVar = "post-draft";\npostDraftUndefined();'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('Verify draft indicator is visible', async () => {
|
||||
await expect(commonLocators.tabs.draftIndicator()).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('Send request and wait for error card', async () => {
|
||||
await sendAndWaitForResponse(page);
|
||||
});
|
||||
|
||||
await test.step('Verify error card shows draft code, not saved code', async () => {
|
||||
const card = scriptErrorLocators.card();
|
||||
await expect(card).toBeVisible();
|
||||
await expect(scriptErrorLocators.title(card)).toContainText('Post-Response Script Error');
|
||||
await expect(scriptErrorLocators.errorLine(card)).toContainText('postDraftUndefined');
|
||||
await expect(scriptErrorLocators.errorLine(card)).not.toContainText('savedData');
|
||||
});
|
||||
});
|
||||
|
||||
test('3. Draft test script error shows draft code in error context', async ({ pageWithUserData: page }) => {
|
||||
await test.step('Open draft-tests-test request', async () => {
|
||||
await openRequest(page, 'script-errors-test', 'draft-tests-test');
|
||||
});
|
||||
|
||||
await test.step('Navigate to Tests tab and edit script', async () => {
|
||||
await selectRequestPaneTab(page, 'Tests');
|
||||
|
||||
await editCodeMirrorEditor(
|
||||
page,
|
||||
'test-script-editor',
|
||||
'const draftTest = "test";\ndraftTestUndefined();'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('Verify draft indicator is visible', async () => {
|
||||
await expect(commonLocators.tabs.draftIndicator()).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('Send request and wait for response', async () => {
|
||||
await sendAndWaitForResponse(page);
|
||||
});
|
||||
|
||||
await test.step('Verify error card shows draft code, not saved code', async () => {
|
||||
const card = scriptErrorLocators.card();
|
||||
await expect(card).toBeVisible();
|
||||
await expect(scriptErrorLocators.title(card)).toContainText('Test Script Error');
|
||||
await expect(scriptErrorLocators.errorLine(card)).toContainText('draftTestUndefined');
|
||||
await expect(scriptErrorLocators.errorLine(card)).not.toContainText('savedTest');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: draft-error-test
|
||||
type: http
|
||||
seq: 9
|
||||
}
|
||||
|
||||
get {
|
||||
url: http://localhost:8081/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
const savedVar = "this works fine";
|
||||
console.log(savedVar);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: draft-postres-test
|
||||
type: http
|
||||
seq: 10
|
||||
}
|
||||
|
||||
get {
|
||||
url: http://localhost:8081/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
const savedData = res.body;
|
||||
console.log(savedData);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: draft-tests-test
|
||||
type: http
|
||||
seq: 11
|
||||
}
|
||||
|
||||
get {
|
||||
url: http://localhost:8081/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
tests {
|
||||
const savedTest = "this works fine";
|
||||
console.log(savedTest);
|
||||
}
|
||||
@@ -1,28 +1,8 @@
|
||||
import { test, expect, Page } from '../../playwright';
|
||||
import { buildScriptErrorLocators, buildCommonLocators } from '../utils/page/locators';
|
||||
import { openRequest, closeAllTabs } from '../utils/page/actions';
|
||||
import { openRequest, closeAllTabs, sendAndWaitForErrorCard, sendAndWaitForResponse } from '../utils/page/actions';
|
||||
import { setSandboxMode, runCollection } from '../utils/page/runner';
|
||||
|
||||
/**
|
||||
* Helper: click send and wait for at least one error card to appear.
|
||||
*/
|
||||
const sendAndWaitForErrorCard = async (page: Page) => {
|
||||
const { request } = buildCommonLocators(page);
|
||||
const scriptErrorLocators = buildScriptErrorLocators(page);
|
||||
await request.sendButton().click();
|
||||
await scriptErrorLocators.card().waitFor({ state: 'visible', timeout: 15000 });
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper: click send and wait for a response status code to appear.
|
||||
* Used for requests that succeed at HTTP level but may have post-response/test errors.
|
||||
*/
|
||||
const sendAndWaitForResponse = async (page: Page) => {
|
||||
const { request, response } = buildCommonLocators(page);
|
||||
await request.sendButton().click();
|
||||
await response.statusCode().waitFor({ state: 'visible', timeout: 15000 });
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper: expand a folder in the sidebar and open a nested request.
|
||||
* Clicking the collection row is idempotent (only expands, never collapses).
|
||||
|
||||
Reference in New Issue
Block a user