mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
chore(release): add 0.25 highlights and a settings search screenshot
Mark the deferred Electron startup wiring as the "Faster startup" highlight next to settings search, and give the settings search note a screenshot: a new `open-settings-search=<term>` capture action types the term into the header search and waits for the ranked results. Guard the manifest tooling with tests that validate the committed screenshots.manifest.json and keep KNOWN_ACTIONS in step with the capture navigation action tables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f38c6f86d1
commit
f0b5cd6b4e
6 files changed
+71
No files matched your search
@@ -1,6 +1,7 @@
|
||||
---
|
||||
type: perf
|
||||
area: electron
|
||||
highlight: Faster startup
|
||||
---
|
||||
|
||||
The desktop app now opens its window before it prepares the portal, program
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
type: feature
|
||||
area: settings
|
||||
screenshot: settings-search
|
||||
highlight: Search your settings
|
||||
---
|
||||
|
||||
|
||||
@@ -164,6 +164,36 @@ async function openSettingsEpg(page: Page): Promise<void> {
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings with a term typed into the header search, so the page shows the
|
||||
* ranked results list and the per-section match counts instead of a section.
|
||||
* The term lives only in the `q` query param: the next action's navigation
|
||||
* clears it, and nothing is staged in the settings form.
|
||||
*/
|
||||
async function openSettingsSearch(
|
||||
page: Page,
|
||||
term: string | null
|
||||
): Promise<void> {
|
||||
if (!term) {
|
||||
throw new Error('open-settings-search needs a term: open-settings-search=<term>');
|
||||
}
|
||||
|
||||
await openSettings(page);
|
||||
await page
|
||||
.locator('app-workspace-shell-header input[type="search"]')
|
||||
.fill(term, { timeout: 10_000 });
|
||||
await page.waitForURL(/\/workspace\/settings\/general\?q=/, {
|
||||
timeout: 15_000,
|
||||
});
|
||||
const results = page.locator('[data-test-id="settings-search-results"]');
|
||||
await results.waitFor({ state: 'visible', timeout: 15_000 });
|
||||
await results
|
||||
.locator('[data-test-id^="settings-search-result-"]')
|
||||
.first()
|
||||
.waitFor({ state: 'visible', timeout: 10_000 });
|
||||
await settleUi(page);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Remote control (guide shots) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -301,6 +331,7 @@ export const SETUP_ACTIONS: Readonly<Record<string, CaptureAction>> = {
|
||||
'open-add-playlist-stalker': openAddPlaylistStalker,
|
||||
'open-add-playlist-m3u-url': openAddPlaylistM3uUrl,
|
||||
'open-settings-epg': openSettingsEpg,
|
||||
'open-settings-search': openSettingsSearch,
|
||||
'open-settings-tmdb': openSettingsTmdb,
|
||||
'open-settings-remote-control': openSettingsRemoteControl,
|
||||
'enable-remote-control': enableRemoteControl,
|
||||
|
||||
@@ -70,6 +70,7 @@ export const KNOWN_ACTIONS = [
|
||||
'open-m3u-channel-menu',
|
||||
'open-epg-mapping-dialog',
|
||||
'open-settings-tmdb',
|
||||
'open-settings-search',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
snapshotDatabaseState,
|
||||
stubbedResponseFor,
|
||||
DEFAULT_SHOT_GROUP,
|
||||
KNOWN_ACTIONS,
|
||||
FICTIONAL_STALKER_MAC,
|
||||
outputDirectoryFor,
|
||||
shotGroup,
|
||||
@@ -81,6 +82,35 @@ describe('manifest validation', () => {
|
||||
assert.deepEqual(validateManifest(validManifest()), []);
|
||||
});
|
||||
|
||||
it('accepts the committed screenshots.manifest.json', () => {
|
||||
const manifest = JSON.parse(
|
||||
readFileSync(new URL('./screenshots.manifest.json', import.meta.url), 'utf8')
|
||||
);
|
||||
|
||||
assert.deepEqual(validateManifest(manifest), []);
|
||||
});
|
||||
|
||||
it('knows exactly the setup actions the capture navigation dispatches', () => {
|
||||
// The dispatcher is TypeScript and cannot be imported here, so read
|
||||
// the action tables' keys from source: an action added on one side
|
||||
// only would fail the manifest check or the capture run.
|
||||
const dir = new URL('./', import.meta.url);
|
||||
const dispatched = readdirSync(dir)
|
||||
.filter((name) => /^capture-navigation-.+-actions\.ts$/.test(name))
|
||||
.flatMap((name) => {
|
||||
const source = readFileSync(new URL(name, dir), 'utf8');
|
||||
const table = source.match(
|
||||
/_ACTIONS: Readonly<Record<string, CaptureAction>> = \{([^}]*)\}/
|
||||
);
|
||||
assert.ok(table, `${name} exports no action table`);
|
||||
return [...table[1].matchAll(/'([a-z0-9-]+)':/g)].map(
|
||||
([, action]) => action
|
||||
);
|
||||
});
|
||||
|
||||
assert.deepEqual([...dispatched].sort(), [...KNOWN_ACTIONS].sort());
|
||||
});
|
||||
|
||||
it('rejects unknown setup actions, bad slugs and duplicates', () => {
|
||||
const manifest = validManifest();
|
||||
manifest.shots.push(
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
"open-settings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "settings-search",
|
||||
"title": "Settings search results",
|
||||
"setup": [
|
||||
"open-settings-search=player"
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "xtream-vod-details",
|
||||
"title": "Movie details",
|
||||
|
||||
Reference in new issue
Block a user