@@ -91,8 +91,8 @@ test('frame normalization reports native and scaled dimensions', async () => {
|
||||
const {FrameNormalizer}=await import('../computer-use/frame.js');
|
||||
const dir=await mkdtemp('/tmp/jarvis-frame-test-');
|
||||
try {
|
||||
const made=spawnSync('python3',['-c','from PIL import Image; import sys; Image.new("RGB",(1600,900),"red").save(sys.argv[1])',dir+'/input.png']);
|
||||
assert.equal(made.status,0);
|
||||
const made=spawnSync('python3',['-c','from PIL import Image; import sys; Image.new("RGB",(1600,900),"red").save(sys.argv[1])',dir+'/input.png'],{encoding:'utf8'});
|
||||
assert.equal(made.status,0,made.error?.message || made.stderr);
|
||||
const frame=await new FrameNormalizer().normalize(dir+'/input.png',dir+'/output.webp');
|
||||
assert.equal(frame.source_width,1600);assert.equal(frame.width,1280);assert.equal(frame.height,720);
|
||||
} finally {await rm(dir,{recursive:true,force:true});}
|
||||
|
||||
@@ -145,6 +145,7 @@ test('web_search can pin a scraped engine and fetch_page reads directly', async
|
||||
globalThis.fetch = async (url) => {
|
||||
const href = String(url);
|
||||
if (href.includes('duckduckgo.com')) return { status: 200, url: href, text: async () => '<a class="result__a" href="https://en.wikipedia.org/wiki/Example.com">Example.com</a>' };
|
||||
if (href.includes('bing.com') && href.includes('format=rss')) return { status: 200, url: href, text: async () => '<rss><item><title>Example.com</title><link>https://en.wikipedia.org/wiki/Example.com</link></item></rss>' };
|
||||
if (href.includes('bing.com') || href.includes('google.com')) return { status: 200, url: href, text: async () => '' };
|
||||
if (href === 'https://example.com/article') return { status: 200, url: href, text: async () => '<html><body><p>Readable article scraped directly</p></body></html>' };
|
||||
throw new Error('unexpected fetch ' + href);
|
||||
|
||||
@@ -54,7 +54,7 @@ test('direct fetch checks redirects, rejects binary pages, and reports challenge
|
||||
globalThis.fetch = async url => response(url, 'binary', 200, { 'content-type': 'application/pdf' });
|
||||
assert.match((await web.fetchPage('https://example.com')).error, /unsupported content type/);
|
||||
globalThis.fetch = async url => response(url, '<p>Verify you are human</p>');
|
||||
assert.match((await web.fetchPage('https://example.com')).warning, /challenge/);
|
||||
assert.match((await web.fetchPage('https://challenge.example.com')).warning, /challenge/);
|
||||
globalThis.fetch = async url => response(url, 'x'.repeat(2 * 1024 * 1024 + 1));
|
||||
assert.match((await web.fetchPage('https://example.com')).error, /limit/);
|
||||
} finally { globalThis.fetch = orig; }
|
||||
@@ -66,3 +66,36 @@ test('stalled streaming bodies are cancelled at the deadline', async () => {
|
||||
await assert.rejects(web.readBodyWithTimeout(res, 30), /timed out/);
|
||||
assert.equal(cancelled, true);
|
||||
});
|
||||
|
||||
|
||||
test('challenge responses fall back and cool down related search hosts', async () => {
|
||||
const orig = globalThis.fetch; const calls = [];
|
||||
globalThis.fetch = async url => {
|
||||
calls.push(String(url));
|
||||
if (String(url).includes('duckduckgo')) return response(url, '<form id="challenge-form">Verify you are human</form>');
|
||||
if (String(url).includes('bing')) return response(url, '<rss><item><title>Available</title><link>https://available.example/page</link></item></rss>');
|
||||
return response(url, '');
|
||||
};
|
||||
try {
|
||||
const hits = await web.runWebSearch('fallback', { limit: 1 });
|
||||
assert.equal(hits[0].source, 'bing_rss');
|
||||
const blocked = await web.runWebSearch('fallback', { engine: 'ddg_lite' });
|
||||
assert.equal(blocked.code, 'bot_challenge');
|
||||
assert.ok(blocked.retry_after_ms > 0);
|
||||
assert.equal(calls.filter(url => url.includes('duckduckgo')).length, 1);
|
||||
} finally { globalThis.fetch = orig; }
|
||||
});
|
||||
|
||||
test('rate limits preserve retry guidance and never expose challenge content', async () => {
|
||||
const orig = globalThis.fetch; let calls = 0;
|
||||
globalThis.fetch = async url => { calls++; return response(url, 'blocked content', 429, { 'retry-after': '120' }); };
|
||||
try {
|
||||
const result = await web.fetchPage('https://limited.example/page');
|
||||
assert.equal(result.code, 'rate_limited');
|
||||
assert.equal(result.retry_after_ms, 120000);
|
||||
assert.equal(result.text, undefined);
|
||||
assert.match(result.next_action, /browser/);
|
||||
await web.fetchPage('https://limited.example/other');
|
||||
assert.equal(calls, 1);
|
||||
} finally { globalThis.fetch = orig; }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user