diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90d36e5..4159aab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,3 +18,21 @@ jobs: - run: npm run lint - run: npm test - run: npm run build + + e2e: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + - run: npm ci + - run: npx playwright install --with-deps chromium + - run: npm run test:e2e + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: playwright-results + path: test-results/ + retention-days: 7 diff --git a/.gitignore b/.gitignore index b79aebc..a4dd486 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,7 @@ vite.config.ts.timestamp-* # Wrangler local state .wrangler/ + +# Playwright +test-results/ +playwright-report/ diff --git a/README.md b/README.md index e1c72af..f48dde0 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,14 @@ Compressly is a **privacy-first file compression tool** that lets you reduce fil ## โจ Features -- **๐๏ธ Compression Level Control** โ Choose how aggressively to compress, from lossless to maximum reduction. -- **๐ฏ Target File Size** โ Set an exact target size and let Compressly do the math for you. -- **๐ Privacy First** โ Files are processed locally or on the edge. Nothing is stored or logged on a remote server. -- **โก Fast & Lightweight** โ Built with Vite and TypeScript for a snappy, modern experience. -- **โ๏ธ Edge-Powered API** โ Backend API runs on Cloudflare Workers for low-latency processing close to you. -- **๐ฅ๏ธ Clean UI** โ A minimal, distraction-free interface designed for creators. +- **๐๏ธ Compression levels and exact targets** โ Pick a level, or set a target size per file. One-click presets for WhatsApp (16 MB), Discord (10 MB), email (25 MB) and form uploads (200 KB / 100 KB). +- **๐ผ๏ธ Images** โ JPG, PNG, WebP, BMP and iPhone HEIC in; same format, JPG, WebP or AVIF out. Optional max dimensions. Before/after comparison slider. +- **๐ PDFs** โ "Keep text selectable" re-compresses only the images inside, or "Smallest size" turns pages into images. +- **๐ฌ Video and audio** โ MP4, WebM or GIF output, resolution, remove audio, trim. Audio becomes MP3. +- **๐๏ธ GIF and SVG** โ Animated GIFs keep every frame (gifsicle); SVGs are optimized with SVGO. +- **๐ Private by design** โ Everything runs in your browser. Photo location and camera data is removed unless you choose to keep it. +- **๐ฑ Installable app** โ Works offline once loaded; on Android, share files to Compressly from any app. +- **โจ Comfortable to use** โ Paste or drop whole folders, cancel any file, per-file options, remembered settings, dark mode. --- @@ -72,10 +74,13 @@ The app will be available at `http://localhost:3000` by default. ### Checks ```bash -npm run lint # type-check -npm test # unit tests +npm run lint # type-check +npm test # unit tests +npm run test:e2e # browser tests against the production build (Playwright) ``` +Run `npx playwright install chromium` once before the browser tests. + ### Building for Production ```bash @@ -97,7 +102,16 @@ npx wrangler deploy With Workers Builds (Git integration), use `npm run build` as the build command and `npx wrangler deploy` (or `npx wrangler versions upload`) as the deploy command. -To run the production setup locally, including the API and KV stats: +Use `npx wrangler deploy` rather than `npx wrangler versions upload`: the stats counter is a Durable Object, and the first deploy has to apply its migration, which version uploads can't do. + +Optional build-time environment variables: + +| Variable | Purpose | +| --- | --- | +| `VITE_SITE_URL` | Public URL used in canonical links, `og:image` and `sitemap.xml` (default: `https://compressly.harshitks2203.workers.dev`) | +| `CF_ANALYTICS_TOKEN` | Enables Cloudflare Web Analytics | + +To run the production setup locally, including the API and stats counter: ```bash npm run build @@ -112,11 +126,15 @@ npx wrangler dev compressly/ โโโ docs/ โ โโโ screenshots/ # README images (not deployed) -โโโ worker/ # Cloudflare Worker: /api/* routes +โโโ worker/ # Cloudflare Worker: /api/* routes, stats Durable Object +โโโ tests/e2e/ # Playwright browser tests +โโโ scripts/ # Generates the PWA icons and og-image.png โโโ public/ # Static assets โโโ src/ โ โโโ components/ # UI components -โ โโโ lib/ # Compression logic, loaded on demand per file type +โ โโโ hooks/ # Settings and theme state +โ โโโ lib/ # Compression logic, loaded on demand per file type +โ โโโ sw.ts # Service worker (offline, caching, share target) โโโ index.html # App entry point โโโ vite.config.ts # Vite configuration โโโ wrangler.toml # Cloudflare Worker config @@ -129,9 +147,10 @@ compressly/ Compressly is built with privacy as a core principle: -- **No file storage** โ Your files are never persisted on any server. -- **No tracking** โ No analytics or telemetry are attached to your files. -- **Edge processing** โ API functions run on Cloudflare's edge network, meaning processing happens ephemerally and close to you. +- **Files never leave your device** โ All compression runs in the browser (WebAssembly and web workers). No file is uploaded, stored or logged. +- **Metadata removed by default** โ Re-encoded photos drop EXIF data such as GPS location, unless "Keep photo metadata" is on. +- **Minimal network use** โ The only requests with user activity are an anonymous count of files and bytes saved for the public stats. Fonts and libraries are self-hosted; the FFmpeg core (~31 MB, too large for Cloudflare's 25 MiB file limit) is fetched from unpkg only when you add a video or audio file, then cached. +- **Optional analytics** โ If `CF_ANALYTICS_TOKEN` is set at build time, Cloudflare Web Analytics counts page views. It uses no cookies and never sees your files. You can verify this by inspecting the source code in `worker/` and `src/`. diff --git a/index.html b/index.html index 6f5943b..5b45a34 100644 --- a/index.html +++ b/index.html @@ -3,40 +3,50 @@
- -