import { test, expect, APIRequestContext } from '@playwright/test'; // Shared state between tests let ranoshTemporaryPassword: string; let ranoshRealmId: string; const ADMIN_BASE_URL = 'http://localhost:3001'; const USER_BASE_URL = 'http://localhost:3000'; test.describe.serial('Ranosh Realm E2E Setup', () => { test('Step 1: Create Ranosh realm with ranosh user via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms`, { data: { name: 'Ranosh', slug: 'ranosh', description: 'Ranosh test realm', privacy: 'public', is_nsfw: false, max_users: 100, allow_guest_access: true, new_owner: { username: 'ranosh', email: 'ranosh@example.com', display_name: 'Ranosh', }, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); // Capture the temporary password for later use expect(body.owner_temporary_password).toBeDefined(); expect(body.realm_id).toBeDefined(); expect(body.slug).toBe('ranosh'); ranoshTemporaryPassword = body.owner_temporary_password; ranoshRealmId = body.realm_id; console.log(`Created realm: ${body.slug}`); console.log(`Owner temporary password captured`); }); test('Step 2: Create Ranosh Patio Daytime scene via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms/ranosh/scenes`, { data: { name: 'Ranosh Patio Daytime', slug: 'ranosh-patio-daytime', description: 'The main entry scene for Ranosh realm during the day', background_image_url: 'https://upload.wikimedia.org/wikipedia/commons/2/29/Ranosh_%2840577%29.jpg', infer_dimensions_from_image: true, is_entry_point: true, is_hidden: false, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); expect(body.slug).toBe('ranosh-patio-daytime'); console.log(`Created scene: ${body.slug} (id: ${body.id})`); // Verify the scene has a background image by fetching scene details const sceneResponse = await request.get(`${ADMIN_BASE_URL}/api/admin/scenes/${body.id}`); expect(sceneResponse.ok()).toBeTruthy(); const sceneDetails = await sceneResponse.json(); // Verify background image path is set expect(sceneDetails.background_image_path).toBeTruthy(); expect(sceneDetails.background_image_path).toContain('/static/realm/'); console.log(`Background image path: ${sceneDetails.background_image_path}`); // Verify dimensions were inferred from the image (not default 800x600) expect(sceneDetails.bounds_wkt).toBeTruthy(); console.log(`Scene bounds: ${sceneDetails.bounds_wkt}`); }); test('Step 2b: Create Ranosh Patio Nighttime scene via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms/ranosh/scenes`, { data: { name: 'Ranosh Patio Nighttime', slug: 'ranosh-patio-nighttime', description: 'The patio scene for Ranosh realm at night', background_image_url: 'https://upload.wikimedia.org/wikipedia/commons/f/f3/Ranosh_%2816019%29.jpg', infer_dimensions_from_image: true, is_entry_point: false, is_hidden: false, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); expect(body.slug).toBe('ranosh-patio-nighttime'); console.log(`Created scene: ${body.slug} (id: ${body.id})`); // Verify the scene has a background image by fetching scene details const sceneResponse = await request.get(`${ADMIN_BASE_URL}/api/admin/scenes/${body.id}`); expect(sceneResponse.ok()).toBeTruthy(); const sceneDetails = await sceneResponse.json(); // Verify background image path is set expect(sceneDetails.background_image_path).toBeTruthy(); expect(sceneDetails.background_image_path).toContain('/static/realm/'); console.log(`Background image path: ${sceneDetails.background_image_path}`); // Verify dimensions were inferred from the image expect(sceneDetails.bounds_wkt).toBeTruthy(); console.log(`Scene bounds: ${sceneDetails.bounds_wkt}`); }); test('Step 2c: Create The Smoking Room scene via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms/ranosh/scenes`, { data: { name: 'The Smoking Room', slug: 'the-smoking-room', description: 'A cozy smoking room in Ranosh realm', background_image_url: 'https://upload.wikimedia.org/wikipedia/commons/f/f8/Ranosh_%2814682%29.jpg', infer_dimensions_from_image: true, is_entry_point: false, is_hidden: false, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); expect(body.slug).toBe('the-smoking-room'); console.log(`Created scene: ${body.slug} (id: ${body.id})`); // Verify the scene has a background image by fetching scene details const sceneResponse = await request.get(`${ADMIN_BASE_URL}/api/admin/scenes/${body.id}`); expect(sceneResponse.ok()).toBeTruthy(); const sceneDetails = await sceneResponse.json(); // Verify background image path is set expect(sceneDetails.background_image_path).toBeTruthy(); expect(sceneDetails.background_image_path).toContain('/static/realm/'); console.log(`Background image path: ${sceneDetails.background_image_path}`); // Verify dimensions were inferred from the image expect(sceneDetails.bounds_wkt).toBeTruthy(); console.log(`Scene bounds: ${sceneDetails.bounds_wkt}`); }); test('Step 2d: Create The Corridor scene via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms/ranosh/scenes`, { data: { name: 'The Corridor', slug: 'the-corridor', description: 'A corridor in Ranosh realm', background_image_url: 'https://upload.wikimedia.org/wikipedia/commons/4/48/Ranosh_%2843389%29.jpg', infer_dimensions_from_image: true, is_entry_point: false, is_hidden: false, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); expect(body.slug).toBe('the-corridor'); console.log(`Created scene: ${body.slug} (id: ${body.id})`); // Verify the scene has a background image by fetching scene details const sceneResponse = await request.get(`${ADMIN_BASE_URL}/api/admin/scenes/${body.id}`); expect(sceneResponse.ok()).toBeTruthy(); const sceneDetails = await sceneResponse.json(); // Verify background image path is set expect(sceneDetails.background_image_path).toBeTruthy(); expect(sceneDetails.background_image_path).toContain('/static/realm/'); console.log(`Background image path: ${sceneDetails.background_image_path}`); // Verify dimensions were inferred from the image expect(sceneDetails.bounds_wkt).toBeTruthy(); console.log(`Scene bounds: ${sceneDetails.bounds_wkt}`); }); test('Step 2e: Create Ranosh Family Room scene via Admin API', async ({ request }) => { const response = await request.post(`${ADMIN_BASE_URL}/api/admin/realms/ranosh/scenes`, { data: { name: 'Ranosh Family Room', slug: 'ranosh-family-room', description: 'The family room in Ranosh realm', background_image_url: 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ranosh_%2815637%29.jpg', infer_dimensions_from_image: true, is_entry_point: false, is_hidden: false, }, }); expect(response.ok()).toBeTruthy(); const body = await response.json(); expect(body.slug).toBe('ranosh-family-room'); console.log(`Created scene: ${body.slug} (id: ${body.id})`); // Verify the scene has a background image by fetching scene details const sceneResponse = await request.get(`${ADMIN_BASE_URL}/api/admin/scenes/${body.id}`); expect(sceneResponse.ok()).toBeTruthy(); const sceneDetails = await sceneResponse.json(); // Verify background image path is set expect(sceneDetails.background_image_path).toBeTruthy(); expect(sceneDetails.background_image_path).toContain('/static/realm/'); console.log(`Background image path: ${sceneDetails.background_image_path}`); // Verify dimensions were inferred from the image expect(sceneDetails.bounds_wkt).toBeTruthy(); console.log(`Scene bounds: ${sceneDetails.bounds_wkt}`); }); test('Step 2f: Verify background in Admin UI', async ({ page }) => { // Navigate to admin UI and verify background is shown await page.goto(`${ADMIN_BASE_URL}/admin/realms/ranosh/scenes`); await page.waitForLoadState('networkidle'); // Click on Ranosh Patio Daytime scene (the entry point) await page.getByRole('link', { name: 'Ranosh Patio Daytime' }).click(); await page.waitForLoadState('networkidle'); // Verify the background field is not "None" const backgroundText = await page.locator('text=Background').locator('..').locator('text=None').count(); expect(backgroundText).toBe(0); // Should not find "None" next to Background // Take a screenshot for verification await page.screenshot({ path: 'test-results/ranosh-patio-daytime-background-admin.png' }); console.log('Admin UI screenshot saved'); }); test('Step 3: Login as ranosh to Ranosh realm on User App', async ({ page }) => { // Ensure we have the password from step 1 expect(ranoshTemporaryPassword).toBeDefined(); // Navigate to user app login page await page.goto(USER_BASE_URL); // Wait for the page to load await page.waitForLoadState('networkidle'); // Enter the private realm slug const privateRealmInput = page.getByPlaceholder('Or enter a private realm name'); await privateRealmInput.fill('ranosh'); // Enter username await page.locator('#username').fill('ranosh'); // Enter password (temporary password from realm creation) await page.locator('#password').fill(ranoshTemporaryPassword); // Click the login button await page.getByRole('button', { name: 'Enter Realm' }).click(); // Wait for navigation - should redirect to password reset page await page.waitForURL('**/password-reset', { timeout: 10000 }); expect(page.url()).toContain('/password-reset'); console.log('Redirected to password reset page'); // Fill in new password await page.locator('#new-password').fill('ranoshranosh'); await page.locator('#confirm-password').fill('ranoshranosh'); // Submit password reset await page.getByRole('button', { name: 'Reset Password' }).click(); // Wait for navigation to the realm page await page.waitForURL('**/realms/ranosh', { timeout: 10000 }); expect(page.url()).toContain('/realms/ranosh'); console.log('Successfully logged in and redirected to realm page'); // Verify we're on the realm page await expect(page).toHaveURL(/\/realms\/ranosh/); // Take a screenshot for verification await page.screenshot({ path: 'test-results/ranosh-realm-success.png' }); console.log('Screenshot saved to test-results/ranosh-realm-success.png'); }); });