LinkDesk/frontend/test-shot-detail-panel-opti...

256 lines
9.4 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ShotDetailPanel Optimization Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.test-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.test-result {
padding: 10px;
border-radius: 4px;
margin: 10px 0;
}
.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.info {
background-color: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.code {
background-color: #f8f9fa;
padding: 10px;
border-radius: 4px;
font-family: monospace;
white-space: pre-wrap;
border: 1px solid #e9ecef;
}
button {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background-color: #0056b3;
}
.network-log {
max-height: 300px;
overflow-y: auto;
background-color: #f8f9fa;
padding: 10px;
border: 1px solid #e9ecef;
border-radius: 4px;
}
</style>
</head>
<body>
<h1>ShotDetailPanel Optimization Test</h1>
<p>This test verifies that ShotDetailPanel uses embedded task data instead of making redundant API calls.</p>
<div class="test-container">
<h2>Test Setup</h2>
<p>We'll monitor network requests to ensure no redundant task API calls are made when loading shot details.</p>
<button onclick="startTest()">Start Test</button>
<button onclick="clearLog()">Clear Log</button>
</div>
<div class="test-container">
<h2>Network Request Monitor</h2>
<div id="networkLog" class="network-log">
<p>Click "Start Test" to begin monitoring...</p>
</div>
</div>
<div class="test-container">
<h2>Test Results</h2>
<div id="testResults">
<p>No tests run yet.</p>
</div>
</div>
<div class="test-container">
<h2>Expected Behavior</h2>
<div class="info">
<strong>✅ Optimized Behavior:</strong>
<ul>
<li>Only one API call to <code>/api/shots/{shotId}</code> should be made</li>
<li>No separate calls to <code>/api/tasks/?shot_id={shotId}</code> should occur</li>
<li>Task data should be displayed using embedded <code>task_details</code> from shot response</li>
<li>Component should render task information without additional network requests</li>
</ul>
</div>
<div class="error">
<strong>❌ Non-Optimized Behavior (what we're avoiding):</strong>
<ul>
<li>Multiple API calls: first <code>/api/shots/{shotId}</code>, then <code>/api/tasks/?shot_id={shotId}</code></li>
<li>N+1 query pattern causing performance issues</li>
<li>Redundant network requests for data already available</li>
</ul>
</div>
</div>
<script>
let networkRequests = [];
let originalFetch = window.fetch;
let originalXHROpen = XMLHttpRequest.prototype.open;
let testStartTime = null;
// Override fetch to monitor requests
window.fetch = function(...args) {
if (testStartTime) {
logRequest('FETCH', args[0], args[1]);
}
return originalFetch.apply(this, args);
};
// Override XMLHttpRequest to monitor requests
XMLHttpRequest.prototype.open = function(method, url, ...args) {
if (testStartTime) {
logRequest('XHR', url, { method });
}
return originalXHROpen.apply(this, [method, url, ...args]);
};
function logRequest(type, url, options = {}) {
const timestamp = new Date().toISOString();
const request = {
type,
url: url.toString(),
method: options.method || 'GET',
timestamp
};
networkRequests.push(request);
updateNetworkLog();
}
function updateNetworkLog() {
const logElement = document.getElementById('networkLog');
if (networkRequests.length === 0) {
logElement.innerHTML = '<p>No requests captured yet...</p>';
return;
}
let html = '<h4>Captured Requests:</h4>';
networkRequests.forEach((req, index) => {
const isTaskRequest = req.url.includes('/tasks') && req.url.includes('shot_id');
const isShotRequest = req.url.includes('/shots/') && !req.url.includes('/tasks');
let className = '';
if (isTaskRequest) {
className = 'error'; // This should not happen in optimized version
} else if (isShotRequest) {
className = 'success'; // This is expected
}
html += `<div class="${className}" style="margin: 5px 0; padding: 5px; border-radius: 3px;">
<strong>${index + 1}.</strong> ${req.method} ${req.url}
<br><small>${req.timestamp}</small>
</div>`;
});
logElement.innerHTML = html;
}
function analyzeRequests() {
const shotRequests = networkRequests.filter(req =>
req.url.includes('/shots/') && !req.url.includes('/tasks')
);
const taskRequests = networkRequests.filter(req =>
req.url.includes('/tasks') && req.url.includes('shot_id')
);
let results = '<h4>Analysis Results:</h4>';
if (shotRequests.length > 0) {
results += `<div class="success">✅ Found ${shotRequests.length} shot request(s) - Expected</div>`;
} else {
results += `<div class="error">❌ No shot requests found - Unexpected</div>`;
}
if (taskRequests.length === 0) {
results += `<div class="success">✅ No redundant task requests found - Optimization working!</div>`;
} else {
results += `<div class="error">❌ Found ${taskRequests.length} redundant task request(s) - Optimization needed</div>`;
taskRequests.forEach(req => {
results += `<div class="code">Redundant request: ${req.method} ${req.url}</div>`;
});
}
// Check for other API requests that might be relevant
const otherRequests = networkRequests.filter(req =>
req.url.includes('/api/') &&
!req.url.includes('/shots/') &&
!req.url.includes('/tasks')
);
if (otherRequests.length > 0) {
results += `<div class="info"> Other API requests: ${otherRequests.length}</div>`;
}
document.getElementById('testResults').innerHTML = results;
}
function startTest() {
testStartTime = Date.now();
networkRequests = [];
document.getElementById('testResults').innerHTML = '<p>Test in progress... Please navigate to a shot detail view in the application.</p>';
document.getElementById('networkLog').innerHTML = '<p>Monitoring network requests...</p>';
// Auto-analyze after 30 seconds
setTimeout(() => {
if (networkRequests.length > 0) {
analyzeRequests();
} else {
document.getElementById('testResults').innerHTML =
'<div class="info">No requests captured. Make sure to interact with the ShotDetailPanel in the application.</div>';
}
}, 30000);
}
function clearLog() {
networkRequests = [];
testStartTime = null;
document.getElementById('networkLog').innerHTML = '<p>Log cleared. Click "Start Test" to begin monitoring...</p>';
document.getElementById('testResults').innerHTML = '<p>No tests run yet.</p>';
}
// Manual analysis button
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('.test-container:nth-child(2)');
const button = document.createElement('button');
button.textContent = 'Analyze Current Requests';
button.onclick = analyzeRequests;
container.appendChild(button);
});
</script>
</body>
</html>