S7_snap7_Stremer_n_Recorder/testing/browser-automation.js

256 lines
6.8 KiB
JavaScript

import { chromium, firefox, webkit } from 'playwright';
import fs from 'fs/promises';
import path from 'path';
/**
* PLC Streamer Browser Automation and Testing Suite
* This class provides MCP-like functionality for browser automation
*/
class PLCStreamerBrowserAutomation {
constructor() {
this.browser = null;
this.context = null;
this.page = null;
this.baseURL = 'http://localhost:5173';
this.backendURL = 'http://localhost:5000';
}
/**
* Initialize browser instance
* @param {string} browserType - 'chromium', 'firefox', or 'webkit'
* @param {object} options - Browser launch options
*/
async initBrowser(browserType = 'chromium', options = {}) {
const browserLaunchers = {
chromium: chromium,
firefox: firefox,
webkit: webkit
};
const defaultOptions = {
headless: false,
slowMo: 100,
args: ['--disable-web-security', '--disable-features=VizDisplayCompositor']
};
this.browser = await browserLaunchers[browserType].launch({
...defaultOptions,
...options
});
this.context = await this.browser.newContext({
viewport: { width: 1920, height: 1080 },
recordVideo: { dir: 'videos/' }
});
this.page = await this.context.newPage();
// Add console logging
this.page.on('console', msg => {
console.log(`Browser Console [${msg.type()}]: ${msg.text()}`);
});
// Add error logging
this.page.on('pageerror', error => {
console.error(`Browser Error: ${error.message}`);
});
return this.page;
}
/**
* Navigate to the PLC Streamer application
*/
async navigateToApp() {
await this.page.goto(`${this.baseURL}/app`);
await this.page.waitForLoadState('networkidle');
return this.page;
}
/**
* Check if backend server is running
*/
async checkBackendStatus() {
try {
const response = await this.page.request.get(`${this.backendURL}/api/status`);
return response.ok();
} catch (error) {
console.error('Backend not reachable:', error.message);
return false;
}
}
/**
* Monitor PLC connection status
*/
async monitorPLCConnection() {
await this.navigateToApp();
const connectionStatus = await this.page.locator('[data-testid="connection-status"]').textContent();
console.log(`PLC Connection Status: ${connectionStatus}`);
return connectionStatus;
}
/**
* Automated configuration testing
*/
async testConfigurationFlow() {
await this.navigateToApp();
// Navigate to configuration
await this.page.click('text=Configuration');
await this.page.waitForSelector('[data-testid="configuration-panel"]');
// Test PLC configuration
const ipInput = this.page.locator('input[name*="ip"]').first();
await ipInput.clear();
await ipInput.fill('192.168.1.100');
// Save configuration
await this.page.click('button:has-text("Save")');
// Wait for save confirmation
await this.page.waitForSelector('text*=saved', { timeout: 5000 });
console.log('Configuration test completed successfully');
return true;
}
/**
* Automated streaming test
*/
async testStreamingFlow() {
await this.navigateToApp();
// Navigate to streaming
await this.page.click('text=Data Streaming');
await this.page.waitForSelector('[data-testid="streaming-panel"]');
// Start streaming
await this.page.click('button:has-text("Start Streaming")');
// Wait a bit for streaming to initialize
await this.page.waitForTimeout(3000);
// Stop streaming
await this.page.click('button:has-text("Stop Streaming")');
console.log('Streaming test completed successfully');
return true;
}
/**
* Take screenshots for documentation
*/
async captureScreenshots() {
await this.navigateToApp();
const tabs = ['Dashboard', 'Configuration', 'Data Streaming', 'Plots'];
for (const tab of tabs) {
await this.page.click(`text=${tab}`);
await this.page.waitForTimeout(1000);
const screenshot = await this.page.screenshot({
path: `screenshots/${tab.toLowerCase().replace(' ', '_')}.png`,
fullPage: true
});
console.log(`Screenshot saved: ${tab}`);
}
return true;
}
/**
* Performance monitoring
*/
async monitorPerformance() {
await this.navigateToApp();
// Start performance monitoring
await this.page.evaluate(() => performance.mark('test-start'));
// Navigate through all tabs
const tabs = ['Configuration', 'Data Streaming', 'Plots', 'Dashboard'];
for (const tab of tabs) {
const startTime = performance.now();
await this.page.click(`text=${tab}`);
await this.page.waitForLoadState('networkidle');
const endTime = performance.now();
console.log(`Tab ${tab} load time: ${endTime - startTime}ms`);
}
// Get performance metrics
const metrics = await this.page.evaluate(() => {
return JSON.stringify(performance.getEntriesByType('navigation'));
});
await fs.writeFile('performance-metrics.json', metrics);
console.log('Performance metrics saved');
return JSON.parse(metrics);
}
/**
* Generate test report
*/
async generateReport() {
const backendStatus = await this.checkBackendStatus();
const plcStatus = await this.monitorPLCConnection();
const report = {
timestamp: new Date().toISOString(),
backendStatus: backendStatus ? 'Online' : 'Offline',
plcConnectionStatus: plcStatus,
browserInfo: await this.page.evaluate(() => navigator.userAgent),
url: this.page.url()
};
await fs.writeFile('automation-report.json', JSON.stringify(report, null, 2));
console.log('Report generated: automation-report.json');
return report;
}
/**
* Cleanup resources
*/
async cleanup() {
if (this.page) await this.page.close();
if (this.context) await this.context.close();
if (this.browser) await this.browser.close();
}
}
// Export for use in other scripts
export default PLCStreamerBrowserAutomation;
// CLI usage example
if (import.meta.url === `file://${process.argv[1]}`) {
const automation = new PLCStreamerBrowserAutomation();
try {
await automation.initBrowser('chromium', { headless: false });
console.log('Starting automated testing...');
// Run all tests
await automation.testConfigurationFlow();
await automation.testStreamingFlow();
await automation.captureScreenshots();
await automation.monitorPerformance();
await automation.generateReport();
console.log('Automation completed successfully!');
} catch (error) {
console.error('Automation failed:', error);
} finally {
await automation.cleanup();
}
}