mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-22 04:05:42 +00:00
fix(timeline): scope scripted requests to their own request (#8210)
* fix(timeline): scope scripted requests to their own request * fix: oauth playwright test
This commit is contained in:
@@ -36,7 +36,7 @@ const BodyBlock = ({ collection, data, dataBuffer, headers, error, item, type })
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="tl-empty">No Body found</div>
|
||||
<div className="tl-empty">No Body</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -31,7 +31,7 @@ const Headers = ({ headers }) => {
|
||||
</button>
|
||||
{isOpen && (
|
||||
count === 0
|
||||
? <div className="tl-empty">No Headers found</div>
|
||||
? <div className="tl-empty">No Headers</div>
|
||||
: (
|
||||
<table className="tl-headers-table">
|
||||
<tbody>
|
||||
|
||||
@@ -21,6 +21,7 @@ const Status = ({ statusCode }) => {
|
||||
return (
|
||||
<span
|
||||
className="timeline-status"
|
||||
data-testid="timeline-status"
|
||||
style={{
|
||||
color,
|
||||
background,
|
||||
|
||||
@@ -137,7 +137,7 @@ const TimelineItem = ({
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className={`tl-row-wrap ${isOauth2 ? 'tl-row-wrap--oauth2' : ''}`}>
|
||||
<div className={`tl-row-wrap ${isOauth2 ? 'tl-row-wrap--oauth2' : ''}`} data-testid="timeline-entry">
|
||||
<div
|
||||
className={`tl-row ${isExpanded ? 'is-expanded' : ''}`}
|
||||
role="button"
|
||||
@@ -155,9 +155,9 @@ const TimelineItem = ({
|
||||
<div className="tl-col-method">
|
||||
<Method method={method} />
|
||||
</div>
|
||||
<div className="tl-col-url" title={url}>{url}</div>
|
||||
<div className="tl-col-url" title={url} data-testid="timeline-url">{url}</div>
|
||||
<div className="tl-col-badge">
|
||||
<span className={badge.badgeClass}>{badge.badgeLabel}</span>
|
||||
<span className={badge.badgeClass} data-testid={`timeline-badge-${badge.kind}`}>{badge.badgeLabel}</span>
|
||||
</div>
|
||||
{!hideTimestamp && (
|
||||
<div className="tl-col-time">
|
||||
@@ -167,7 +167,7 @@ const TimelineItem = ({
|
||||
</div>
|
||||
|
||||
{isExpanded && (
|
||||
<div className="tl-detail">
|
||||
<div className="tl-detail" data-testid="timeline-detail">
|
||||
<div className="tl-header">
|
||||
<div className="tl-header-url" title={`${method || ''} ${url}`}>
|
||||
<span className="tl-header-url-method">{method}</span>
|
||||
@@ -179,8 +179,9 @@ const TimelineItem = ({
|
||||
href="#"
|
||||
title={canNavigate ? `Open ${sourceFile}` : sourceFile}
|
||||
onClick={canNavigate ? handleNavigate : (ev) => ev.preventDefault()}
|
||||
data-testid="timeline-source-link"
|
||||
>
|
||||
<span className="tl-header-src-file">{sourceFile}</span>
|
||||
<span className="tl-header-src-file" data-testid="timeline-source-file">{sourceFile}</span>
|
||||
<span className="tl-header-src-icon">↗</span>
|
||||
</a>
|
||||
)}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Keys must match getEntryKind() in buildEntries.js.
|
||||
// `kind` is a stable identifier used for data-testids (e.g. timeline-badge-pre).
|
||||
export const ENTRY_KINDS = {
|
||||
main: { chipLabel: 'Main', badgeLabel: 'main', badgeClass: 'tl-badge tl-badge--main' },
|
||||
oauth: { chipLabel: 'OAuth', badgeLabel: 'oauth2.0', badgeClass: 'tl-badge tl-badge--oauth2' },
|
||||
pre: { chipLabel: 'Pre-Request', badgeLabel: 'sendRequest', badgeClass: 'tl-badge tl-badge--scripted' },
|
||||
post: { chipLabel: 'Post-Response', badgeLabel: 'runRequest', badgeClass: 'tl-badge tl-badge--run-request' }
|
||||
main: { kind: 'main', chipLabel: 'Request', badgeLabel: 'request', badgeClass: 'tl-badge tl-badge--main' },
|
||||
oauth: { kind: 'oauth', chipLabel: 'OAuth', badgeLabel: 'oauth2.0', badgeClass: 'tl-badge tl-badge--oauth2' },
|
||||
pre: { kind: 'pre', chipLabel: 'Pre-Request', badgeLabel: 'sendRequest', badgeClass: 'tl-badge tl-badge--scripted' },
|
||||
post: { kind: 'post', chipLabel: 'Post-Response', badgeLabel: 'runRequest', badgeClass: 'tl-badge tl-badge--run-request' }
|
||||
};
|
||||
|
||||
export const FILTER_CHIPS = [
|
||||
|
||||
@@ -78,22 +78,23 @@ const Timeline = ({ collection, item }) => {
|
||||
ref={wrapperRef}
|
||||
>
|
||||
{showFilterBar && (
|
||||
<div className="timeline-filter-bar">
|
||||
<div className="timeline-filter-bar" data-testid="timeline-filter-bar">
|
||||
{visibleChips.map((chip) => (
|
||||
<button
|
||||
key={chip.id}
|
||||
type="button"
|
||||
className={`timeline-chip ${activeFilter === chip.id ? 'is-active' : ''}`}
|
||||
onClick={() => setActiveFilter(chip.id)}
|
||||
data-testid={`timeline-chip-${chip.id}`}
|
||||
>
|
||||
{chip.label}
|
||||
<span className="timeline-chip-count">{counts[chip.id] ?? 0}</span>
|
||||
<span className="timeline-chip-count" data-testid="timeline-chip-count">{counts[chip.id] ?? 0}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="timeline-container">
|
||||
<div className="timeline-container" data-testid="timeline-container">
|
||||
{entries.map((entry, index) => {
|
||||
const kind = getEntryKind(entry);
|
||||
if (activeFilter !== 'all' && activeFilter !== kind) return null;
|
||||
|
||||
@@ -274,8 +274,10 @@ const mergeScripts = (collection, request, requestTreePath, scriptFlow) => {
|
||||
displayPath: config.collectionFile
|
||||
};
|
||||
|
||||
const requestSegmentSource = request?.pathname && collection?.pathname
|
||||
? { displayPath: posixifyPath(path.relative(collection.pathname, request.pathname)) }
|
||||
const requestItem = requestTreePath?.[requestTreePath.length - 1];
|
||||
const requestPathname = request?.pathname || requestItem?.pathname;
|
||||
const requestSegmentSource = requestPathname && collection?.pathname
|
||||
? { displayPath: posixifyPath(path.relative(collection.pathname, requestPathname)) }
|
||||
: null;
|
||||
|
||||
const withContent = (source, script) =>
|
||||
|
||||
@@ -55,32 +55,31 @@ test.describe('Timeline — nested bru.runRequest bubbles inner scripted entries
|
||||
await test.step('Outer Timeline shows three rows: main + runRequest + bubbled inner sendRequest', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
// Without the fix: 2 (main + runRequest); inner sendRequest is dropped.
|
||||
await expect(rows).toHaveCount(3);
|
||||
|
||||
// Badge mix guards against an accidental wrong-3-rows pass.
|
||||
await expect(rows.locator('.tl-badge--main')).toHaveCount(1);
|
||||
await expect(rows.locator('.tl-badge--run-request')).toHaveCount(1);
|
||||
await expect(rows.locator('.tl-badge--scripted')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-main')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-post')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-pre')).toHaveCount(1);
|
||||
});
|
||||
|
||||
await test.step('Bubbled sendRequest row targets the inner-script URL (proving it came from inner)', async () => {
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const scriptedRow = rows.filter({ has: page.locator('.tl-badge--scripted') });
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
const scriptedRow = rows.filter({ has: page.getByTestId('timeline-badge-pre') });
|
||||
await expect(scriptedRow).toHaveCount(1);
|
||||
await expect(scriptedRow.locator('.tl-col-url')).toContainText('/headers');
|
||||
await expect(scriptedRow.getByTestId('timeline-url')).toContainText('/headers');
|
||||
});
|
||||
|
||||
await test.step('Filter chips count the bubbled entry under Pre-Request', async () => {
|
||||
const chips = page.locator('.timeline-filter-bar .timeline-chip');
|
||||
const countFor = (label: string) =>
|
||||
chips.filter({ hasText: label }).locator('.timeline-chip-count').first();
|
||||
const countFor = (id: string) =>
|
||||
page.getByTestId(`timeline-chip-${id}`).getByTestId('timeline-chip-count');
|
||||
|
||||
await expect(countFor('All')).toHaveText('3');
|
||||
await expect(countFor('Main')).toHaveText('1');
|
||||
await expect(countFor('all')).toHaveText('3');
|
||||
await expect(countFor('main')).toHaveText('1');
|
||||
// runRequest + bubbled sendRequest both ran during outer's pre-request.
|
||||
await expect(countFor('Pre-Request')).toHaveText('2');
|
||||
await expect(countFor('pre')).toHaveText('2');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -119,13 +118,13 @@ test.describe('Timeline — nested bru.runRequest bubbles inner scripted entries
|
||||
await test.step('Outer Timeline shows the bubbled post-response sendRequest row', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(rows).toHaveCount(3);
|
||||
|
||||
// URL match confirms the scripted row is the post-response one.
|
||||
const scriptedRow = rows.filter({ has: page.locator('.tl-badge--scripted') });
|
||||
const scriptedRow = rows.filter({ has: page.getByTestId('timeline-badge-pre') });
|
||||
await expect(scriptedRow).toHaveCount(1);
|
||||
await expect(scriptedRow.locator('.tl-col-url')).toContainText('/query');
|
||||
await expect(scriptedRow.getByTestId('timeline-url')).toContainText('/query');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -47,13 +47,13 @@ test.describe('Timeline — runRequest network-error row shows URL and error cod
|
||||
await test.step('Outer Timeline has the runRequest row with inner URL (URL fallback)', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(rows).toHaveCount(2); // main + runRequest
|
||||
|
||||
// Without the URL fallback this column would be empty.
|
||||
const runRequestRow = rows.filter({ has: page.locator('.tl-badge--run-request') });
|
||||
const runRequestRow = rows.filter({ has: page.getByTestId('timeline-badge-post') });
|
||||
await expect(runRequestRow).toHaveCount(1);
|
||||
await expect(runRequestRow.locator('.tl-col-url')).toContainText('localhost:9999');
|
||||
await expect(runRequestRow.getByTestId('timeline-url')).toContainText('localhost:9999');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -42,13 +42,13 @@ test.describe('Timeline — bru.runRequest skips unsupported item types', () =>
|
||||
await test.step('Timeline has main + two Skipped runRequest rows', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(rows).toHaveCount(3);
|
||||
|
||||
const skippedRows = rows.filter({ has: page.locator('.tl-badge--run-request') });
|
||||
const skippedRows = rows.filter({ has: page.getByTestId('timeline-badge-post') });
|
||||
await expect(skippedRows).toHaveCount(2);
|
||||
await expect(skippedRows.nth(0).locator('.timeline-status')).toContainText('Skipped');
|
||||
await expect(skippedRows.nth(1).locator('.timeline-status')).toContainText('Skipped');
|
||||
await expect(skippedRows.nth(0).getByTestId('timeline-status')).toContainText('Skipped');
|
||||
await expect(skippedRows.nth(1).getByTestId('timeline-status')).toContainText('Skipped');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import {
|
||||
closeAllCollections,
|
||||
createCollection,
|
||||
createFolder,
|
||||
createRequest,
|
||||
expandFolder,
|
||||
openRequest,
|
||||
addCollectionScript,
|
||||
addFolderScript,
|
||||
addPreRequestScript,
|
||||
saveRequest,
|
||||
sendRequest,
|
||||
selectResponsePaneTab
|
||||
} from '../../utils/page/actions';
|
||||
|
||||
test.describe('Timeline — scoped request attribution', () => {
|
||||
test.afterEach(async ({ page }) => {
|
||||
await closeAllCollections(page);
|
||||
});
|
||||
|
||||
test('request-level sendRequest is attributed to the request, not the collection script', async ({
|
||||
page,
|
||||
createTmpDir
|
||||
}) => {
|
||||
const collectionName = 'timeline-scope-collection';
|
||||
const requestName = 'scoped-driver';
|
||||
const url = 'http://localhost:8081/ping';
|
||||
|
||||
await test.step('Create collection with a (non-empty) collection-level pre-request script', async () => {
|
||||
await createCollection(page, collectionName, await createTmpDir(collectionName), 'yml');
|
||||
// Non-empty collection script => stamps the collection scope before the request runs.
|
||||
await addCollectionScript(page, collectionName, 'pre-request', `bru.setVar('collectionRan', true);`);
|
||||
});
|
||||
|
||||
await test.step('Create a request whose pre-request script issues a sendRequest', async () => {
|
||||
await createRequest(page, requestName, collectionName, { url });
|
||||
await openRequest(page, collectionName, requestName);
|
||||
await addPreRequestScript(page, `await bru.sendRequest({ url: "${url}", method: "GET" });`);
|
||||
await saveRequest(page);
|
||||
});
|
||||
|
||||
await test.step('Send the request', async () => {
|
||||
await sendRequest(page, 200);
|
||||
});
|
||||
|
||||
const scriptedRow = page
|
||||
.getByTestId('timeline-entry')
|
||||
.filter({ has: page.getByTestId('timeline-badge-pre') });
|
||||
|
||||
await test.step('Open Timeline and expand the scripted (sendRequest) row', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
await expect(scriptedRow).toHaveCount(1);
|
||||
await scriptedRow.getByTestId('timeline-item-header').click();
|
||||
});
|
||||
|
||||
await test.step('Source file points to the request, not the collection', async () => {
|
||||
const sourceFile = scriptedRow.getByTestId('timeline-source-file');
|
||||
await expect(sourceFile).toBeVisible();
|
||||
await expect(sourceFile).toHaveText('scoped-driver.yml');
|
||||
await expect(sourceFile).not.toContainText('opencollection.yml');
|
||||
});
|
||||
|
||||
await test.step('Clicking the source link opens the request Script tab', async () => {
|
||||
await scriptedRow.getByTestId('timeline-source-link').click();
|
||||
await expect(page.locator('.request-tab.active')).toContainText(requestName);
|
||||
await expect(page.getByTestId('responsive-tab-script')).toHaveClass(/active/);
|
||||
});
|
||||
});
|
||||
|
||||
test('request-level sendRequest is attributed to the request, not the parent folder script', async ({
|
||||
page,
|
||||
createTmpDir
|
||||
}) => {
|
||||
const collectionName = 'timeline-scope-folder';
|
||||
const folderName = 'auth';
|
||||
const requestName = 'folder-driver';
|
||||
const url = 'http://localhost:8081/ping';
|
||||
|
||||
await test.step('Create a folder with a (non-empty) folder-level pre-request script', async () => {
|
||||
await createCollection(page, collectionName, await createTmpDir(collectionName), 'yml');
|
||||
await createFolder(page, folderName, collectionName);
|
||||
await expandFolder(page, folderName);
|
||||
// Folder script runs after the collection and overwrites the scope — used to
|
||||
// be what a nested request's sendRequest inherited.
|
||||
await addFolderScript(page, folderName, 'pre-request', `bru.setVar('folderRan', true);`);
|
||||
});
|
||||
|
||||
await test.step('Create a request inside the folder whose pre-request script issues a sendRequest', async () => {
|
||||
await createRequest(page, requestName, folderName, { url, inFolder: true });
|
||||
await page.locator('.collection-item-name').filter({ hasText: requestName }).first().click();
|
||||
await addPreRequestScript(page, `await bru.sendRequest({ url: "${url}", method: "GET" });`);
|
||||
await saveRequest(page);
|
||||
});
|
||||
|
||||
await test.step('Send the request', async () => {
|
||||
await sendRequest(page, 200);
|
||||
});
|
||||
|
||||
const scriptedRow = page
|
||||
.getByTestId('timeline-entry')
|
||||
.filter({ has: page.getByTestId('timeline-badge-pre') });
|
||||
|
||||
await test.step('Open Timeline and expand the scripted (sendRequest) row', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
await expect(scriptedRow).toHaveCount(1);
|
||||
await scriptedRow.getByTestId('timeline-item-header').click();
|
||||
});
|
||||
|
||||
await test.step('Source file points to the request file, not the folder script', async () => {
|
||||
const sourceFile = scriptedRow.getByTestId('timeline-source-file');
|
||||
await expect(sourceFile).toBeVisible();
|
||||
await expect(sourceFile).toHaveText('auth/folder-driver.yml');
|
||||
await expect(sourceFile).not.toContainText('auth/folder.yml');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -54,55 +54,53 @@ test.describe('Timeline — scripted requests (sendRequest / runRequest)', () =>
|
||||
|
||||
await test.step('Open Timeline and assert four rows', async () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(rows).toHaveCount(4);
|
||||
});
|
||||
|
||||
await test.step('Filter chips appear with correct counts (only Main + Pre-Request show)', async () => {
|
||||
const chips = page.locator('.timeline-filter-bar .timeline-chip');
|
||||
await expect(chips).toHaveCount(3); // All, Main, Pre-Request
|
||||
await test.step('Filter chips appear with correct counts (only Request + Pre-Request show)', async () => {
|
||||
const filterBar = page.getByTestId('timeline-filter-bar');
|
||||
await expect(filterBar.getByRole('button')).toHaveCount(3); // All, Request, Pre-Request
|
||||
|
||||
const countFor = (label: string) =>
|
||||
chips.filter({ hasText: label }).locator('.timeline-chip-count').first();
|
||||
const countFor = (id: string) =>
|
||||
page.getByTestId(`timeline-chip-${id}`).getByTestId('timeline-chip-count');
|
||||
|
||||
await expect(countFor('All')).toHaveText('4');
|
||||
await expect(countFor('Main')).toHaveText('1');
|
||||
await expect(countFor('Pre-Request')).toHaveText('3');
|
||||
await expect(countFor('all')).toHaveText('4');
|
||||
await expect(countFor('main')).toHaveText('1');
|
||||
await expect(countFor('pre')).toHaveText('3');
|
||||
});
|
||||
|
||||
await test.step('Rows are sorted newest-first; the collection-script row sits last', async () => {
|
||||
const rows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
|
||||
// Execution order: collection → folder → request → main.
|
||||
// Newest-first: main → request-script → folder-script → collection-script.
|
||||
await expect(rows.nth(0).locator('.tl-badge--main')).toHaveCount(1);
|
||||
await expect(rows.nth(0).getByTestId('timeline-badge-main')).toHaveCount(1);
|
||||
|
||||
const requestScriptRow = rows.nth(1);
|
||||
await expect(requestScriptRow.locator('.tl-badge--scripted')).toHaveCount(1);
|
||||
await expect(requestScriptRow.locator('.tl-col-url')).toContainText('/query');
|
||||
await expect(requestScriptRow.getByTestId('timeline-badge-pre')).toHaveCount(1);
|
||||
await expect(requestScriptRow.getByTestId('timeline-url')).toContainText('/query');
|
||||
|
||||
const folderScriptRow = rows.nth(2);
|
||||
await expect(folderScriptRow.locator('.tl-badge--scripted')).toHaveCount(1);
|
||||
await expect(folderScriptRow.locator('.tl-col-url')).toContainText('/headers');
|
||||
await expect(folderScriptRow.getByTestId('timeline-badge-pre')).toHaveCount(1);
|
||||
await expect(folderScriptRow.getByTestId('timeline-url')).toContainText('/headers');
|
||||
|
||||
const collectionScriptRow = rows.nth(3);
|
||||
await expect(collectionScriptRow.locator('.tl-badge--scripted')).toHaveCount(1);
|
||||
await expect(collectionScriptRow.locator('.tl-col-url')).toContainText('/echo/path');
|
||||
await expect(collectionScriptRow.getByTestId('timeline-badge-pre')).toHaveCount(1);
|
||||
await expect(collectionScriptRow.getByTestId('timeline-url')).toContainText('/echo/path');
|
||||
});
|
||||
|
||||
await test.step('Clicking the Pre-Request chip narrows to the three sendRequest rows', async () => {
|
||||
const chips = page.locator('.timeline-filter-bar .timeline-chip');
|
||||
await chips.filter({ hasText: 'Pre-Request' }).click();
|
||||
await page.getByTestId('timeline-chip-pre').click();
|
||||
|
||||
const visibleRows = page.locator('.timeline-container .tl-row-wrap');
|
||||
const visibleRows = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(visibleRows).toHaveCount(3);
|
||||
await expect(visibleRows.locator('.tl-badge--scripted')).toHaveCount(3);
|
||||
await expect(visibleRows.getByTestId('timeline-badge-pre')).toHaveCount(3);
|
||||
});
|
||||
|
||||
await test.step('Clicking All restores every row', async () => {
|
||||
const chips = page.locator('.timeline-filter-bar .timeline-chip');
|
||||
await chips.filter({ hasText: 'All' }).click();
|
||||
await expect(page.locator('.timeline-container .tl-row-wrap')).toHaveCount(4);
|
||||
await page.getByTestId('timeline-chip-all').click();
|
||||
await expect(page.getByTestId('timeline-container').getByTestId('timeline-entry')).toHaveCount(4);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -139,15 +137,15 @@ test.describe('Timeline — scripted requests (sendRequest / runRequest)', () =>
|
||||
});
|
||||
|
||||
await test.step('Runner timeline shows main + sendRequest + runRequest rows', async () => {
|
||||
const rows = page.locator('.tl-row-wrap');
|
||||
const rows = page.getByTestId('timeline-entry');
|
||||
await expect(rows).toHaveCount(3, { timeout: 10000 });
|
||||
|
||||
await expect(rows.locator('.tl-badge--main')).toHaveCount(1);
|
||||
await expect(rows.locator('.tl-badge--scripted')).toHaveCount(1);
|
||||
await expect(rows.locator('.tl-badge--run-request')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-main')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-pre')).toHaveCount(1);
|
||||
await expect(rows.getByTestId('timeline-badge-post')).toHaveCount(1);
|
||||
|
||||
// The runner view never shows the filter chip bar (no chip-bar UI here).
|
||||
await expect(page.locator('.timeline-filter-bar')).toHaveCount(0);
|
||||
await expect(page.getByTestId('timeline-filter-bar')).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ test.describe('Timeline URL Update', () => {
|
||||
await selectResponsePaneTab(page, 'Timeline');
|
||||
|
||||
// Get all timeline entries
|
||||
const timelineItems = page.locator('.tl-row-wrap');
|
||||
const timelineItems = page.getByTestId('timeline-container').getByTestId('timeline-entry');
|
||||
await expect(timelineItems).toHaveCount(2, { timeout: 5000 });
|
||||
|
||||
// Most recent entry (first in list) should show the second URL
|
||||
|
||||
Reference in New Issue
Block a user