mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
fix(tools): capture the Xtream guide shot against the current connection test (#1807)
This commit is contained in:
1 parent
ef795e56bc
commit
7fd3d1dab0
5 files changed
+38
-17
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 418 KiB After Width: | Height: | Size: 417 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 407 KiB |
@@ -66,18 +66,21 @@ credentials. IPTVnator can read them out of the link for you, as shown below.
|
||||
'Open the Add playlist dialog. You will find the button on the dashboard, in the header playlist switcher, and in the command palette under "Add Xtream Codes playlist".',
|
||||
'Choose the "Xtream credentials" method.',
|
||||
'Fill in a playlist title of your choice, the server URL, the username and the password.',
|
||||
'Click "Test Connection". IPTVnator asks the portal for the account status and shows the result under the form.',
|
||||
'Click "Add". IPTVnator downloads the categories for live TV, movies and series and opens the new source.',
|
||||
'Click "Test HTTPS and HTTP". IPTVnator asks the portal for the account status and shows the result under the server URL. If an `https://` address refuses the connection or does not speak HTTPS, the test retries the same address over plain HTTP once, which is why the dialog warns that your username and password may travel unencrypted.',
|
||||
'Click "Add playlist". IPTVnator downloads the categories for live TV, movies and series and opens the new source.',
|
||||
]}
|
||||
/>
|
||||
|
||||

|
||||
|
||||
The connection test reports one of four states. **Connection successful! Portal is active** is
|
||||
the one you want. **Portal subscription has expired** and **Portal is inactive** mean the
|
||||
portal answered but refuses the account; check the subscription with your provider. **Could
|
||||
not connect to the portal** means no answer at all: a typo in the server URL, a wrong port, a
|
||||
missing `http://` or `https://`, or a host that is down.
|
||||
**Connected. The portal is active.** is the result you want; **Connected using HTTP** means the
|
||||
same over an unencrypted connection, after the HTTPS attempt failed and the server URL was
|
||||
switched to `http://`. **The subscription has expired** and **The account is inactive or the
|
||||
credentials are incorrect** mean the portal answered but refuses the account: check the
|
||||
credentials, then the subscription with your provider. **Could not reach the server** means no
|
||||
answer at all: a typo in the server URL, a wrong port, or a host that is down. The remaining
|
||||
messages name what went wrong instead: a failed secure connection, an HTTP error status, or a
|
||||
server that answered without valid account information.
|
||||
|
||||
<Alert type="success" title="Paste the whole link">
|
||||
If you paste a complete `get.php` or `player_api.php` link into the Server URL field while the
|
||||
|
||||
@@ -168,7 +168,11 @@ into `apps/website/public/blog/guides/screenshots/` instead of a release folder
|
||||
guard a release shot does; the add-playlist dialog shots fill the form with the
|
||||
mock's fictional `marketing` credentials and use a labeled hand-out for the
|
||||
Auto-detect method rather than a `get.php?username=…` link, because G4 rejects
|
||||
any URL carrying query credentials. Shots that walk into a Stalker portal
|
||||
any URL carrying query credentials. The Xtream shot clicks **Test HTTPS and
|
||||
HTTP** against the plain-`http://` mock, so no HTTPS probe is made, and fails
|
||||
the run unless the status line reports an active portal; the mock does not
|
||||
check passwords, so that verdict proves the scenario answered, not that the
|
||||
password is right. Shots that walk into a Stalker portal
|
||||
(`open-stalker-live`) make the run start the stalker-mock-server on port 3210
|
||||
and seed its `marketing-demo` portal as a third source, which is why they are
|
||||
never part of a release run. That scenario's MAC, `00:1A:79:00:00:07`, is the
|
||||
|
||||
@@ -63,17 +63,31 @@ async function openAddPlaylistXtream(page: Page): Promise<void> {
|
||||
await dialog.locator('#serverUrl').fill(XTREAM_MOCK_ORIGIN);
|
||||
await dialog.locator('#username').fill(XTREAM_FIXTURE_CREDENTIALS.username);
|
||||
await dialog.locator('#password').fill(XTREAM_FIXTURE_CREDENTIALS.password);
|
||||
// The status probe only talks to the local mock, so the frame can
|
||||
// show the successful "portal is active" verdict the guide explains.
|
||||
// The server URL is plain http://, so the probe never tries HTTPS and
|
||||
// only talks to the local mock; the frame can show the successful
|
||||
// "portal is active" verdict the guide explains.
|
||||
await dialog
|
||||
.getByRole('button', { name: /test connection/i })
|
||||
.first()
|
||||
.getByRole('button', { name: 'Test HTTPS and HTTP', exact: true })
|
||||
.click();
|
||||
const status = dialog.locator('.connection-status');
|
||||
await status.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
// The dialog body scrolls; bring the verdict the guide explains
|
||||
// into frame together with the credential fields above it.
|
||||
await status.scrollIntoViewIfNeeded();
|
||||
// The status line first reads "Testing connection…"; wait for the
|
||||
// verdict itself, so a refused account fails the shot instead of
|
||||
// publishing a frame that contradicts the guide.
|
||||
const status = dialog.getByRole('status');
|
||||
await status
|
||||
.filter({ hasText: /portal is active/i })
|
||||
.waitFor({ state: 'visible', timeout: 30_000 })
|
||||
.catch(async () => {
|
||||
const shown = await status
|
||||
.textContent({ timeout: 1_000 })
|
||||
.catch(() => null);
|
||||
throw new Error(
|
||||
`Xtream connection test did not report an active portal within 30s (status: ${shown?.trim() || 'none'})`
|
||||
);
|
||||
});
|
||||
// The dialog body scrolls. The verdict sits under the server URL,
|
||||
// above the credentials, so scrolling to the last field frames the
|
||||
// whole filled form together with the verdict the guide explains.
|
||||
await dialog.locator('#password').scrollIntoViewIfNeeded();
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user