Scope skills and memory to request profile
This commit is contained in:
+12
-11
@@ -8,37 +8,38 @@ test('redirects protected routes to the login screen without a token', async ({
|
||||
|
||||
await expect(page).toHaveURL(/#\/$/)
|
||||
await expect(page.getByRole('heading', { name: 'Hermes Web UI' })).toBeVisible()
|
||||
await expect(page.getByPlaceholder('Access token')).toBeVisible()
|
||||
await expect(page.getByPlaceholder('Username')).toBeVisible()
|
||||
await expect(page.getByPlaceholder('Password')).toBeVisible()
|
||||
expect(api.unexpectedRequests).toEqual([])
|
||||
})
|
||||
|
||||
test('rejects an invalid access token without persisting it', async ({ page }) => {
|
||||
test('rejects invalid credentials without persisting a token', async ({ page }) => {
|
||||
const api = await mockHermesApi(page, { tokenValidationStatus: 401 })
|
||||
|
||||
await page.goto('/')
|
||||
await page.getByPlaceholder('Access token').fill('bad-token')
|
||||
await page.getByPlaceholder('Username').fill('playwright')
|
||||
await page.getByPlaceholder('Password').fill('bad-password')
|
||||
await page.getByRole('button', { name: 'Login' }).click()
|
||||
|
||||
await expect(page.getByText('Invalid token')).toBeVisible()
|
||||
await expect(page.getByText('Invalid username or password')).toBeVisible()
|
||||
await expect(page).toHaveURL(/#\/$/)
|
||||
await expect(page.evaluate(() => window.localStorage.getItem('hermes_api_key'))).resolves.toBeNull()
|
||||
expect(api.unexpectedRequests).toEqual([])
|
||||
})
|
||||
|
||||
test('validates token login through the BFF before entering the app', async ({ page }) => {
|
||||
test('logs in with password through the BFF before entering the app', async ({ page }) => {
|
||||
const api = await mockHermesApi(page)
|
||||
|
||||
await page.goto('/')
|
||||
await page.getByPlaceholder('Access token').fill(TEST_ACCESS_KEY)
|
||||
await page.getByPlaceholder('Username').fill('playwright')
|
||||
await page.getByPlaceholder('Password').fill('correct-password')
|
||||
await page.getByRole('button', { name: 'Login' }).click()
|
||||
|
||||
await expect(page).toHaveURL(/#\/hermes\/chat$/)
|
||||
await expect(page.evaluate(() => window.localStorage.getItem('hermes_api_key'))).resolves.toBe(TEST_ACCESS_KEY)
|
||||
|
||||
const validationRequest = api.requests.find((request) => (
|
||||
request.pathname === '/api/hermes/sessions' &&
|
||||
request.headers.authorization === `Bearer ${TEST_ACCESS_KEY}`
|
||||
))
|
||||
expect(validationRequest).toBeTruthy()
|
||||
const loginRequest = api.requests.find((request) => request.pathname === '/api/auth/login')
|
||||
expect(loginRequest?.method).toBe('POST')
|
||||
expect(loginRequest?.postData).toBe(JSON.stringify({ username: 'playwright', password: 'correct-password' }))
|
||||
expect(api.unexpectedRequests).toEqual([])
|
||||
})
|
||||
|
||||
@@ -101,7 +101,7 @@ test('uses the newly selected profile for the next chat-run socket after profile
|
||||
await page.getByTestId('profile-selector-select').click()
|
||||
await expect(page.getByRole('dialog').filter({ hasText: 'research' })).toBeVisible()
|
||||
const reloadPromise = page.waitForEvent('framenavigated', frame => frame === page.mainFrame())
|
||||
await page.locator('.profile-runtime-item').filter({ hasText: /^research/ }).getByRole('button', { name: 'Switch Profile' }).click()
|
||||
await page.locator('.profile-runtime-item').filter({ hasText: /^research/ }).getByRole('button', { name: 'Switch Frontend Profile' }).click()
|
||||
await reloadPromise
|
||||
await page.waitForLoadState('domcontentloaded')
|
||||
await expect(page.getByTestId('profile-selector-select').filter({ hasText: 'research' })).toBeVisible()
|
||||
@@ -115,9 +115,7 @@ test('uses the newly selected profile for the next chat-run socket after profile
|
||||
expect(run.input).toBe('Use the active research profile')
|
||||
expect(await page.evaluate(() => window.localStorage.getItem('hermes_active_profile_name'))).toBe('research')
|
||||
|
||||
const switchRequest = api.requests.find((request) => request.pathname === '/api/hermes/profiles/active')
|
||||
expect(switchRequest?.method).toBe('PUT')
|
||||
expect(switchRequest?.postData).toBe(JSON.stringify({ name: 'research' }))
|
||||
expect(api.requests.some((request) => request.pathname === '/api/hermes/profiles/active')).toBe(false)
|
||||
expect(api.unexpectedRequests).toEqual([])
|
||||
})
|
||||
|
||||
|
||||
+30
-2
@@ -98,7 +98,35 @@ export async function mockHermesApi(page: Page, options: MockHermesApiOptions =
|
||||
}
|
||||
|
||||
if (pathname === '/api/auth/status') {
|
||||
await route.fulfill(jsonResponse({ hasPasswordLogin: false, username: null }))
|
||||
await route.fulfill(jsonResponse({ hasPasswordLogin: true, username: 'playwright' }))
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname === '/api/auth/login') {
|
||||
if (request.method() !== 'POST') {
|
||||
await route.fulfill(jsonResponse({ error: 'Method not allowed' }, 405))
|
||||
return
|
||||
}
|
||||
if (tokenValidationStatus !== 200) {
|
||||
await route.fulfill(jsonResponse({ error: 'Invalid username or password' }, tokenValidationStatus))
|
||||
return
|
||||
}
|
||||
await route.fulfill(jsonResponse({ token: TEST_ACCESS_KEY }))
|
||||
return
|
||||
}
|
||||
|
||||
if (pathname === '/api/auth/me') {
|
||||
await route.fulfill(jsonResponse({
|
||||
user: {
|
||||
id: 1,
|
||||
username: 'playwright',
|
||||
role: 'super_admin',
|
||||
status: 'active',
|
||||
created_at: 0,
|
||||
updated_at: 0,
|
||||
last_login_at: 0,
|
||||
},
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -234,7 +262,7 @@ export async function authenticate(page: Page, accessKey = TEST_ACCESS_KEY, prof
|
||||
await page.addInitScript((state: { storedToken: string; storedProfileName?: string }) => {
|
||||
const { storedToken, storedProfileName } = state
|
||||
window.localStorage.setItem('hermes_api_key', storedToken)
|
||||
if (storedProfileName) {
|
||||
if (storedProfileName && !window.localStorage.getItem('hermes_active_profile_name')) {
|
||||
window.localStorage.setItem('hermes_active_profile_name', storedProfileName)
|
||||
}
|
||||
}, { storedToken: accessKey, storedProfileName: profileName })
|
||||
|
||||
Reference in New Issue
Block a user