Speedofmastery commited on
Commit
bb2ffb0
·
1 Parent(s): 01b3736

Auto-commit: app.py updated

Browse files
Files changed (1) hide show
  1. app.py +181 -1
app.py CHANGED
@@ -532,7 +532,187 @@ async def get_preview(preview_id: str):
532
  @app.get("/health")
533
  async def health():
534
  """Health check endpoint"""
535
- return {"status": "healthy", "sandbox": "landrun", "security": "kernel-level"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
 
537
 
538
  if __name__ == "__main__":
 
532
  @app.get("/health")
533
  async def health():
534
  """Health check endpoint"""
535
+ return {"status": "healthy", "sandbox": "landrun", "security": "kernel-level", "browser": "playwright-chromium"}
536
+
537
+
538
+ @app.post("/browser/test")
539
+ async def test_browser_automation(request: Request):
540
+ """
541
+ Test browser automation on executed code preview
542
+ AI agents can use this to automatically test UIs
543
+ """
544
+ data = await request.json()
545
+ preview_url = data.get("preview_url", "") # e.g., "/preview/uuid"
546
+ test_actions = data.get("actions", []) # List of actions to perform
547
+
548
+ if not preview_url:
549
+ return JSONResponse({"error": "No preview_url provided"})
550
+
551
+ # Build full URL
552
+ full_url = f"http://localhost:7860{preview_url}"
553
+
554
+ try:
555
+ async with async_playwright() as p:
556
+ browser = await p.chromium.launch(headless=True)
557
+ page = await browser.new_page()
558
+
559
+ # Navigate to preview
560
+ await page.goto(full_url, wait_until="networkidle", timeout=10000)
561
+
562
+ # Take initial screenshot
563
+ screenshot_initial = await page.screenshot()
564
+
565
+ # Perform test actions
566
+ test_results = []
567
+ for action in test_actions:
568
+ action_type = action.get("type")
569
+ selector = action.get("selector")
570
+ value = action.get("value")
571
+
572
+ try:
573
+ if action_type == "click":
574
+ await page.click(selector, timeout=5000)
575
+ test_results.append({"action": "click", "selector": selector, "status": "success"})
576
+
577
+ elif action_type == "type":
578
+ await page.fill(selector, value, timeout=5000)
579
+ test_results.append({"action": "type", "selector": selector, "status": "success"})
580
+
581
+ elif action_type == "wait":
582
+ await page.wait_for_selector(selector, timeout=5000)
583
+ test_results.append({"action": "wait", "selector": selector, "status": "success"})
584
+
585
+ elif action_type == "screenshot":
586
+ screenshot = await page.screenshot()
587
+ test_results.append({
588
+ "action": "screenshot",
589
+ "status": "success",
590
+ "data": base64.b64encode(screenshot).decode()
591
+ })
592
+
593
+ elif action_type == "get_text":
594
+ text = await page.inner_text(selector, timeout=5000)
595
+ test_results.append({
596
+ "action": "get_text",
597
+ "selector": selector,
598
+ "status": "success",
599
+ "text": text
600
+ })
601
+
602
+ except Exception as e:
603
+ test_results.append({
604
+ "action": action_type,
605
+ "selector": selector,
606
+ "status": "error",
607
+ "error": str(e)
608
+ })
609
+
610
+ # Take final screenshot
611
+ screenshot_final = await page.screenshot()
612
+
613
+ await browser.close()
614
+
615
+ return JSONResponse({
616
+ "status": "success",
617
+ "url_tested": full_url,
618
+ "test_results": test_results,
619
+ "screenshot_initial": base64.b64encode(screenshot_initial).decode(),
620
+ "screenshot_final": base64.b64encode(screenshot_final).decode()
621
+ })
622
+
623
+ except Exception as e:
624
+ return JSONResponse({
625
+ "status": "error",
626
+ "error": str(e),
627
+ "url_tested": full_url
628
+ })
629
+
630
+
631
+ @app.post("/browser/execute_and_test")
632
+ async def execute_and_test(request: Request):
633
+ """
634
+ Execute code AND automatically test it with browser automation
635
+ One-shot API for AI agents: execute → preview → test
636
+ """
637
+ data = await request.json()
638
+ language = data.get("language", "react")
639
+ code = data.get("code", "")
640
+ test_actions = data.get("actions", [])
641
+
642
+ if not code:
643
+ return JSONResponse({"error": "No code provided"})
644
+
645
+ # Step 1: Execute code
646
+ exec_result = execute_with_landrun(language, code)
647
+
648
+ if exec_result.get("error"):
649
+ return JSONResponse({
650
+ "status": "execution_failed",
651
+ "execution": exec_result
652
+ })
653
+
654
+ preview_url = exec_result.get("preview_url")
655
+ if not preview_url:
656
+ return JSONResponse({
657
+ "status": "no_preview",
658
+ "execution": exec_result,
659
+ "message": "Code executed but no preview available"
660
+ })
661
+
662
+ # Step 2: Test with browser automation
663
+ full_url = f"http://localhost:7860{preview_url}"
664
+
665
+ try:
666
+ async with async_playwright() as p:
667
+ browser = await p.chromium.launch(headless=True)
668
+ page = await browser.new_page()
669
+
670
+ await page.goto(full_url, wait_until="networkidle", timeout=10000)
671
+
672
+ # Perform automated tests
673
+ test_results = []
674
+ for action in test_actions:
675
+ action_type = action.get("type")
676
+ selector = action.get("selector")
677
+ value = action.get("value")
678
+
679
+ try:
680
+ if action_type == "click":
681
+ await page.click(selector, timeout=5000)
682
+ test_results.append({"action": "click", "selector": selector, "status": "success"})
683
+ elif action_type == "type":
684
+ await page.fill(selector, value, timeout=5000)
685
+ test_results.append({"action": "type", "selector": selector, "status": "success"})
686
+ elif action_type == "get_text":
687
+ text = await page.inner_text(selector, timeout=5000)
688
+ test_results.append({"action": "get_text", "selector": selector, "status": "success", "text": text})
689
+ elif action_type == "screenshot":
690
+ screenshot = await page.screenshot()
691
+ test_results.append({"action": "screenshot", "status": "success", "data": base64.b64encode(screenshot).decode()})
692
+ except Exception as e:
693
+ test_results.append({"action": action_type, "selector": selector, "status": "error", "error": str(e)})
694
+
695
+ # Final screenshot
696
+ final_screenshot = await page.screenshot()
697
+
698
+ await browser.close()
699
+
700
+ return JSONResponse({
701
+ "status": "success",
702
+ "execution": exec_result,
703
+ "browser_tests": {
704
+ "url_tested": full_url,
705
+ "test_results": test_results,
706
+ "screenshot": base64.b64encode(final_screenshot).decode()
707
+ }
708
+ })
709
+
710
+ except Exception as e:
711
+ return JSONResponse({
712
+ "status": "browser_error",
713
+ "execution": exec_result,
714
+ "browser_error": str(e)
715
+ })
716
 
717
 
718
  if __name__ == "__main__":