From 148b948a4b1235f271f3658dacb6c6ebd481e7e2 Mon Sep 17 00:00:00 2001 From: Josh at WLTechBlog Date: Tue, 16 Dec 2025 13:29:28 -0700 Subject: [PATCH] bump --- daemon/daemon.go | 143 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 130 insertions(+), 13 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index da874a5..fce3a4f 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -2653,6 +2653,9 @@ func (d *Daemon) isPageStable(page *rod.Page) (bool, error) { if err != nil { return false, err } + if result == nil { + return false, fmt.Errorf("page stability check returned nil result") + } isComplete := result.Value.Bool() @@ -2677,11 +2680,17 @@ func (d *Daemon) detectNavigationInProgress(page *rod.Page, monitorDuration time if err != nil { return false, err } + if currentURL == nil { + return false, fmt.Errorf("failed to get current URL: nil result") + } currentReadyState, err := page.Eval(`() => document.readyState`) if err != nil { return false, err } + if currentReadyState == nil { + return false, fmt.Errorf("failed to get current readyState: nil result") + } startURL := currentURL.Value.Str() startReadyState := currentReadyState.Value.Str() @@ -2701,12 +2710,12 @@ func (d *Daemon) detectNavigationInProgress(page *rod.Page, monitorDuration time case <-ticker.C: // Check if URL or readyState changed newURL, err := page.Eval(`() => window.location.href`) - if err != nil { + if err != nil || newURL == nil { continue // Ignore errors during monitoring } newReadyState, err := page.Eval(`() => document.readyState`) - if err != nil { + if err != nil || newReadyState == nil { continue // Ignore errors during monitoring } @@ -2905,6 +2914,9 @@ func (d *Daemon) fillFormField(tabID, selector, value string, selectionTimeout, if err != nil { return fmt.Errorf("failed to get element type attribute: %w", err) } + if tagName == nil || inputType == nil { + return fmt.Errorf("failed to get element properties: nil result") + } // Handle different input types tagNameStr := tagName.Value.String() @@ -3409,7 +3421,7 @@ func (d *Daemon) evalJS(tabID, jsCode string, timeout int) (string, error) { go func() { result, err := page.Eval(wrappedCode) var resultStr string - if err == nil { + if err == nil && result != nil { // Convert the result to a string representation if result.Value.Nil() { resultStr = "null" @@ -3439,6 +3451,9 @@ func (d *Daemon) evalJS(tabID, jsCode string, timeout int) (string, error) { if err != nil { return "", fmt.Errorf("failed to execute JavaScript: %w", err) } + if result == nil { + return "", fmt.Errorf("JavaScript execution returned nil result") + } // Convert the result to a string representation if result.Value.Nil() { @@ -3535,7 +3550,7 @@ func (d *Daemon) takeScreenshotEnhanced(tabID, outputPath string, fullPage bool, height: window.innerHeight }; }`) - if err == nil { + if err == nil && currentViewport != nil { var viewportData struct { Width int `json:"width"` Height int `json:"height"` @@ -4401,9 +4416,9 @@ func (d *Daemon) extractMultiple(tabID, selectorsJSON string, timeout int) (*Mul var err error // Check if it's a form input element and get its value - tagName, _ := element.Eval("() => this.tagName.toLowerCase()") + tagName, err := element.Eval("() => this.tagName.toLowerCase()") - if tagName.Value.Str() == "input" || tagName.Value.Str() == "textarea" || tagName.Value.Str() == "select" { + if err == nil && tagName != nil && (tagName.Value.Str() == "input" || tagName.Value.Str() == "textarea" || tagName.Value.Str() == "select") { // For form elements, get the value property valueProp, err := element.Property("value") if err == nil && valueProp.Str() != "" { @@ -4718,7 +4733,7 @@ func (d *Daemon) extractText(tabID, selector, pattern, extractType string, timeo case "innerText": // Use JavaScript to get innerText jsResult, jsErr := element.Eval("() => this.innerText") - if jsErr == nil && jsResult.Value.Str() != "" { + if jsErr == nil && jsResult != nil && jsResult.Value.Str() != "" { text = jsResult.Value.Str() } else { text, err = element.Text() // Fallback @@ -4726,7 +4741,7 @@ func (d *Daemon) extractText(tabID, selector, pattern, extractType string, timeo case "textContent": // Use JavaScript to get textContent jsResult, jsErr := element.Eval("() => this.textContent") - if jsErr == nil && jsResult.Value.Str() != "" { + if jsErr == nil && jsResult != nil && jsResult.Value.Str() != "" { text = jsResult.Value.Str() } else { text, err = element.Text() // Fallback @@ -4877,7 +4892,7 @@ func (d *Daemon) analyzeForm(tabID, selector string, timeout int) (*FormAnalysis field.Type = *fieldType } else { // Get tag name if no type - if tagName, err := element.Eval("() => this.tagName.toLowerCase()"); err == nil { + if tagName, err := element.Eval("() => this.tagName.toLowerCase()"); err == nil && tagName != nil { field.Type = tagName.Value.Str() } } @@ -5376,6 +5391,9 @@ func (d *Daemon) getPageInfo(tabID string, timeout int) (*PageInfo, error) { if err != nil { return nil, fmt.Errorf("failed to execute JavaScript: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("page info JavaScript returned nil result") + } // Parse the JavaScript result if props := jsResult.Value.Map(); props != nil { @@ -5459,6 +5477,9 @@ func (d *Daemon) getViewportInfo(tabID string, timeout int) (*ViewportInfo, erro if err != nil { return nil, fmt.Errorf("failed to execute JavaScript: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("viewport info JavaScript returned nil result") + } // Parse the JavaScript result if props := jsResult.Value.Map(); props != nil { @@ -5556,6 +5577,9 @@ func (d *Daemon) getPerformance(tabID string, timeout int) (*PerformanceMetrics, if err != nil { return nil, fmt.Errorf("failed to execute JavaScript: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("performance metrics JavaScript returned nil result") + } // Parse the JavaScript result if props := jsResult.Value.Map(); props != nil { @@ -5726,6 +5750,9 @@ func (d *Daemon) checkContent(tabID string, contentType string, timeout int) (*C if err != nil { return nil, fmt.Errorf("failed to execute JavaScript: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("content check JavaScript returned nil result") + } // Parse the JavaScript result if props := jsResult.Value.Map(); props != nil { @@ -5869,6 +5896,9 @@ func (d *Daemon) screenshotEnhanced(tabID, outputPath string, fullPage bool, tim if err != nil { return nil, fmt.Errorf("failed to get viewport: %w", err) } + if viewport == nil { + return nil, fmt.Errorf("viewport evaluation returned nil result") + } viewportData := viewport.Value.Map() viewportWidth := int(viewportData["width"].Num()) @@ -8991,7 +9021,7 @@ func (d *Daemon) runAxeCore(tabID string, options map[string]interface{}, timeou // Check if axe is loaded, auto-inject if not checkCode := `() => typeof axe !== 'undefined'` checkResult, err := page.Eval(checkCode) - if err != nil || !checkResult.Value.Bool() { + if err != nil || checkResult == nil || !checkResult.Value.Bool() { d.debugLog("axe-core not loaded, auto-injecting...") if err := d.injectAxeCore(tabID, "", 30); err != nil { return nil, fmt.Errorf("failed to auto-inject axe-core: %v", err) @@ -9048,6 +9078,10 @@ func (d *Daemon) runAxeCore(tabID string, options map[string]interface{}, timeou } } + if jsResult == nil { + return nil, fmt.Errorf("axe-core execution returned nil result") + } + // Parse the results resultsJSON := jsResult.Value.Str() var results AxeResults @@ -9575,6 +9609,10 @@ func (d *Daemon) checkContrast(tabID string, selector string, timeout int) (*Con } } + if jsResult == nil { + return nil, fmt.Errorf("contrast check returned nil result") + } + // Parse the results resultsJSON := jsResult.Value.Str() var elements []ContrastCheckElement @@ -9672,6 +9710,9 @@ func (d *Daemon) checkGradientContrast(tabID string, selector string, timeout in if err != nil { return nil, fmt.Errorf("failed to get element styles: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("element styles evaluation returned nil result") + } var styleInfo struct { Color string `json:"color"` @@ -9984,6 +10025,9 @@ func (d *Daemon) validateMedia(tabID string, timeout int) (*MediaValidationResul if err != nil { return nil, fmt.Errorf("failed to execute media validation: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("media validation returned nil result") + } // Parse the JavaScript result var mediaData struct { @@ -10111,6 +10155,9 @@ func (d *Daemon) checkTrackAccessibility(tabID, trackSrc string, timeout int) (b if err != nil { return false, err } + if jsResult == nil { + return false, fmt.Errorf("track validation returned nil result") + } return jsResult.Value.Bool(), nil } @@ -10230,6 +10277,9 @@ func (d *Daemon) testHoverFocusContent(tabID string, timeout int) (*HoverFocusTe if err != nil { return nil, fmt.Errorf("failed to find hover/focus elements: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("hover/focus element search returned nil result") + } // Parse the JavaScript result var elementsData struct { @@ -10378,6 +10428,9 @@ func (d *Daemon) detectTextInImages(tabID string, timeout int) (*TextInImagesRes if err != nil { return nil, fmt.Errorf("failed to find images: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("image search returned nil result") + } // Parse the JavaScript result var imagesData struct { @@ -10698,6 +10751,9 @@ func (d *Daemon) analyzePageConsistency(tabID, url string, timeout int) (*PageCo if err != nil { return nil, fmt.Errorf("failed to analyze page structure: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("page structure analysis returned nil result") + } // Parse the JavaScript result var analysis PageConsistencyAnalysis @@ -10859,6 +10915,9 @@ func (d *Daemon) detectAnimationFlash(tabID string, timeout int) (*AnimationFlas if err != nil { return nil, fmt.Errorf("failed to detect animations: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("animation detection returned nil result") + } // Parse the JavaScript result var animationsData struct { @@ -11111,6 +11170,9 @@ func (d *Daemon) analyzeEnhancedAccessibility(tabID string, timeout int) (*Enhan if err != nil { return nil, fmt.Errorf("failed to analyze accessibility: %v", err) } + if jsResult == nil { + return nil, fmt.Errorf("accessibility analysis returned nil result") + } // Parse the JavaScript result var elementsData struct { @@ -11322,6 +11384,9 @@ func (d *Daemon) detectAccessibilityFeatures(page *rod.Page) (*AccessibilityFeat if err != nil { return nil, fmt.Errorf("failed to detect accessibility features: %w", err) } + if result == nil { + return nil, fmt.Errorf("accessibility features detection returned nil result") + } var features AccessibilityFeatures err = json.Unmarshal([]byte(result.Value.String()), &features) @@ -11524,6 +11589,10 @@ func (d *Daemon) testKeyboardNavigationWithRealKeys(tabID string, timeout int) ( } } + if jsResult == nil { + return nil, fmt.Errorf("interactive elements scan returned nil result") + } + // Parse initial results var initialResult KeyboardTestResult err = json.Unmarshal([]byte(jsResult.Value.String()), &initialResult) @@ -11617,6 +11686,10 @@ func (d *Daemon) testKeyboardNavigationWithRealKeys(tabID string, timeout int) ( d.debugLog("Warning: failed to check focused element: %v", err) break } + if checkResult == nil { + d.debugLog("Warning: focus check returned nil result") + break + } var focusInfo struct { Done bool `json:"done"` @@ -11744,6 +11817,9 @@ func (d *Daemon) testZoom(tabID string, zoomLevels []float64, timeout int) (*Zoo if err != nil { return nil, fmt.Errorf("failed to get viewport size: %w", err) } + if originalViewport == nil { + return nil, fmt.Errorf("viewport size evaluation returned nil result") + } var viewportData struct { Width int `json:"width"` @@ -11896,6 +11972,16 @@ func (d *Daemon) testZoom(tabID string, zoomLevels []float64, timeout int) (*Zoo } } + if jsResult == nil { + result.Issues = append(result.Issues, ZoomTestIssue{ + ZoomLevel: zoom, + Type: "nil_result", + Severity: "high", + Description: "Evaluation returned nil result", + }) + continue + } + // Parse the results var zoomTest ZoomLevelTest resultStr := jsResult.Value.Str() @@ -12014,6 +12100,9 @@ func (d *Daemon) testReflow(tabID string, widths []int, timeout int) (*ReflowTes if err != nil { return nil, fmt.Errorf("failed to get viewport size: %w", err) } + if originalViewport == nil { + return nil, fmt.Errorf("viewport size evaluation returned nil result") + } var viewportData struct { Width int `json:"width"` @@ -12155,6 +12244,16 @@ func (d *Daemon) testReflow(tabID string, widths []int, timeout int) (*ReflowTes } } + if jsResult == nil { + result.Issues = append(result.Issues, ReflowTestIssue{ + Width: width, + Type: "nil_result", + Severity: "high", + Description: "Evaluation returned nil result", + }) + continue + } + // Parse the results var breakpoint ReflowBreakpoint err = json.Unmarshal([]byte(jsResult.Value.Str()), &breakpoint) @@ -12839,6 +12938,9 @@ func (d *Daemon) getFormAccessibilityAudit(tabID, formSelector string, timeout i if result.err != nil { return nil, fmt.Errorf("failed to analyze forms: %v", result.err) } + if result.result == nil { + return nil, fmt.Errorf("form analysis returned nil result") + } // Convert the result to JSON jsonBytes, err := json.Marshal(result.result.Value.Val()) if err != nil { @@ -12853,6 +12955,9 @@ func (d *Daemon) getFormAccessibilityAudit(tabID, formSelector string, timeout i if err != nil { return nil, fmt.Errorf("failed to analyze forms: %v", err) } + if res == nil { + return nil, fmt.Errorf("form analysis returned nil result") + } // Convert the result to JSON jsonBytes, err := json.Marshal(res.Value.Val()) if err != nil { @@ -13109,10 +13214,14 @@ func (d *Daemon) extractDiviStructure(tabID string, timeout int) (*DiviStructure go func() { data, err := page.Eval(jsCode) + var value interface{} + if data != nil { + value = data.Value + } done <- struct { data interface{} err error - }{data.Value, err} + }{value, err} }() select { @@ -13217,10 +13326,14 @@ func (d *Daemon) extractDiviImages(tabID string, timeout int) ([]DiviImage, erro go func() { data, err := page.Eval(jsCode) + var value interface{} + if data != nil { + value = data.Value + } done <- struct { data interface{} err error - }{data.Value, err} + }{value, err} }() select { @@ -13361,10 +13474,14 @@ func (d *Daemon) extractDiviContent(tabID string, timeout int) (*DiviContent, er go func() { data, err := page.Eval(jsCode) + var value interface{} + if data != nil { + value = data.Value + } done <- struct { data interface{} err error - }{data.Value, err} + }{value, err} }() select {