Files
openobserve/tests/api-testing/rum-test.html
T
priyabrata-stackandClaude Sonnet 4.5 0cf0e8937c fix(tests): implement POM compliance for metrics tests (72% complete)
Major refactoring to fix Page Object Model violations in metrics test suite.
This addresses critical code quality issues identified in the Sentinel audit.

## Changes

### Page Objects Enhanced
- **metricsPage.js**: Added 350+ lines of new methods
  - Data visualization verification methods
  - Config sidebar operations
  - Stream selection, date ranges, notifications
  - Chart types, inputs, and generic UI helpers

### Test Files Fixed (5/8 - 62.5%)
- ✅ **metrics-advanced.spec.js**: Fixed 13 POM violations
- ✅ **metrics-aggregations.spec.js**: Fixed 8 POM violations
- ✅ **metrics-config-tabs.spec.js**: Fixed 31/33 POM violations
- ✅ **metrics-queries.spec.js**: Fixed 28 POM violations
- ✅ **metrics-visualizations.spec.js**: Fixed 44 POM violations

### Additional Fixes
- **apiCleanup.js**: Fixed error handling consistency
  - Unified error response format (message vs error field)
  - Added explicit code: 200 for successful responses

## Statistics
- **Violations Fixed**: 132/184 (72%)
- **Helper Functions Refactored**: 3 (eliminated 200+ lines of duplication)
- **All fixed files**: ✓ Syntax validated

## Remaining Work
- metrics-config.spec.js: 28 violations
- metrics.spec.js: 30 violations
- See POM_COMPLIANCE_FIXES_SUMMARY.md for completion guide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 18:48:25 +05:30

385 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenObserve RUM Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
margin: 10px 5px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0056b3;
}
.error-btn {
background: #dc3545;
}
.error-btn:hover {
background: #c82333;
}
.log-output {
background: #f8f9fa;
border: 1px solid #ddd;
padding: 15px;
margin-top: 20px;
border-radius: 4px;
max-height: 300px;
overflow-y: auto;
}
.log-entry {
padding: 5px;
margin: 5px 0;
border-bottom: 1px solid #eee;
}
input, textarea {
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.section {
margin: 20px 0;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 4px;
}
.section h3 {
margin-top: 0;
color: #555;
}
</style>
</head>
<body>
<div class="container">
<h1>OpenObserve RUM & Logs Test</h1>
<div class="section">
<h3>User Interactions</h3>
<button onclick="trackButtonClick()">Track Button Click</button>
<button onclick="makeAPICall()">Make API Call</button>
<button onclick="simulateLongTask()">Simulate Long Task</button>
<button onclick="navigatePage()" id="navigate-btn">Navigate (Change URL)</button>
</div>
<div class="section">
<h3>Logging</h3>
<button onclick="sendInfoLog()">Send Info Log</button>
<button onclick="sendWarningLog()">Send Warning Log</button>
<button class="error-btn" onclick="sendErrorLog()">Send Error Log</button>
<button class="error-btn" onclick="throwError()">Throw Error</button>
</div>
<div class="section">
<h3>Custom Logs</h3>
<input type="text" id="customLogMessage" placeholder="Enter custom log message">
<select id="logLevel">
<option value="debug">Debug</option>
<option value="info">Info</option>
<option value="warn">Warning</option>
<option value="error">Error</option>
</select>
<button onclick="sendCustomLog()">Send Custom Log</button>
</div>
<div class="section">
<h3>User Context</h3>
<input type="text" id="userId" placeholder="User ID" value="user-123">
<input type="text" id="userName" placeholder="User Name" value="Test User">
<input type="text" id="userEmail" placeholder="User Email" value="testuser@example.com">
<button onclick="updateUserContext()">Update User Context</button>
</div>
<div class="section">
<h3>Custom Actions & Context</h3>
<input type="text" id="actionName" placeholder="Action Name" value="custom_action">
<textarea id="contextData" placeholder='Context Data (JSON)' rows="3">{"feature": "test", "version": "1.0"}</textarea>
<button onclick="addCustomAction()">Add Custom Action</button>
<button onclick="addGlobalContext()">Add Global Context</button>
</div>
<div class="log-output" id="logOutput">
<strong>Activity Log:</strong>
</div>
</div>
<!-- Load OpenObserve SDKs from CDN -->
<script src="https://unpkg.com/@openobserve/browser-rum/dist/openobserve-rum.js"></script>
<script src="https://unpkg.com/@openobserve/browser-logs/dist/openobserve-logs.js"></script>
<script>
// Configuration - Update these values with your OpenObserve instance details
const options = {
clientToken: 'rumZelN4P22dP1G9R9N',
applicationId: 'web-application-id',
site: 'test.internal.zinclabs.dev',
service: 'my-web-application',
env: 'production',
version: '0.0.1',
organizationIdentifier: 'default',
insecureHTTP: false,
apiVersion: 'v1',
};
// Initialize OpenObserve RUM
window.openobserveRum.init({
applicationId: options.applicationId,
clientToken: options.clientToken,
site: options.site,
organizationIdentifier: options.organizationIdentifier,
service: options.service,
env: options.env,
version: options.version,
trackResources: true,
trackLongTasks: true,
trackUserInteractions: true,
apiVersion: options.apiVersion,
insecureHTTP: options.insecureHTTP,
defaultPrivacyLevel: 'allow',
sessionSampleRate: 100,
sessionReplaySampleRate: 100,
trackViewsManually: false,
trackFrustrations: true,
});
// Initialize OpenObserve Logs
window.openobserveLogs.init({
clientToken: options.clientToken,
site: options.site,
organizationIdentifier: options.organizationIdentifier,
service: options.service,
env: options.env,
version: options.version,
forwardErrorsToLogs: true,
insecureHTTP: options.insecureHTTP,
apiVersion: options.apiVersion,
});
// Set initial user context
window.openobserveRum.setUser({
id: "1",
name: "Captain Hook",
email: "captainhook@example.com",
});
// Start session replay recording
window.openobserveRum.startSessionReplayRecording();
// Helper function to log activity to the page
function logActivity(message, type = 'info') {
const logOutput = document.getElementById('logOutput');
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.innerHTML = `<strong>[${new Date().toLocaleTimeString()}]</strong> ${message}`;
entry.style.color = type === 'error' ? '#dc3545' : type === 'warning' ? '#ff9800' : '#28a745';
logOutput.appendChild(entry);
logOutput.scrollTop = logOutput.scrollHeight;
}
// Track button click
function trackButtonClick() {
window.openobserveRum.addAction('button_clicked', {
button_name: 'Track Button Click',
timestamp: new Date().toISOString()
});
logActivity('Button click tracked via RUM');
}
// Make API call
async function makeAPICall() {
try {
logActivity('Making API call...');
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
logActivity('API call successful: ' + data.title);
window.openobserveRum.addAction('api_call_success', {
endpoint: 'jsonplaceholder.typicode.com',
status: response.status
});
} catch (error) {
logActivity('API call failed: ' + error.message, 'error');
window.openobserveLogs.logger.error('API call failed', { error: error.message });
}
}
// Simulate long task
function simulateLongTask() {
logActivity('Starting long task (3 seconds)...');
const start = Date.now();
// Block main thread for demonstration
setTimeout(() => {
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += Math.random();
}
const duration = Date.now() - start;
logActivity(`Long task completed (${duration}ms)`);
}, 0);
}
// Navigate page
function navigatePage() {
window.history.pushState({}, '', '/test-page-' + Date.now());
window.openobserveRum.addAction('navigation', {
url: window.location.href
});
logActivity('Navigation tracked: ' + window.location.href);
}
// Send info log
function sendInfoLog() {
const message = 'This is an informational log message';
window.openobserveLogs.logger.info(message, {
custom_attribute: 'info_value',
timestamp: new Date().toISOString()
});
logActivity('Info log sent: ' + message);
}
// Send warning log
function sendWarningLog() {
const message = 'This is a warning log message';
window.openobserveLogs.logger.warn(message, {
warning_type: 'user_action',
severity: 'medium'
});
logActivity('Warning log sent: ' + message, 'warning');
}
// Send error log
function sendErrorLog() {
const message = 'This is an error log message';
window.openobserveLogs.logger.error(message, {
error_code: 'ERR_001',
component: 'rum-test',
severity: 'high'
});
logActivity('Error log sent: ' + message, 'error');
}
// Throw actual error
function throwError() {
try {
throw new Error('Intentional error for testing RUM error tracking');
} catch (error) {
logActivity('Error thrown and caught: ' + error.message, 'error');
window.openobserveLogs.logger.error('Caught error', {
error_name: error.name,
error_message: error.message,
stack: error.stack
});
}
}
// Send custom log
function sendCustomLog() {
const message = document.getElementById('customLogMessage').value || 'Custom log message';
const level = document.getElementById('logLevel').value;
window.openobserveLogs.logger[level](message, {
custom_field: 'custom_value',
user_input: true,
timestamp: new Date().toISOString()
});
logActivity(`${level.toUpperCase()} log sent: ${message}`, level === 'error' ? 'error' : level === 'warn' ? 'warning' : 'info');
}
// Update user context
function updateUserContext() {
const userId = document.getElementById('userId').value;
const userName = document.getElementById('userName').value;
const userEmail = document.getElementById('userEmail').value;
window.openobserveRum.setUser({
id: userId,
name: userName,
email: userEmail
});
logActivity(`User context updated: ${userName} (${userEmail})`);
}
// Add custom action
function addCustomAction() {
const actionName = document.getElementById('actionName').value || 'custom_action';
let context = {};
try {
context = JSON.parse(document.getElementById('contextData').value || '{}');
} catch (e) {
context = { raw: document.getElementById('contextData').value };
}
window.openobserveRum.addAction(actionName, context);
logActivity(`Custom action added: ${actionName}`);
}
// Add global context
function addGlobalContext() {
let context = {};
try {
context = JSON.parse(document.getElementById('contextData').value || '{}');
} catch (e) {
context = { raw: document.getElementById('contextData').value };
}
window.openobserveRum.setGlobalContextProperty('custom_context', context);
logActivity('Global context added');
}
// Automatic event tracking
document.addEventListener('click', (e) => {
if (e.target.tagName === 'BUTTON') {
console.log('Button clicked:', e.target.textContent);
}
});
// Track page load
window.addEventListener('load', () => {
logActivity('Page loaded - RUM tracking initialized');
window.openobserveLogs.logger.info('Page loaded', {
url: window.location.href,
referrer: document.referrer
});
});
// Track page visibility changes
document.addEventListener('visibilitychange', () => {
const state = document.hidden ? 'hidden' : 'visible';
logActivity(`Page visibility changed: ${state}`);
window.openobserveRum.addAction('visibility_change', { state });
});
console.log('OpenObserve RUM Test initialized');
</script>
</body>
</html>