Add npm test:e2e command and harden smoke checks (v4.0.2)
Expose a single runnable end-to-end test command for fast regression sweeps and update the smoke test to validate preflight and localization-aware clip errors reliably across language modes.
This commit is contained in:
parent
089e0085ee
commit
614e5cd20f
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.1",
|
||||
"version": "4.0.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
||||
"main": "dist/main.js",
|
||||
"author": "xRangerDE",
|
||||
@ -8,6 +8,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "npm run build && electron .",
|
||||
"test:e2e": "npm exec --yes --package=playwright -- node scripts/smoke-test.js",
|
||||
"pack": "npm run build && electron-builder --dir",
|
||||
"dist": "npm run build && electron-builder",
|
||||
"dist:win": "npm run build && electron-builder --win"
|
||||
|
||||
149
typescript-version/scripts/smoke-test.js
Normal file
149
typescript-version/scripts/smoke-test.js
Normal file
@ -0,0 +1,149 @@
|
||||
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 = [];
|
||||
|
||||
win.on('pageerror', (err) => {
|
||||
issues.push(`pageerror: ${String(err)}`);
|
||||
});
|
||||
|
||||
win.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
issues.push(`console.error: ${msg.text()}`);
|
||||
}
|
||||
});
|
||||
|
||||
await win.waitForTimeout(2500);
|
||||
|
||||
const globals = await win.evaluate(async () => {
|
||||
const names = [
|
||||
'showTab',
|
||||
'addStreamer',
|
||||
'refreshVODs',
|
||||
'downloadClip',
|
||||
'selectCutterVideo',
|
||||
'startCutting',
|
||||
'addMergeFiles',
|
||||
'startMerging',
|
||||
'saveSettings',
|
||||
'checkUpdate',
|
||||
'downloadUpdate',
|
||||
'updateFromInput',
|
||||
'updateFromSlider',
|
||||
'runPreflight',
|
||||
'retryFailedDownloads',
|
||||
'toggleDebugAutoRefresh'
|
||||
];
|
||||
const map = {};
|
||||
for (const n of names) map[n] = typeof window[n];
|
||||
return map;
|
||||
});
|
||||
|
||||
await win.evaluate(() => {
|
||||
window.showTab('clips');
|
||||
window.showTab('cutter');
|
||||
window.showTab('merge');
|
||||
window.showTab('settings');
|
||||
window.showTab('vods');
|
||||
});
|
||||
|
||||
const input = win.locator('#newStreamer');
|
||||
const randomName = `smoketest_${Date.now()}`;
|
||||
await input.fill(randomName);
|
||||
await win.evaluate(async () => {
|
||||
await window.addStreamer();
|
||||
});
|
||||
|
||||
const hasTempStreamer = await win.locator('#streamerList').innerText();
|
||||
|
||||
await win.evaluate(async (name) => {
|
||||
await window.removeStreamer(name);
|
||||
}, randomName);
|
||||
|
||||
await win.evaluate(async () => {
|
||||
await window.selectStreamer('xrohat');
|
||||
});
|
||||
|
||||
await win.waitForTimeout(3500);
|
||||
|
||||
const vodCount = await win.locator('.vod-card').count();
|
||||
|
||||
if (vodCount > 0) {
|
||||
await win.locator('.vod-card .vod-btn.primary').first().click();
|
||||
await win.waitForTimeout(500);
|
||||
}
|
||||
|
||||
const queueCountAfterAdd = await win.locator('#queueCount').innerText();
|
||||
|
||||
const queueRemove = win.locator('#queueList .remove').first();
|
||||
if (await queueRemove.count()) {
|
||||
await queueRemove.click();
|
||||
await win.waitForTimeout(300);
|
||||
}
|
||||
|
||||
await win.evaluate(() => {
|
||||
window.showTab('clips');
|
||||
});
|
||||
|
||||
await win.fill('#clipUrl', '');
|
||||
await win.evaluate(async () => {
|
||||
await window.downloadClip();
|
||||
});
|
||||
|
||||
const clipStatus = await win.locator('#clipStatus').innerText();
|
||||
|
||||
await win.evaluate(async () => {
|
||||
await window.runPreflight(false);
|
||||
await window.startCutting();
|
||||
await window.startMerging();
|
||||
});
|
||||
|
||||
const mergeButtonDisabled = await win.locator('#btnMerge').isDisabled();
|
||||
const preflightText = await win.locator('#preflightResult').innerText();
|
||||
const healthBadge = await win.locator('#healthBadge').innerText();
|
||||
|
||||
await app.close();
|
||||
|
||||
const failedGlobals = Object.entries(globals)
|
||||
.filter(([, type]) => type !== 'function')
|
||||
.map(([name, type]) => `${name}=${type}`);
|
||||
|
||||
const summary = {
|
||||
failedGlobals,
|
||||
hasTempStreamer: hasTempStreamer.includes(randomName),
|
||||
vodCount,
|
||||
queueCountAfterAdd,
|
||||
clipStatus,
|
||||
mergeButtonDisabled,
|
||||
preflightText,
|
||||
healthBadge,
|
||||
issues
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(summary, null, 2));
|
||||
|
||||
const hasFailure =
|
||||
failedGlobals.length > 0 ||
|
||||
!summary.hasTempStreamer ||
|
||||
summary.vodCount < 1 ||
|
||||
!(summary.clipStatus.includes('Bitte URL eingeben') || summary.clipStatus.includes('Please enter a URL')) ||
|
||||
!summary.mergeButtonDisabled ||
|
||||
!summary.preflightText ||
|
||||
!summary.healthBadge ||
|
||||
summary.issues.length > 0;
|
||||
|
||||
process.exit(hasFailure ? 1 : 0);
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@ -345,7 +345,7 @@
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="updateTitle">Updates</h3>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.0.1</p>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.0.2</p>
|
||||
<button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button>
|
||||
</div>
|
||||
|
||||
@ -377,7 +377,7 @@
|
||||
<div class="status-dot" id="statusDot"></div>
|
||||
<span id="statusText">Nicht verbunden</span>
|
||||
</div>
|
||||
<span id="versionText">v4.0.1</span>
|
||||
<span id="versionText">v4.0.2</span>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
|
||||
// ==========================================
|
||||
// CONFIG & CONSTANTS
|
||||
// ==========================================
|
||||
const APP_VERSION = '4.0.1';
|
||||
const APP_VERSION = '4.0.2';
|
||||
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
|
||||
|
||||
// Paths
|
||||
|
||||
Loading…
Reference in New Issue
Block a user