fix: add missing type hints and improve test logging (#12810)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Chujiang
2026-02-19 07:58:39 +08:00
committed by GitHub
parent fede37b496
commit 6676cae249
2 changed files with 69 additions and 51 deletions

View File

@@ -1,5 +1,6 @@
import json
from datetime import datetime
from typing import Any
from json_repair import repair_json
from litellm.types.utils import ModelResponse
@@ -32,7 +33,7 @@ class OpenHandsJSONEncoder(json.JSONEncoder):
_json_encoder = OpenHandsJSONEncoder()
def dumps(obj, **kwargs):
def dumps(obj, **kwargs) -> str:
"""Serialize an object to str format"""
if not kwargs:
return _json_encoder.encode(obj)
@@ -47,7 +48,7 @@ def dumps(obj, **kwargs):
return json.dumps(obj, **encoder_kwargs)
def loads(json_str, **kwargs):
def loads(json_str: str, **kwargs) -> Any:
"""Create a JSON object from str"""
try:
return json.loads(json_str, **kwargs)

View File

@@ -6,10 +6,13 @@ then ensures the GitHub token is set in Settings → Integrations and that the
home screen shows the repository selector.
"""
import logging
import os
from playwright.sync_api import Page, expect
logger = logging.getLogger(__name__)
def test_github_token_configuration(page: Page, base_url: str):
"""
@@ -28,51 +31,51 @@ def test_github_token_configuration(page: Page, base_url: str):
base_url = 'http://localhost:12000'
# Navigate to the OpenHands application
print(f'Step 1: Navigating to OpenHands application at {base_url}...')
logger.info(f'Step 1: Navigating to OpenHands application at {base_url}...')
page.goto(base_url)
page.wait_for_load_state('networkidle', timeout=30000)
# Take initial screenshot
page.screenshot(path='test-results/token_01_initial_load.png')
print('Screenshot saved: token_01_initial_load.png')
logger.info('Screenshot saved: token_01_initial_load.png')
# Step 1.5: Handle any initial modals that might appear (LLM API key configuration)
try:
# Check for AI Provider Configuration modal
config_modal = page.locator('text=AI Provider Configuration')
if config_modal.is_visible(timeout=5000):
print('AI Provider Configuration modal detected')
logger.info('AI Provider Configuration modal detected')
# Fill in the LLM API key if available
llm_api_key_input = page.locator('[data-testid="llm-api-key-input"]')
if llm_api_key_input.is_visible(timeout=3000):
llm_api_key = os.getenv('LLM_API_KEY', 'test-key')
llm_api_key_input.fill(llm_api_key)
print(f'Filled LLM API key (length: {len(llm_api_key)})')
logger.info(f'Filled LLM API key (length: {len(llm_api_key)})')
# Click the Save button
save_button = page.locator('button:has-text("Save")')
if save_button.is_visible(timeout=3000):
save_button.click()
page.wait_for_timeout(2000)
print('Saved LLM API key configuration')
logger.info('Saved LLM API key configuration')
# Check for Privacy Preferences modal
privacy_modal = page.locator('text=Your Privacy Preferences')
if privacy_modal.is_visible(timeout=5000):
print('Privacy Preferences modal detected')
logger.info('Privacy Preferences modal detected')
confirm_button = page.locator('button:has-text("Confirm Preferences")')
if confirm_button.is_visible(timeout=3000):
confirm_button.click()
page.wait_for_timeout(2000)
print('Confirmed privacy preferences')
logger.info('Confirmed privacy preferences')
except Exception as e:
print(f'Error handling initial modals: {e}')
logger.error(f'Error handling initial modals: {e}')
page.screenshot(path='test-results/token_01_5_modal_error.png')
print('Screenshot saved: token_01_5_modal_error.png')
logger.info('Screenshot saved: token_01_5_modal_error.png')
# Step 2: Check if GitHub token is already configured or needs to be set
print('Step 2: Checking if GitHub token is configured...')
logger.info('Step 2: Checking if GitHub token is configured...')
try:
# First, check if we're already on the home screen with repository selection
@@ -80,7 +83,7 @@ def test_github_token_configuration(page: Page, base_url: str):
connect_to_provider = page.locator('text=Connect to a Repository')
if connect_to_provider.is_visible(timeout=3000):
print('Found "Connect to a Repository" section')
logger.info('Found "Connect to a Repository" section')
# Check if we need to configure a provider (GitHub token)
navigate_to_settings_button = page.locator(
@@ -88,7 +91,9 @@ def test_github_token_configuration(page: Page, base_url: str):
)
if navigate_to_settings_button.is_visible(timeout=3000):
print('GitHub token not configured. Need to navigate to settings...')
logger.info(
'GitHub token not configured. Need to navigate to settings...'
)
# Click the Settings button to navigate to the settings page
navigate_to_settings_button.click()
@@ -96,19 +101,21 @@ def test_github_token_configuration(page: Page, base_url: str):
page.wait_for_timeout(3000) # Wait for navigation to complete
# We should now be on the /settings/integrations page
print('Navigated to settings page, looking for GitHub token input...')
logger.info(
'Navigated to settings page, looking for GitHub token input...'
)
# Check if we're on the settings page with the integrations tab
settings_screen = page.locator('[data-testid="settings-screen"]')
if settings_screen.is_visible(timeout=5000):
print('Settings screen is visible')
logger.info('Settings screen is visible')
# Make sure we're on the Integrations tab
integrations_tab = page.locator('text=Integrations')
if integrations_tab.is_visible(timeout=3000):
# Check if we need to click the tab
if not page.url.endswith('/settings/integrations'):
print('Clicking Integrations tab...')
logger.info('Clicking Integrations tab...')
integrations_tab.click()
page.wait_for_load_state('networkidle')
page.wait_for_timeout(2000)
@@ -118,7 +125,7 @@ def test_github_token_configuration(page: Page, base_url: str):
'[data-testid="github-token-input"]'
)
if github_token_input.is_visible(timeout=5000):
print('Found GitHub token input field')
logger.info('Found GitHub token input field')
# Fill in the GitHub token from environment variable
github_token = os.getenv('GITHUB_TOKEN', '')
@@ -126,18 +133,18 @@ def test_github_token_configuration(page: Page, base_url: str):
# Clear the field first, then fill it
github_token_input.clear()
github_token_input.fill(github_token)
print(
logger.info(
f'Filled GitHub token from environment variable (length: {len(github_token)})'
)
# Verify the token was filled
filled_value = github_token_input.input_value()
if filled_value:
print(
logger.info(
f'Token field now contains value of length: {len(filled_value)}'
)
else:
print(
logger.warning(
'WARNING: Token field appears to be empty after filling'
)
@@ -146,12 +153,12 @@ def test_github_token_configuration(page: Page, base_url: str):
if save_button.is_visible(timeout=3000):
# Check if button is enabled
is_disabled = save_button.is_disabled()
print(
logger.info(
f'Save Changes button found, disabled: {is_disabled}'
)
if not is_disabled:
print('Clicking Save Changes button...')
logger.info('Clicking Save Changes button...')
save_button.click()
# Wait for the save operation to complete
@@ -164,46 +171,52 @@ def test_github_token_configuration(page: Page, base_url: str):
'document.querySelector(\'[data-testid="submit-button"]\').disabled === true',
timeout=10000,
)
print(
logger.info(
'Save operation completed - form is now clean'
)
except Exception:
print(
logger.warning(
'Save operation completed (timeout waiting for form clean state)'
)
# Navigate back to home page after successful save
print('Navigating back to home page...')
logger.info('Navigating back to home page...')
page.goto(base_url)
page.wait_for_load_state('networkidle')
page.wait_for_timeout(
5000
) # Wait longer for providers to be updated
else:
print(
logger.warning(
'Save Changes button is disabled - form may be invalid'
)
else:
print('Save Changes button not found')
logger.warning('Save Changes button not found')
else:
print('No GitHub token found in environment variables')
logger.warning(
'No GitHub token found in environment variables'
)
else:
print('GitHub token input field not found on settings page')
logger.warning(
'GitHub token input field not found on settings page'
)
# Take a screenshot to see what's on the page
page.screenshot(path='test-results/token_02_settings_debug.png')
print('Debug screenshot saved: token_02_settings_debug.png')
logger.info(
'Debug screenshot saved: token_02_settings_debug.png'
)
else:
print('Settings screen not found')
logger.warning('Settings screen not found')
else:
# Branch 2: GitHub token is already configured, repository selection is available
print(
logger.info(
'GitHub token is already configured, repository selection is available'
)
# Check if we need to update the token by going to settings manually
settings_button = page.locator('button:has-text("Settings")')
if settings_button.is_visible(timeout=3000):
print(
logger.info(
'Settings button found, clicking to navigate to settings page...'
)
settings_button.click()
@@ -213,7 +226,7 @@ def test_github_token_configuration(page: Page, base_url: str):
# Navigate to the Integrations tab
integrations_tab = page.locator('text=Integrations')
if integrations_tab.is_visible(timeout=3000):
print('Clicking Integrations tab...')
logger.info('Clicking Integrations tab...')
integrations_tab.click()
page.wait_for_load_state('networkidle')
page.wait_for_timeout(2000)
@@ -223,7 +236,7 @@ def test_github_token_configuration(page: Page, base_url: str):
'[data-testid="github-token-input"]'
)
if github_token_input.is_visible(timeout=5000):
print('Found GitHub token input field')
logger.info('Found GitHub token input field')
# Fill in the GitHub token from environment variable
github_token = os.getenv('GITHUB_TOKEN', '')
@@ -231,7 +244,7 @@ def test_github_token_configuration(page: Page, base_url: str):
# Clear the field first, then fill it
github_token_input.clear()
github_token_input.fill(github_token)
print(
logger.info(
f'Filled GitHub token from environment variable (length: {len(github_token)})'
)
@@ -243,52 +256,56 @@ def test_github_token_configuration(page: Page, base_url: str):
save_button.is_visible(timeout=3000)
and not save_button.is_disabled()
):
print('Clicking Save Changes button...')
logger.info('Clicking Save Changes button...')
save_button.click()
page.wait_for_timeout(3000)
# Navigate back to home page
print('Navigating back to home page...')
logger.info('Navigating back to home page...')
page.goto(base_url)
page.wait_for_load_state('networkidle')
page.wait_for_timeout(3000)
else:
print(
logger.warning(
'GitHub token input field not found, going back to home page'
)
page.goto(base_url)
page.wait_for_load_state('networkidle')
else:
print('Integrations tab not found, going back to home page')
logger.warning(
'Integrations tab not found, going back to home page'
)
page.goto(base_url)
page.wait_for_load_state('networkidle')
else:
print('Settings button not found, continuing with existing token')
logger.info(
'Settings button not found, continuing with existing token'
)
else:
print('Could not find "Connect to a Repository" section')
logger.warning('Could not find "Connect to a Repository" section')
page.screenshot(path='test-results/token_03_after_settings.png')
print('Screenshot saved: token_03_after_settings.png')
logger.info('Screenshot saved: token_03_after_settings.png')
except Exception as e:
print(f'Error checking GitHub token configuration: {e}')
logger.error(f'Error checking GitHub token configuration: {e}')
page.screenshot(path='test-results/token_04_error.png')
print('Screenshot saved: token_04_error.png')
logger.info('Screenshot saved: token_04_error.png')
# Step 3: Verify we're back on the home screen with repository selection available
print('Step 3: Verifying repository selection is available...')
logger.info('Step 3: Verifying repository selection is available...')
# Wait for the home screen to load
home_screen = page.locator('[data-testid="home-screen"]')
expect(home_screen).to_be_visible(timeout=15000)
print('Home screen is visible')
logger.info('Home screen is visible')
# Look for the repository dropdown/selector
repo_dropdown = page.locator('[data-testid="repo-dropdown"]')
expect(repo_dropdown).to_be_visible(timeout=15000)
print('Repository dropdown is visible')
logger.info('Repository dropdown is visible')
# Success - we've verified the GitHub token configuration
print('GitHub token configuration verified successfully')
logger.info('GitHub token configuration verified successfully')
page.screenshot(path='test-results/token_05_success.png')
print('Screenshot saved: token_05_success.png')
logger.info('Screenshot saved: token_05_success.png')