implement wp testing

This commit is contained in:
southseact-3d
2026-02-08 19:27:26 +00:00
parent 541b6bc946
commit 39136e863f
16 changed files with 954 additions and 8 deletions

View File

@@ -91,6 +91,10 @@
opencodeBackupForm: document.getElementById('opencode-backup-form'),
opencodeBackup: document.getElementById('opencode-backup'),
opencodeBackupStatus: document.getElementById('opencode-backup-status'),
externalTestingRun: document.getElementById('external-testing-run'),
externalTestingStatus: document.getElementById('external-testing-status'),
externalTestingOutput: document.getElementById('external-testing-output'),
externalTestingConfig: document.getElementById('external-testing-config'),
};
console.log('Element check - opencodeBackupForm:', el.opencodeBackupForm);
console.log('Element check - opencodeBackup:', el.opencodeBackup);
@@ -178,6 +182,128 @@
el.opencodeBackupStatus.style.color = isError ? 'var(--danger)' : 'inherit';
}
function setExternalTestingStatus(msg, isError = false) {
if (!el.externalTestingStatus) return;
el.externalTestingStatus.textContent = msg || '';
el.externalTestingStatus.style.color = isError ? 'var(--danger)' : 'inherit';
}
function renderExternalTestingConfig(config) {
if (!el.externalTestingConfig) return;
el.externalTestingConfig.innerHTML = '';
if (!config) return;
const rows = [
['WP host', config.wpHost || '—'],
['WP path', config.wpPath || '—'],
['Base URL', config.wpBaseUrl || '—'],
['Multisite enabled', config.enableMultisite ? 'Yes' : 'No'],
['Subsite mode', config.subsiteMode || '—'],
['Subsite domain', config.subsiteDomain || '—'],
['Max concurrent tests', String(config.maxConcurrentTests ?? '—')],
['Auto cleanup', config.autoCleanup ? 'Yes' : 'No'],
['Cleanup delay (ms)', String(config.cleanupDelayMs ?? '—')],
['SSH key configured', config.sshKeyConfigured ? 'Yes' : 'No'],
];
rows.forEach(([label, value]) => {
const row = document.createElement('div');
row.className = 'admin-row';
const labelWrap = document.createElement('div');
labelWrap.style.minWidth = '180px';
const strong = document.createElement('strong');
strong.textContent = label;
labelWrap.appendChild(strong);
const valueWrap = document.createElement('div');
valueWrap.textContent = value;
row.appendChild(labelWrap);
row.appendChild(valueWrap);
el.externalTestingConfig.appendChild(row);
});
}
function renderExternalTestingOutput(result) {
if (!el.externalTestingOutput) return;
el.externalTestingOutput.innerHTML = '';
if (!result) return;
const summary = document.createElement('div');
summary.className = 'admin-row';
const summaryLabel = document.createElement('div');
summaryLabel.style.minWidth = '180px';
const summaryStrong = document.createElement('strong');
summaryStrong.textContent = 'Overall result';
summaryLabel.appendChild(summaryStrong);
const summaryValue = document.createElement('div');
summaryValue.textContent = result.ok ? 'Passed' : 'Failed';
summary.appendChild(summaryLabel);
summary.appendChild(summaryValue);
el.externalTestingOutput.appendChild(summary);
const detailRows = [
['Subsite URL', result.subsite_url || '—'],
['Duration', typeof result.duration === 'number' ? `${(result.duration / 1000).toFixed(1)}s` : '—'],
];
detailRows.forEach(([label, value]) => {
const row = document.createElement('div');
row.className = 'admin-row';
const labelWrap = document.createElement('div');
labelWrap.style.minWidth = '180px';
const strong = document.createElement('strong');
strong.textContent = label;
labelWrap.appendChild(strong);
const valueWrap = document.createElement('div');
valueWrap.textContent = value;
row.appendChild(labelWrap);
row.appendChild(valueWrap);
el.externalTestingOutput.appendChild(row);
});
const scenarioResults = result?.test_results?.cli_tests?.results || [];
if (scenarioResults.length) {
scenarioResults.forEach((scenario) => {
const row = document.createElement('div');
row.className = 'admin-row';
const labelWrap = document.createElement('div');
labelWrap.style.minWidth = '180px';
const strong = document.createElement('strong');
strong.textContent = scenario.name || 'Scenario';
labelWrap.appendChild(strong);
const valueWrap = document.createElement('div');
valueWrap.textContent = scenario.status === 'passed' ? 'Passed' : 'Failed';
if (scenario.status !== 'passed') {
valueWrap.style.color = 'var(--danger)';
}
row.appendChild(labelWrap);
row.appendChild(valueWrap);
el.externalTestingOutput.appendChild(row);
});
}
const errors = Array.isArray(result.errors) ? result.errors : [];
if (errors.length) {
errors.forEach((err) => {
const row = document.createElement('div');
row.className = 'admin-row';
const labelWrap = document.createElement('div');
labelWrap.style.minWidth = '180px';
const strong = document.createElement('strong');
strong.textContent = 'Error';
labelWrap.appendChild(strong);
const valueWrap = document.createElement('div');
valueWrap.textContent = err;
valueWrap.style.color = 'var(--danger)';
row.appendChild(labelWrap);
row.appendChild(valueWrap);
el.externalTestingOutput.appendChild(row);
});
}
}
async function loadExternalTestingStatus() {
const data = await api('/api/admin/external-testing-status');
renderExternalTestingConfig(data.config || {});
}
async function api(path, options = {}) {
const res = await fetch(path, {
credentials: 'same-origin',
@@ -1844,6 +1970,7 @@
() => (el.planTokensTable ? loadPlanTokens() : null),
() => ((el.tokenRateUsd || el.tokenRateGbp || el.tokenRateEur) ? loadTokenRates() : null),
() => ((el.providerUsage || el.providerLimitForm) ? loadProviderLimits() : null),
() => (el.externalTestingConfig ? loadExternalTestingStatus() : null),
];
await Promise.all(loaders.map((fn) => fn()).filter(Boolean));
// Always try to load provider limits if not already loaded (needed for backup dropdown)
@@ -2139,6 +2266,22 @@
});
}
if (el.externalTestingRun) {
el.externalTestingRun.addEventListener('click', async () => {
el.externalTestingRun.disabled = true;
setExternalTestingStatus('Running self-test...');
try {
const data = await api('/api/admin/external-testing-self-test', { method: 'POST' });
renderExternalTestingOutput(data.result || null);
setExternalTestingStatus(data.result && data.result.ok ? 'Self-test passed.' : 'Self-test failed.', !data.result || !data.result.ok);
} catch (err) {
setExternalTestingStatus(err.message || 'Self-test failed.', true);
} finally {
el.externalTestingRun.disabled = false;
}
});
}
if (el.logout) {
el.logout.addEventListener('click', async () => {
await api('/api/admin/logout', { method: 'POST' }).catch(() => { });