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(120000); 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 { // Wait for the button to be visible and enabled console.log(`Waiting for button with title: ${activateButtonTitle}`); await page.waitForSelector(`[title="${activateButtonTitle}"]`, { state: 'visible', timeout: 20000 }); // Click the button console.log(`Clicking button with title: ${activateButtonTitle}`); await page.getByTitle(activateButtonTitle).click(); // Wait for the panel to become visible console.log(`Waiting for panel to become visible...`); await expect(panelLocator).toBeVisible({ timeout: 10000 }); } catch (error) { console.error(`Failed to activate panel: ${activateButtonTitle}`); console.error(error); 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 () => { console.log('Removing all items from panels...'); const panelOrder = ['top', 'right', 'bottom', 'left']; for (const panelName of panelOrder) { console.log(`Removing items from ${panelName} panel...`); await removeButtons[panelName].click(); await page.waitForTimeout(2000); // Wait for removal animation or transition } }; // 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()); // Go to Visualization > Zone console.log(`Navigating to Visualization > ${vis.name}...`); await page.getByText('Visualization').click(); await page.getByText(vis.name).click(); // Drag widgets into all panels console.log('Dragging widgets into all panels...'); const panelOrder = ['left', 'right', 'bottom', 'top']; for (const panelName of panelOrder) { await activateAndCheckPanel(panels[panelName], `Activate ${panelName} panel`); for (const widget of widgets) { await dragWithRetry(widget, panels[panelName]); } } // Verify that all panels contain widgets console.log('Verifying all panels contain widgets...'); await page.waitForFunction(() => { return ( document.querySelector('.left-panel')?.children.length > 0 && document.querySelector('.right-panel')?.children.length > 0 && document.querySelector('.bottom-panel')?.children.length > 0 && document.querySelector('.top-panel')?.children.length > 0 ); }); // Take a screenshot after drag-and-drop operations console.log('Taking screenshot after drag-and-drop...'); await page.screenshot({ path: path.join(screenshotsDir, `${vis.name}-after-drag.png`) }); // Save the template console.log('Saving template...'); await page.getByRole('button', { name: /save template/i }).click(); await expect(page.getByRole('button', { name: /save template/i })).toBeVisible(); // Navigate to Templates tab console.log('Navigating to Templates tab...'); await page.getByText('Templates', { exact: true }).click(); await page.getByText('Zone 4').click(); await page.waitForTimeout(2000); // Apply the saved template (Template 1) console.log('Applying saved template...'); await page.locator('.template-item', { hasText: 'Template 1' }).click(); await page.waitForTimeout(2000); // Optionally, assert widgets are restored in all panels console.log('Verifying widgets are restored in all panels...'); await page.waitForFunction(() => { return ( document.querySelector('.left-panel')?.children.length > 0 && document.querySelector('.right-panel')?.children.length > 0 && document.querySelector('.bottom-panel')?.children.length > 0 && document.querySelector('.top-panel')?.children.length > 0 ); }); // Remove all items from panels await removeAllItemsFromPanels(); // Add a grace period for animations or transitions console.log('Waiting for panels to clear...'); await page.waitForTimeout(3000); // Wait for 3 seconds to allow any animations or transitions to complete // Take a final screenshot after removal console.log('Taking screenshot after removal...'); await page.screenshot({ path: path.join(screenshotsDir, `${vis.name}-after-remove.png`) }); // Navigating back to Visualization > Zone console.log(`Navigating to Visualization > ${vis.name}...`); await page.getByText('Visualization').click(); await page.getByText(vis.name).click(); // Remove all items from panels again await removeAllItemsFromPanels(); // Locate and click the delete button for "Template 1" console.log('Locating and clicking the delete button for "Template 1"...'); const deleteButton = page.locator( '.template-details:has(.template-name > .input-value:text("Template 1")) #template-delete-button' ); await deleteButton.waitFor({ state: 'visible', timeout: 10000 }); // Ensure the button is visible await deleteButton.click(); console.log(`Test for ${vis.name} completed successfully.`); }); }); }