feat: add 5 lines context around search matches in accessibilitySnapshot, getCleanHTML, getLatestLogs
This commit is contained in:
@@ -104,9 +104,10 @@ export async function getCleanHTML(options: GetCleanHTMLOptions): Promise<string
|
|||||||
// Handle search
|
// Handle search
|
||||||
if (search) {
|
if (search) {
|
||||||
const lines = htmlStr.split('\n')
|
const lines = htmlStr.split('\n')
|
||||||
const matches: string[] = []
|
const matchIndices: number[] = []
|
||||||
|
|
||||||
for (const line of lines) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i]
|
||||||
let isMatch = false
|
let isMatch = false
|
||||||
if (isRegExp(search)) {
|
if (isRegExp(search)) {
|
||||||
isMatch = search.test(line)
|
isMatch = search.test(line)
|
||||||
@@ -115,16 +116,38 @@ export async function getCleanHTML(options: GetCleanHTMLOptions): Promise<string
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isMatch) {
|
if (isMatch) {
|
||||||
matches.push(line)
|
matchIndices.push(i)
|
||||||
if (matches.length >= 10) break
|
if (matchIndices.length >= 10) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches.length === 0) {
|
if (matchIndices.length === 0) {
|
||||||
return 'No matches found'
|
return 'No matches found'
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches.join('\n')
|
// Collect lines with 5 lines of context above and below each match
|
||||||
|
const CONTEXT_LINES = 5
|
||||||
|
const includedLines = new Set<number>()
|
||||||
|
for (const idx of matchIndices) {
|
||||||
|
const start = Math.max(0, idx - CONTEXT_LINES)
|
||||||
|
const end = Math.min(lines.length - 1, idx + CONTEXT_LINES)
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
includedLines.add(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build result with separators between non-contiguous sections
|
||||||
|
const sortedIndices = [...includedLines].sort((a, b) => a - b)
|
||||||
|
const result: string[] = []
|
||||||
|
for (let i = 0; i < sortedIndices.length; i++) {
|
||||||
|
const lineIdx = sortedIndices[i]
|
||||||
|
if (i > 0 && sortedIndices[i - 1] !== lineIdx - 1) {
|
||||||
|
result.push('---')
|
||||||
|
}
|
||||||
|
result.push(lines[lineIdx])
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
return htmlStr
|
return htmlStr
|
||||||
|
|||||||
@@ -979,7 +979,8 @@ describe('MCP Server Tests', () => {
|
|||||||
|
|
||||||
const errorOutput = (errorLogsResult as any).content[0].text
|
const errorOutput = (errorLogsResult as any).content[0].text
|
||||||
expect(errorOutput).toContain('[error] Test error 67890')
|
expect(errorOutput).toContain('[error] Test error 67890')
|
||||||
expect(errorOutput).not.toContain('[log] Test log 12345')
|
// With context lines (5 above/below), nearby logs are also included
|
||||||
|
expect(errorOutput).toContain('[log] Test log 12345')
|
||||||
|
|
||||||
// Test that logs are cleared on page reload
|
// Test that logs are cleared on page reload
|
||||||
await client.callTool({
|
await client.callTool({
|
||||||
|
|||||||
+63
-11
@@ -747,9 +747,10 @@ server.tool(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const lines = snapshotStr.split('\n')
|
const lines = snapshotStr.split('\n')
|
||||||
const matches: string[] = []
|
const matchIndices: number[] = []
|
||||||
|
|
||||||
for (const line of lines) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i]
|
||||||
let isMatch = false
|
let isMatch = false
|
||||||
if (isRegExp(search)) {
|
if (isRegExp(search)) {
|
||||||
isMatch = search.test(line)
|
isMatch = search.test(line)
|
||||||
@@ -758,16 +759,38 @@ server.tool(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isMatch) {
|
if (isMatch) {
|
||||||
matches.push(line)
|
matchIndices.push(i)
|
||||||
if (matches.length >= 10) break
|
if (matchIndices.length >= 10) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches.length === 0) {
|
if (matchIndices.length === 0) {
|
||||||
return 'No matches found'
|
return 'No matches found'
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches.join('\n')
|
// Collect lines with 5 lines of context above and below each match
|
||||||
|
const CONTEXT_LINES = 5
|
||||||
|
const includedLines = new Set<number>()
|
||||||
|
for (const idx of matchIndices) {
|
||||||
|
const start = Math.max(0, idx - CONTEXT_LINES)
|
||||||
|
const end = Math.min(lines.length - 1, idx + CONTEXT_LINES)
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
includedLines.add(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build result with separators between non-contiguous sections
|
||||||
|
const sortedIndices = [...includedLines].sort((a, b) => a - b)
|
||||||
|
const result: string[] = []
|
||||||
|
for (let i = 0; i < sortedIndices.length; i++) {
|
||||||
|
const lineIdx = sortedIndices[i]
|
||||||
|
if (i > 0 && sortedIndices[i - 1] !== lineIdx - 1) {
|
||||||
|
result.push('---')
|
||||||
|
}
|
||||||
|
result.push(lines[lineIdx])
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.join('\n')
|
||||||
}
|
}
|
||||||
throw new Error('accessibilitySnapshot is not available on this page')
|
throw new Error('accessibilitySnapshot is not available on this page')
|
||||||
}
|
}
|
||||||
@@ -812,14 +835,43 @@ server.tool(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (search) {
|
if (search) {
|
||||||
allLogs = allLogs.filter((log) => {
|
const matchIndices: number[] = []
|
||||||
|
for (let i = 0; i < allLogs.length; i++) {
|
||||||
|
const log = allLogs[i]
|
||||||
|
let isMatch = false
|
||||||
if (typeof search === 'string') {
|
if (typeof search === 'string') {
|
||||||
return log.includes(search)
|
isMatch = log.includes(search)
|
||||||
} else if (isRegExp(search)) {
|
} else if (isRegExp(search)) {
|
||||||
return search.test(log)
|
isMatch = search.test(log)
|
||||||
}
|
}
|
||||||
return false
|
if (isMatch) {
|
||||||
})
|
matchIndices.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect logs with 5 lines of context above and below each match
|
||||||
|
const CONTEXT_LINES = 5
|
||||||
|
const includedIndices = new Set<number>()
|
||||||
|
for (const idx of matchIndices) {
|
||||||
|
const start = Math.max(0, idx - CONTEXT_LINES)
|
||||||
|
const end = Math.min(allLogs.length - 1, idx + CONTEXT_LINES)
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
includedIndices.add(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build result with separators between non-contiguous sections
|
||||||
|
const sortedIndices = [...includedIndices].sort((a, b) => a - b)
|
||||||
|
const result: string[] = []
|
||||||
|
for (let i = 0; i < sortedIndices.length; i++) {
|
||||||
|
const logIdx = sortedIndices[i]
|
||||||
|
if (i > 0 && sortedIndices[i - 1] !== logIdx - 1) {
|
||||||
|
result.push('---')
|
||||||
|
}
|
||||||
|
result.push(allLogs[logIdx])
|
||||||
|
}
|
||||||
|
|
||||||
|
allLogs = result
|
||||||
}
|
}
|
||||||
|
|
||||||
return count !== undefined ? allLogs.slice(-count) : allLogs
|
return count !== undefined ? allLogs.slice(-count) : allLogs
|
||||||
|
|||||||
Reference in New Issue
Block a user