combination-query.spec.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. import { test, expect } from '../../utils/test-setup';
  2. test.describe('组合查询流程 E2E 测试', () => {
  3. test.beforeEach(async ({ page }) => {
  4. // 确保数据库中有测试数据
  5. await page.goto('/');
  6. });
  7. test('完整组合查询流程 - 大巴拼车', async ({ page }) => {
  8. // 1. 访问首页
  9. await page.goto('/');
  10. await expect(page.locator('text=便捷出行')).toBeVisible();
  11. // 2. 验证默认选择大巴拼车
  12. const busOption = page.locator('text=大巴拼车').first();
  13. await expect(busOption).toBeVisible();
  14. await expect(busOption).toHaveClass(/bg-gradient-to-r/);
  15. // 3. 设置出发地
  16. const startLocationButton = page.locator('button:has-text("出发地")').first();
  17. await startLocationButton.click();
  18. // 等待地区选择器显示
  19. await expect(page.locator('text=选择出发地')).toBeVisible();
  20. // 选择地区(这里使用模拟的地区选择)
  21. const confirmButton = page.locator('button:has-text("确认")').first();
  22. await confirmButton.click();
  23. // 4. 设置目的地
  24. const endLocationButton = page.locator('button:has-text("目的地")').first();
  25. await endLocationButton.click();
  26. await expect(page.locator('text=选择目的地')).toBeVisible();
  27. await confirmButton.click();
  28. // 5. 验证地区选择成功
  29. await expect(page.locator('text=北京市 北京市 朝阳区')).toBeVisible();
  30. // 6. 点击查询按钮
  31. const searchButton = page.locator('button:has-text("查询路线")').first();
  32. await searchButton.click();
  33. // 7. 验证导航到活动选择页面
  34. await expect(page).toHaveURL(/.*pages\/select-activity\/ActivitySelectPage/);
  35. // 8. 验证查询参数传递正确
  36. const currentUrl = page.url();
  37. expect(currentUrl).toContain('vehicleType=bus');
  38. expect(currentUrl).toContain('travelMode=carpool');
  39. expect(currentUrl).toContain('startAreaIds=');
  40. expect(currentUrl).toContain('endAreaIds=');
  41. // 9. 验证活动选择页面显示
  42. await expect(page.locator('text=选择活动')).toBeVisible();
  43. // 10. 选择第一个活动
  44. const firstActivity = page.locator('[data-testid="activity-card"]').first();
  45. await firstActivity.click();
  46. // 11. 验证导航到班次列表页面
  47. await expect(page).toHaveURL(/.*pages\/schedule-list\/ScheduleListPage/);
  48. // 12. 验证班次列表页面显示
  49. await expect(page.locator('text=路线列表')).toBeVisible();
  50. // 13. 验证路线卡片显示车型和出行方式
  51. const routeCard = page.locator('[data-testid="route-card"]').first();
  52. await expect(routeCard).toBeVisible();
  53. // 验证包含车型信息
  54. await expect(routeCard).toContainText(/大巴|中巴|小车|商务车/);
  55. // 验证包含出行方式信息
  56. await expect(routeCard).toContainText(/拼车|包车/);
  57. });
  58. test('完整组合查询流程 - 商务车', async ({ page }) => {
  59. // 1. 访问首页
  60. await page.goto('/');
  61. await expect(page.locator('text=便捷出行')).toBeVisible();
  62. // 2. 选择商务车
  63. const businessOption = page.locator('text=商务车').first();
  64. await businessOption.click();
  65. await expect(businessOption).toHaveClass(/bg-gradient-to-r/);
  66. // 3. 设置出发地
  67. const startLocationButton = page.locator('button:has-text("出发地")').first();
  68. await startLocationButton.click();
  69. // 等待地区选择器显示
  70. await expect(page.locator('text=选择出发地')).toBeVisible();
  71. // 选择地区
  72. const confirmButton = page.locator('button:has-text("确认")').first();
  73. await confirmButton.click();
  74. // 4. 设置目的地
  75. const endLocationButton = page.locator('button:has-text("目的地")').first();
  76. await endLocationButton.click();
  77. await expect(page.locator('text=选择目的地')).toBeVisible();
  78. await confirmButton.click();
  79. // 5. 点击查询按钮
  80. const searchButton = page.locator('button:has-text("查询路线")').first();
  81. await searchButton.click();
  82. // 6. 验证导航到活动选择页面
  83. await expect(page).toHaveURL(/.*pages\/select-activity\/ActivitySelectPage/);
  84. // 7. 验证商务车组合查询参数
  85. const currentUrl = page.url();
  86. expect(currentUrl).toContain('vehicleType=business');
  87. expect(currentUrl).toContain('travelMode=carpool,charter');
  88. // 8. 选择第一个活动
  89. const firstActivity = page.locator('[data-testid="activity-card"]').first();
  90. await firstActivity.click();
  91. // 9. 验证导航到班次列表页面
  92. await expect(page).toHaveURL(/.*pages\/schedule-list\/ScheduleListPage/);
  93. // 10. 验证班次列表页面显示
  94. await expect(page.locator('text=路线列表')).toBeVisible();
  95. // 11. 验证路线卡片显示商务车信息
  96. const routeCard = page.locator('[data-testid="route-card"]').first();
  97. await expect(routeCard).toBeVisible();
  98. // 验证包含商务车型信息
  99. await expect(routeCard).toContainText(/商务车/);
  100. });
  101. test('完整组合查询流程 - 包车', async ({ page }) => {
  102. // 1. 访问首页
  103. await page.goto('/');
  104. await expect(page.locator('text=便捷出行')).toBeVisible();
  105. // 2. 选择包车
  106. const charterOption = page.locator('text=包车').first();
  107. await charterOption.click();
  108. await expect(charterOption).toHaveClass(/bg-gradient-to-r/);
  109. // 3. 设置出发地
  110. const startLocationButton = page.locator('button:has-text("出发地")').first();
  111. await startLocationButton.click();
  112. // 等待地区选择器显示
  113. await expect(page.locator('text=选择出发地')).toBeVisible();
  114. // 选择地区
  115. const confirmButton = page.locator('button:has-text("确认")').first();
  116. await confirmButton.click();
  117. // 4. 设置目的地
  118. const endLocationButton = page.locator('button:has-text("目的地")').first();
  119. await endLocationButton.click();
  120. await expect(page.locator('text=选择目的地')).toBeVisible();
  121. await confirmButton.click();
  122. // 5. 点击查询按钮
  123. const searchButton = page.locator('button:has-text("查询路线")').first();
  124. await searchButton.click();
  125. // 6. 验证导航到活动选择页面
  126. await expect(page).toHaveURL(/.*pages\/select-activity\/ActivitySelectPage/);
  127. // 7. 验证包车组合查询参数
  128. const currentUrl = page.url();
  129. expect(currentUrl).toContain('vehicleType=bus,business');
  130. expect(currentUrl).toContain('travelMode=charter');
  131. // 8. 选择第一个活动
  132. const firstActivity = page.locator('[data-testid="activity-card"]').first();
  133. await firstActivity.click();
  134. // 9. 验证导航到班次列表页面
  135. await expect(page).toHaveURL(/.*pages\/schedule-list\/ScheduleListPage/);
  136. // 10. 验证班次列表页面显示
  137. await expect(page.locator('text=路线列表')).toBeVisible();
  138. // 11. 验证路线卡片显示包车信息
  139. const routeCard = page.locator('[data-testid="route-card"]').first();
  140. await expect(routeCard).toBeVisible();
  141. // 验证包含包车出行方式信息
  142. await expect(routeCard).toContainText(/包车/);
  143. });
  144. test('组合查询选项切换', async ({ page }) => {
  145. // 1. 访问首页
  146. await page.goto('/');
  147. // 2. 验证默认选择大巴拼车
  148. const busOption = page.locator('text=大巴拼车').first();
  149. const businessOption = page.locator('text=商务车').first();
  150. const charterOption = page.locator('text=包车').first();
  151. await expect(busOption).toHaveClass(/bg-gradient-to-r/);
  152. await expect(businessOption).not.toHaveClass(/text-white/);
  153. await expect(charterOption).not.toHaveClass(/text-white/);
  154. // 3. 切换到商务车
  155. await businessOption.click();
  156. await expect(busOption).not.toHaveClass(/text-white/);
  157. await expect(businessOption).toHaveClass(/bg-gradient-to-r/);
  158. await expect(charterOption).not.toHaveClass(/text-white/);
  159. // 4. 切换到包车
  160. await charterOption.click();
  161. await expect(busOption).not.toHaveClass(/text-white/);
  162. await expect(businessOption).not.toHaveClass(/text-white/);
  163. await expect(charterOption).toHaveClass(/bg-gradient-to-r/);
  164. // 5. 切换回大巴拼车
  165. await busOption.click();
  166. await expect(busOption).toHaveClass(/bg-gradient-to-r/);
  167. await expect(businessOption).not.toHaveClass(/text-white/);
  168. await expect(charterOption).not.toHaveClass(/text-white/);
  169. });
  170. test('组合查询参数验证', async ({ page }) => {
  171. // 1. 访问首页
  172. await page.goto('/');
  173. // 2. 设置出发地和目的地
  174. const startLocationButton = page.locator('button:has-text("出发地")').first();
  175. await startLocationButton.click();
  176. const confirmButton = page.locator('button:has-text("确认")').first();
  177. await confirmButton.click();
  178. const endLocationButton = page.locator('button:has-text("目的地")').first();
  179. await endLocationButton.click();
  180. await confirmButton.click();
  181. // 3. 测试大巴拼车参数
  182. const busOption = page.locator('text=大巴拼车').first();
  183. await busOption.click();
  184. const searchButton = page.locator('button:has-text("查询路线")').first();
  185. await searchButton.click();
  186. let currentUrl = page.url();
  187. expect(currentUrl).toContain('vehicleType=bus');
  188. expect(currentUrl).toContain('travelMode=carpool');
  189. // 4. 返回首页测试商务车参数
  190. await page.goBack();
  191. const businessOption = page.locator('text=商务车').first();
  192. await businessOption.click();
  193. await searchButton.click();
  194. currentUrl = page.url();
  195. expect(currentUrl).toContain('vehicleType=business');
  196. expect(currentUrl).toContain('travelMode=carpool,charter');
  197. // 5. 返回首页测试包车参数
  198. await page.goBack();
  199. const charterOption = page.locator('text=包车').first();
  200. await charterOption.click();
  201. await searchButton.click();
  202. currentUrl = page.url();
  203. expect(currentUrl).toContain('vehicleType=bus,business');
  204. expect(currentUrl).toContain('travelMode=charter');
  205. });
  206. test('组合查询结果验证', async ({ page }) => {
  207. // 1. 访问首页并设置查询条件
  208. await page.goto('/');
  209. // 设置出发地和目的地
  210. const startLocationButton = page.locator('button:has-text("出发地")').first();
  211. await startLocationButton.click();
  212. const confirmButton = page.locator('button:has-text("确认")').first();
  213. await confirmButton.click();
  214. const endLocationButton = page.locator('button:has-text("目的地")').first();
  215. await endLocationButton.click();
  216. await confirmButton.click();
  217. // 2. 测试大巴拼车查询结果
  218. const busOption = page.locator('text=大巴拼车').first();
  219. await busOption.click();
  220. const searchButton = page.locator('button:has-text("查询路线")').first();
  221. await searchButton.click();
  222. // 等待活动选择页面加载
  223. await expect(page.locator('text=选择活动')).toBeVisible();
  224. // 验证活动列表显示
  225. const activityCards = page.locator('[data-testid="activity-card"]');
  226. await expect(activityCards.first()).toBeVisible();
  227. // 3. 选择活动并验证路线列表
  228. await activityCards.first().click();
  229. // 等待班次列表页面加载
  230. await expect(page.locator('text=路线列表')).toBeVisible();
  231. // 验证路线列表显示
  232. const routeCards = page.locator('[data-testid="route-card"]');
  233. await expect(routeCards.first()).toBeVisible();
  234. // 4. 验证路线信息包含车型和出行方式
  235. const firstRouteCard = routeCards.first();
  236. const routeText = await firstRouteCard.textContent();
  237. // 验证包含车型信息
  238. expect(routeText).toMatch(/大巴|中巴|小车|商务车/);
  239. // 验证包含出行方式信息
  240. expect(routeText).toMatch(/拼车|包车/);
  241. // 5. 验证路线详情显示完整信息
  242. await firstRouteCard.click();
  243. // 验证路线详情页面显示
  244. await expect(page.locator('text=路线详情')).toBeVisible();
  245. // 验证详情页面包含车型和出行方式信息
  246. const detailText = await page.textContent('body');
  247. expect(detailText).toMatch(/车型.*[大巴|中巴|小车|商务车]/);
  248. expect(detailText).toMatch(/出行方式.*[拼车|包车]/);
  249. });
  250. test('组合查询错误处理', async ({ page }) => {
  251. // 1. 访问首页
  252. await page.goto('/');
  253. // 2. 不设置出发地和目的地,直接点击查询
  254. const searchButton = page.locator('button:has-text("查询路线")').first();
  255. await searchButton.click();
  256. // 3. 验证页面没有跳转(应该停留在首页)
  257. await expect(page).toHaveURL(/\/$/);
  258. // 4. 验证错误提示显示(如果有的话)
  259. // 这里可以根据实际实现检查是否有错误提示
  260. // 5. 只设置出发地,不设置目的地
  261. const startLocationButton = page.locator('button:has-text("出发地")').first();
  262. await startLocationButton.click();
  263. const confirmButton = page.locator('button:has-text("确认")').first();
  264. await confirmButton.click();
  265. // 6. 再次点击查询
  266. await searchButton.click();
  267. // 7. 验证页面仍然没有跳转
  268. await expect(page).toHaveURL(/\/$/);
  269. // 8. 设置目的地
  270. const endLocationButton = page.locator('button:has-text("目的地")').first();
  271. await endLocationButton.click();
  272. await confirmButton.click();
  273. // 9. 现在应该可以正常查询
  274. await searchButton.click();
  275. // 10. 验证页面跳转到活动选择页面
  276. await expect(page).toHaveURL(/.*pages\/select-activity\/ActivitySelectPage/);
  277. });
  278. test('组合查询性能测试', async ({ page }) => {
  279. // 1. 访问首页
  280. await page.goto('/');
  281. // 2. 设置查询条件
  282. const startLocationButton = page.locator('button:has-text("出发地")').first();
  283. await startLocationButton.click();
  284. const confirmButton = page.locator('button:has-text("确认")').first();
  285. await confirmButton.click();
  286. const endLocationButton = page.locator('button:has-text("目的地")').first();
  287. await endLocationButton.click();
  288. await confirmButton.click();
  289. // 3. 测试不同组合查询的响应时间
  290. const travelOptions = [
  291. { name: '大巴拼车', expectedParams: { vehicleType: 'bus', travelMode: 'carpool' } },
  292. { name: '商务车', expectedParams: { vehicleType: 'business', travelMode: 'carpool,charter' } },
  293. { name: '包车', expectedParams: { vehicleType: 'bus,business', travelMode: 'charter' } }
  294. ];
  295. for (const option of travelOptions) {
  296. // 选择出行方式
  297. const optionElement = page.locator(`text=${option.name}`).first();
  298. await optionElement.click();
  299. // 记录开始时间
  300. const startTime = Date.now();
  301. // 点击查询
  302. const searchButton = page.locator('button:has-text("查询路线")').first();
  303. await searchButton.click();
  304. // 等待页面加载完成
  305. await expect(page).toHaveURL(/.*pages\/select-activity\/ActivitySelectPage/);
  306. // 记录结束时间
  307. const endTime = Date.now();
  308. const responseTime = endTime - startTime;
  309. // 验证响应时间在合理范围内(小于5秒)
  310. expect(responseTime).toBeLessThan(5000);
  311. // 验证查询参数正确
  312. const currentUrl = page.url();
  313. expect(currentUrl).toContain(`vehicleType=${option.expectedParams.vehicleType}`);
  314. expect(currentUrl).toContain(`travelMode=${option.expectedParams.travelMode}`);
  315. // 返回首页进行下一个测试
  316. await page.goBack();
  317. }
  318. });
  319. });