package test import ( "encoding/json" "fmt" "os" "testing" "time" "git.teamworkapps.com/shortcut/cremote/client" ) const ( testServerURL = "http://localhost:8080" daemonAddr = "localhost:9223" ) // TestAccessibilityToolsIntegration runs comprehensive integration tests for all accessibility tools func TestAccessibilityToolsIntegration(t *testing.T) { // Skip if not in integration test mode if os.Getenv("INTEGRATION_TESTS") != "true" { t.Skip("Skipping integration tests. Set INTEGRATION_TESTS=true to run.") } // Create client c := client.NewClient(daemonAddr) // Wait for daemon to be ready time.Sleep(2 * time.Second) // Navigate to test page err := c.Navigate("", testServerURL+"/test-accessible.html", false, 10) if err != nil { t.Fatalf("Failed to navigate to test page: %v", err) } // Wait for page load time.Sleep(2 * time.Second) // Run all accessibility tests t.Run("AxeCoreIntegration", testAxeCoreIntegration(c)) t.Run("ContrastChecking", testContrastChecking(c)) t.Run("KeyboardNavigation", testKeyboardNavigation(c)) t.Run("ZoomTesting", testZoomTesting(c)) t.Run("ReflowTesting", testReflowTesting(c)) t.Run("ScreenshotEnhancements", testScreenshotEnhancements(c)) t.Run("LibraryInjection", testLibraryInjection(c)) t.Run("AccessibilityTree", testAccessibilityTree(c)) } // testAxeCoreIntegration tests axe-core injection and execution func testAxeCoreIntegration(c *client.Client) func(*testing.T) { return func(t *testing.T) { // Inject axe-core err := c.InjectAxeCore("", "4.8.0", 30) if err != nil { t.Fatalf("Failed to inject axe-core: %v", err) } // Run axe tests runOnly := []string{"wcag2a", "wcag2aa"} result, err := c.RunAxeCore("", runOnly, nil, 30) if err != nil { t.Fatalf("Failed to run axe-core: %v", err) } // Verify result structure if result == nil { t.Fatal("Axe result is nil") } // Check that we got some results totalChecks := len(result.Violations) + len(result.Passes) + len(result.Incomplete) + len(result.Inapplicable) if totalChecks == 0 { t.Error("Axe-core returned no results") } t.Logf("Axe-core results: %d violations, %d passes, %d incomplete, %d inapplicable", len(result.Violations), len(result.Passes), len(result.Incomplete), len(result.Inapplicable)) // For accessible page, we expect few or no violations if len(result.Violations) > 5 { t.Errorf("Expected few violations on accessible page, got %d", len(result.Violations)) } } } // testContrastChecking tests color contrast checking func testContrastChecking(c *client.Client) func(*testing.T) { return func(t *testing.T) { result, err := c.CheckContrast("", "body", 10) if err != nil { t.Fatalf("Failed to check contrast: %v", err) } if result == nil { t.Fatal("Contrast result is nil") } // Verify result structure if result.TotalElements == 0 { t.Error("No elements checked for contrast") } t.Logf("Contrast check: %d elements, %d AA pass, %d AA fail, %d AAA pass, %d AAA fail", result.TotalElements, result.WCAGAAPass, result.WCAGAAFail, result.WCAGAAAPass, result.WCAGAAAFail) // For accessible page, we expect high AA pass rate if result.TotalElements > 0 { passRate := float64(result.WCAGAAPass) / float64(result.TotalElements) if passRate < 0.8 { t.Errorf("Expected high AA pass rate on accessible page, got %.2f%%", passRate*100) } } // Verify violation details for _, violation := range result.Violations { if violation.Ratio == 0 { t.Error("Violation has zero contrast ratio") } if violation.Element == "" { t.Error("Violation missing element selector") } } } } // testKeyboardNavigation tests keyboard navigation testing func testKeyboardNavigation(c *client.Client) func(*testing.T) { return func(t *testing.T) { result, err := c.TestKeyboard("", 10) if err != nil { t.Fatalf("Failed to test keyboard navigation: %v", err) } if result == nil { t.Fatal("Keyboard test result is nil") } // Verify result structure if result.TotalElements == 0 { t.Error("No interactive elements found") } t.Logf("Keyboard test: %d elements, %d focusable, %d not focusable, %d missing focus indicator, %d keyboard traps", result.TotalElements, result.Focusable, result.NotFocusable, result.MissingFocusIndicator, result.KeyboardTraps) // For accessible page, we expect high focusability rate if result.TotalElements > 0 { focusableRate := float64(result.Focusable) / float64(result.TotalElements) if focusableRate < 0.8 { t.Errorf("Expected high focusability rate on accessible page, got %.2f%%", focusableRate*100) } } // Verify tab order if len(result.TabOrder) == 0 { t.Error("Tab order is empty") } // Verify issue details for _, issue := range result.Issues { if issue.Type == "" { t.Error("Issue missing type") } if issue.Element == "" { t.Error("Issue missing element selector") } } } } // testZoomTesting tests zoom functionality testing func testZoomTesting(c *client.Client) func(*testing.T) { return func(t *testing.T) { zoomLevels := []float64{1.0, 2.0, 4.0} result, err := c.TestZoom("", zoomLevels, 10) if err != nil { t.Fatalf("Failed to test zoom: %v", err) } if result == nil { t.Fatal("Zoom test result is nil") } // Verify we tested all zoom levels if len(result.ZoomLevels) != len(zoomLevels) { t.Errorf("Expected %d zoom levels, got %d", len(zoomLevels), len(result.ZoomLevels)) } t.Logf("Zoom test: tested %d levels, found %d issues", len(result.ZoomLevels), len(result.Issues)) // Verify zoom level details for _, zoomTest := range result.ZoomLevels { if zoomTest.ZoomLevel == 0 { t.Error("Zoom level is zero") } if zoomTest.ViewportWidth == 0 || zoomTest.ViewportHeight == 0 { t.Error("Viewport dimensions are zero") } // For accessible page at 200%, we expect no horizontal scroll if zoomTest.ZoomLevel == 2.0 && zoomTest.HasHorizontalScroll { t.Error("Expected no horizontal scroll at 200% zoom on accessible page") } } } } // testReflowTesting tests responsive reflow testing func testReflowTesting(c *client.Client) func(*testing.T) { return func(t *testing.T) { widths := []int{320, 1280} result, err := c.TestReflow("", widths, 10) if err != nil { t.Fatalf("Failed to test reflow: %v", err) } if result == nil { t.Fatal("Reflow test result is nil") } // Verify we tested all widths if len(result.Breakpoints) != len(widths) { t.Errorf("Expected %d breakpoints, got %d", len(widths), len(result.Breakpoints)) } t.Logf("Reflow test: tested %d breakpoints, found %d issues", len(result.Breakpoints), len(result.Issues)) // Verify breakpoint details for _, breakpoint := range result.Breakpoints { if breakpoint.Width == 0 { t.Error("Breakpoint width is zero") } if breakpoint.Height == 0 { t.Error("Breakpoint height is zero") } // For accessible page at 320px, we expect no horizontal scroll if breakpoint.Width == 320 && breakpoint.HasHorizontalScroll { t.Error("Expected no horizontal scroll at 320px on accessible page") } // Verify responsive layout if !breakpoint.ResponsiveLayout { t.Errorf("Expected responsive layout at %dpx", breakpoint.Width) } } } } // testScreenshotEnhancements tests enhanced screenshot functionality func testScreenshotEnhancements(c *client.Client) func(*testing.T) { return func(t *testing.T) { // Test basic screenshot err := c.TakeScreenshot("", "/tmp/test-screenshot.png", false, 5) if err != nil { t.Fatalf("Failed to take screenshot: %v", err) } // Verify file exists if _, err := os.Stat("/tmp/test-screenshot.png"); os.IsNotExist(err) { t.Error("Screenshot file was not created") } // Clean up os.Remove("/tmp/test-screenshot.png") t.Log("Screenshot functionality verified") } } // testLibraryInjection tests library injection via console_command func testLibraryInjection(c *client.Client) func(*testing.T) { return func(t *testing.T) { // Test injecting jQuery params := map[string]string{ "command": "typeof jQuery", "inject_library": "jquery", "timeout": "10", } resp, err := c.SendCommand("console-command", params) if err != nil { t.Fatalf("Failed to execute console command with library injection: %v", err) } if !resp.Success { t.Fatalf("Console command failed: %s", resp.Error) } // Verify jQuery was injected if resp.Data == nil { t.Error("Console command returned no data") } t.Log("Library injection functionality verified") } } // testAccessibilityTree tests accessibility tree retrieval func testAccessibilityTree(c *client.Client) func(*testing.T) { return func(t *testing.T) { depth := 3 result, err := c.GetAccessibilityTree("", &depth, 10) if err != nil { t.Fatalf("Failed to get accessibility tree: %v", err) } if result == nil { t.Fatal("Accessibility tree result is nil") } // Verify we got nodes if len(result.Nodes) == 0 { t.Error("Accessibility tree has no nodes") } t.Logf("Accessibility tree: %d nodes", len(result.Nodes)) // Verify node structure foundRootNode := false for _, node := range result.Nodes { if node.NodeID == "" { t.Error("Node missing NodeID") } // Check for root node if node.Role != nil && node.Role.Value == "WebArea" { foundRootNode = true } } if !foundRootNode { t.Error("No root node found in accessibility tree") } } } // TestInaccessiblePage tests tools against a page with known accessibility issues func TestInaccessiblePage(t *testing.T) { // Skip if not in integration test mode if os.Getenv("INTEGRATION_TESTS") != "true" { t.Skip("Skipping integration tests. Set INTEGRATION_TESTS=true to run.") } c := client.NewClient(daemonAddr) // Navigate to inaccessible test page err := c.Navigate("", testServerURL+"/test-inaccessible.html", false, 10) if err != nil { t.Fatalf("Failed to navigate to test page: %v", err) } time.Sleep(2 * time.Second) // Inject and run axe-core err = c.InjectAxeCore("", "4.8.0", 30) if err != nil { t.Fatalf("Failed to inject axe-core: %v", err) } runOnly := []string{"wcag2a", "wcag2aa"} result, err := c.RunAxeCore("", runOnly, nil, 30) if err != nil { t.Fatalf("Failed to run axe-core: %v", err) } // For inaccessible page, we expect violations if len(result.Violations) == 0 { t.Error("Expected violations on inaccessible page, got none") } t.Logf("Found %d violations on inaccessible page (expected)", len(result.Violations)) // Test contrast checking - expect failures contrastResult, err := c.CheckContrast("", "body", 10) if err != nil { t.Fatalf("Failed to check contrast: %v", err) } if contrastResult.WCAGAAFail == 0 { t.Error("Expected contrast failures on inaccessible page, got none") } t.Logf("Found %d contrast failures on inaccessible page (expected)", contrastResult.WCAGAAFail) } // BenchmarkAxeCore benchmarks axe-core execution func BenchmarkAxeCore(b *testing.B) { if os.Getenv("INTEGRATION_TESTS") != "true" { b.Skip("Skipping integration tests. Set INTEGRATION_TESTS=true to run.") } c := client.NewClient(daemonAddr) // Navigate once c.Navigate("", testServerURL+"/test-accessible.html", false, 10) time.Sleep(2 * time.Second) // Inject once c.InjectAxeCore("", "4.8.0", 30) b.ResetTimer() for i := 0; i < b.N; i++ { runOnly := []string{"wcag2aa"} _, err := c.RunAxeCore("", runOnly, nil, 30) if err != nil { b.Fatalf("Failed to run axe-core: %v", err) } } } // Helper function to pretty print JSON func prettyPrint(v interface{}) string { b, err := json.MarshalIndent(v, "", " ") if err != nil { return fmt.Sprintf("%+v", v) } return string(b) }