59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
|
|
import { Page } from '@playwright/test';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Log in to LuCI with empty root password.
|
||
|
|
* Handles the "No password set" notification if it appears.
|
||
|
|
*/
|
||
|
|
export async function login(page: Page): Promise<void> {
|
||
|
|
await page.goto('/cgi-bin/luci');
|
||
|
|
// Wait for the JS framework to finish instantiating the login view.
|
||
|
|
await page.waitForFunction(() => {
|
||
|
|
const view = document.querySelector('#view');
|
||
|
|
return view && !view.querySelector('.spinning');
|
||
|
|
}, { timeout: 30_000, polling: 500 });
|
||
|
|
await page.waitForSelector('#luci_username', { state: 'visible', timeout: 30_000 });
|
||
|
|
await page.fill('#luci_username', 'root');
|
||
|
|
await page.fill('#luci_password', '');
|
||
|
|
await page.click('.cbi-button-positive');
|
||
|
|
// Wait for navigation into the admin overview.
|
||
|
|
await page.waitForURL(/\/cgi-bin\/luci\//, { timeout: 30_000 });
|
||
|
|
// LuCI admin page can take ~15s on first cold load; give it time to render.
|
||
|
|
await page.waitForFunction(() => {
|
||
|
|
const view = document.querySelector('#view');
|
||
|
|
return view && !view.querySelector('.spinning');
|
||
|
|
}, { timeout: 30_000, polling: 500 });
|
||
|
|
// Dismiss "No password set" modal/notification if present.
|
||
|
|
const closeBtn = page.locator('.alert-message .close, .alert-message button, [data-dismiss="alert"]').first();
|
||
|
|
try {
|
||
|
|
await closeBtn.click({ timeout: 2_000 });
|
||
|
|
} catch {
|
||
|
|
// No notification to dismiss.
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reset the active gateway back to amsterdam via direct ubus RPC.
|
||
|
|
*/
|
||
|
|
export async function resetToAmsterdam(page: Page): Promise<void> {
|
||
|
|
const loginRes = await page.request.post('/ubus', {
|
||
|
|
data: {
|
||
|
|
jsonrpc: '2.0',
|
||
|
|
id: 1,
|
||
|
|
method: 'call',
|
||
|
|
params: ['00000000000000000000000000000000', 'session', 'login', { username: 'root', password: '' }],
|
||
|
|
},
|
||
|
|
});
|
||
|
|
const loginData = await loginRes.json();
|
||
|
|
const token = loginData.result?.[1]?.ubus_rpc_session;
|
||
|
|
if (!token) throw new Error('ubus login failed');
|
||
|
|
|
||
|
|
await page.request.post('/ubus', {
|
||
|
|
data: {
|
||
|
|
jsonrpc: '2.0',
|
||
|
|
id: 2,
|
||
|
|
method: 'call',
|
||
|
|
params: [token, 'zt-gateway', 'switch', { region: 'amsterdam', mode: 'force' }],
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|