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 = ` Test Results

Test Results

{{range .Results}}

{{.Name}}

Status: {{.Status}}

{{if eq .Status "Failed"}} {{end}}
{{end}} ` t := template.New("report") t = t.Funcs(template.FuncMap{ "toLowerCase": strings.ToLower, "safeHTML": func(s string) template.HTML { return template.HTML(s) }, "safeURL": func(s string) template.URL { return template.URL(s) }, }) t, err := t.Parse(tmpl) if err != nil { return fmt.Errorf("failed to parse template: %v", err) } if err := os.MkdirAll("test-results", 0755); err != nil { return fmt.Errorf("failed to create results directory: %v", err) } basePath := os.Getenv("CONTEXT_PATH") if basePath == "" { basePath = "." } f, err := os.Create(filepath.Join(basePath, "e2e-report.html")) if err != nil { return fmt.Errorf("failed to create report file: %v", err) } defer f.Close() return t.Execute(f, r) }