package playwright import ( "encoding/base64" "fmt" "html/template" "io" "os" "path/filepath" "strings" "time" ) type AssertionResult struct { Message string Status string Error string Screenshot string // Base64 screenshot, only for failures } type TestResult struct { Name string Status string Timestamp time.Time Assertions []AssertionResult } type TestReporter struct { Results map[string]*TestResult } var globalReporter = &TestReporter{ Results: make(map[string]*TestResult), } func GetReporter() *TestReporter { return globalReporter } func (r *TestReporter) AddResult(testName string, passed bool, screenshotPath string, message, errorMessage string) { status := "Passed" if !passed { status = "Failed" } var screenshot string if !passed && screenshotPath != "" { imageFile, err := os.Open(screenshotPath) if err == nil { defer imageFile.Close() if data, err := io.ReadAll(imageFile); err == nil { screenshot = "data:image/png;base64," + base64.StdEncoding.EncodeToString(data) } else { fmt.Printf("Failed to read screenshot %s: %v\n", screenshotPath, err) } } else { fmt.Printf("Failed to open screenshot %s: %v\n", screenshotPath, err) } } // Get or create test result testResult, exists := r.Results[testName] if !exists { testResult = &TestResult{ Name: testName, Status: "Passed", Timestamp: time.Now(), Assertions: make([]AssertionResult, 0), } r.Results[testName] = testResult } // Add assertion result testResult.Assertions = append(testResult.Assertions, AssertionResult{ Message: message, Error: errorMessage, Status: status, Screenshot: screenshot, }) // Update test status if any assertion failed if !passed { testResult.Status = "Failed" } } func (r *TestReporter) GenerateHTML() error { const tmpl = `
Status: {{.Status}}
{{if eq .Status "Failed"}}{{if eq .Status "Passed"}}✓ {{end}}{{.Message}}
{{.Error}}
{{if .Screenshot}}