Files
tokens-reef/tests/e2e/pages/ApiKeysPage.ts
Developer 8b19f56ba4 fix: update E2E test API paths and payloads to match backend
- user-apikey-lifecycle: /api/v1/keys -> /api/v1/api-keys (24 occurrences)
- admin-users: balance payload uses balance+operation+notes
- admin-groups: rate-multiplier already uses correct format
2026-04-02 22:35:48 +08:00

73 lines
2.4 KiB
TypeScript

/**
* ApiKeysPage — Page Object for /keys (User API Key management)
*
* Provides typed helpers for interacting with the API Key management UI.
*/
import { Page, Locator, expect } from '@playwright/test';
export class ApiKeysPage {
readonly page: Page;
readonly table: Locator;
readonly createButton: Locator;
readonly createModal: Locator;
readonly keyNameField: Locator;
readonly saveButton: Locator;
/** The revealed API key value (shown once after creation). */
readonly revealedKeyValue: Locator;
constructor(page: Page) {
this.page = page;
this.table = page.locator('table, [class*="t-table"], [class*="table"]').first();
this.createButton = page.locator(
'button:has-text("Create"), button:has-text("New"), ' +
'button:has-text("新建"), button:has-text("创建")'
).first();
this.createModal = page.locator(
'[class*="t-dialog"], [class*="modal"], [role="dialog"]'
).first();
this.keyNameField = this.createModal.locator(
'input[name="name"], input[placeholder*="name" i], input[placeholder*="名称"]'
).first();
this.saveButton = this.createModal.locator(
'button[type="submit"], button:has-text("Create"), button:has-text("确认"), button:has-text("保存")'
).first();
// After creation the raw key is sometimes shown in a read-only input or code block
this.revealedKeyValue = page.locator(
'[class*="key-value"], [class*="api-key"] code, input[readonly][value^="sk-"]'
).first();
}
async goto() {
await this.page.goto('/keys', { waitUntil: 'networkidle' });
}
async expectTableVisible() {
await expect(this.table).toBeVisible({ timeout: 10_000 });
}
async openCreateModal() {
await this.createButton.click();
await expect(this.createModal).toBeVisible({ timeout: 5_000 });
}
async createKey(name: string) {
await this.openCreateModal();
await this.keyNameField.fill(name);
await this.saveButton.click();
// Wait for modal to close (key was created)
await expect(this.createModal).not.toBeVisible({ timeout: 10_000 });
}
rowWithText(text: string): Locator {
return this.table.locator(`tr:has-text("${text}")`);
}
/** Return the delete button within a specific table row. */
deleteButtonInRow(rowText: string): Locator {
return this.rowWithText(rowText).locator(
'button:has-text("Delete"), button:has-text("删除"), [class*="delete"]'
).first();
}
}