diff --git a/src/__tests__/commands/scrape.test.ts b/src/__tests__/commands/scrape.test.ts index b9c9606882..9389e31eb7 100644 --- a/src/__tests__/commands/scrape.test.ts +++ b/src/__tests__/commands/scrape.test.ts @@ -3,7 +3,7 @@ */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { executeScrape } from '../../commands/scrape'; +import { executeScrape, handleScrapeCommand } from '../../commands/scrape'; import { getClient, isKeylessMode, keylessRequest } from '../../utils/client'; import { initializeConfig } from '../../utils/config'; import { setupTest, teardownTest } from '../utils/mock-client'; @@ -192,6 +192,53 @@ describe('executeScrape', () => { }); }); + it('sends a single screenshot format when --screenshot and --full-page-screenshot are both set', async () => { + mockClient.scrape.mockResolvedValue({ screenshot: 'https://x/s.png' }); + + await executeScrape({ + url: 'https://example.com', + formats: ['markdown'], + screenshot: true, + fullPageScreenshot: true, + }); + + expect(mockClient.scrape).toHaveBeenCalledWith('https://example.com', { + formats: ['markdown', { type: 'screenshot', fullPage: true }], + integration: 'cli', + }); + }); + + it('drops every plain screenshot format when a full-page screenshot is requested', async () => { + mockClient.scrape.mockResolvedValue({ screenshot: 'https://x/s.png' }); + + await executeScrape({ + url: 'https://example.com', + formats: ['screenshot', 'markdown', 'screenshot'], + fullPageScreenshot: true, + }); + + expect(mockClient.scrape).toHaveBeenCalledWith('https://example.com', { + formats: ['markdown', { type: 'screenshot', fullPage: true }], + integration: 'cli', + }); + }); + + it('sends a single screenshot format when --full-page-screenshot is combined with --format screenshot', async () => { + mockClient.scrape.mockResolvedValue({ screenshot: 'https://x/s.png' }); + + await executeScrape({ + url: 'https://example.com', + formats: ['markdown', 'screenshot'], + fullPageScreenshot: true, + }); + + // The API rejects more than one screenshot format. + expect(mockClient.scrape).toHaveBeenCalledWith('https://example.com', { + formats: ['markdown', { type: 'screenshot', fullPage: true }], + integration: 'cli', + }); + }); + it('should include onlyMainContent parameter when provided', async () => { const mockResponse = { markdown: '# Test' }; mockClient.scrape.mockResolvedValue(mockResponse); @@ -519,4 +566,33 @@ describe('executeScrape', () => { }); }); }); + + describe('Full-page screenshot output', () => { + it('prints the screenshot URL alongside markdown for --full-page-screenshot', async () => { + mockClient.scrape.mockResolvedValue({ + markdown: '# Test', + screenshot: 'https://cdn.example.com/full.png', + }); + const write = vi + .spyOn(process.stdout, 'write') + .mockImplementation(() => true); + + try { + await handleScrapeCommand({ + url: 'https://example.com', + formats: ['markdown'], + fullPageScreenshot: true, + }); + const printed = write.mock.calls + .map((call) => String(call[0])) + .join(''); + expect(JSON.parse(printed)).toEqual({ + markdown: '# Test', + screenshot: 'https://cdn.example.com/full.png', + }); + } finally { + write.mockRestore(); + } + }); + }); }); diff --git a/src/commands/scrape.ts b/src/commands/scrape.ts index 5407275df6..df2cc0e806 100644 --- a/src/commands/scrape.ts +++ b/src/commands/scrape.ts @@ -66,8 +66,13 @@ export async function executeScrape( formats.push(...options.formats); } - // Add screenshot format if requested and not already included + // Add screenshot format if requested and not already included. The API + // accepts only one screenshot format, so a full-page screenshot replaces a + // plain `screenshot` from --format instead of being added next to it. if (options.fullPageScreenshot) { + for (let i = formats.length - 1; i >= 0; i--) { + if (formats[i] === 'screenshot') formats.splice(i, 1); + } formats.push({ type: 'screenshot', fullPage: true }); } else if (options.screenshot && !formats.includes('screenshot')) { formats.push('screenshot'); @@ -225,7 +230,10 @@ export async function handleScrapeCommand( : ['markdown']; // Add screenshot to effective formats if it was requested separately - if (options.screenshot && !effectiveFormats.includes('screenshot')) { + if ( + (options.screenshot || options.fullPageScreenshot) && + !effectiveFormats.includes('screenshot') + ) { effectiveFormats.push('screenshot'); }