Skip to content

Conversation

@Mzack9999
Copy link
Member

@Mzack9999 Mzack9999 commented Oct 24, 2025

Closes #2067

Previously implemented at #2066

Summary by CodeRabbit

  • New Features

    • Run one or more custom JavaScript snippets on pages during screenshot operations via the new --javascript-code (alias -jsc) flag; multiple snippets supported and their outputs are collected.
  • Improvements

    • More robust screenshot flow with better error handling that returns partial results (screenshot, HTML, and network data) when navigation or script execution fails.

@Mzack9999 Mzack9999 added the Type: Enhancement Most issues will probably ask for additions or changes. label Oct 24, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Walkthrough

Adds support for injecting and executing multiple JavaScript snippets during headless browsing. Introduces page setup/navigation with network capture, separates screenshot/body extraction and page closing, exposes ExecuteJavascriptCodesWithPage, updates ScreenshotWithBody signature to accept jsCodes, and adds a CLI flag for JavaScript snippets.

Changes

Cohort / File(s) Summary
Headless runtime & JS execution
runner/headless.go
ScreenshotWithBody signature extended to accept jsCodes []string. Added setupPageAndNavigate, takeScreenshotAndGetBody, closePage, and ExecuteJavascriptCodesWithPage. Reworked flow to collect network requests during navigation, optionally execute multiple JS snippets, capture screenshot and HTML body, and return partial network data on error.
CLI / Options
runner/options.go
Added JavascriptCodes field (goflags.StringSlice) to Options and registered --javascript-code / -jsc flag (StringSlice) to collect multiple JS snippets from CLI.
Integration & error handling
runner/runner.go
Updated call sites to pass options.JavascriptCodes into ScreenshotWithBody. Replaced errorutil usage with errkit and adjusted error wrapping accordingly.
Docs
README.md
Documented new CLI option -jsc, --javascript-code for providing JavaScript snippets to execute after navigation.

Sequence Diagram(s)

sequenceDiagram
    participant CLI
    participant Runner
    participant Browser
    participant Page as "rod.Page"
    participant JS as "JS Runtime"

    CLI->>Runner: options (url, ..., JavascriptCodes)
    Runner->>Browser: ScreenshotWithBody(url, ..., jsCodes)
    Browser->>Page: setupPageAndNavigate(url, timeout, headers, jsCodes)
    Page->>Browser: network events captured (requests/responses/failed)
    alt jsCodes present
        Browser->>Page: ExecuteJavascriptCodesWithPage(page, jsCodes)
        loop per snippet
            Page->>JS: Eval(snippet)
            JS-->>Page: RuntimeRemoteObject (result)
        end
        Page-->>Browser: js results
    end
    Browser->>Page: takeScreenshotAndGetBody(page, idle, fullPage)
    Page-->>Browser: screenshot + HTML body
    Browser->>Browser: closePage(page)
    Browser-->>Runner: screenshot, body, networkData, error?
    Runner-->>CLI: output/results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop and whisper tiny code,
into pages where the cookies glow.
I set a value, nudge the DOM,
click a snap, then softly roam.
Tiny rabbit, scripts in tow.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "JS injection support" accurately and concisely summarizes the main change introduced in this pull request. The changes across all modified files center on adding JavaScript injection capabilities to the headless browser functionality through a new CLI flag, extended method signatures, and supporting execution infrastructure. The title is clear, specific enough for developers scanning the history to understand the primary enhancement, and avoids vague terminology. It directly reflects the core feature being added without unnecessary details.
Linked Issues Check ✅ Passed The pull request successfully implements all coding-related requirements from issue #2067. The changes include: adding a jsCodes []string parameter to ScreenshotWithBody [#2067], implementing ExecuteJavascriptCodesWithPage method to execute JavaScript snippets on the page [#2067], introducing a --javascript-code / -jsc CLI flag with support for multiple values in the headless group [#2067], and integrating JavaScript execution into the navigation and screenshot workflow [#2067]. These changes enable users to inject and execute arbitrary JavaScript snippets to manipulate client-side state like localStorage, directly addressing the use case described in the issue.
Out of Scope Changes Check ✅ Passed
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-2067-js-inject

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
runner/headless.go (1)

279-292: Consider error handling strategy for multiple JS snippets.

Currently, if one JavaScript snippet fails (line 287), all subsequent snippets are skipped. Depending on your use case, you might want to:

  • Continue executing remaining snippets and collect all errors
  • Add logging to indicate which snippet failed
  • Add per-snippet timeouts to prevent long-running scripts
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1e39db and e34656f.

📒 Files selected for processing (3)
  • runner/headless.go (3 hunks)
  • runner/options.go (2 hunks)
  • runner/runner.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
runner/runner.go (1)
common/customheader/customheader.go (1)
  • CustomHeaders (10-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Test Builds (ubuntu-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Functional Test (windows-latest)
  • GitHub Check: Functional Test (ubuntu-latest)
  • GitHub Check: release-test
🔇 Additional comments (5)
runner/options.go (2)

337-339: LGTM! JavaScript codes field properly added.

The new JavascriptCodes field is well-placed and follows Go naming conventions.


410-410: LGTM! CLI flag properly configured.

The --javascript-code flag is correctly configured with StringSliceOptions to accept multiple JavaScript snippets.

runner/runner.go (1)

71-71: LGTM! Error handling updated consistently.

The migration from errorutil to errkit for error wrapping is applied consistently.

Also applies to: 2517-2517

runner/headless.go (2)

113-113: LGTM! Signature properly extended.

The new jsCodes parameter is correctly added to support JavaScript injection.


195-200: Verify that ignoring ExecuteJavascriptCodesWithPage outputs is intentional.

The method returns []*proto.RuntimeRemoteObject (line 279) but the caller discards this return value (line 196, using _). If the outputs are needed for debugging, logging, or validation, consider capturing and using them.

@Mzack9999
Copy link
Member Author

@coderabbitai resolve

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
runner/headless.go (2)

302-315: Consider adding context to JS execution errors.

When a JS snippet fails to execute, the error doesn't indicate which snippet in the slice caused the failure. This could make debugging difficult when multiple JS codes are provided.

Consider wrapping the error with the index or a snippet of the failing JS:

 	for _, js := range jsc {
 		if js == "" {
 			continue
 		}
 		output, err := page.Eval(js)
 		if err != nil {
-			return nil, err
+			return nil, fmt.Errorf("failed to execute JS snippet (index %d): %w", len(outputs), err)
 		}
 		outputs = append(outputs, output)
 	}

302-315: Simplify method signature to return only error.

The method's return value []*proto.RuntimeRemoteObject is unused. The sole caller at line 209 discards it with _ and only checks the error. Change the signature to func (b *Browser) ExecuteJavascriptCodesWithPage(page *rod.Page, jsc []string) error and remove the outputs slice and return statement.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a7d7f5 and 1b6883c.

📒 Files selected for processing (1)
  • runner/headless.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Test Builds (ubuntu-latest)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Functional Test (windows-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Functional Test (ubuntu-latest)
🔇 Additional comments (3)
runner/headless.go (3)

208-213: JS injection timing is appropriate for the use case.

Executing JavaScript after navigation but before waiting for FirstMeaningfulPaint is the correct approach for the stated objective of manipulating client-side storage (e.g., localStorage) before the page fully renders. This allows injected code to modify page state that affects rendering and behavior.


220-238: Well-structured error handling with graceful degradation.

The incremental error handling is appropriate:

  • Critical errors (WaitLoad, screenshot) are propagated
  • Best-effort operations (WaitIdle) are attempted but not fatal
  • Partial success is supported (screenshot returned even if body extraction fails at line 234)

This allows useful data capture even when some operations fail.


240-243: LGTM!

Simple, focused cleanup method. Ignoring the Close error is acceptable for cleanup operations where no recovery is possible.

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

✅ Actions performed

Comments resolved.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
README.md (1)

133-133: Documentation for the new JavaScript injection flag is clear and consistent.

The flag is correctly positioned in the HEADLESS section, uses proper naming conventions, and accurately describes the feature with string[] to indicate multiple values can be provided.

Consider adding an example or cross-reference in the # Running httpx section to help users discover this feature. For instance, you might add a brief usage example showing how to inject a JavaScript snippet that sets localStorage entries, similar to how other complex features are illustrated.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b6883c and ef56623.

📒 Files selected for processing (1)
  • README.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test Builds (windows-latest)
  • GitHub Check: Test Builds (macOS-latest)
  • GitHub Check: Test Builds (ubuntu-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Functional Test (ubuntu-latest)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Functional Test (windows-latest)

@Mzack9999 Mzack9999 merged commit 649a85d into dev Oct 24, 2025
14 checks passed
@Mzack9999 Mzack9999 deleted the feat-2067-js-inject branch October 24, 2025 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Enhancement Most issues will probably ask for additions or changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Headless inject javascript

2 participants