import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options def test_workspace_position(): options = Options() options.add_argument('--headless') # Run in headless mode for CI options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome(options=options) try: # Navigate to local server driver.get('http://localhost:3015') # Wait for page to load wait = WebDriverWait(driver, 10) # Find Railseek title (SiteInfo.name) title = wait.until(EC.presence_of_element_located((By.XPATH, "//span[contains(@class, 'font-bold') and text()='Railseek']"))) print(f"Title found: {title.text}") # Find workspace dropdown (SelectTrigger) dropdown = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[role='combobox']"))) print(f"Workspace dropdown found") # Find delete button (trash icon) - only visible when workspace selected # We need to select a workspace first. Let's see if there is a default workspace. # If not, we can skip delete button check. # Instead, check that the workspace selector container exists. workspace_container = driver.find_element(By.CSS_SELECTOR, ".flex.flex-col.sm\\:flex-row") print(f"Workspace container found") # Verify that workspace container is below title (in DOM order) # Get location of title and workspace container title_y = title.location['y'] container_y = workspace_container.location['y'] print(f"Title Y: {title_y}, Container Y: {container_y}") if container_y >= title_y: print("PASS: Workspace container is below title (or same line)") else: print("FAIL: Workspace container is above title") # Find Document Management heading (might be in document panel) # Wait for tab to be active (documents tab) # Click documents tab if not active documents_tab = driver.find_element(By.XPATH, "//button[contains(text(), 'Documents')]") documents_tab.click() time.sleep(1) # Look for heading "Document Management" heading = wait.until(EC.presence_of_element_located((By.XPATH, "//h2[contains(text(), 'Document Management')] | //div[contains(text(), 'Document Management')]"))) print(f"Document Management heading found: {heading.text}") # Verify heading is below workspace container heading_y = heading.location['y'] if heading_y >= container_y: print("PASS: Document Management heading is below workspace container") else: print("FAIL: Document Management heading is above workspace container") # Check that workspace dropdown, delete icon, add icon are in same row # Find the flex container inside workspace selector inner_flex = driver.find_element(By.CSS_SELECTOR, ".flex.items-center.gap-2") # Check if it contains three items: dropdown, trash, plus items = inner_flex.find_elements(By.CSS_SELECTOR, "*") print(f"Number of items in workspace row: {len(items)}") # Expect at least 2 (dropdown and plus) maybe 3 if workspace selected if len(items) >= 2: print("PASS: Workspace row contains multiple items") else: print("FAIL: Workspace row missing items") # Check mobile view (resize window) driver.set_window_size(375, 667) # iPhone 6/7/8 time.sleep(1) # Verify that workspace container becomes column (flex-col) # We can check if the container has flex-col class (but it's sm:flex-row) # Instead, check if dropdown width is full width dropdown_width = dropdown.size['width'] window_width = driver.get_window_size()['width'] if dropdown_width >= window_width * 0.9: # roughly full width print("PASS: Dropdown is full width on mobile") else: print("FAIL: Dropdown not full width on mobile") # Reset window size driver.set_window_size(1280, 800) time.sleep(1) print("All checks passed.") except Exception as e: print(f"Error during test: {e}") import traceback traceback.print_exc() raise finally: driver.quit() if __name__ == "__main__": test_workspace_position()