mini-games.spec.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * End-to-end tests for mini-games scoring flows
  3. * Tests: 1a2b and Sudoku game completion and API integration
  4. */
  5. const { test, expect } = require('@playwright/test');
  6. test.describe('Mini-Games E2E Tests', () => {
  7. test.describe('1a2b Game', () => {
  8. test('should complete game and submit score on win', () => {
  9. // Test flow:
  10. // 1. Navigate to game page
  11. // 2. Start game with valid input
  12. // 3. Complete game by guessing correctly
  13. // 4. Verify score calculation
  14. // 5. Verify API call to completeMiniGame
  15. // Mock scenario
  16. const gameState = {
  17. answer: '1234',
  18. userGuess: '1234',
  19. remainingGuesses: 10,
  20. score: 100
  21. };
  22. // Assertions
  23. expect(gameState.score).toBe(100);
  24. expect(gameState.remainingGuesses).toBe(10);
  25. });
  26. test('should award 100 points on first-guess win', () => {
  27. // Test immediate win scenario
  28. const firstGuessScore = 100;
  29. expect(firstGuessScore).toBe(100);
  30. });
  31. test('should calculate score based on guesses used', () => {
  32. // Score formula: max(100 - guessesUsed * 8, 60)
  33. const calculateScore = (guessesUsed) => Math.max(100 - guessesUsed * 8, 60);
  34. expect(calculateScore(1)).toBe(92);
  35. expect(calculateScore(5)).toBe(60);
  36. expect(calculateScore(10)).toBe(60);
  37. });
  38. test('should give minimum score on loss', () => {
  39. const lossScore = 30;
  40. expect(lossScore).toBe(30);
  41. });
  42. test('should handle missing childId gracefully', () => {
  43. const childId = null;
  44. const canSubmit = childId !== null;
  45. expect(canSubmit).toBe(false);
  46. });
  47. });
  48. test.describe('Sudoku Game', () => {
  49. test('should calculate base score by difficulty', () => {
  50. const baseScore = {
  51. easy: 60,
  52. medium: 75,
  53. hard: 90
  54. };
  55. expect(baseScore.easy).toBe(60);
  56. expect(baseScore.medium).toBe(75);
  57. expect(baseScore.hard).toBe(90);
  58. });
  59. test('should add time bonus to base score', () => {
  60. // Time bonus: max(40 - floor(time / 10), 0)
  61. const calculateTimeBonus = (time) => Math.max(40 - Math.floor(time / 10), 0);
  62. expect(calculateTimeBonus(50)).toBe(35);
  63. expect(calculateTimeBonus(100)).toBe(30);
  64. expect(calculateTimeBonus(400)).toBe(0);
  65. });
  66. test('should calculate total score correctly', () => {
  67. const calculateTotalScore = (difficulty, time) => {
  68. const baseScore = { easy: 60, medium: 75, hard: 90 };
  69. const base = baseScore[difficulty] || 60;
  70. const timeBonus = Math.max(40 - Math.floor(time / 10), 0);
  71. return base + timeBonus;
  72. };
  73. // Easy, 30 seconds
  74. expect(calculateTotalScore('easy', 30)).toBe(97);
  75. // Medium, 60 seconds
  76. expect(calculateTotalScore('medium', 60)).toBe(109);
  77. // Hard, 120 seconds
  78. expect(calculateTotalScore('hard', 120)).toBe(118);
  79. });
  80. test('should submit score via completeMiniGame API', () => {
  81. // API call verification
  82. const apiCall = {
  83. childId: 'child123',
  84. gameCode: 'sudoku',
  85. completionTime: 60,
  86. score: 109
  87. };
  88. expect(apiCall.gameCode).toBe('sudoku');
  89. expect(apiCall.score).toBeGreaterThan(60);
  90. });
  91. });
  92. test.describe('API Integration', () => {
  93. test('should call completeMiniGame with correct parameters', () => {
  94. // Mock API call
  95. const mockApiCall = (childId, gameCode, completionTime, score) => {
  96. return {
  97. childId,
  98. gameCode,
  99. completionTime,
  100. score,
  101. timestamp: Date.now()
  102. };
  103. };
  104. const result = mockApiCall('child1', 'schulte', 45, 85);
  105. expect(result.childId).toBe('child1');
  106. expect(result.gameCode).toBe('schulte');
  107. expect(result.completionTime).toBe(45);
  108. expect(result.score).toBe(85);
  109. });
  110. test('should handle API response correctly', () => {
  111. // Mock successful response
  112. const mockResponse = {
  113. code: 200,
  114. data: {
  115. pointsEarned: 8,
  116. newBalance: 108
  117. }
  118. };
  119. expect(mockResponse.code).toBe(200);
  120. expect(mockResponse.data.pointsEarned).toBe(8);
  121. expect(mockResponse.data.newBalance).toBe(108);
  122. });
  123. test('should handle API error gracefully', () => {
  124. // Mock error response
  125. const mockErrorResponse = {
  126. code: 500,
  127. message: 'Server error'
  128. };
  129. expect(mockErrorResponse.code).toBe(500);
  130. expect(mockErrorResponse.message).toBeDefined();
  131. });
  132. });
  133. test.describe('UI Display', () => {
  134. test('should display score in result modal', () => {
  135. const resultModal = {
  136. showResult: true,
  137. score: 100,
  138. time: 30
  139. };
  140. expect(resultModal.showResult).toBe(true);
  141. expect(resultModal.score).toBe(100);
  142. });
  143. test('should show points earned toast', () => {
  144. const pointsEarned = 10;
  145. const toastMessage = `获得${pointsEarned}积分!`;
  146. expect(toastMessage).toContain('10');
  147. expect(toastMessage).toContain('积分');
  148. });
  149. });
  150. });