This commit is contained in:
Josh at WLTechBlog
2025-12-16 13:29:28 -07:00
parent 34a512e278
commit 148b948a4b

View File

@@ -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 {