Skip to content

🧪 Test: add unit tests for browser-capture service#486

Draft
Dexploarer wants to merge 1 commit into
developfrom
test/add-browser-capture-tests-2984555860994460587
Draft

🧪 Test: add unit tests for browser-capture service#486
Dexploarer wants to merge 1 commit into
developfrom
test/add-browser-capture-tests-2984555860994460587

Conversation

@Dexploarer

Copy link
Copy Markdown
Owner

🎯 What: Add a comprehensive suite of unit tests for the src/services/browser-capture.ts service since none existed previously.

📊 Coverage:

  • startBrowserCapture configs, popout logic, and instance constraints.
  • Page.screencastFrame logic mimicking internal Chrome CDP behavior, and ensuring proper writes to FRAME_FILE.
  • stopBrowserCapture logic and clean browser termination.
  • isBrowserCaptureRunning and hasFrameFile utilities.

✨ Result: Improves test coverage for the browser capture orchestration logic using vitest without actually spawning instances by mocking puppeteer-core and node:fs.


PR created automatically by Jules for task 2984555860994460587 started by @Dexploarer

@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Apr 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: af837230-664c-49b5-848c-5abaa87cb7cf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/add-browser-capture-tests-2984555860994460587

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment on lines +46 to +49
afterEach(async () => {
vi.clearAllMocks();
await stopBrowserCapture();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Isolation and Cleanup:
The afterEach block calls stopBrowserCapture() without checking if a capture was actually started. If a test fails before starting the capture, this could lead to inconsistent cleanup or errors. Consider adding a check to ensure that cleanup only occurs if a capture was started, or handle errors gracefully in the cleanup phase.

Recommended solution:

afterEach(async () => {
  vi.clearAllMocks();
  if (isBrowserCaptureRunning()) {
    await stopBrowserCapture();
  }
});

Comment on lines +117 to +133
it('should handle screencast frames correctly', async () => {
await startBrowserCapture({ url: 'http://localhost' });

// Simulate frame
const onCall = mockCdp.on.mock.calls.find((call: any) => call[0] === 'Page.screencastFrame');
expect(onCall).toBeDefined();

const handler = onCall[1];

await handler({
data: Buffer.from('test frame').toString('base64'),
sessionId: 123
});

expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(FRAME_FILE, expect.any(Buffer));
expect(mockCdp.send).toHaveBeenCalledWith('Page.screencastFrameAck', { sessionId: 123 });
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frame File Content Verification:
The test for handling screencast frames verifies that fs.writeFileSync is called, but does not check the actual content written to the file. This could miss issues where the frame data is incorrectly encoded or corrupted.

Recommended solution:
Add an assertion to verify the content of the buffer passed to writeFileSync, for example:

expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(FRAME_FILE, Buffer.from('test frame'));

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive test suite for the browser capture service, covering initialization, URL parameter logic, and frame processing using Vitest and Puppeteer. The review feedback suggests enhancing the tests by replacing 'any' types with specific Puppeteer interfaces for better type safety, reordering cleanup operations in the afterEach hook to ensure mock history is preserved until after service shutdown, and strengthening assertions to verify the actual content of captured frames.

Comment on lines +21 to +23
let mockPage: any;
let mockCdp: any;
let mockBrowser: any;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using any for mock objects bypasses TypeScript's type checking. It is recommended to use specific types from puppeteer-core (e.g., Page, CDPSession, Browser) combined with Vitest's mocking types to ensure the mocks align with the actual API and provide better type safety.

Comment on lines +47 to +48
vi.clearAllMocks();
await stopBrowserCapture();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It is recommended to call stopBrowserCapture() before vi.clearAllMocks(). This ensures that the service's internal state is fully cleaned up and any resulting mock interactions (like closing the browser) are completed before the mock history is cleared for the next test.

Suggested change
vi.clearAllMocks();
await stopBrowserCapture();
await stopBrowserCapture();
vi.clearAllMocks();

sessionId: 123
});

expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(FRAME_FILE, expect.any(Buffer));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of using expect.any(Buffer), verify that the buffer written to the file contains the expected decoded data. This ensures the base64 decoding logic in the service is working correctly.

Suggested change
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(FRAME_FILE, expect.any(Buffer));
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(FRAME_FILE, Buffer.from('test frame'));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant