Skip to content

Conversation

@Serizao
Copy link
Contributor

@Serizao Serizao commented Jul 23, 2025

on classical page with alert the browser fall un timeout beacause alert block loading. This pr lead to close alert and take screen

Summary by CodeRabbit

  • Bug Fixes
    • Screenshot operations now automatically accept unexpected JavaScript dialogs (including those triggered during page load or interaction), preventing interruptions and making captures more reliable. No public APIs or behaviors were changed.

on classical page with alert the browser fall un timeout beacause alert block loading. This pr lead to close alert and take screen
@coderabbitai
Copy link

coderabbitai bot commented Jul 23, 2025

Walkthrough

ScreenshotWithBody now registers a PageJavascriptDialogOpening event handler (via page.EachEvent) in a goroutine that calls PageHandleJavaScriptDialog with Accept:true and empty PromptText to auto-accept dialogs before headers, navigation, and screenshot capture.

Changes

Cohort / File(s) Change Summary
Browser dialog handling
runner/headless.go
Replaced previous dialog handling approach with an event-based handler: spawns a goroutine that registers a PageJavascriptDialogOpening event via page.EachEvent and calls PageHandleJavaScriptDialog{Accept:true, PromptText:""} to automatically accept dialogs prior to applying headers and navigation.
Lint/comment removal
runner/runner.go
Removed a // nolint:gomnd directive; the host percentage calculation now uses the literal 100.0 without the nolint suppression. No behavior changes.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Browser.ScreenshotWithBody
    participant Page as page
    participant Goroutine as Dialog Goroutine

    Browser->>Page: start goroutine: page.EachEvent(PageJavascriptDialogOpening, handler)
    Note right of Goroutine #F0F8FF: handler -> PageHandleJavaScriptDialog(Accept:true, PromptText:"")
    Browser->>Page: set headers
    Browser->>Page: navigate / interact
    alt JavaScript dialog opens
        Page->>Goroutine: emit PageJavascriptDialogOpening event
        Goroutine->>Page: invoke PageHandleJavaScriptDialog(Accept:true, PromptText:"")
    end
    Browser->>Browser: continue timeout/wait/screenshot/html retrieval
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly reflects the PR's primary intent — dismissing/handling alerts so a screenshot can be taken to avoid timeouts — and matches the changes in runner/headless.go that auto-accept JavaScript dialogs before navigation; therefore it is related and informative for a quick scan. The phrasing is slightly awkward ("lead to"), but it still conveys the main change unambiguously.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

In my burrow I listen, whiskers alert,
A pop-up appears — I handle the spurt.
I accept with a hop, no pause or delay,
Screenshots proceed, clear as the day. 🐇

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbba454 and d9a2775.

📒 Files selected for processing (1)
  • runner/headless.go (1 hunks)

@ehsandeep ehsandeep changed the base branch from main to dev July 23, 2025 13:31
@Mzack9999 Mzack9999 self-requested a review September 12, 2025 10:22
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

♻️ Duplicate comments (2)
runner/headless.go (2)

107-114: Security/regression caution: auto-accepts all dialogs, not just alerts.

Accepting confirm/prompt can trigger unintended actions. Consider restricting to alerts only, or making behavior configurable.

Example approach (conceptual):

// Pseudocode: react based on dialog type
wait := page.WaitEvent(&proto.PageJavascriptDialogOpening{})
go func() {
    for {
        ev := wait().(*proto.PageJavascriptDialogOpening)
        accept := ev.Type == "alert" // dismiss only alerts by "OK"
        _ = proto.PageHandleJavaScriptDialog{Accept: accept}.Call(page)
    }
}()

Would you prefer a follow-up PR that introduces a flag (e.g., --dialog-policy=alerts-only|accept-all|dismiss-non-alerts) and appropriate logging?


110-113: Check and handle error returned by handle() (fix errcheck)

handle(&proto.PageHandleJavaScriptDialog{...}) returns an error — check it to satisfy errcheck and avoid silent failures.

File: runner/headless.go lines 110–113

-        handle(&proto.PageHandleJavaScriptDialog{
-            Accept:     true,
-            PromptText: "",
-        })
+        if err := handle(&proto.PageHandleJavaScriptDialog{
+            Accept:     true,
+            PromptText: "",
+        }); err != nil {
+            // best-effort: ignore dialog handling errors (e.g., page closed)
+        }

After patch, verify with: golangci-lint run ./...

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

107-114: Make dialog handling resilient to multiple dialogs and panics.

Handle more than one dialog and guard against potential panics if the page closes mid-wait.

Apply this diff:

-    go func() {
-        wait()
-        if err := handle(&proto.PageHandleJavaScriptDialog{
-            Accept:     true,
-            PromptText: "",
-        }); err != nil {
-            // best-effort: ignore dialog handling errors (e.g., page closed) to avoid crashing
-        }
-    }()
+    go func() {
+        defer func() { _ = recover() }() // defensive: rod may panic on page teardown
+        for {
+            wait()
+            if err := handle(&proto.PageHandleJavaScriptDialog{
+                Accept:     true,
+                PromptText: "",
+            }); err != nil {
+                break // stop on error (page closed, no target, etc.)
+            }
+        }
+    }()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04fd376 and 84a54b9.

📒 Files selected for processing (1)
  • runner/headless.go (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Lint Test
runner/headless.go

[failure] 110-110:
Error return value is not checked (errcheck)

⏰ 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). (4)
  • GitHub Check: release-test
  • GitHub Check: Analyze (go)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Functional Test (windows-latest)

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

♻️ Duplicate comments (1)
runner/headless.go (1)

107-114: Safer handling: dismiss beforeunload, keep accepting others; don’t swallow errors.

Accepting all dialog types can unintentionally confirm beforeunload navigations. Prefer dismissing beforeunload while still accepting alert/confirm/prompt; also surface errors (even as debug) rather than assigning to _. CDP explicitly distinguishes dialog types and semantics for Page.handleJavaScriptDialog. (chromedevtools.github.io)

Apply within this hunk:

-go page.EachEvent(func(e *proto.PageJavascriptDialogOpening) {
-	_ = proto.PageHandleJavaScriptDialog{
-		Accept:     true,
-		PromptText: "",
-	}.Call(page)
-})()
+go page.EachEvent(func(e *proto.PageJavascriptDialogOpening) {
+	// Accept alerts/confirm/prompts to unblock; dismiss beforeunload to avoid unintended navigations.
+	h := proto.PageHandleJavaScriptDialog{Accept: true}
+	switch string(e.Type) { // values: "alert" | "confirm" | "prompt" | "beforeunload"
+	case "beforeunload":
+		h.Accept = false
+	case "prompt":
+		h.PromptText = ""
+	}
+	if err := h.Call(page); err != nil {
+		// TODO: optional debug log; keep non-fatal to avoid impacting screenshot flow
+	}
+})()
🧹 Nitpick comments (1)
runner/headless.go (1)

107-114: Optional: add minimal observability and guardrails.

  • Log dialog type/message at verbose level for auditability and repros.
  • Consider a soft cap (e.g., <= 50 dialogs/page) to avoid pathological pages firing dialog storms.
    These are nice-to-haves; the current fix is functional. (github.com)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84a54b9 and ad83070.

📒 Files selected for processing (2)
  • runner/headless.go (1 hunks)
  • runner/runner.go (0 hunks)
💤 Files with no reviewable changes (1)
  • runner/runner.go
⏰ 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). (4)
  • GitHub Check: Analyze (go)
  • GitHub Check: Functional Test (macOS-latest)
  • GitHub Check: Functional Test (ubuntu-latest)
  • GitHub Check: Functional Test (windows-latest)
🔇 Additional comments (1)
runner/headless.go (1)

107-114: LGTM: event-based dialog handling prevents hangs before navigation.

Registering a Page.javascriptDialogOpening listener via page.EachEvent and accepting dialogs asynchronously is the right pattern here and should eliminate alert-induced timeouts during load. This mirrors Rod’s documented approach and prior guidance to handle dialogs via events. (github.com)

@Mzack9999
Copy link
Member

@coderabbitai resolve
@coderabbitai make an issue for this

@coderabbitai
Copy link

coderabbitai bot commented Sep 12, 2025

🧩 Analysis chain

@Mzack9999 I'll resolve the review comments and create an issue for this PR.


🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for the alert dismissal feature
gh issue create \
  --title "Implement alert dismissal for screenshot functionality" \
  --body "This issue tracks the implementation of automatic JavaScript alert dismissal when taking screenshots to prevent browser timeouts.

## Background
On pages with JavaScript alerts, the browser times out because the alert blocks page loading. This prevents successful screenshot capture.

## Solution
Implement automatic alert dismissal by:
- Registering a PageJavascriptDialogOpening event handler
- Automatically accepting dialogs with PageHandleJavaScriptDialog
- Setting up event-based handling before navigation

## Reference
- Pull Request: https://github.com/projectdiscovery/httpx/pull/2219
- Requested by: @Mzack9999
- Original implementation by: @Serizao

## Files to modify
- runner/headless.go: ScreenshotWithBody method" \
  --assignee Mzack9999

Length of output: 53


@Mzack9999 Done! I've resolved all review comments and created issue #2267 for implementing the alert dismissal functionality: #2267

The issue includes the background context, proposed solution details, and references to this PR for tracking purposes.

✅ Actions performed

Comments resolved.

@Mzack9999 Mzack9999 linked an issue Sep 12, 2025 that may be closed by this pull request
@Mzack9999 Mzack9999 merged commit 8f6a1ca into projectdiscovery:dev Sep 12, 2025
15 checks passed
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.

Implement alert dismissal for screenshot functionality

2 participants