mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-13 23:53:25 +00:00
Compare commits
2 Commits
fix/github
...
fix/mar20-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df2763f93d | ||
|
|
3087630f18 |
@@ -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)
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user