256 lines
9.4 KiB
HTML
256 lines
9.4 KiB
HTML
<!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> |