166 lines
5.3 KiB
TypeScript
166 lines
5.3 KiB
TypeScript
import { test, chromium } from '@playwright/test';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
/**
|
|
* This test captures the complete network traffic (HAR file) for the "Join Session" flow
|
|
* from the legacy JamKazam application. The captured data will be used to:
|
|
* 1. Document all API calls to /api/*
|
|
* 2. Document all WebSocket messages
|
|
* 3. Create a migration test plan for the new jam-ui interface
|
|
*/
|
|
test('Capture network traffic for joining a music session', async () => {
|
|
// Launch browser with ability to capture network traffic
|
|
const browser = await chromium.launch({
|
|
headless: false, // Use headed mode to see what's happening
|
|
slowMo: 1000, // Slow down by 1 second to make actions visible
|
|
});
|
|
|
|
const context = await browser.newContext({
|
|
ignoreHTTPSErrors: true,
|
|
recordHar: {
|
|
path: path.join(__dirname, '../test-results/session-join-flow.har'),
|
|
mode: 'full', // Capture full request/response bodies
|
|
},
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
// Array to collect all WebSocket messages
|
|
const wsMessages: any[] = [];
|
|
const apiCalls: any[] = [];
|
|
|
|
// Listen to all network requests
|
|
page.on('request', request => {
|
|
const url = request.url();
|
|
if (url.includes('/api/')) {
|
|
console.log(`API REQUEST: ${request.method()} ${url}`);
|
|
apiCalls.push({
|
|
type: 'request',
|
|
method: request.method(),
|
|
url: url,
|
|
headers: request.headers(),
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
}
|
|
});
|
|
|
|
page.on('response', async response => {
|
|
const url = response.url();
|
|
if (url.includes('/api/')) {
|
|
console.log(`API RESPONSE: ${response.status()} ${url}`);
|
|
let body = null;
|
|
try {
|
|
body = await response.text();
|
|
} catch (e) {
|
|
// Some responses can't be read
|
|
}
|
|
apiCalls.push({
|
|
type: 'response',
|
|
status: response.status(),
|
|
url: url,
|
|
headers: response.headers(),
|
|
body: body,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
}
|
|
});
|
|
|
|
// Listen to WebSocket events
|
|
page.on('websocket', ws => {
|
|
console.log(`WebSocket opened: ${ws.url()}`);
|
|
wsMessages.push({
|
|
type: 'websocket-open',
|
|
url: ws.url(),
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
|
|
ws.on('framesent', frame => {
|
|
console.log(`WS SENT: ${frame.payload}`);
|
|
wsMessages.push({
|
|
type: 'sent',
|
|
payload: frame.payload,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
});
|
|
|
|
ws.on('framereceived', frame => {
|
|
console.log(`WS RECEIVED: ${frame.payload}`);
|
|
wsMessages.push({
|
|
type: 'received',
|
|
payload: frame.payload,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
console.log('WebSocket closed');
|
|
wsMessages.push({
|
|
type: 'websocket-close',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
});
|
|
});
|
|
|
|
try {
|
|
console.log('Step 1: Navigate to signin page');
|
|
await page.goto('http://www.jamkazam.com:3000/signin', {
|
|
waitUntil: 'networkidle',
|
|
timeout: 30000,
|
|
});
|
|
|
|
console.log('Step 2: Login with credentials');
|
|
// Fill in login form
|
|
await page.fill('input[name="email"], input[type="email"]', 'nuwan@jamkazam.com');
|
|
await page.fill('input[name="password"], input[type="password"]', 'jam123');
|
|
|
|
// Click sign in button
|
|
await page.click('button[type="submit"], input[type="submit"], button:has-text("Sign in"), button:has-text("Login")');
|
|
|
|
// Wait for navigation after login
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(2000);
|
|
|
|
console.log('Step 3: Click "create session" tile');
|
|
// Look for create session button/tile
|
|
await page.click('[data-testid="create-session"], button:has-text("Create Session"), a:has-text("Create Session")');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(2000);
|
|
|
|
console.log('Step 4: Press Control+Shift+0 to trick browser as native client');
|
|
await page.keyboard.press('Control+Shift+Digit0');
|
|
await page.waitForTimeout(1000);
|
|
|
|
console.log('Step 5: Click "create quick start" button');
|
|
await page.click('button:has-text("Create Quick Start"), button:has-text("Quick Start")');
|
|
|
|
// Wait for session to load
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(5000); // Give time for WebSocket messages
|
|
|
|
console.log('Recording complete. Saving captured data...');
|
|
|
|
// Save API calls to a separate JSON file
|
|
const apiCallsPath = path.join(__dirname, '../test-results/api-calls.json');
|
|
fs.writeFileSync(apiCallsPath, JSON.stringify(apiCalls, null, 2));
|
|
console.log(`API calls saved to: ${apiCallsPath}`);
|
|
|
|
// Save WebSocket messages to a separate JSON file
|
|
const wsMessagesPath = path.join(__dirname, '../test-results/websocket-messages.json');
|
|
fs.writeFileSync(wsMessagesPath, JSON.stringify(wsMessages, null, 2));
|
|
console.log(`WebSocket messages saved to: ${wsMessagesPath}`);
|
|
|
|
// Keep browser open for manual inspection
|
|
console.log('Keeping browser open for 30 seconds for manual inspection...');
|
|
await page.waitForTimeout(30000);
|
|
|
|
} catch (error) {
|
|
console.error('Error during test:', error);
|
|
throw error;
|
|
} finally {
|
|
// Close context to save HAR file
|
|
await context.close();
|
|
await browser.close();
|
|
}
|
|
});
|