feat(zones): rename tabs to zones across api, ui, and storage

Made-with: Cursor
This commit is contained in:
pi
2026-04-06 18:22:03 +12:00
parent d1ffb857c8
commit fd618d7714
35 changed files with 1347 additions and 1303 deletions

View File

@@ -162,13 +162,13 @@ class BrowserTest:
print(f" ⚠ Failed to cleanup preset {preset_id}: {e}")
# Delete created tabs by ID
for tab_id in self.created_tabs:
for zone_id in self.created_tabs:
try:
response = session.delete(f"{self.base_url}/tabs/{tab_id}")
response = session.delete(f"{self.base_url}/zones/{zone_id}")
if response.status_code == 200:
print(f" ✓ Cleaned up tab: {tab_id}")
print(f" ✓ Cleaned up zone: {zone_id}")
except Exception as e:
print(f" ⚠ Failed to cleanup tab {tab_id}: {e}")
print(f" ⚠ Failed to cleanup zone {zone_id}: {e}")
# Delete created profiles by ID
for profile_id in self.created_profiles:
@@ -180,20 +180,20 @@ class BrowserTest:
print(f" ⚠ Failed to cleanup profile {profile_id}: {e}")
# Also try to cleanup by name pattern (in case IDs weren't tracked)
test_names = ['Browser Test Tab', 'Browser Test Profile', 'Browser Test Preset',
'Preset 1', 'Preset 2', 'Preset 3', 'Edited Browser Tab']
test_names = ['Browser Test Zone', 'Browser Test Profile', 'Browser Test Preset',
'Preset 1', 'Preset 2', 'Preset 3', 'Edited Browser Zone']
# Cleanup tabs by name
try:
tabs_response = session.get(f"{self.base_url}/tabs")
tabs_response = session.get(f"{self.base_url}/zones")
if tabs_response.status_code == 200:
tabs_data = tabs_response.json()
tabs = tabs_data.get('tabs', {})
for tab_id, tab_data in tabs.items():
tabs = tabs_data.get('zones', {})
for zone_id, tab_data in zones.items():
if isinstance(tab_data, dict) and tab_data.get('name') in test_names:
try:
session.delete(f"{self.base_url}/tabs/{tab_id}")
print(f" ✓ Cleaned up tab by name: {tab_data.get('name')}")
session.delete(f"{self.base_url}/zones/{zone_id}")
print(f" ✓ Cleaned up zone by name: {tab_data.get('name')}")
except:
pass
except:
@@ -330,11 +330,11 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
# Test 2: Open tabs modal
total += 1
if browser.click_element(By.ID, 'tabs-btn'):
if browser.click_element(By.ID, 'zones-btn'):
print("✓ Clicked Tabs button")
# Wait for modal to appear
time.sleep(0.5)
modal = browser.wait_for_element(By.ID, 'tabs-modal')
modal = browser.wait_for_element(By.ID, 'zones-modal')
if modal and 'active' in modal.get_attribute('class'):
print("✓ Tabs modal opened")
passed += 1
@@ -343,58 +343,58 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
else:
print("✗ Failed to click Tabs button")
# Test 3: Create a tab via UI
# Test 3: Create a zone via UI
total += 1
try:
# Fill in tab name
if browser.fill_input(By.ID, 'new-tab-name', 'Browser Test Tab'):
print(" ✓ Filled tab name")
# Fill in zone name
if browser.fill_input(By.ID, 'new-zone-name', 'Browser Test Zone'):
print(" ✓ Filled zone name")
# Devices default from registry or placeholder name "1"
# Click create button
if browser.click_element(By.ID, 'create-tab-btn'):
if browser.click_element(By.ID, 'create-zone-btn'):
print(" ✓ Clicked create button")
time.sleep(1) # Wait for creation
# Check if tab appears in list and extract ID
tabs_list = browser.wait_for_element(By.ID, 'tabs-list-modal')
# Check if zone appears in list and extract ID
tabs_list = browser.wait_for_element(By.ID, 'zones-list-modal')
if tabs_list:
list_text = tabs_list.text
if 'Browser Test Tab' in list_text:
print("✓ Created tab via UI")
# Try to extract tab ID from the list (look for data-tab-id attribute)
if 'Browser Test Zone' in list_text:
print("✓ Created zone via UI")
# Try to extract zone ID from the list (look for data-zone-id attribute)
try:
tab_rows = browser.driver.find_elements(By.CSS_SELECTOR, '#tabs-list-modal .profiles-row')
tab_rows = browser.driver.find_elements(By.CSS_SELECTOR, '#zones-list-modal .profiles-row')
for row in tab_rows:
if 'Browser Test Tab' in row.text:
tab_id = row.get_attribute('data-tab-id')
if tab_id:
browser.created_tabs.append(tab_id)
if 'Browser Test Zone' in row.text:
zone_id = row.get_attribute('data-zone-id')
if zone_id:
browser.created_tabs.append(zone_id)
break
except:
pass # If we can't extract ID, cleanup will try by name
passed += 1
else:
print("Tab not found in list after creation")
print("Zone not found in list after creation")
else:
print("✗ Tabs list not found")
else:
print("✗ Failed to click create button")
except Exception as e:
print(f"✗ Failed to create tab via UI: {e}")
print(f"✗ Failed to create zone via UI: {e}")
# Test 4: Edit a tab via UI (right-click in Tabs list)
# Test 4: Edit a zone via UI (right-click in Tabs list)
total += 1
try:
# First, close and reopen modal to refresh
browser.click_element(By.ID, 'tabs-close-btn')
browser.click_element(By.ID, 'zones-close-btn')
time.sleep(0.5)
browser.click_element(By.ID, 'tabs-btn')
browser.click_element(By.ID, 'zones-btn')
time.sleep(0.5)
# Right-click the row corresponding to 'Browser Test Tab'
# Right-click the row corresponding to 'Browser Test Zone'
try:
tab_row = browser.driver.find_element(
By.XPATH,
"//div[@id='tabs-list-modal']//div[contains(@class,'profiles-row')][.//span[contains(text(), 'Browser Test Tab')]]"
"//div[@id='zones-list-modal']//div[contains(@class,'profiles-row')][.//span[contains(text(), 'Browser Test Zone')]]"
)
except Exception:
tab_row = None
@@ -405,14 +405,14 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
time.sleep(0.5)
# Check if edit modal opened
edit_modal = browser.wait_for_element(By.ID, 'edit-tab-modal')
edit_modal = browser.wait_for_element(By.ID, 'edit-zone-modal')
if edit_modal:
print("✓ Edit modal opened via right-click")
# Fill in new name
if browser.fill_input(By.ID, 'edit-tab-name', 'Edited Browser Tab'):
print(" ✓ Filled new tab name")
if browser.fill_input(By.ID, 'edit-zone-name', 'Edited Browser Zone'):
print(" ✓ Filled new zone name")
# Submit form
edit_form = browser.wait_for_element(By.ID, 'edit-tab-form')
edit_form = browser.wait_for_element(By.ID, 'edit-zone-form')
if edit_form:
browser.driver.execute_script("arguments[0].submit();", edit_form)
time.sleep(1) # Wait for update
@@ -423,24 +423,24 @@ def test_tabs_ui(browser: BrowserTest) -> bool:
else:
print("✗ Edit modal didn't open after right-click")
else:
print("✗ Could not find tab row for 'Browser Test Tab'")
print("✗ Could not find zone row for 'Browser Test Zone'")
except Exception as e:
print(f"✗ Failed to edit tab via UI: {e}")
print(f"✗ Failed to edit zone via UI: {e}")
import traceback
traceback.print_exc()
# Test 5: Check current tab cookie
# Test 5: Check current zone cookie
total += 1
cookie = browser.get_cookie('current_tab')
cookie = browser.get_cookie('current_zone')
if cookie:
print(f"✓ Found current_tab cookie: {cookie.get('value')}")
print(f"✓ Found current_zone cookie: {cookie.get('value')}")
passed += 1
else:
print("⚠ No current_tab cookie found (might be normal if no tab selected)")
print("⚠ No current_zone cookie found (might be normal if no zone selected)")
passed += 1 # Not a failure, just informational
# Close modal
browser.click_element(By.ID, 'tabs-close-btn')
browser.click_element(By.ID, 'zones-close-btn')
except Exception as e:
print(f"✗ Browser test error: {e}")
@@ -519,7 +519,7 @@ def test_profiles_ui(browser: BrowserTest) -> bool:
def test_mobile_tab_presets_two_columns():
"""
Verify that the tab preset selecting area shows roughly two preset tiles per row
Verify that the zone preset selecting area shows roughly two preset tiles per row
on a phone-sized viewport.
"""
bt = BrowserTest(base_url=BASE_URL, headless=True)
@@ -531,18 +531,18 @@ def test_mobile_tab_presets_two_columns():
bt.driver.set_window_size(400, 800)
assert bt.navigate('/'), "Failed to load main page"
# Click the first tab button to load presets for that tab
first_tab = bt.wait_for_element(By.CSS_SELECTOR, '.tab-button', timeout=10)
assert first_tab is not None, "No tab buttons found"
# Click the first zone button to load presets for that zone
first_tab = bt.wait_for_element(By.CSS_SELECTOR, '.zone-button', timeout=10)
assert first_tab is not None, "No zone buttons found"
first_tab.click()
time.sleep(1)
container = bt.wait_for_element(By.ID, 'presets-list-tab', timeout=10)
assert container is not None, "presets-list-tab not found"
container = bt.wait_for_element(By.ID, 'presets-list-zone', timeout=10)
assert container is not None, "presets-list-zone not found"
tiles = bt.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .preset-tile-row')
tiles = bt.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .preset-tile-row')
# Need at least 2 presets to make this meaningful
assert len(tiles) >= 2, "Fewer than 2 presets found for tab"
assert len(tiles) >= 2, "Fewer than 2 presets found for zone"
container_width = container.size['width']
first_width = tiles[0].size['width']
@@ -760,8 +760,8 @@ def test_color_palette_ui(browser: BrowserTest) -> bool:
return passed >= total - 1 # Allow one failure (alert handling might be flaky)
def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
"""Test dragging presets around in a tab."""
print("\n=== Testing Preset Drag and Drop in Tab ===")
"""Test dragging presets around in a zone."""
print("\n=== Testing Preset Drag and Drop in Zone ===")
passed = 0
total = 0
@@ -769,7 +769,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
return False
try:
# Test 1: Load page and ensure we have a tab
# Test 1: Load page and ensure we have a zone
total += 1
if browser.navigate('/'):
print("✓ Loaded main page")
@@ -778,33 +778,33 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
browser.teardown()
return False
# Test 2: Open tabs modal and create/select a tab
# Test 2: Open tabs modal and create/select a zone
total += 1
browser.click_element(By.ID, 'tabs-btn')
browser.click_element(By.ID, 'zones-btn')
time.sleep(0.5)
# Check if we have tabs, if not create one
tabs_list = browser.wait_for_element(By.ID, 'tabs-list-modal')
tabs_list = browser.wait_for_element(By.ID, 'zones-list-modal')
if tabs_list and 'No tabs found' in tabs_list.text:
# Create a tab
browser.fill_input(By.ID, 'new-tab-name', 'Drag Test Tab')
browser.click_element(By.ID, 'create-tab-btn')
# Create a zone
browser.fill_input(By.ID, 'new-zone-name', 'Drag Test Zone')
browser.click_element(By.ID, 'create-zone-btn')
time.sleep(1)
# Select first tab (or the one we just created)
# Select first zone (or the one we just created)
select_buttons = browser.driver.find_elements(By.XPATH, "//button[contains(text(), 'Select')]")
if select_buttons:
select_buttons[0].click()
time.sleep(1)
print("✓ Selected a tab")
print("✓ Selected a zone")
passed += 1
else:
print("✗ No tabs available to select")
browser.click_element(By.ID, 'tabs-close-btn')
browser.click_element(By.ID, 'zones-close-btn')
browser.teardown()
return False
browser.click_element(By.ID, 'tabs-close-btn', use_js=True)
browser.click_element(By.ID, 'zones-close-btn', use_js=True)
time.sleep(0.5)
# Test 3: Open presets modal and create presets
@@ -845,54 +845,54 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
print("✓ Created 3 presets for drag test")
passed += 1
# Test 4: Add presets to the tab (via Edit Tab modal Add buttons in list)
# Test 4: Add presets to the zone (via Edit Zone modal Add buttons in list)
total += 1
try:
tab_id = browser.driver.execute_script(
zone_id = browser.driver.execute_script(
"return (window.tabsManager && window.tabsManager.getCurrentTabId && window.tabsManager.getCurrentTabId()) || null;"
)
if not tab_id:
print("✗ Could not get current tab id")
if not zone_id:
print("✗ Could not get current zone id")
else:
browser.driver.execute_script(
"if (window.tabsManager && window.tabsManager.openEditTabModal) { window.tabsManager.openEditTabModal(arguments[0], null); }",
tab_id
zone_id
)
time.sleep(1)
list_el = browser.wait_for_element(By.ID, 'edit-tab-presets-list', timeout=5)
list_el = browser.wait_for_element(By.ID, 'edit-zone-presets-list', timeout=5)
if list_el:
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
if len(select_buttons) >= 2:
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
time.sleep(1.5)
browser.handle_alert(accept=True, timeout=1)
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
if len(select_buttons) >= 1:
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
time.sleep(1.5)
browser.handle_alert(accept=True, timeout=1)
print(" ✓ Added 2 presets to tab")
print(" ✓ Added 2 presets to zone")
passed += 1
elif len(select_buttons) == 1:
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
time.sleep(1.5)
browser.handle_alert(accept=True, timeout=1)
print(" ✓ Added 1 preset to tab")
print(" ✓ Added 1 preset to zone")
passed += 1
else:
print(" ⚠ No presets available to add (all already in tab)")
print(" ⚠ No presets available to add (all already in zone)")
else:
print("✗ Edit tab presets list not found")
print("✗ Edit zone presets list not found")
except Exception as e:
print(f"✗ Failed to add presets to tab: {e}")
print(f"✗ Failed to add presets to zone: {e}")
import traceback
traceback.print_exc()
# Test 5: Find presets in tab and test drag and drop (Edit mode only)
# Test 5: Find presets in zone and test drag and drop (Edit mode only)
total += 1
try:
# Wait for presets to load in the tab
presets_list_tab = browser.wait_for_element(By.ID, 'presets-list-tab', timeout=5)
# Wait for presets to load in the zone
presets_list_tab = browser.wait_for_element(By.ID, 'presets-list-zone', timeout=5)
if presets_list_tab:
time.sleep(1) # Wait for presets to render
@@ -904,7 +904,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
# Find draggable preset elements - wait a bit more for rendering
time.sleep(1)
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
if len(draggable_presets) >= 2:
print(f" ✓ Found {len(draggable_presets)} draggable presets")
@@ -922,7 +922,7 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
time.sleep(1) # Wait for reorder to complete
# Check if order changed
draggable_presets_after = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
draggable_presets_after = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
if len(draggable_presets_after) >= 2:
new_order = [p.text for p in draggable_presets_after]
print(f" New order: {new_order[:3]}")
@@ -936,28 +936,28 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
else:
print("✗ Presets disappeared after drag")
elif len(draggable_presets) == 1:
print(f"⚠ Only 1 preset found in tab (need 2 for drag test). Preset: {draggable_presets[0].text}")
tab_id = browser.driver.execute_script(
print(f"⚠ Only 1 preset found in zone (need 2 for drag test). Preset: {draggable_presets[0].text}")
zone_id = browser.driver.execute_script(
"return (window.tabsManager && window.tabsManager.getCurrentTabId && window.tabsManager.getCurrentTabId()) || null;"
)
if tab_id:
if zone_id:
browser.driver.execute_script(
"if (window.tabsManager && window.tabsManager.openEditTabModal) { window.tabsManager.openEditTabModal(arguments[0], null); }",
tab_id
zone_id
)
time.sleep(1)
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-tab-presets-list']//button[text()='Add']")
select_buttons = browser.driver.find_elements(By.XPATH, "//div[@id='edit-zone-presets-list']//button[text()='Add']")
if select_buttons:
print(" Attempting to add another preset...")
browser.driver.execute_script("arguments[0].click();", select_buttons[0])
time.sleep(1.5)
browser.handle_alert(accept=True, timeout=1)
try:
browser.driver.execute_script("document.getElementById('edit-tab-modal').classList.remove('active');")
browser.driver.execute_script("document.getElementById('edit-zone-modal').classList.remove('active');")
except Exception:
pass
time.sleep(1)
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-tab .draggable-preset')
draggable_presets = browser.driver.find_elements(By.CSS_SELECTOR, '#presets-list-zone .draggable-preset')
if len(draggable_presets) >= 2:
print(" ✓ Added another preset, now testing drag...")
source = draggable_presets[0]
@@ -970,11 +970,11 @@ def test_preset_drag_and_drop(browser: BrowserTest) -> bool:
else:
print(f" ✗ Still only {len(draggable_presets)} preset(s) after adding")
else:
print(" ✗ No Add buttons found in Edit Tab modal")
print(" ✗ No Add buttons found in Edit Zone modal")
else:
print(f"✗ No presets found in tab (found {len(draggable_presets)})")
print(f"✗ No presets found in zone (found {len(draggable_presets)})")
else:
print("✗ Presets list in tab not found")
print("✗ Presets list in zone not found")
except Exception as e:
print(f"✗ Drag and drop test error: {e}")
import traceback