fix(browser): inject snippets into exec_code context; fix(ui): step order starts at 1 in run detail
- BrowserService.exec() now builds snippet map via SnippetService and passes it to CodeExecutorService.execute() for both named-session and anonymous paths - SnippetModule added to BrowserModule imports to wire the dependency - RunDetailPage step order column renders s.order + 1 (was 0-based)
This commit is contained in:
@@ -154,7 +154,7 @@ export function RunDetailPage() {
|
|||||||
}, [id, runId]);
|
}, [id, runId]);
|
||||||
|
|
||||||
const stepColumns: TableColumn<ScenarioRunStep>[] = [
|
const stepColumns: TableColumn<ScenarioRunStep>[] = [
|
||||||
{ key: 'order', header: t('runs.step_order'), render: (s) => s.order, width: 50 },
|
{ key: 'order', header: t('runs.step_order'), render: (s) => s.order + 1, width: 50 },
|
||||||
{
|
{
|
||||||
key: 'title',
|
key: 'title',
|
||||||
header: t('runs.step_title'),
|
header: t('runs.step_title'),
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import { BrowserController } from "./browser.controller";
|
|||||||
import { BrowserService } from "./browser.service";
|
import { BrowserService } from "./browser.service";
|
||||||
import { SessionModule } from "../session/session.module";
|
import { SessionModule } from "../session/session.module";
|
||||||
import { CodeExecutorModule } from "../code-executor/code-executor.module";
|
import { CodeExecutorModule } from "../code-executor/code-executor.module";
|
||||||
|
import { SnippetModule } from "../snippet/snippet.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [SessionModule, CodeExecutorModule],
|
imports: [SessionModule, CodeExecutorModule, SnippetModule],
|
||||||
controllers: [BrowserController],
|
controllers: [BrowserController],
|
||||||
providers: [BrowserService],
|
providers: [BrowserService],
|
||||||
exports: [BrowserService],
|
exports: [BrowserService],
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { SessionContextService } from "../session/session-context.service";
|
|||||||
import { SessionService } from "../session/session.service";
|
import { SessionService } from "../session/session.service";
|
||||||
import { CodeExecutorService } from "../code-executor/code-executor.service";
|
import { CodeExecutorService } from "../code-executor/code-executor.service";
|
||||||
import type { ExecResult } from "../code-executor/code-executor.service";
|
import type { ExecResult } from "../code-executor/code-executor.service";
|
||||||
|
import { SnippetService } from "../snippet/snippet.service";
|
||||||
import type { Cookie } from "playwright";
|
import type { Cookie } from "playwright";
|
||||||
|
|
||||||
export type { ExecResult } from "../code-executor/code-executor.service";
|
export type { ExecResult } from "../code-executor/code-executor.service";
|
||||||
@@ -30,6 +31,7 @@ export class BrowserService {
|
|||||||
private readonly sessionContextService: SessionContextService,
|
private readonly sessionContextService: SessionContextService,
|
||||||
private readonly sessionService: SessionService,
|
private readonly sessionService: SessionService,
|
||||||
private readonly codeExecutor: CodeExecutorService,
|
private readonly codeExecutor: CodeExecutorService,
|
||||||
|
private readonly snippetService: SnippetService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private parseCookies(raw: string | null | undefined): Cookie[] {
|
private parseCookies(raw: string | null | undefined): Cookie[] {
|
||||||
@@ -171,13 +173,25 @@ export class BrowserService {
|
|||||||
const { page, context } =
|
const { page, context } =
|
||||||
await this.getOrCreateNamedHandle(sessionName);
|
await this.getOrCreateNamedHandle(sessionName);
|
||||||
this.logger.log(`[${label}] exec: using persistent context`);
|
this.logger.log(`[${label}] exec: using persistent context`);
|
||||||
|
const snippets = await this.snippetService
|
||||||
|
.buildSnippetMap()
|
||||||
|
.catch(() => ({}) as Record<string, string>);
|
||||||
try {
|
try {
|
||||||
if (url) {
|
if (url) {
|
||||||
this.logger.log(`[${label}] exec: navigating to ${url}`);
|
this.logger.log(`[${label}] exec: navigating to ${url}`);
|
||||||
await page.goto(url, { waitUntil: "networkidle" });
|
await page.goto(url, { waitUntil: "networkidle" });
|
||||||
}
|
}
|
||||||
this.logger.log(`[${label}] exec: running user code`);
|
this.logger.log(`[${label}] exec: running user code`);
|
||||||
const result = await this.codeExecutor.execute(page, context, code);
|
const result = await this.codeExecutor.execute(
|
||||||
|
page,
|
||||||
|
context,
|
||||||
|
code,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
snippets,
|
||||||
|
);
|
||||||
this.logger.log(`[${label}] exec: done`);
|
this.logger.log(`[${label}] exec: done`);
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -186,6 +200,9 @@ export class BrowserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Anonymous — ephemeral browser
|
// Anonymous — ephemeral browser
|
||||||
|
const snippetMap = await this.snippetService
|
||||||
|
.buildSnippetMap()
|
||||||
|
.catch(() => ({}) as Record<string, string>);
|
||||||
const browser = await chromium.launch({
|
const browser = await chromium.launch({
|
||||||
headless: true,
|
headless: true,
|
||||||
executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH,
|
executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH,
|
||||||
@@ -200,7 +217,16 @@ export class BrowserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.log(`[${label}] exec: running user code`);
|
this.logger.log(`[${label}] exec: running user code`);
|
||||||
const result = await this.codeExecutor.execute(page, context, code);
|
const result = await this.codeExecutor.execute(
|
||||||
|
page,
|
||||||
|
context,
|
||||||
|
code,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
snippetMap,
|
||||||
|
);
|
||||||
this.logger.log(`[${label}] exec: done`);
|
this.logger.log(`[${label}] exec: done`);
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user