#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
独立的测试用例执行脚本
完全独立于FastAPI，直接通过子进程运行Playwright
"""

import json
import os
import sys
import time

def run_test(case_steps, screenshots_dir):
    """运行Playwright测试步骤"""
    from playwright.sync_api import sync_playwright

    results = []

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])
        context = browser.new_context(ignore_https_errors=True, viewport={'width': 1920, 'height': 1080})
        page = context.new_page()
        page.set_default_timeout(30000)

        os.makedirs(screenshots_dir, exist_ok=True)

        for step in case_steps:
            order = step['order']
            name = step['name']
            action = step['action']
            params = step.get('params', {})

            step_result = {
                'order': order,
                'name': name,
                'action': action,
                'status': 'running',
                'log': '',
                'error': None,
                'screenshot': None,
                'duration': 0
            }

            start = time.time()

            try:
                if action == 'navigate':
                    url = params.get('url', '')
                    page.goto(url, wait_until='networkidle', timeout=30000)
                    step_result['log'] = f'Nav to {url}'
                    step_result['status'] = 'passed'

                elif action == 'click':
                    selector = params.get('selector', '')
                    page.click(selector, timeout=30000)
                    step_result['log'] = f'Clicked {selector}'
                    step_result['status'] = 'passed'

                elif action == 'fill':
                    selector = params.get('selector', '')
                    value = params.get('value', '')
                    page.fill(selector, str(value))
                    step_result['log'] = f'Filled {selector} = {value}'
                    step_result['status'] = 'passed'

                elif action == 'wait':
                    selector = params.get('selector', '')
                    timeout = params.get('timeout', 30000)
                    page.wait_for_selector(selector, timeout=timeout)
                    step_result['log'] = f'Waited for {selector}'
                    step_result['status'] = 'passed'

                elif action == 'screenshot':
                    screenshot_path = os.path.join(screenshots_dir, f'step_{order}_{int(time.time())}.png')
                    page.screenshot(path=screenshot_path, full_page=False)
                    step_result['log'] = 'Screenshot taken'
                    step_result['screenshot'] = screenshot_path
                    step_result['status'] = 'passed'

                elif action == 'assert':
                    assert_type = params.get('type', 'visible')
                    selector = params.get('selector', '')
                    expected = params.get('expected', '')

                    if assert_type == 'visible':
                        el = page.wait_for_selector(selector, state='visible', timeout=10000)
                        if not el:
                            raise Exception(f'Element not visible: {selector}')
                    elif assert_type == 'url':
                        if expected not in page.url:
                            raise Exception(f'URL does not contain {expected}')
                    elif assert_type == 'title':
                        if expected not in page.title():
                            raise Exception(f'Title does not contain {expected}')

                    step_result['log'] = f'Assert {assert_type} passed'
                    step_result['status'] = 'passed'

                else:
                    raise Exception(f'Unknown action: {action}')

            except Exception as e:
                step_result['status'] = 'failed'
                step_result['error'] = str(e)
                step_result['log'] = f'Failed: {str(e)}'

            finally:
                step_result['duration'] = time.time() - start
                results.append(step_result)

                # 将后续步骤标记为 skipped
                if step_result['status'] == 'failed':
                    for remaining in case_steps:
                        if remaining['order'] > step_result['order']:
                            results.append({
                                'order': remaining['order'],
                                'name': remaining['name'],
                                'action': remaining['action'],
                                'status': 'skipped',
                                'log': 'Skipped due to previous failure',
                                'error': None,
                                'screenshot': None,
                                'duration': 0
                            })
                    break

        browser.close()

    return results


if __name__ == '__main__':
    # 从stdin读取JSON数据
    input_data = json.loads(sys.stdin.read())

    case_steps = input_data['steps']
    screenshots_dir = input_data.get('screenshots_dir', './data/screenshots')

    try:
        results = run_test(case_steps, screenshots_dir)
        print(json.dumps({'status': 'ok', 'results': results}, ensure_ascii=False))
    except Exception as e:
        print(json.dumps({'status': 'error', 'error': str(e)}, ensure_ascii=False))
