Add template-guide E2E test and release validation gate (v4.0.7)
This commit is contained in:
parent
1e5e9137ff
commit
e4ab08cd88
@ -45,9 +45,15 @@ npm start
|
||||
# Quick UI smoke test
|
||||
npm run test:e2e
|
||||
|
||||
# Template guide + live preview checks
|
||||
npm run test:e2e:guide
|
||||
|
||||
# Full end-to-end validation pass
|
||||
npm run test:e2e:full
|
||||
|
||||
# Release validation suite (build + smoke + guide + full)
|
||||
npm run test:e2e:release
|
||||
|
||||
# Build Windows installer
|
||||
npm run dist:win
|
||||
```
|
||||
|
||||
4
typescript-version/package-lock.json
generated
4
typescript-version/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.7",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.7",
|
||||
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
||||
"main": "dist/main.js",
|
||||
"author": "xRangerDE",
|
||||
@ -9,10 +9,12 @@
|
||||
"build": "tsc",
|
||||
"start": "npm run build && electron .",
|
||||
"test:e2e": "npm exec --yes --package=playwright -- node scripts/smoke-test.js",
|
||||
"test:e2e:guide": "npm exec --yes --package=playwright -- node scripts/smoke-test-template-guide.js",
|
||||
"test:e2e:full": "npm exec --yes --package=playwright -- node scripts/smoke-test-full.js",
|
||||
"test:e2e:release": "npm run build && npm run test:e2e && npm run test:e2e:guide && npm run test:e2e:full",
|
||||
"pack": "npm run build && electron-builder --dir",
|
||||
"dist": "npm run build && electron-builder",
|
||||
"dist:win": "npm run build && electron-builder --win"
|
||||
"dist:win": "npm run test:e2e:release && electron-builder --win"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
|
||||
146
typescript-version/scripts/smoke-test-template-guide.js
Normal file
146
typescript-version/scripts/smoke-test-template-guide.js
Normal file
@ -0,0 +1,146 @@
|
||||
const { _electron: electron } = require('playwright');
|
||||
|
||||
async function run() {
|
||||
const electronPath = require('electron');
|
||||
const app = await electron.launch({
|
||||
executablePath: electronPath,
|
||||
args: ['.'],
|
||||
cwd: process.cwd()
|
||||
});
|
||||
|
||||
const win = await app.firstWindow();
|
||||
const issues = [];
|
||||
const failures = [];
|
||||
|
||||
win.on('pageerror', (err) => {
|
||||
issues.push(`pageerror: ${String(err)}`);
|
||||
});
|
||||
|
||||
win.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
issues.push(`console.error: ${msg.text()}`);
|
||||
}
|
||||
});
|
||||
|
||||
const fail = (message) => failures.push(message);
|
||||
|
||||
let settingsPreview = '';
|
||||
let variableRows = 0;
|
||||
let clipPreviewBefore = '';
|
||||
let clipPreviewAfter = '';
|
||||
|
||||
try {
|
||||
await win.waitForTimeout(2500);
|
||||
|
||||
await win.evaluate(() => {
|
||||
window.showTab('settings');
|
||||
});
|
||||
await win.waitForTimeout(200);
|
||||
|
||||
await win.click('#settingsTemplateGuideBtn');
|
||||
await win.waitForTimeout(180);
|
||||
|
||||
const guideVisibleFromSettings = await win.evaluate(() => {
|
||||
return document.getElementById('templateGuideModal')?.classList.contains('show') || false;
|
||||
});
|
||||
|
||||
if (!guideVisibleFromSettings) {
|
||||
fail('Template guide did not open from settings');
|
||||
}
|
||||
|
||||
await win.fill('#templateGuideInput', '{title}_{part_padded}_{date_custom="yyyy-MM-dd"}.mp4');
|
||||
await win.waitForTimeout(160);
|
||||
|
||||
settingsPreview = await win.locator('#templateGuideOutput').innerText();
|
||||
if (!settingsPreview.includes('.mp4')) {
|
||||
fail('Settings template preview missing .mp4 output');
|
||||
}
|
||||
if (settingsPreview.includes('{title}') || settingsPreview.includes('{part_padded}') || settingsPreview.includes('{date_custom=')) {
|
||||
fail('Settings template preview did not replace placeholders');
|
||||
}
|
||||
|
||||
variableRows = await win.locator('#templateGuideBody tr').count();
|
||||
if (variableRows < 12) {
|
||||
fail(`Template variable table too short (${variableRows})`);
|
||||
}
|
||||
|
||||
await win.click('#templateGuideUseParts');
|
||||
await win.waitForTimeout(150);
|
||||
const partsContext = await win.locator('#templateGuideContext').innerText();
|
||||
if (!/part|teil/i.test(partsContext)) {
|
||||
fail('Template guide parts context text missing');
|
||||
}
|
||||
|
||||
await win.click('#templateGuideCloseBtn');
|
||||
await win.waitForTimeout(100);
|
||||
|
||||
await win.evaluate(async () => {
|
||||
window.showTab('vods');
|
||||
await window.selectStreamer('xrohat');
|
||||
});
|
||||
await win.waitForTimeout(3200);
|
||||
|
||||
const clipButtons = win.locator('.vod-card .vod-btn.secondary');
|
||||
const clipCount = await clipButtons.count();
|
||||
if (clipCount < 1) {
|
||||
fail('No clip buttons found in VOD list');
|
||||
} else {
|
||||
await clipButtons.first().click();
|
||||
await win.waitForTimeout(260);
|
||||
|
||||
await win.locator('input[name="filenameFormat"][value="template"]').check();
|
||||
await win.waitForTimeout(140);
|
||||
|
||||
await win.click('#clipTemplateGuideBtn');
|
||||
await win.waitForTimeout(140);
|
||||
|
||||
const clipContext = await win.locator('#templateGuideContext').innerText();
|
||||
if (!/clip/i.test(clipContext)) {
|
||||
fail('Template guide clip context text missing');
|
||||
}
|
||||
|
||||
await win.fill('#templateGuideInput', '{trim_start}_{part}.mp4');
|
||||
await win.waitForTimeout(120);
|
||||
clipPreviewBefore = await win.locator('#templateGuideOutput').innerText();
|
||||
|
||||
await win.fill('#clipStartTime', '00:00:10');
|
||||
await win.evaluate(() => {
|
||||
window.updateFromInput('start');
|
||||
});
|
||||
await win.waitForTimeout(240);
|
||||
|
||||
clipPreviewAfter = await win.locator('#templateGuideOutput').innerText();
|
||||
if (clipPreviewAfter === clipPreviewBefore) {
|
||||
fail('Clip template guide preview did not react to clip start time changes');
|
||||
}
|
||||
|
||||
await win.click('#templateGuideCloseBtn');
|
||||
await win.evaluate(() => {
|
||||
window.closeClipDialog();
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
|
||||
const summary = {
|
||||
failures,
|
||||
issues,
|
||||
checks: {
|
||||
settingsPreview,
|
||||
variableRows,
|
||||
clipPreviewBefore,
|
||||
clipPreviewAfter
|
||||
}
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(summary, null, 2));
|
||||
|
||||
const hasFailure = failures.length > 0 || issues.length > 0;
|
||||
process.exit(hasFailure ? 1 : 0);
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@ -428,7 +428,7 @@
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="updateTitle">Updates</h3>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.0.6</p>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.0.7</p>
|
||||
<button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button>
|
||||
</div>
|
||||
|
||||
@ -460,7 +460,7 @@
|
||||
<div class="status-dot" id="statusDot"></div>
|
||||
<span id="statusText">Nicht verbunden</span>
|
||||
</div>
|
||||
<span id="versionText">v4.0.6</span>
|
||||
<span id="versionText">v4.0.7</span>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
|
||||
// ==========================================
|
||||
// CONFIG & CONSTANTS
|
||||
// ==========================================
|
||||
const APP_VERSION = '4.0.6';
|
||||
const APP_VERSION = '4.0.7';
|
||||
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
|
||||
|
||||
// Paths
|
||||
|
||||
Loading…
Reference in New Issue
Block a user