{"version":3,"names":["test","expect","describe","testUser","email","Date","now","password","name","phone","page","step","goto","waitForLoadState","locator","toBeVisible","registerButton","isVisible","timeout","catch","first","click","waitForURL","toHaveURL","emailInput","fill","passwordInputs","count","nth","nameInput","screenshot","path","submitButton","toBeEnabled","console","log","passwordInput","loginButton","waitForTimeout","isOnLogin","url","includes","toBeTruthy","publicPages","pageInfo","body","isEnabled","isStillOnLogin"],"sources":["user-journey-client.spec.js"],"sourcesContent":["import { test, expect } from '@playwright/test'\n\n/**\n * E2E Test: 客户完整用户旅程\n * 模拟真实客户从注册到下单的完整流程\n */\n\ntest.describe('客户用户旅程', () => {\n\n  // 测试数据\n  const testUser = {\n    email: `test_client_${Date.now()}@example.com`,\n    password: 'TestPassword123!',\n    name: '测试客户',\n    phone: '13800138000'\n  }\n\n  test('完整流程：注册 → 登录 → 查看仪表板 → 创建订单', async ({ page }) => {\n\n    // ========== 步骤 1: 访问首页 ==========\n    await test.step('访问首页', async () => {\n      await page.goto('/')\n      await page.waitForLoadState('networkidle')\n\n      // 验证首页加载成功\n      await expect(page.locator('body')).toBeVisible()\n    })\n\n    // ========== 步骤 2: 点击注册 ==========\n    await test.step('导航到注册页面', async () => {\n      // 查找注册按钮/链接\n      const registerButton = page.locator('a[href*=\"register\"], button:has-text(\"注册\"), button:has-text(\"Register\")')\n\n      if (await registerButton.isVisible({ timeout: 3000 }).catch(() => false)) {\n        await registerButton.first().click()\n        await page.waitForURL('**/register**')\n      } else {\n        // 直接访问注册页\n        await page.goto('/register')\n      }\n\n      await expect(page).toHaveURL(/.*register.*/)\n    })\n\n    // ========== 步骤 3: 填写注册表单 ==========\n    await test.step('填写注册表单', async () => {\n      // 填写邮箱\n      const emailInput = page.locator('input[type=\"email\"]')\n      await emailInput.fill(testUser.email)\n\n      // 填写密码\n      const passwordInputs = page.locator('input[type=\"password\"]')\n      await passwordInputs.first().fill(testUser.password)\n\n      // 如果有确认密码字段\n      if (await passwordInputs.count() > 1) {\n        await passwordInputs.nth(1).fill(testUser.password)\n      }\n\n      // 填写姓名（如果有）\n      const nameInput = page.locator('input[name=\"name\"], input[placeholder*=\"姓名\"], input[placeholder*=\"Name\"]')\n      if (await nameInput.isVisible({ timeout: 1000 }).catch(() => false)) {\n        await nameInput.fill(testUser.name)\n      }\n\n      // 截图记录\n      await page.screenshot({ path: 'test-results/client-journey-register-form.png' })\n    })\n\n    // ========== 步骤 4: 提交注册（模拟，不实际提交）==========\n    await test.step('验证注册按钮可点击', async () => {\n      const submitButton = page.locator('button[type=\"submit\"], button:has-text(\"注册\"), button:has-text(\"Register\")')\n      await expect(submitButton).toBeVisible()\n      await expect(submitButton).toBeEnabled()\n\n      // 注意：这里不实际点击提交，避免创建真实用户\n      console.log('✓ 注册表单验证通过（未实际提交）')\n    })\n\n    // ========== 步骤 5: 访问登录页 ==========\n    await test.step('导航到登录页面', async () => {\n      await page.goto('/login')\n      await page.waitForLoadState('networkidle')\n\n      await expect(page.locator('text=📦 FETCH CHINA')).toBeVisible()\n    })\n\n    // ========== 步骤 6: 填写登录表单（使用测试账号）==========\n    await test.step('填写登录表单', async () => {\n      // 使用预设的测试账号（如果有）\n      const emailInput = page.locator('input[type=\"email\"], input[type=\"text\"]').first()\n      const passwordInput = page.locator('input[type=\"password\"]')\n\n      await emailInput.fill('test@example.com')\n      await passwordInput.fill('password')\n\n      await page.screenshot({ path: 'test-results/client-journey-login-form.png' })\n    })\n\n    // ========== 步骤 7: 验证登录按钮 ==========\n    await test.step('验证登录按钮可用', async () => {\n      const loginButton = page.locator('button[type=\"submit\"], button:has-text(\"登录\"), button:has-text(\"Login\")')\n      await expect(loginButton).toBeVisible()\n      await expect(loginButton).toBeEnabled()\n\n      console.log('✓ 登录表单验证通过（未实际登录）')\n    })\n\n    // ========== 步骤 8: 模拟访问仪表板 ==========\n    await test.step('访问客户仪表板（未登录状态）', async () => {\n      await page.goto('/dashboard')\n      await page.waitForLoadState('networkidle')\n\n      // 未登录应该重定向到登录页\n      await page.waitForTimeout(2000)\n      const isOnLogin = page.url().includes('login')\n\n      expect(isOnLogin).toBeTruthy()\n      console.log('✓ 未登录访问受保护页面，正确重定向到登录页')\n    })\n\n    // ========== 步骤 9: 访问新订单页面 ==========\n    await test.step('访问新订单页面（未登录状态）', async () => {\n      await page.goto('/orders/new')\n      await page.waitForLoadState('networkidle')\n      await page.waitForTimeout(2000)\n\n      // 应该重定向到登录页\n      const isOnLogin = page.url().includes('login')\n      expect(isOnLogin).toBeTruthy()\n\n      console.log('✓ 订单创建页面需要登录，验证通过')\n    })\n  })\n\n  test('客户导航流程：浏览各个页面', async ({ page }) => {\n\n    await test.step('访问首页', async () => {\n      await page.goto('/')\n      await page.waitForLoadState('networkidle')\n    })\n\n    // 测试公开页面导航\n    const publicPages = [\n      { path: '/faq', name: 'FAQ页面' },\n      { path: '/about', name: '关于我们' },\n      { path: '/terms', name: '服务条款' },\n      { path: '/support', name: '客服支持' }\n    ]\n\n    for (const pageInfo of publicPages) {\n      await test.step(`访问${pageInfo.name}`, async () => {\n        await page.goto(pageInfo.path)\n        await page.waitForLoadState('networkidle')\n\n        // 验证页面加载\n        const body = page.locator('body')\n        await expect(body).toBeVisible()\n\n        console.log(`✓ ${pageInfo.name} 加载成功`)\n      })\n    }\n  })\n\n  test('客户表单交互：测试输入验证', async ({ page }) => {\n\n    await test.step('访问登录页', async () => {\n      await page.goto('/login')\n      await page.waitForLoadState('networkidle')\n    })\n\n    await test.step('测试空表单提交', async () => {\n      const loginButton = page.locator('button[type=\"submit\"]')\n\n      // 尝试点击登录按钮（表单为空）\n      if (await loginButton.isEnabled()) {\n        await loginButton.click()\n        await page.waitForTimeout(1000)\n\n        // 应该显示验证错误或保持在登录页\n        const isStillOnLogin = page.url().includes('login')\n        expect(isStillOnLogin).toBeTruthy()\n\n        console.log('✓ 空表单验证正常')\n      }\n    })\n\n    await test.step('测试无效邮箱格式', async () => {\n      const emailInput = page.locator('input[type=\"email\"], input[type=\"text\"]').first()\n      const passwordInput = page.locator('input[type=\"password\"]')\n\n      await emailInput.fill('invalid-email')\n      await passwordInput.fill('password123')\n\n      const loginButton = page.locator('button[type=\"submit\"]')\n      await loginButton.click()\n      await page.waitForTimeout(1000)\n\n      // 应该保持在登录页或显示错误\n      const isStillOnLogin = page.url().includes('login')\n      expect(isStillOnLogin).toBeTruthy()\n\n      console.log('✓ 邮箱格式验证正常')\n    })\n  })\n})\n"],"mappings":"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","ignoreList":[]}