The home-sections browser test clicked `.copy-btn` and immediately asserted
`textContent() === 'Copied'`. The button flips its label only after the
asynchronous `navigator.clipboard.writeText` promise resolves, which is after
Playwright's `click()` has already returned, so a loaded CI runner sometimes
still read "Copy" (PR #1619, run 35369544094).
Poll for the label with Playwright's `expect(locator).toHaveText` (bounded
5 s) before reading the clipboard. The import is dynamic and sits after
`launchBrowser()`, so the local no-Chromium skip path is unchanged.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat(updater): nightly builds and a stable/nightly update channel
Every master push publishes its artifacts as a prerelease of
4gray/iptvnator-nightly instead of the rolling test-master draft, with a
version of <next patch>-nightly.<commit date>.<run number> applied in
every build job. Settings → About gains an Update channel switch;
AppUpdateService re-points electron-updater per check (feed repository,
allowPrerelease, channel name, allowDowngrade reset) and reads release
notes from the repository the requested version belongs to. Channel
switches are forward-only: a nightly build stays until a newer stable
release exists.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix(updater): compute the nightly version once and keep re-runs safe
Review follow-ups: the nightly version is resolved by a leading job and
handed to every build job, and the patch is bumped only when the base
tag already exists so the release-cut window stays below the imminent
release. A re-run never deletes a published nightly; only a draft left
by a failed run is replaced. Typed update-status literals in the
remaining specs carry the new channel fields.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test(packaging): expect the nightly-version prerequisite in the build workflow graph
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* chore(deps): upgrade Angular to 22.1 and Nx to 23.2
* fix(deps): complete Angular migrations after rebasing on master
* fix(ci): use the Node pin for Windows runtime refresh
* docs(deps): synchronize the workspace-shell Node requirements
Every page pulled its three typefaces from fonts.googleapis.com and
fonts.gstatic.com, each blog post fetched the author avatar from
githubusercontent.com, and the giscus client script ran on page load. That is
four outside origins contacted before a reader does anything, each costing a
DNS lookup and a TLS handshake on the critical path.
Fonts now come from the @fontsource packages the app already uses and are
emitted as .woff2 beside the site; the avatar is a 3 KB file in public/; and
the giscus embed is created by a "Show comments" button that carries the
configuration as data attributes, so the script is only built when a reader
asks for it.
A delivered page now makes no third-party request at all, verified across the
whole build. The variable Bricolage package names itself "Bricolage Grotesque
Variable", so that exact name leads the display stack in the Tailwind config.
The giscus test now checks the button configuration and asserts the client
script is absent from the delivered HTML.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"TiviMate for PC" is the query behind most of this page's traffic, so the
page now names the apps people mean instead of describing a category. What
it says about them is what could actually be verified: TiviMate's Google
Play listing (Android and Android TV, reads M3U, Xtream Codes and Stalker,
"a media player that provides no content"), and IPTV Smarters publishing
Windows and macOS builds — which is why the page does not claim TV apps
have no desktop version.
The useful half is the part no affiliate site writes: these names are
heavily abused, the stores carry copycat listings, and much of the search
result for any of them is someone selling "subscriptions" under the app's
brand. The developers are player authors who do not sell channels, which is
exactly what IPTVnator says about itself — the page links to our own
unofficial-websites post for the same reason.
Three FAQ entries answer the query directly, and the page joins the
NAMES_THIRD_PARTY_SOFTWARE set so the test requires its dated disclaimer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Third page in the set, and the one that answers the question people ask
before installing anything: where should IPTV actually run. It compares the
two places rather than two products — everything that needs a keyboard
(adding a provider, attaching a guide, mapping a channel, working out why a
stream fails) against everything that needs a couch — and states plainly
that IPTVnator has no TV build, with the phone remote as the answer for a
laptop wired to the television.
No third-party software is named, so the page carries no ThirdPartyNote: the
rows describe the ordinary experience of each kind of device and say so in
the caption.
The compare hub's lead no longer claims every page is a choice inside the
app, and the three newest entries get distinct icons.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>