import { test, expect } from '@playwright/test'; import fs from 'fs'; // Setup: Create screenshots directory if it doesn't exist const screenshotDir = 'screenshots'; fs.mkdirSync(screenshotDir, { recursive: true }); // Wall coordinates (shared between tests) const wallCoordinates = [ { x: 147, y: 212 }, { x: 138, y: 542 }, { x: 619, y: 548 }, { x: 614, y: 286 }, { x: 693, y: 284 }, { x: 696, y: 374 }, { x: 820, y: 369 }, { x: 823, y: 285 }, { x: 889, y: 285 }, { x: 899, y: 662 }, { x: 1249, y: 661 }, { x: 1238, y: 122 }, { x: 142, y: 116 }, { x: 53, y: 124 }, { x: 147, y: 212 }, // Closing the loop ]; /** * Reusable function for creating or deleting walls. * @param {Object} page - Playwright page object * @param {Array} coordinates - Array of {x, y} objects representing wall points * @param {String} action - 'create' or 'delete' */ async function drawOrDeleteWalls(page, coordinates, action) { console.log(`${action === 'create' ? 'Creating' : 'Deleting'} walls...`); for (let i = 0; i < coordinates.length; i++) { const { x, y } = coordinates[i]; console.log(`${action === 'create' ? 'Creating' : 'Deleting'} at (${x}, ${y})`); await simulatePointerClick(page, x, y); await page.waitForTimeout(300); // Adjust timeout if necessary // Add midpoints for deletion if (action === 'delete' && i < coordinates.length - 1) { const nextPoint = coordinates[i + 1]; const midX = (x + nextPoint.x) / 2; const midY = (y + nextPoint.y) / 2; console.log(`Deleting midpoint at (${midX}, ${midY})`); await simulatePointerClick(page, midX, midY); await page.waitForTimeout(300); } } if (action === 'create') { // Finalize wall creation with right-click await simulatePointerClick(page, 100, 160, 'right'); // Right-click to finalize } } /** * Zone paths (shared between tests) */ const zonePaths = [ { start: { x: 172, y: 220 }, end: { x: 292, y: 339 } }, { start: { x: 328, y: 220 }, end: { x: 441, y: 340 } }, { start: { x: 470, y: 220 }, end: { x: 593, y: 342 } }, { start: { x: 174, y: 378 }, end: { x: 289, y: 517 } }, { start: { x: 327, y: 378 }, end: { x: 442, y: 519 } }, { start: { x: 468, y: 378 }, end: { x: 593, y: 521 } }, { start: { x: 699, y: 197 }, end: { x: 801, y: 359 } }, { start: { x: 913, y: 516 }, end: { x: 1040, y: 644 } }, { start: { x: 1079, y: 518 }, end: { x: 1205, y: 647 } }, { start: { x: 912, y: 355 }, end: { x: 1036, y: 473 } }, { start: { x: 1082, y: 357 }, end: { x: 1203, y: 476 } }, { start: { x: 916, y: 190 }, end: { x: 1193, y: 333 } }, ]; /** * Aisle coordinates (shared between tests) */ const aisleCoordinates = [ { x: 191, y: 237 }, { x: 271, y: 238 }, { x: 301, y: 170, button: 'right' }, { x: 191, y: 266 }, { x: 270, y: 268 }, { x: 377, y: 171, button: 'right' }, { x: 188, y: 295 }, { x: 270, y: 297 }, { x: 335, y: 189, button: 'right' }, { x: 187, y: 321 }, { x: 267, y: 320 }, { x: 341, y: 183, button: 'right' }, { x: 190, y: 238 }, { x: 189, y: 321 }, { x: 240, y: 358, button: 'right' }, { x: 351, y: 247 }, { x: 425, y: 246 }, { x: 426, y: 327 }, { x: 346, y: 325 }, { x: 350, y: 248 }, { x: 372, y: 167, button: 'right' }, { x: 491, y: 240 }, { x: 577, y: 242 }, { x: 577, y: 329 }, { x: 490, y: 328 }, { x: 489, y: 240 }, { x: 478, y: 294, button: 'right' }, { x: 489, y: 294 }, { x: 577, y: 297 }, { x: 386, y: 360, button: 'right' }, { x: 193, y: 400 }, { x: 194, y: 496 }, { x: 250, y: 496 }, { x: 251, y: 400 }, { x: 191, y: 401 }, { x: 301, y: 362, button: 'right' }, { x: 346, y: 402 }, { x: 386, y: 401 }, { x: 387, y: 435 }, { x: 344, y: 434 }, { x: 343, y: 397 }, { x: 309, y: 361, button: 'right' }, { x: 340, y: 444 }, { x: 387, y: 444 }, { x: 387, y: 472 }, { x: 339, y: 474 }, { x: 341, y: 444 }, { x: 338, y: 501, button: 'right' }, { x: 337, y: 486 }, { x: 386, y: 489 }, { x: 386, y: 512 }, { x: 339, y: 511 }, { x: 336, y: 486 }, { x: 419, y: 466, button: 'right' }, { x: 484, y: 395 }, { x: 577, y: 395 }, { x: 580, y: 509 }, { x: 484, y: 507 }, { x: 484, y: 396 }, { x: 471, y: 424, button: 'right' }, { x: 484, y: 453 }, { x: 576, y: 456 }, { x: 669, y: 596, button: 'right' }, { x: 715, y: 220 }, { x: 789, y: 222 }, { x: 793, y: 344 }, { x: 711, y: 342 }, { x: 714, y: 219 }, { x: 759, y: 294, button: 'right' }, { x: 713, y: 283 }, { x: 790, y: 280 }, { x: 844, y: 172, button: 'right' }, { x: 931, y: 210 }, { x: 934, y: 316 }, { x: 996, y: 316 }, { x: 998, y: 212 }, { x: 930, y: 211 }, { x: 1031, y: 212, button: 'right' }, { x: 1012, y: 212 }, { x: 1014, y: 316 }, { x: 1074, y: 314 }, { x: 1072, y: 210 }, { x: 1010, y: 210 }, { x: 1087, y: 210, button: 'right' }, { x: 1091, y: 211 }, { x: 1094, y: 315 }, { x: 1172, y: 317 }, { x: 1220, y: 285, button: 'right' }, { x: 1090, y: 212 }, { x: 1172, y: 214 }, { x: 1173, y: 315 }, { x: 1064, y: 359, button: 'right' }, { x: 928, y: 368 }, { x: 927, y: 457 }, { x: 1022, y: 452 }, { x: 1022, y: 371 }, { x: 928, y: 374 }, { x: 964, y: 417, button: 'right' }, { x: 1094, y: 370 }, { x: 1095, y: 456 }, { x: 1186, y: 457 }, { x: 1186, y: 374 }, { x: 1095, y: 377 }, { x: 1061, y: 500, button: 'right' }, { x: 923, y: 535 }, { x: 1022, y: 535 }, { x: 1020, y: 627 }, { x: 922, y: 628 }, { x: 921, y: 534 }, { x: 1059, y: 625, button: 'right' }, { x: 1091, y: 537 }, { x: 1185, y: 534 }, { x: 1183, y: 627 }, { x: 1089, y: 631 }, { x: 1092, y: 536 }, { x: 1079, y: 693, button: 'right' }, ]; /** * Simulates a pointer click at specific coordinates. */ async function simulatePointerClick(page, x, y, button = 'left') { await page.mouse.move(x, y); await page.mouse.down({ button }); await page.mouse.up({ button }); } /** * Common setup function for logging in and switching to full-screen mode. */ async function loginAndSetup(page) { await page.goto('http://185.100.212.76:8200'); await page.getByPlaceholder('Email').fill('ramkumar@testdomin.local'); await page.getByPlaceholder('Password').fill('123456'); await page.getByRole('button', { name: 'Continue', exact: true }).click(); console.log('Switching to full-screen mode...'); await page.keyboard.press('F11'); // Simulate pressing F11 to enter full-screen mode } /** * Common function to move the canvas. */ async function moveCanvas(page) { console.log('Moving canvas to the top position...'); const canvas = page.locator('canvas').first(); const canvasBox = await canvas.boundingBox(); if (!canvasBox) { throw new Error('Canvas bounding box not found. Ensure the canvas is visible.'); } const startX = canvasBox.x + canvasBox.width / 2; const startY = canvasBox.y + canvasBox.height / 2; await page.mouse.move(startX, startY); await page.mouse.down(); await page.mouse.move(startX, startY + 100, { steps: 20 }); await page.mouse.wheel(0, 500); // Scroll down 500px await page.mouse.up(); } /** * Main test case for creating and deleting walls, zones, and aisles. */ test('Create and delete walls, zones, and aisles', async ({ page }) => { test.setTimeout(300000); // Set timeout to 5 minutes // Step 1: Login and setup await loginAndSetup(page); // Step 2: Switch to 2D mode await page.locator('.toggle-option:has-text("2d")').click(); // Step 3: Move the canvas await moveCanvas(page); // Step 4: Create walls console.log('Selecting Wall tool...'); await page.getByTitle('Wall').getByRole('img').click(); await drawOrDeleteWalls(page, wallCoordinates, 'create'); // Step 5: Create zones console.log('Selecting Zone tool...'); await page.getByTitle('Zone').getByRole('img').click(); for (const { start, end } of zonePaths) { await simulatePointerClick(page, start.x, start.y); await simulatePointerClick(page, end.x, end.y); await page.waitForTimeout(500); } // Step 6: Create aisles console.log('Selecting Aisle tool...'); await page.getByTitle('Aisle').getByRole('img').click(); for (const { x, y, button = 'left' } of aisleCoordinates) { await simulatePointerClick(page, x, y, button); await page.waitForTimeout(300); } await page.waitForTimeout(5000); // Stay for 5 seconds after creation // Step 7: Delete aisles console.log('Opening three-dot menu...'); await page.locator('.drop-down-option-button > svg').click(); await page.locator('div').filter({ hasText: /^Delete$/ }).first().click(); await drawOrDeleteWalls(page, aisleCoordinates.map(({ x, y }) => ({ x, y })), 'delete'); // Step 8: Delete zones await drawOrDeleteWalls(page, zonePaths.flatMap(({ start, end }) => [start, end]), 'delete'); // Step 9: Delete walls await drawOrDeleteWalls(page, wallCoordinates, 'delete'); await page.waitForTimeout(5000); // Stay for 5 seconds after deletion // Take a final screenshot const finalScreenshotPath = `${screenshotDir}/final-screenshot.png`; await page.screenshot({ path: finalScreenshotPath }); console.log(`Final screenshot saved at: ${finalScreenshotPath}`); });