import { test, expect } from '@playwright/test'; import path from 'path'; import fs from 'fs'; const visualizationTests = [ { name: 'pztour', viewport: { width: 1440, height: 900, name: 'laptop-hd' } }, ]; for (const vis of visualizationTests) { test.describe(`Visualization-Drag&Drop Page - ${vis.name}`, () => { test(`Drag & Drop Widgets, Save Template, Apply Template, and Remove Widgets in ${vis.name}`, async ({ page }) => { // Increase timeout for the whole test test.setTimeout(600000); // 10 minutes page.setDefaultTimeout(60000); // Create screenshots directory if it doesn't exist const screenshotsDir = path.join(process.cwd(), `screenshots/visualization2D/${vis.viewport.name}`); if (!fs.existsSync(screenshotsDir)) { fs.mkdirSync(screenshotsDir, { recursive: true }); } // Widget locators const widgets = [ page.locator('.chart.chart-1'), page.locator('.chart.chart-2'), page.locator('.chart.chart-3'), page.locator('.chart.chart-4'), page.locator('.chart.chart-5'), page.getByText('Widget 7').first(), page.getByText('Widget 8').first(), ]; // Panel locators const panels = { left: page.locator('.left-panel.panel'), bottom: page.locator('.bottom-panel.panel'), top: page.locator('.top-panel.panel'), right: page.locator('.right-panel.panel'), }; // Remove button locators const removeButtons = { top: page.getByTitle('Remove all items and close top panel'), right: page.getByTitle('Remove all items and close right panel'), bottom: page.getByTitle('Remove all items and close bottom panel'), left: page.getByTitle('Remove all items and close left panel'), }; // Helper function to activate panel and wait for visibility const activateAndCheckPanel = async (panelLocator, activateButtonTitle) => { console.log(`Activating ${activateButtonTitle}...`); try { console.log(`Waiting for ${activateButtonTitle} button to be visible...`); const activationButton = page.locator(`[title="${activateButtonTitle}"]`); const isButtonVisible = await activationButton.isVisible(); if (!isButtonVisible) { console.warn(`${activateButtonTitle} button not visible, skipping activation.`); return; } await activationButton.click(); await expect(panelLocator).toBeVisible({ timeout: 10000 }); } catch (error) { console.error(`Failed to activate panel: ${activateButtonTitle}`); throw error; } }; // Helper function to drag widgets with retries const dragWithRetry = async (source, target, retries = 3) => { for (let i = 0; i < retries; i++) { try { console.log(`Dragging widget to panel (attempt ${i + 1})...`); await source.dragTo(target, { force: true }); return; } catch (error) { if (i === retries - 1) throw error; console.warn(`Drag failed (attempt ${i + 1}), retrying...`); await new Promise(res => setTimeout(res, 1000)); } } }; // Helper function to remove all items from panels const removeAllItemsFromPanels = async (zone, panelsToCheck) => { console.log(`Removing all items from panels in ${zone}...`); let panelsFound = false; for (const panelName of panelsToCheck) { try { console.log(`Checking for ${panelName} panel in ${zone}...`); const isPanelVisible = await panels[panelName].isVisible(); if (isPanelVisible) { panelsFound = true; console.log(`${panelName} panel found in ${zone}, proceeding with removal.`); await removeButtons[panelName].click(); await page.waitForTimeout(2000); } else { console.warn(`${panelName} panel not visible in ${zone}, skipping removal.`); } } catch (error) { console.warn(`Failed to remove items from ${panelName} panel in ${zone}:`, error.message); } } if (!panelsFound) { console.log(`No panels found in ${zone}, skipping removal.`); } }; // Navigate to app console.log(`Navigating to app for ${vis.name}...`); 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(); await expect(page.getByText('Visualization')).toBeVisible({ timeout: 20000 }); // Set viewport size and toggle full-screen mode console.log('Setting viewport size and toggling full-screen mode...'); await page.setViewportSize({ width: vis.viewport.width, height: vis.viewport.height, }); await page.evaluate(() => document.documentElement.requestFullscreen()); // ------------------------ // **CASE 1: Create Template 1 in pztour** console.log('Creating Template 1 in pztour...'); await page.getByText('Visualization').click(); await page.getByText('pztour').click(); // Drag widgets into all panels const allPanels = ['left', 'right', 'bottom', 'top']; for (const panelName of allPanels) { await activateAndCheckPanel(panels[panelName], `Activate ${panelName} panel`); for (const widget of widgets) { await dragWithRetry(widget, panels[panelName]); } } // Save Template 1 console.log('Saving Template 1...'); await page.getByRole('button', { name: /save template/i }).click(); await expect(page.getByRole('button', { name: /save template/i })).toBeVisible(); // ------------------------ // **CASE 2: Create Template 2 in Zone 2** console.log('Creating Template 2 in Zone 2...'); await page.getByText('Visualization').click(); await page.getByText('Zone 2').click(); // Activate panels in Zone 2 const panelsForCase2 = ['top', 'bottom', 'left']; for (const panelName of panelsForCase2) { await activateAndCheckPanel(panels[panelName], `Activate ${panelName} panel`); } // Drag widgets into panels for (const panelName of panelsForCase2) { for (const widget of widgets) { await dragWithRetry(widget, panels[panelName]); } } // Save Template 2 console.log('Saving Template 2...'); await page.getByRole('button', { name: /save template/i }).click(); await expect(page.getByRole('button', { name: /save template/i })).toBeVisible(); // ------------------------ // **CASE 3: Create Template 3 in Zone 3** console.log('Creating Template 3 in Zone 3...'); await page.getByText('Visualization').click(); await page.getByText('Zone 3').click(); // Activate panels in Zone 3 const panelsForCase3 = ['top', 'right', 'bottom']; for (const panelName of panelsForCase3) { await activateAndCheckPanel(panels[panelName], `Activate ${panelName} panel`); } // Drag widgets into panels (skip bottom) for (const panelName of panelsForCase3) { if (panelName !== 'bottom') { for (const widget of widgets) { await dragWithRetry(widget, panels[panelName]); } } } // Save Template 3 console.log('Saving Template 3...'); await page.getByRole('button', { name: /save template/i }).click(); await expect(page.getByRole('button', { name: /save template/i })).toBeVisible(); // ------------------------ // **Apply Templates** console.log('Applying Templates...'); await page.getByText('Templates', { exact: true }).click(); // Apply Template 1 to Zone 4 console.log('Applying Template 1 to Zone 4...'); await page.getByText('Zone 4').click(); await page.locator('.template-item', { hasText: 'Template 1' }).click(); await page.waitForTimeout(2000); // Apply Template 2 to Zone 5 console.log('Applying Template 2 to Zone 5...'); await page.getByText('Zone 5').click(); await page.locator('.template-item', { hasText: 'Template 2' }).click(); await page.waitForTimeout(2000); // Apply Template 3 to Zone 6 console.log('Applying Template 3 to Zone 6...'); await page.getByText('Zone 6').click(); await page.locator('.template-item', { hasText: 'Template 3' }).click(); await page.waitForTimeout(2000); // ------------------------ // **Delete Zones** console.log('Deleting Zones...'); const zonesToDelete = [ { zone: 'pztour', panelsToCheck: allPanels }, { zone: 'Zone 4', panelsToCheck: allPanels }, { zone: 'Zone 2', panelsToCheck: panelsForCase2 }, { zone: 'Zone 5', panelsToCheck: panelsForCase2 }, { zone: 'Zone 3', panelsToCheck: panelsForCase3 }, { zone: 'Zone 6', panelsToCheck: panelsForCase3 }, ]; for (const { zone, panelsToCheck } of zonesToDelete) { console.log(`Navigating to Visualization > ${zone}...`); await page.getByText('Visualization').click(); await page.getByText(zone).click(); // Remove all items from panels await removeAllItemsFromPanels(zone, panelsToCheck); } // ------------------------ // **Delete Templates** console.log('Deleting Templates...'); await page.getByText('Templates', { exact: true }).click(); // Wait for templates to load await page.waitForSelector('.template-details', { timeout: 20000 }); // Delete Template 1 console.log('Deleting Template 1...'); const template1DeleteButton = page.locator('.template-details:has(.template-name > .input-value:text("Template 1")) #template-delete-button'); await template1DeleteButton.waitFor({ state: 'visible', timeout: 20000 }); await template1DeleteButton.click(); // Delete Template 2 console.log('Deleting Template 2...'); const template2DeleteButton = page.locator('.template-details:has(.template-name > .input-value:text("Template 2")) #template-delete-button'); await template2DeleteButton.waitFor({ state: 'visible', timeout: 20000 }); await template2DeleteButton.click(); // Delete Template 3 console.log('Deleting Template 3...'); const template3DeleteButton = page.locator('.template-details:has(.template-name > .input-value:text("Template 3")) #template-delete-button'); await template3DeleteButton.waitFor({ state: 'visible', timeout: 20000 }); await template3DeleteButton.click(); console.log(`Test for ${vis.name} completed successfully.`); }); }); }