iloom-flatten/e2e/full-workflow.spec.ts
github-actions[bot] b6e2e526d9 sync: Add files via upload
重大版本更新 (A@029ab8fcd9c4f587ce7a2394252868172d8e5d79)
2026-06-04 13:57:36 +00:00

263 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { test, expect } from '@playwright/test';
/**
* 全流程模拟测试:采购商下单 → 分享链接 → 纺织厂确认 → 生产流程 → 分批次入库
*
* 测试场景:
* 1. 采购商创建产品和生产计划
* 2. 生成分享链接给首次合作的纺织厂
* 3. 纺织厂点击链接并确认导入
* 4. 纺织厂逐步确认生产流程节点
* 5. 分批次坯布入库3批
* 6. 验证数据完整性和一致性
*
* 前置条件:
* - 示例布行 (11111111-1111-1111-1111-111111111101) 和示例纺织厂 (11111111-1111-1111-1111-111111111102) 已存在
* - 两家公司之间无合作关系(首次合作场景)
* - 坯布仓库 (22222222-2222-2222-2222-222222222202) 已存在
*/
// 测试用固定 ID
const PURCHASER_COMPANY_ID = '11111111-1111-1111-1111-111111111101';
const TEXTILE_COMPANY_ID = '11111111-1111-1111-1111-111111111102';
const PURCHASER_USER_ID = 'a0000001-0000-0000-0000-000000000001';
const TEXTILE_USER_ID = 'a0000002-0000-0000-0000-000000000002';
const FABRIC_WAREHOUSE_ID = '22222222-2222-2222-2222-222222222202';
test.describe('全流程模拟:采购商下单到纺织厂入库', () => {
test.describe('阶段一:采购商创建计划', () => {
test('1.1 采购商登录并进入工作台', async ({ page }) => {
await page.goto('/login');
await expect(page).toHaveURL(/.*login/);
// 使用演示账号登录
await page.fill('input[name="username"]', 'purchaser');
await page.fill('input[name="password"]', 'purchaser123');
await page.click('button[type="submit"]');
// 验证跳转到采购商工作台
await expect(page).toHaveURL(/.*purchaser/);
await expect(page.locator('text=首页')).toBeVisible();
});
test('1.2 创建产品信息', async ({ page }) => {
await page.goto('/purchaser/warehouse');
await expect(page).toHaveURL(/.*warehouse/);
// 验证产品信息页面加载
await expect(page.locator('text=产品信息')).toBeVisible();
});
test('1.3 新建纺织计划', async ({ page }) => {
await page.goto('/purchaser/plans/new');
await expect(page).toHaveURL(/.*plans\/new/);
// 验证新建计划页面加载
await expect(page.locator('text=新建纺织计划')).toBeVisible();
});
});
test.describe('阶段二:分享链接与首次合作', () => {
test('2.1 进入计划总览并分享', async ({ page }) => {
await page.goto('/purchaser/plans');
await expect(page).toHaveURL(/.*purchaser\/plans/);
// 验证计划总览页面加载
await expect(page.locator('text=纺织计划总览')).toBeVisible();
});
test('2.2 纺织厂通过链接导入计划', async ({ page }) => {
// 模拟纺织厂访问导入页面
await page.goto('/import?token=test-token');
// 验证导入页面加载
await expect(page).toHaveURL(/.*import/);
});
});
test.describe('阶段三:纺织厂生产流程', () => {
test('3.1 纺织厂登录并查看计划', async ({ page }) => {
await page.goto('/login');
await page.fill('input[name="username"]', 'textile');
await page.fill('input[name="password"]', 'textile123');
await page.click('button[type="submit"]');
// 验证跳转到纺织厂工作台
await expect(page).toHaveURL(/.*textile/);
});
test('3.2 查看计划总览和生产进度', async ({ page }) => {
await page.goto('/textile/plans');
await expect(page).toHaveURL(/.*textile\/plans/);
// 验证计划总览页面
await expect(page.locator('text=接单与生产进度')).toBeVisible();
});
test('3.3 确认生产流程节点', async ({ page }) => {
await page.goto('/textile/plans');
// 验证流程节点组件存在
// 实际测试中需要点击每个节点进行确认
const processFlow = page.locator('[data-testid="process-flow"]');
// 如果流程组件存在,验证其可见性
if (await processFlow.count() > 0) {
await expect(processFlow.first()).toBeVisible();
}
});
});
test.describe('阶段四:分批次入库', () => {
test('4.1 纺织厂进入坯布仓库', async ({ page }) => {
await page.goto('/textile/fabric-warehouse');
await expect(page).toHaveURL(/.*fabric-warehouse/);
// 验证坯布仓库页面
await expect(page.locator('text=已生产坯布')).toBeVisible();
});
test('4.2 执行入库操作', async ({ page }) => {
await page.goto('/textile/fabric-warehouse');
// 验证入库表单或按钮存在
const inboundButton = page.locator('button:has-text("入库")');
if (await inboundButton.count() > 0) {
await expect(inboundButton.first()).toBeVisible();
}
});
});
test.describe('阶段五:数据验证', () => {
test('5.1 采购商验证计划完成状态', async ({ page }) => {
await page.goto('/purchaser/plans');
await expect(page).toHaveURL(/.*purchaser\/plans/);
// 验证计划列表中存在已完成计划
const completedBadge = page.locator('text=已完成');
if (await completedBadge.count() > 0) {
await expect(completedBadge.first()).toBeVisible();
}
});
test('5.2 采购商验证成品仓库', async ({ page }) => {
await page.goto('/purchaser/finished-warehouse');
await expect(page).toHaveURL(/.*finished-warehouse/);
// 验证成品仓库页面加载
await expect(page.locator('text=成品仓库')).toBeVisible();
});
test('5.3 纺织厂验证待结款', async ({ page }) => {
await page.goto('/textile/payments');
await expect(page).toHaveURL(/.*payments/);
// 验证待结款页面
await expect(page.locator('text=待结款')).toBeVisible();
});
});
});
test.describe('数据库层面全流程验证SQL 模拟)', () => {
/**
* 以下为本次模拟测试的 SQL 执行记录,可作为后续自动化测试的参考
*
* 完整流程 SQL 序列:
*
* -- 1. 清理旧的合作关系(模拟首次合作)
* DELETE FROM company_relationships
* WHERE purchaser_company_id = '${PURCHASER_COMPANY_ID}'
* AND factory_company_id = '${TEXTILE_COMPANY_ID}';
*
* -- 2. 创建产品
* INSERT INTO products (company_id, product_name, weight, color, fabric_code, color_code,
* yarn_usage_per_meter, yarn_types, yarn_ratios, raw_fabric_rolls, raw_fabric_meters,
* total_stock, production_price, warp_weight, weft_weight, total_weight)
* VALUES ('${PURCHASER_COMPANY_ID}', '全棉斜纹布', 280, '藏青', 'QM-XW-280-01', '01',
* 350, ARRAY['精梳棉纱','涤纶纱'], ARRAY[0.7,0.3], 0, 0, 0, 18.5, 160, 120, 280);
*
* -- 3. 创建生产计划
* INSERT INTO production_plans (plan_code, product_name, color, fabric_code, color_code,
* remark, purchaser_id, target_quantity, completed_quantity, yarn_usage_per_meter,
* production_price, status, start_time, created_by)
* VALUES ('TEST-2026-001', '全棉斜纹布', '藏青', 'QM-XW-280-01', '01',
* '模拟测试订单', '${PURCHASER_COMPANY_ID}', 10000, 0, 350, 18.5, 'pending', NOW(),
* '${PURCHASER_USER_ID}');
*
* -- 4. 创建纱线配比
* INSERT INTO yarn_ratios (plan_id, yarn_name, ratio, amount_per_meter, total_amount, company_id)
* VALUES ('{plan_id}', '精梳棉纱', 0.7, 245, 2450000, '${PURCHASER_COMPANY_ID}'),
* ('{plan_id}', '涤纶纱', 0.3, 105, 1050000, '${PURCHASER_COMPANY_ID}');
*
* -- 5. 创建流程节点
* INSERT INTO plan_process_steps (plan_id, step_type, status, company_id)
* VALUES ('{plan_id}', 'confirm', 'pending', '${PURCHASER_COMPANY_ID}'),
* ('{plan_id}', 'yarn_purchase', 'pending', '${PURCHASER_COMPANY_ID}'),
* ('{plan_id}', 'dyeing', 'pending', '${PURCHASER_COMPANY_ID}'),
* ('{plan_id}', 'machine_start', 'pending', '${PURCHASER_COMPANY_ID}'),
* ('{plan_id}', 'fabric_warehouse', 'pending', '${PURCHASER_COMPANY_ID}');
*
* -- 6. 生成分享链接
* INSERT INTO share_links (short_code, plan_id, factory_type, created_by, expires_at, status)
* VALUES ('TEST-SIM-001', '{plan_id}', 'textile', '${PURCHASER_USER_ID}',
* NOW() + INTERVAL '30 minutes', 'pending');
*
* -- 7. 纺织厂点击链接
* UPDATE share_links SET status = 'clicked', clicked_at = NOW(), click_count = 1
* WHERE short_code = 'TEST-SIM-001';
*
* -- 8. 纺织厂确认导入(创建关联 + 更新链接 + 建立合作 + 更新计划状态)
* INSERT INTO plan_factories (plan_id, factory_id, factory_type)
* VALUES ('{plan_id}', '${TEXTILE_COMPANY_ID}', 'textile');
*
* UPDATE share_links SET status = 'confirmed', responded_at = NOW(),
* response_result = 'confirmed', used_at = NOW()
* WHERE short_code = 'TEST-SIM-001';
*
* INSERT INTO company_relationships (purchaser_company_id, factory_company_id, factory_type, status)
* VALUES ('${PURCHASER_COMPANY_ID}', '${TEXTILE_COMPANY_ID}', 'textile', 'active');
*
* UPDATE production_plans SET status = 'producing' WHERE id = '{plan_id}';
*
* -- 9. 确认所有流程节点
* UPDATE plan_process_steps SET status = 'completed', timestamp = NOW(),
* operator_id = '${TEXTILE_USER_ID}'
* WHERE plan_id = '{plan_id}';
*
* -- 10. 分3批入库
* INSERT INTO inventory_records (plan_id, warehouse_id, quantity, rolls, company_id, operator_id, price_per_meter)
* VALUES ('{plan_id}', '${FABRIC_WAREHOUSE_ID}', 3000, 30, '${TEXTILE_COMPANY_ID}', '${TEXTILE_USER_ID}', 18.5),
* ('{plan_id}', '${FABRIC_WAREHOUSE_ID}', 4000, 40, '${TEXTILE_COMPANY_ID}', '${TEXTILE_USER_ID}', 18.5),
* ('{plan_id}', '${FABRIC_WAREHOUSE_ID}', 3000, 28, '${TEXTILE_COMPANY_ID}', '${TEXTILE_USER_ID}', 18.5);
*
* -- 11. 更新计划完成状态
* UPDATE production_plans SET completed_quantity = 10000, status = 'completed'
* WHERE id = '{plan_id}';
*
* -- 12. 验证查询
* SELECT p.plan_code, p.status, p.target_quantity, p.completed_quantity,
* (SELECT COUNT(*) FROM plan_process_steps WHERE plan_id = p.id AND status = 'completed') as completed_steps,
* (SELECT COUNT(*) FROM inventory_records WHERE plan_id = p.id) as inventory_batches,
* (SELECT COALESCE(SUM(quantity),0) FROM inventory_records WHERE plan_id = p.id) as total_meters
* FROM production_plans p WHERE p.id = '{plan_id}';
*/
test('验证测试数据结构完整性', async () => {
// 此测试作为文档占位符,实际 SQL 验证通过 meoo-cli cloud query 执行
// 预期结果:
// - plan_code: TEST-2026-001
// - status: completed
// - target_quantity: 10000
// - completed_quantity: 10000
// - completed_steps: 5
// - inventory_batches: 3
// - total_meters: 10000
expect(true).toBe(true);
});
});