Constrain UI tests to disposable targets
This commit is contained in:
parent
1ef0b80415
commit
7c4f4ffe0d
3 changed files with 18 additions and 9 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# OPNsense WebGUI integration tests
|
||||
|
||||
These Playwright tests use a disposable OPNsense deployment. They create and delete NordVPN enrollment records and require `OPNSENSE_UI_TEST_ALLOW_MUTATION=1`.
|
||||
These Playwright tests use a disposable OPNsense deployment. They create and delete only entries containing the synthetic `UI_TEST_NETWORK` alias and require `OPNSENSE_UI_TEST_ALLOW_MUTATION=1`.
|
||||
|
||||
Start a QEMU fixture after building a package. The launcher needs a compatible OPNsense base image and transfer disk, neither of which is stored in this repository.
|
||||
|
||||
|
|
@ -22,3 +22,5 @@ sh -c 'cd tests/ui && pnpm install --frozen-lockfile && pnpm test'
|
|||
```
|
||||
|
||||
The suite mocks only the countries API response with synthetic values. It covers populated country options, failure-policy labels, native alias selectors, Add/Edit/Clone state restoration, and the selector menu/footer layout.
|
||||
|
||||
The browser target must be loopback by default. A remote disposable deployment requires `OPNSENSE_UI_TEST_ALLOW_REMOTE=1` and a trusted TLS certificate.
|
||||
|
|
|
|||
|
|
@ -6,13 +6,20 @@ if (!baseURL) {
|
|||
throw new Error('Set OPNSENSE_UI_BASE_URL to the disposable OPNsense WebGUI URL.');
|
||||
}
|
||||
|
||||
const hostname = new URL(baseURL).hostname;
|
||||
const isLoopback = ['127.0.0.1', '::1', '[::1]', 'localhost'].includes(hostname);
|
||||
|
||||
if (!isLoopback && process.env.OPNSENSE_UI_TEST_ALLOW_REMOTE !== '1') {
|
||||
throw new Error('Set OPNSENSE_UI_TEST_ALLOW_REMOTE=1 to test a remote disposable OPNsense deployment.');
|
||||
}
|
||||
|
||||
module.exports = defineConfig({
|
||||
testDir: './specs',
|
||||
timeout: 30000,
|
||||
workers: 1,
|
||||
use: {
|
||||
baseURL,
|
||||
ignoreHTTPSErrors: true,
|
||||
ignoreHTTPSErrors: isLoopback,
|
||||
trace: 'retain-on-failure',
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -50,13 +50,13 @@ test('renders and preserves NordVPN enrollment controls', async ({ page }) => {
|
|||
await expect(failurePolicy.locator('option[value="fail_open"]')).toHaveText('Use direct egress');
|
||||
|
||||
const grid = page.getByRole('grid');
|
||||
const deleteButtons = grid.getByRole('button', { name: 'Delete', exact: true });
|
||||
while (await deleteButtons.count()) {
|
||||
const before = await deleteButtons.count();
|
||||
await deleteButtons.first().click();
|
||||
const testRows = grid.getByRole('row').filter({ hasText: 'UI_TEST_NETWORK' });
|
||||
while (await testRows.count()) {
|
||||
const before = await testRows.count();
|
||||
await testRows.first().getByRole('button', { name: 'Delete' }).click();
|
||||
const removal = page.getByRole('dialog', { name: 'Remove' });
|
||||
await removal.getByRole('button', { name: 'Yes' }).click();
|
||||
await expect(deleteButtons).toHaveCount(before - 1);
|
||||
await expect(testRows).toHaveCount(before - 1);
|
||||
}
|
||||
|
||||
await page.getByRole('button', { name: 'Add', exact: true }).click();
|
||||
|
|
@ -104,12 +104,12 @@ test('renders and preserves NordVPN enrollment controls', async ({ page }) => {
|
|||
await dialog.getByRole('button', { name: 'Close' }).click();
|
||||
await expect(dialog).toBeHidden();
|
||||
|
||||
const beforeDelete = await deleteButtons.count();
|
||||
const beforeDelete = await testRows.count();
|
||||
await row.getByRole('button', { name: 'Delete' }).click();
|
||||
const removal = page.getByRole('dialog', { name: 'Remove' });
|
||||
await expect(removal).toBeVisible();
|
||||
await removal.getByRole('button', { name: 'Yes' }).click();
|
||||
await expect(deleteButtons).toHaveCount(beforeDelete - 1);
|
||||
await expect(testRows).toHaveCount(beforeDelete - 1);
|
||||
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue