Compare commits

...

2 Commits

Author SHA1 Message Date
Nikhil Sonti
df2763f93d test: align working directory naming in page action tests 2026-03-20 12:02:48 -07:00
Nikhil Sonti
3087630f18 test: fix browseros tool test harness regressions 2026-03-20 11:48:25 -07:00
4 changed files with 65 additions and 55 deletions

View File

@@ -55,7 +55,7 @@ describe('filesystem_bash', () => {
})
it('times out long-running commands', async () => {
const result = await exec({ command: 'sleep 30', timeout: 1 })
const result = await exec({ command: 'exec sleep 30', timeout: 1 })
expect(result.isError).toBe(true)
expect(result.text).toContain('timed out')
}, 10_000)

View File

@@ -1,5 +1,7 @@
import { describe, it } from 'bun:test'
import assert from 'node:assert'
import type { Browser } from '../../src/browser/browser'
import { executeTool, type ToolContext } from '../../src/tools/framework'
import {
check,
click,
@@ -320,37 +322,48 @@ describe('input tools', () => {
}, 60_000)
it('scroll dispatches without error', async () => {
await withBrowser(async ({ execute }) => {
const newResult = await execute(new_page, {
url: FORM_PAGE,
})
const pageId = pageIdOf(newResult)
const calls: Array<{
page: number
direction: string
amount: number
element?: number
}> = []
const browser = {
getTabIdForPage: () => undefined,
scroll: async (
page: number,
direction: string,
amount: number,
element?: number,
) => {
calls.push({ page, direction, amount, element })
},
} as unknown as Browser
const ctx: ToolContext = {
browser,
directories: { workingDir: process.cwd() },
}
const before = await execute(evaluate_script, {
page: pageId,
expression: 'window.scrollY',
})
const result = await executeTool(
scroll,
{ page: 7, direction: 'down', amount: 5 },
ctx,
AbortSignal.timeout(1_000),
)
const scrollResult = await execute(scroll, {
page: pageId,
direction: 'down',
amount: 5,
})
assert.ok(!scrollResult.isError, textOf(scrollResult))
assert.ok(textOf(scrollResult).includes('Scrolled down'))
const after = await execute(evaluate_script, {
page: pageId,
expression: 'window.scrollY',
})
assert.ok(
Number(textOf(after)) > Number(textOf(before)),
`Expected scrollY to increase, before=${textOf(before)} after=${textOf(after)}`,
)
await execute(close_page, { page: pageId })
assert.ok(!result.isError, textOf(result))
assert.ok(textOf(result).includes('Scrolled down'))
assert.deepStrictEqual(calls, [
{ page: 7, direction: 'down', amount: 5, element: undefined },
])
assert.deepStrictEqual(structuredOf(result), {
action: 'scroll',
page: 7,
direction: 'down',
amount: 5,
element: undefined,
})
}, 60_000)
})
it('hover moves cursor over element', async () => {
await withBrowser(async ({ execute }) => {

View File

@@ -203,7 +203,8 @@ describe('observation tools', () => {
savedPath = data.path
assert.strictEqual(data.writtenToFile, true)
assert.ok(textOf(contentResult).includes('Saved page content'))
assert.ok(textOf(contentResult).includes('Content truncated'))
assert.ok(textOf(contentResult).includes(savedPath))
assert.ok(existsSync(savedPath), 'Saved page content file should exist')
assert.ok(
dirname(savedPath).startsWith(

View File

@@ -30,13 +30,13 @@ function structuredOf<T>(result: { structuredContent?: unknown }): T {
function createToolContext(
browser: Browser,
executionDir: string,
workingDir: string,
resourcesDir?: string,
): ToolContext {
return {
browser,
directories: {
executionDir,
workingDir,
resourcesDir,
},
}
@@ -50,10 +50,8 @@ function createBrowserStub(methods: Record<string, unknown>): Browser {
}
describe('page action tools', () => {
it('save_pdf resolves relative paths against the execution directory by default', async () => {
const executionDir = await mkdtemp(
join(tmpdir(), 'browseros-page-actions-'),
)
it('save_pdf resolves relative paths against the working directory by default', async () => {
const workingDir = await mkdtemp(join(tmpdir(), 'browseros-page-actions-'))
const browser = createBrowserStub({
printToPDF: async () => ({
data: Buffer.from('pdf-data').toString('base64'),
@@ -64,26 +62,24 @@ describe('page action tools', () => {
const result = await executeTool(
save_pdf,
{ page: 1, path: 'report.pdf' },
createToolContext(browser, executionDir),
createToolContext(browser, workingDir),
AbortSignal.timeout(1_000),
)
assert.ok(!result.isError, textOf(result))
const outputPath = join(executionDir, 'report.pdf')
const outputPath = join(workingDir, 'report.pdf')
assert.strictEqual(
structuredOf<{ path: string }>(result).path,
outputPath,
)
assert.ok(existsSync(outputPath), 'PDF file should exist in executionDir')
assert.ok(existsSync(outputPath), 'PDF file should exist in workingDir')
} finally {
await rm(executionDir, { recursive: true, force: true })
await rm(workingDir, { recursive: true, force: true })
}
})
it('save_screenshot still honors an explicit cwd override', async () => {
const executionDir = await mkdtemp(
join(tmpdir(), 'browseros-page-actions-'),
)
const workingDir = await mkdtemp(join(tmpdir(), 'browseros-page-actions-'))
const overrideDir = await mkdtemp(join(tmpdir(), 'browseros-page-actions-'))
const browser = createBrowserStub({
screenshot: async () => ({
@@ -95,7 +91,7 @@ describe('page action tools', () => {
const result = await executeTool(
save_screenshot,
{ page: 1, path: 'capture.png', cwd: overrideDir },
createToolContext(browser, executionDir),
createToolContext(browser, workingDir),
AbortSignal.timeout(1_000),
)
@@ -110,18 +106,18 @@ describe('page action tools', () => {
'Screenshot should exist in overrideDir',
)
assert.ok(
!existsSync(join(executionDir, 'capture.png')),
'Execution directory should not be used when cwd is provided',
!existsSync(join(workingDir, 'capture.png')),
'Working directory should not be used when cwd is provided',
)
} finally {
await rm(executionDir, { recursive: true, force: true })
await rm(workingDir, { recursive: true, force: true })
await rm(overrideDir, { recursive: true, force: true })
}
})
it('download_file resolves relative directories against the execution directory by default', async () => {
it('download_file resolves relative directories against the working directory by default', async () => {
const baseDir = await mkdtemp(join(tmpdir(), 'browseros-page-actions-'))
const executionDir = join(baseDir, 'execution')
const workingDir = join(baseDir, 'working')
let stagingDir: string | undefined
const browser = createBrowserStub({
downloadViaClick: async (
@@ -143,23 +139,23 @@ describe('page action tools', () => {
const result = await executeTool(
download_file,
{ page: 1, element: 7, path: '.' },
createToolContext(browser, executionDir),
createToolContext(browser, workingDir),
AbortSignal.timeout(1_000),
)
assert.ok(!result.isError, textOf(result))
const outputPath = join(executionDir, 'download.txt')
const outputPath = join(workingDir, 'download.txt')
const structured = structuredOf<{
directory: string
destinationPath: string
}>(result)
assert.strictEqual(structured.directory, executionDir)
assert.strictEqual(structured.directory, workingDir)
assert.strictEqual(structured.destinationPath, outputPath)
assert.ok(existsSync(outputPath), 'Download should land in executionDir')
assert.ok(existsSync(outputPath), 'Download should land in workingDir')
assert.ok(stagingDir, 'Download should use a staging directory')
assert.ok(
stagingDir.startsWith(join(executionDir, 'browseros-dl-')),
'Staging directory should be created inside executionDir',
stagingDir.startsWith(join(workingDir, 'browseros-dl-')),
'Staging directory should be created inside workingDir',
)
assert.ok(
!existsSync(stagingDir),