Files
YouTubeDL/tests/onboarding.test.mjs
T
DepressedCat 5f2aad00f4
Check extension and helper / check (push) Canceled after 0s
Publish YouTubeDL 1.4.5 and website on Gitea
2026-10-10 23:53:17 +03:00

111 lines
7.3 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { chromium } from "playwright";
const root = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
const artifacts = path.join(root, "test-artifacts");
await fs.mkdir(artifacts, { recursive: true });
const browser = await chromium.launch({ headless: true, executablePath: "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" });
const context = await browser.newContext({ viewport: { width: 520, height: 820 }, reducedMotion: "reduce" });
await context.addInitScript({ path: path.join(root, "tests/ui-fixture.js") });
await context.route("https://ui.ytdl.test/**", async route => {
const name = new URL(route.request().url()).pathname.slice(1);
if (!["downloader.html", "downloader.js", "onboarding.js", "ui-connection.js", "theme-init.js", "styles.css", "shared.js", "session.js"].includes(name)) return route.abort();
return route.fulfill({ body: await fs.readFile(path.join(root, "extension", name)), contentType: name.endsWith(".html") ? "text/html" : name.endsWith(".css") ? "text/css" : "application/javascript" });
});
const errors = [];
context.on("page", page => page.on("pageerror", error => errors.push(error.message)));
try {
const page = await context.newPage();
await page.addInitScript(() => { window.__firstRun = true; window.__helperMissing = true; });
await page.goto("https://ui.ytdl.test/downloader.html?theme=dark");
await page.locator("#setup[open]").waitFor();
await page.screenshot({ path: path.join(artifacts, "onboarding-welcome.png"), animations: "disabled" });
await page.locator("#setup-next").click();
await page.locator('#setup-helper[data-state="missing"]').waitFor();
assert.equal(await page.locator("#setup-next").isDisabled(), true);
assert.equal(await page.locator("#setup-install").isVisible(), true);
assert.equal(await page.locator("#setup-install").getAttribute("href"), "https://git.lonarpgproxy.space/OwnerLink/YouTubeDL/releases/latest");
assert.equal(await page.locator("#setup-install").getAttribute("target"), "_blank");
assert.equal(await page.locator("#setup-install").getAttribute("download"), null);
assert.equal(await page.locator("#setup-install-steps li").count(), 3);
await page.screenshot({ path: path.join(artifacts, "onboarding-install.png"), animations: "disabled" });
// A connected helper with a broken component is insufficient to continue.
await page.evaluate(() => { window.__helperMissing = false; window.__dependencyMissing = true; });
await page.locator("#setup-check").click();
await page.locator("#setup-check:not([disabled])").waitFor();
assert.equal(await page.locator("#setup-next").isDisabled(), true);
assert.match(await page.locator("#setup-install").textContent(), /восстановления/);
await page.evaluate(() => { window.__dependencyMissing = false; });
await page.locator("#setup-check").click();
await page.locator("#setup-next:not([disabled])").waitFor();
assert.match(await page.locator("#setup-helper-message").textContent(), /5\/5/);
assert.match(await page.locator("#setup-gpu").textContent(), /RTX 5080.*NVENC/);
await page.locator("#setup-updates").uncheck();
await page.locator("#setup-next:not([disabled])").waitFor();
assert.equal(await page.locator("#setup-updates").isChecked(), false);
await page.locator("#setup-next").click();
await page.locator("#setup-folder").fill("");
await page.locator("#setup-next").click();
assert.match(await page.locator("#setup-error").textContent(), /Выберите папку/);
await page.locator("#setup-pick-folder").click();
await page.locator("#setup-pick-folder:not([disabled])").waitFor();
assert.equal(await page.locator("#setup-folder").inputValue(), "D:\\Videos\\YouTube");
await page.locator("#setup-pick-work-folder").click();
await page.locator("#setup-pick-work-folder:not([disabled])").waitFor();
assert.equal(await page.locator("#setup-work-folder").inputValue(), "D:\\Videos\\YouTube");
await page.locator("#setup-work-folder").fill("F:\\Scratch");
await page.locator("#setup-mode").selectOption("audio");
assert.equal(await page.locator("#setup-quality-field").isVisible(), false);
await page.locator("#setup-format").selectOption("mp3");
await page.locator("#setup-mode").selectOption("video");
await page.locator("#setup-format").selectOption("mkv");
await page.locator("#setup-quality").selectOption("1080");
await page.screenshot({ path: path.join(artifacts, "onboarding-settings.png"), animations: "disabled" });
await page.locator("#setup-next").click();
await page.locator('[data-setup-step="3"]').waitFor({ state: "visible" });
assert.match(await page.locator("#setup-saved").textContent(), /D:\\Videos\\YouTube/);
await page.locator("#setup-next").click();
await page.locator("#setup").waitFor({ state: "hidden" });
const result = await page.evaluate(() => window.__fixtureStorage);
assert.equal(result.onboarding.state, "complete");
assert.equal(result.preferences.videoContainer, "mkv");
assert.equal(result.preferences.audioContainer, "mp3");
assert.equal(result.preferences.quality.height, 1080);
assert.equal(result.preferences.workFolder, "F:\\Scratch");
assert.equal(result.preferences.engine, "auto");
await page.locator("#open-setup").click();
await page.locator("#setup[open]").waitFor();
await page.keyboard.press("Escape");
await page.locator("#setup").waitFor({ state: "hidden" });
assert.equal(await page.evaluate(() => window.__fixtureStorage.onboarding.state), "skipped");
await page.close();
const narrow = await context.newPage();
await narrow.setViewportSize({ width: 340, height: 560 });
await narrow.addInitScript(() => { window.__firstRun = true; });
await narrow.goto("https://ui.ytdl.test/downloader.html?theme=light");
await narrow.locator("#setup[open]").waitFor();
await narrow.locator("#setup-next").click();
await narrow.locator("#setup-next:not([disabled])").waitFor();
const box = await narrow.locator("#setup").boundingBox();
assert.ok(box.x >= 0 && box.x + box.width <= 340 && box.y >= 0 && box.y + box.height <= 560);
assert.equal(await narrow.locator("#setup-next").isVisible(), true);
await narrow.screenshot({ path: path.join(artifacts, "onboarding-light-narrow.png"), animations: "disabled" });
await narrow.locator("#setup-skip").click();
await narrow.locator("#setup").waitFor({ state: "hidden" });
assert.equal(await narrow.evaluate(() => window.__fixtureStorage.onboarding.state), "skipped");
await narrow.close();
const existing = await context.newPage();
await existing.addInitScript(() => { window.__firstRun = true; window.__fixtureStorage.preferences = { folder: "D:\\Existing", videoContainer: "webm" }; });
await existing.goto("https://ui.ytdl.test/downloader.html");
await existing.locator('#helper-panel[data-state="running"]').waitFor();
assert.equal(await existing.locator("#setup").evaluate(dialog => dialog.open), false, "Configured profiles are not interrupted by a new guide");
assert.equal(await existing.locator("#folder").inputValue(), "D:\\Existing");
assert.deepEqual(errors, []);
console.log("Onboarding passed: first launch, missing/broken helper, real-state gating, update toggle, folder validation, video/audio defaults, skip, reopen, Escape, existing profiles and narrow light theme.");
} finally { await browser.close(); }