@@ -477,3 +477,158 @@ func TestBrowserEvaluate_ScriptContainsExpression(t *testing.T) {
477477 t .Error ("script should use page.evaluate" )
478478 }
479479}
480+
481+ // ---------------------------------------------------------------------------
482+ // Integration tests — require Docker and network access
483+ // ---------------------------------------------------------------------------
484+
485+ func TestBrowserNavigate_Integration (t * testing.T ) {
486+ if testing .Short () {
487+ t .Skip ("skipping integration test" )
488+ }
489+ dockerAvailableForBrowser (t )
490+
491+ c := & BrowserNavigateConnector {}
492+ out , err := c .Execute (context .Background (), map [string ]any {
493+ "url" : "https://example.com" ,
494+ "pull" : "missing" ,
495+ })
496+ if err != nil {
497+ t .Skipf ("Execute failed (may need network/npm): %v" , err )
498+ }
499+ title , _ := out ["title" ].(string )
500+ if ! strings .Contains (title , "Example Domain" ) {
501+ t .Errorf ("title = %q, want 'Example Domain'" , title )
502+ }
503+ if out ["session_state" ] == nil {
504+ t .Error ("session_state should be present in output" )
505+ }
506+ }
507+
508+ func TestBrowserNavigateExtract_SessionChain (t * testing.T ) {
509+ if testing .Short () {
510+ t .Skip ("skipping integration test" )
511+ }
512+ dockerAvailableForBrowser (t )
513+
514+ // Step 1: navigate
515+ nav := & BrowserNavigateConnector {}
516+ navOut , err := nav .Execute (context .Background (), map [string ]any {
517+ "url" : "https://example.com" ,
518+ "pull" : "missing" ,
519+ })
520+ if err != nil {
521+ t .Skipf ("navigate failed (may need network/npm): %v" , err )
522+ }
523+
524+ // Step 2: extract using session from step 1
525+ ext := & BrowserExtractConnector {}
526+ extOut , err := ext .Execute (context .Background (), map [string ]any {
527+ "selectors" : map [string ]any {"heading" : "h1" },
528+ "session_state" : navOut ["session_state" ],
529+ "pull" : "missing" ,
530+ })
531+ if err != nil {
532+ t .Skipf ("extract failed: %v" , err )
533+ }
534+ data , ok := extOut ["data" ].(map [string ]any )
535+ if ! ok {
536+ t .Fatalf ("data output is not a map: %T" , extOut ["data" ])
537+ }
538+ heading , _ := data ["heading" ].(string )
539+ if ! strings .Contains (heading , "Example Domain" ) {
540+ t .Errorf ("heading = %q, want 'Example Domain'" , heading )
541+ }
542+ }
543+
544+ func TestBrowserScreenshot_Integration (t * testing.T ) {
545+ if testing .Short () {
546+ t .Skip ("skipping integration test" )
547+ }
548+ dockerAvailableForBrowser (t )
549+
550+ nav := & BrowserNavigateConnector {}
551+ navOut , err := nav .Execute (context .Background (), map [string ]any {
552+ "url" : "https://example.com" ,
553+ "pull" : "missing" ,
554+ })
555+ if err != nil {
556+ t .Skipf ("navigate failed (may need network/npm): %v" , err )
557+ }
558+
559+ ss := & BrowserScreenshotConnector {}
560+ ssOut , err := ss .Execute (context .Background (), map [string ]any {
561+ "session_state" : navOut ["session_state" ],
562+ "pull" : "missing" ,
563+ })
564+ if err != nil {
565+ t .Skipf ("screenshot failed: %v" , err )
566+ }
567+ b64 , _ := ssOut ["base64" ].(string )
568+ if len (b64 ) == 0 {
569+ t .Error ("expected non-empty base64 screenshot" )
570+ }
571+ if ssOut ["path" ] != "screenshot.png" {
572+ t .Errorf ("path = %v, want screenshot.png" , ssOut ["path" ])
573+ }
574+ }
575+
576+ func TestBrowserEvaluate_Integration (t * testing.T ) {
577+ if testing .Short () {
578+ t .Skip ("skipping integration test" )
579+ }
580+ dockerAvailableForBrowser (t )
581+
582+ nav := & BrowserNavigateConnector {}
583+ navOut , err := nav .Execute (context .Background (), map [string ]any {
584+ "url" : "https://example.com" ,
585+ "pull" : "missing" ,
586+ })
587+ if err != nil {
588+ t .Skipf ("navigate failed (may need network/npm): %v" , err )
589+ }
590+
591+ ev := & BrowserEvaluateConnector {}
592+ evOut , err := ev .Execute (context .Background (), map [string ]any {
593+ "expression" : "document.location.hostname" ,
594+ "session_state" : navOut ["session_state" ],
595+ "pull" : "missing" ,
596+ })
597+ if err != nil {
598+ t .Skipf ("evaluate failed: %v" , err )
599+ }
600+ result , _ := evOut ["result" ].(string )
601+ if result != "example.com" {
602+ t .Errorf ("result = %q, want %q" , result , "example.com" )
603+ }
604+ }
605+
606+ func TestBrowserWait_TimeoutError_Integration (t * testing.T ) {
607+ if testing .Short () {
608+ t .Skip ("skipping integration test" )
609+ }
610+ dockerAvailableForBrowser (t )
611+
612+ nav := & BrowserNavigateConnector {}
613+ navOut , err := nav .Execute (context .Background (), map [string ]any {
614+ "url" : "https://example.com" ,
615+ "pull" : "missing" ,
616+ })
617+ if err != nil {
618+ t .Skipf ("navigate failed (may need network/npm): %v" , err )
619+ }
620+
621+ w := & BrowserWaitConnector {}
622+ _ , err = w .Execute (context .Background (), map [string ]any {
623+ "selector" : ".this-selector-does-not-exist" ,
624+ "session_state" : navOut ["session_state" ],
625+ "timeout_ms" : float64 (2000 ),
626+ "pull" : "missing" ,
627+ })
628+ if err == nil {
629+ t .Fatal ("expected error when selector not found within timeout" )
630+ }
631+ if ! strings .Contains (err .Error (), "browser/wait" ) {
632+ t .Errorf ("error = %q, want 'browser/wait' prefix" , err )
633+ }
634+ }
0 commit comments