websocket.spec.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. import { expect, test } from "@playwright/test";
  2. test.describe("WebSocket E2E Tests", () => {
  3. test("should connect to WebSocket server", async ({ page }) => {
  4. // Create a simple test page that can test Socket.IO functionality
  5. await page.setContent(`
  6. <html>
  7. <head>
  8. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  9. <script>
  10. window.testResults = {};
  11. function connectSocketIO() {
  12. const socket = io('http://localhost:3001');
  13. socket.on('connect', () => {
  14. window.testResults.connected = true;
  15. socket.disconnect();
  16. });
  17. socket.on('connect_error', () => {
  18. window.testResults.connected = false;
  19. });
  20. socket.on('disconnect', () => {
  21. window.testResults.disconnected = true;
  22. });
  23. }
  24. window.connectSocketIO = connectSocketIO;
  25. </script>
  26. </head>
  27. <body>
  28. <div id="test">Socket.IO Test</div>
  29. </body>
  30. </html>
  31. `);
  32. // Execute the Socket.IO connection test
  33. await page.evaluate(() => {
  34. (window as any).connectSocketIO();
  35. });
  36. // Wait for connection result
  37. await page.waitForFunction(
  38. () => (window as any).testResults.connected !== undefined
  39. );
  40. const results = await page.evaluate(() => (window as any).testResults);
  41. expect(results.connected).toBe(true);
  42. });
  43. test("should handle Socket.IO connection", async ({ page }) => {
  44. // Test Socket.IO connection using a script that loads socket.io-client
  45. await page.setContent(`
  46. <html>
  47. <head>
  48. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  49. <script>
  50. window.testResults = {};
  51. function testSocketIO() {
  52. const socket = io('http://localhost:3001');
  53. socket.on('connect', () => {
  54. window.testResults.connected = true;
  55. socket.disconnect();
  56. });
  57. socket.on('connect_error', () => {
  58. window.testResults.connected = false;
  59. });
  60. socket.on('disconnect', () => {
  61. window.testResults.disconnected = true;
  62. });
  63. }
  64. window.testSocketIO = testSocketIO;
  65. </script>
  66. </head>
  67. <body>
  68. <div id="test">Socket.IO Test</div>
  69. </body>
  70. </html>
  71. `);
  72. // Execute the Socket.IO connection test
  73. await page.evaluate(() => {
  74. (window as any).testSocketIO();
  75. });
  76. // Wait for connection result
  77. await page.waitForFunction(
  78. () => (window as any).testResults.connected !== undefined,
  79. { timeout: 5000 }
  80. );
  81. const results = await page.evaluate(() => (window as any).testResults);
  82. expect(results.connected).toBe(true);
  83. });
  84. test("should handle room operations via Socket.IO", async ({ page }) => {
  85. await page.setContent(`
  86. <html>
  87. <head>
  88. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  89. <script>
  90. window.testResults = { events: [] };
  91. function testRoomOperations() {
  92. const socket = io('http://localhost:3001');
  93. socket.on('connect', () => {
  94. window.testResults.connected = true;
  95. // Join a room
  96. socket.emit('join', { room: 'testRoom' });
  97. });
  98. socket.on('joined', (data) => {
  99. window.testResults.events.push({ type: 'joined', data });
  100. // Leave the room
  101. socket.emit('leave', { room: 'testRoom' });
  102. });
  103. socket.on('left', (data) => {
  104. window.testResults.events.push({ type: 'left', data });
  105. socket.disconnect();
  106. });
  107. }
  108. window.testRoomOperations = testRoomOperations;
  109. </script>
  110. </head>
  111. <body>
  112. <div id="test">Room Operations Test</div>
  113. </body>
  114. </html>
  115. `);
  116. // Execute the room operations test
  117. await page.evaluate(() => {
  118. (window as any).testRoomOperations();
  119. });
  120. // Wait for events
  121. await page.waitForFunction(
  122. () => (window as any).testResults.events.length >= 2,
  123. { timeout: 5000 }
  124. );
  125. const results = await page.evaluate(() => (window as any).testResults);
  126. expect(results.connected).toBe(true);
  127. expect(results.events).toContainEqual({
  128. type: "joined",
  129. data: { room: "testRoom" }
  130. });
  131. expect(results.events).toContainEqual({
  132. type: "left",
  133. data: { room: "testRoom" }
  134. });
  135. });
  136. test("should receive taskUpdate events", async ({ page }) => {
  137. // Test that client can listen for taskUpdate events
  138. // Note: This test validates WebSocket event subscription, not actual event emission
  139. // which depends on service logic and may not occur in e2e test environment
  140. await page.setContent(`
  141. <html>
  142. <head>
  143. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  144. <script>
  145. window.testResults = { events: [], connected: false };
  146. function testTaskUpdates() {
  147. const socket = io('http://localhost:3001');
  148. socket.on('connect', () => {
  149. window.testResults.connected = true;
  150. });
  151. socket.on('taskUpdate', (data) => {
  152. window.testResults.events.push({ type: 'taskUpdate', data });
  153. });
  154. // Store socket reference
  155. window.testSocket = socket;
  156. // Disconnect after 5 seconds regardless of events
  157. setTimeout(() => {
  158. socket.disconnect();
  159. window.testResults.completed = true;
  160. }, 5000);
  161. }
  162. window.testTaskUpdates = testTaskUpdates;
  163. </script>
  164. </head>
  165. <body>
  166. <div id="test">Task Update Test</div>
  167. </body>
  168. </html>
  169. `);
  170. // Execute the test
  171. await page.evaluate(() => {
  172. (window as any).testTaskUpdates();
  173. });
  174. // Wait for test completion
  175. await page.waitForFunction(
  176. () => (window as any).testResults.completed === true
  177. );
  178. const results = await page.evaluate(() => (window as any).testResults);
  179. expect(results.connected).toBe(true);
  180. // Event reception is optional - just validate connection and subscription capability
  181. console.log("TaskUpdate events received:", results.events.length);
  182. });
  183. test("should receive fileUpdate events", async ({ page }) => {
  184. await page.setContent(`
  185. <html>
  186. <head>
  187. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  188. <script>
  189. window.testResults = { events: [], connected: false };
  190. function testFileUpdates() {
  191. const socket = io('http://localhost:3001');
  192. socket.on('connect', () => {
  193. window.testResults.connected = true;
  194. });
  195. socket.on('fileUpdate', (data) => {
  196. window.testResults.events.push({ type: 'fileUpdate', data });
  197. });
  198. // Store socket reference
  199. window.testSocket = socket;
  200. // Disconnect after a short time
  201. setTimeout(() => {
  202. socket.disconnect();
  203. }, 2000);
  204. }
  205. window.testFileUpdates = testFileUpdates;
  206. </script>
  207. </head>
  208. <body>
  209. <div id="test">File Update Test</div>
  210. </body>
  211. </html>
  212. `);
  213. // Execute the file update test
  214. await page.evaluate(() => {
  215. (window as any).testFileUpdates();
  216. });
  217. // Wait for connection and disconnection
  218. await page.waitForFunction(
  219. () => (window as any).testResults.connected === true,
  220. { timeout: 5000 }
  221. );
  222. await page.waitForFunction(
  223. () =>
  224. (window as any).testSocket &&
  225. (window as any).testSocket.disconnected === true,
  226. { timeout: 5000 }
  227. );
  228. const results = await page.evaluate(() => (window as any).testResults);
  229. expect(results.connected).toBe(true);
  230. // File events are optional - just validate connection capability
  231. console.log(
  232. "No fileUpdate event received - this may be expected if watcher is not active"
  233. );
  234. });
  235. test("should receive watcherUpdate events", async ({ page }) => {
  236. await page.setContent(`
  237. <html>
  238. <head>
  239. <script src="https://cdn.socket.io/4.8.3/socket.io.min.js"></script>
  240. <script>
  241. window.testResults = { events: [], connected: false };
  242. function testWatcherUpdates() {
  243. const socket = io('http://localhost:3001');
  244. socket.on('connect', () => {
  245. window.testResults.connected = true;
  246. });
  247. socket.on('watcherUpdate', (data) => {
  248. window.testResults.events.push({ type: 'watcherUpdate', data });
  249. });
  250. // Store socket reference
  251. window.testSocket = socket;
  252. // Disconnect after a short time
  253. setTimeout(() => {
  254. socket.disconnect();
  255. }, 2000);
  256. }
  257. window.testWatcherUpdates = testWatcherUpdates;
  258. </script>
  259. </head>
  260. <body>
  261. <div id="test">Watcher Update Test</div>
  262. </body>
  263. </html>
  264. `);
  265. // Execute the watcher update test
  266. await page.evaluate(() => {
  267. (window as any).testWatcherUpdates();
  268. });
  269. // Wait for connection and disconnection
  270. await page.waitForFunction(
  271. () => (window as any).testResults.connected === true,
  272. { timeout: 5000 }
  273. );
  274. await page.waitForFunction(
  275. () =>
  276. (window as any).testSocket &&
  277. (window as any).testSocket.disconnected === true,
  278. { timeout: 5000 }
  279. );
  280. const results = await page.evaluate(() => (window as any).testResults);
  281. expect(results.connected).toBe(true);
  282. // Watcher events are optional - just validate connection capability
  283. console.log(
  284. "No watcherUpdate event received - this may be expected if watcher is not active"
  285. );
  286. });
  287. });