refactor(browser): make sessionName optional, add selector filter, deduplicate session setup

- sessionName is now optional in open/exec; skips session restore when omitted
- add selector param to open: returns outerHTML or textContent of matched element
- extract session restore logic into private setupSession() to remove duplication
- replace per-exception instanceof checks with single HttpException base class check
- embed label into InternalServerErrorException message instead of logging separately
- update MCP tool schemas and HTTP DTOs to reflect optional sessionName and new selector
- add integration tests: sessionless open/exec, selector, selector+readerMode
This commit is contained in:
2026-04-08 11:10:08 +03:00
parent f1dadc602a
commit f0437d9390
7 changed files with 109 additions and 86 deletions
+5 -4
View File
@@ -189,14 +189,15 @@ export class McpService {
{
description: 'Open a URL using a stored session and return the page title and content',
inputSchema: {
sessionName: z.string().describe('Session name to restore cookies and localStorage from'),
sessionName: z.string().optional().describe('Session name to restore cookies and localStorage from. Omit to open without a stored session.'),
url: z.string().url().describe('URL to navigate to'),
readerMode: z.boolean().optional().describe('Extract readable plain text instead of raw HTML'),
selector: z.string().optional().describe('CSS selector whose matching element content is returned; applied before readerMode'),
},
},
async ({ sessionName, url, readerMode }) => {
async ({ sessionName, url, readerMode, selector }) => {
try {
const result = await this.browserService.open(sessionName, url, readerMode ?? false);
const result = await this.browserService.open(sessionName, url, readerMode ?? false, selector);
return { content: [{ type: 'text' as const, text: JSON.stringify(result) }] };
} catch (err) {
return { isError: true, content: [{ type: 'text' as const, text: (err as Error).message }] };
@@ -209,7 +210,7 @@ export class McpService {
{
description: 'Execute arbitrary Playwright JavaScript with `page` and `context` in scope',
inputSchema: {
sessionName: z.string().describe('Session name to restore'),
sessionName: z.string().optional().describe('Session name to restore. Omit to run without a stored session.'),
code: z.string().describe('JavaScript code body to execute (async-safe, may use `page` and `context`)'),
url: z.string().url().optional().describe('Optional URL to navigate to before running code'),
},