111 lines
7.3 KiB
JavaScript
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(); }
|