llm / scripts /test_schedule_flow.py
Aswin480
feat: initial commit for PABOT Personal Operating System
34b54ad
Raw History Blame Contribute Delete
5.68 kB
import json
import os
import sys
import time
from datetime import datetime, timedelta
from pathlib import Path
from playwright.sync_api import sync_playwright
from backend.security import auth
# Generate admin JWT
token = auth.create_access_token(data={"sub": "master", "role": "admin"})
artifacts_dir = Path(r"C:\Users\rcnai\.gemini\antigravity-ide\brain\687690db-36e3-42ea-89a5-947c15851521")
screenshot1_path = str(artifacts_dir / "schedule_modal_conflict.png")
screenshot2_path = str(artifacts_dir / "schedule_list_conflicts.png")
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(viewport={"width": 1280, "height": 800})
page = context.new_page()
print("[1] Navigating to http://localhost:8000/...")
page.goto("http://localhost:8000/")
page.wait_for_load_state("networkidle")
# Set JWT in localStorage and reload
print("[2] Injecting auth token...")
page.evaluate(f"localStorage.setItem('pabot_jwt', '{token}');")
page.reload()
page.wait_for_load_state("networkidle")
time.sleep(1)
# Check if auth shield is hidden
shield_display = page.evaluate("document.getElementById('authShield').style.display")
print(f"Auth shield display: {shield_display}")
# Navigate to Schedule page
print("[3] Switching to Schedule tab...")
page.click("button:has-text('Schedule')")
time.sleep(1)
# Check current schedule view state
init_html = page.inner_text("#schedEventsList")
print(f"Initial Schedule List:\n{init_html.strip()}\n")
# Click "+ New Event"
print("[4] Clicking '+ New Event'...")
page.click("button:has-text('New Event')")
page.wait_for_selector("#calendarEventModal.show", state="visible")
# Today's date in local YYYY-MM-DD
now = datetime.now()
start_dt = now.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
end_dt = start_dt + timedelta(hours=1)
start_str = start_dt.strftime("%Y-%m-%dT%H:%M")
end_str = end_dt.strftime("%Y-%m-%dT%H:%M")
print(f"[5] Filling Event 1: 'Sprint Architecture Sync' from {start_str} to {end_str}...")
page.fill("#eventModalTitleInput", "Sprint Architecture Sync")
page.fill("#eventModalStartInput", start_str)
page.fill("#eventModalEndInput", end_str)
page.select_option("#eventModalCategoryInput", "work")
# Submit Event 1
page.click("#calendarEventModal button[type='submit']")
page.wait_for_selector("#calendarEventModal", state="hidden")
time.sleep(1.5)
# Verify Event 1 appears in the list
list_text_1 = page.inner_text("#schedEventsList")
print(f"[6] Events List after adding Event 1:\n{list_text_1.strip()}\n")
assert "Sprint Architecture Sync" in list_text_1, "Event 1 did not appear in the list!"
assert "No events scheduled for this period" not in list_text_1, "Still showing 'No events scheduled'!"
# Create Event 2: Overlapping event
print("[7] Clicking '+ New Event' for second overlapping event...")
page.click("button:has-text('New Event')")
page.wait_for_selector("#calendarEventModal.show", state="visible")
# Overlapping slot: starts 30 mins after Event 1 starts
overlap_start_dt = start_dt + timedelta(minutes=30)
overlap_end_dt = overlap_start_dt + timedelta(hours=1)
overlap_start_str = overlap_start_dt.strftime("%Y-%m-%dT%H:%M")
overlap_end_str = overlap_end_dt.strftime("%Y-%m-%dT%H:%M")
print(f"[8] Filling Event 2: 'Emergency Client Sync' from {overlap_start_str} to {overlap_end_str}...")
page.fill("#eventModalTitleInput", "Emergency Client Sync")
page.fill("#eventModalStartInput", overlap_start_str)
page.fill("#eventModalEndInput", overlap_end_str)
# Trigger input change and conflict check
page.evaluate("checkModalEventConflict();")
time.sleep(1)
# Check modal conflict banner
modal_conflict_style = page.evaluate("document.getElementById('modalConflictAlert').style.display")
modal_conflict_text = page.inner_text("#modalConflictText")
print(f"[9] Modal Conflict Alert Display: {modal_conflict_style}")
print(f" Modal Conflict Alert Text: '{modal_conflict_text}'")
# Take screenshot of modal with conflict warning
page.screenshot(path=screenshot1_path)
print(f" Saved screenshot to {screenshot1_path}")
# Submit Event 2
print("[10] Submitting overlapping event...")
page.click("#calendarEventModal button[type='submit']")
page.wait_for_selector("#calendarEventModal", state="hidden")
time.sleep(1.5)
# Verify both events and global conflict banner on schedule page
list_text_2 = page.inner_text("#schedEventsList")
global_conflict_display = page.evaluate("document.getElementById('schedGlobalConflictBanner').style.display")
global_conflict_text = page.inner_text("#schedGlobalConflictBanner")
print(f"[11] Events List after adding Overlapping Event 2:\n{list_text_2.strip()}\n")
print(f"[12] Global Conflict Banner Display: {global_conflict_display}")
print(f" Global Conflict Banner Text: '{global_conflict_text.strip()}'")
# Check conflict cards and pills
conflict_cards_count = page.evaluate("document.querySelectorAll('.sched-event-card.has-conflict').length")
conflict_pills_count = page.evaluate("document.querySelectorAll('.pill.rose').length")
print(f"[13] Conflict Cards Count: {conflict_cards_count}")
print(f" Conflict Pills Count: {conflict_pills_count}")
page.screenshot(path=screenshot2_path)
print(f" Saved screenshot to {screenshot2_path}")
browser.close()
print("\n=== SCHEDULE & CONFLICT TEST COMPLETED SUCCESSFULLY ===")