first commit
This commit is contained in:
229
tests/e2e/features/governance/pages/governance.page.ts
Normal file
229
tests/e2e/features/governance/pages/governance.page.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
import { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '../../../core/fixtures/base.fixture'
|
||||
import { BasePage } from '../../../core/pages/base.page'
|
||||
import { fillSelect, waitForNetworkIdle } from '../../../core/utils/test-helpers'
|
||||
|
||||
export interface TeamConfig {
|
||||
name: string
|
||||
/** Assign by customer id (from API). Prefer customerName for UI-only flow. */
|
||||
customerId?: string
|
||||
/** Assign by customer name in the create-team dropdown (UI-only, no API). */
|
||||
customerName?: string
|
||||
budget?: { maxLimit: number; resetDuration?: string }
|
||||
rateLimit?: {
|
||||
tokenMaxLimit?: number
|
||||
tokenResetDuration?: string
|
||||
requestMaxLimit?: number
|
||||
requestResetDuration?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface CustomerConfig {
|
||||
name: string
|
||||
budget?: { maxLimit: number; resetDuration?: string }
|
||||
rateLimit?: {
|
||||
tokenMaxLimit?: number
|
||||
tokenResetDuration?: string
|
||||
requestMaxLimit?: number
|
||||
requestResetDuration?: string
|
||||
}
|
||||
}
|
||||
|
||||
export class GovernancePage extends BasePage {
|
||||
// Teams
|
||||
readonly teamsCreateBtn: Locator
|
||||
readonly teamsTable: Locator
|
||||
readonly teamDialog: Locator
|
||||
readonly teamNameInput: Locator
|
||||
|
||||
// Customers
|
||||
readonly customersCreateBtn: Locator
|
||||
readonly customersTable: Locator
|
||||
readonly customerDialog: Locator
|
||||
readonly customerNameInput: Locator
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page)
|
||||
|
||||
this.teamsCreateBtn = page.getByTestId('create-team-btn').or(page.getByTestId('team-button-add'))
|
||||
this.teamsTable = page.getByTestId('teams-table')
|
||||
this.teamDialog = page.getByTestId('team-dialog-content')
|
||||
this.teamNameInput = page.getByTestId('team-name-input')
|
||||
|
||||
this.customersCreateBtn = page.getByTestId('customer-button-create')
|
||||
this.customersTable = page.getByTestId('customer-table-container')
|
||||
this.customerDialog = page.getByTestId('customer-dialog-content')
|
||||
this.customerNameInput = page.getByTestId('customer-name-input')
|
||||
}
|
||||
|
||||
async gotoTeams(): Promise<void> {
|
||||
await this.page.goto('/workspace/governance/teams')
|
||||
await waitForNetworkIdle(this.page)
|
||||
}
|
||||
|
||||
async gotoCustomers(): Promise<void> {
|
||||
await this.page.goto('/workspace/governance/customers')
|
||||
await waitForNetworkIdle(this.page)
|
||||
}
|
||||
|
||||
getTeamRow(name: string): Locator {
|
||||
return this.page.getByTestId(`team-row-${name}`)
|
||||
}
|
||||
|
||||
/** Customer cell for a team row (use for asserting assigned customer in UI). */
|
||||
getTeamRowCustomerCell(teamName: string): Locator {
|
||||
return this.page.getByTestId(`team-row-${teamName}-customer`)
|
||||
}
|
||||
|
||||
async teamExists(name: string): Promise<boolean> {
|
||||
const row = this.getTeamRow(name)
|
||||
return (await row.count()) > 0
|
||||
}
|
||||
|
||||
async createTeam(config: TeamConfig): Promise<void> {
|
||||
await this.teamsCreateBtn.click()
|
||||
await expect(this.teamDialog).toBeVisible({ timeout: 5000 })
|
||||
await this.waitForSheetAnimation()
|
||||
|
||||
await this.teamNameInput.fill(config.name)
|
||||
|
||||
if (config.customerId !== undefined || config.customerName !== undefined) {
|
||||
const trigger = this.page.getByTestId('team-customer-select-trigger')
|
||||
await trigger.click()
|
||||
if (config.customerId === '') {
|
||||
await this.page.getByTestId('team-customer-option-none').click()
|
||||
} else if (config.customerName !== undefined) {
|
||||
const customerOption = this.page
|
||||
.locator('[data-testid^="team-customer-option-"]')
|
||||
.filter({ hasText: config.customerName })
|
||||
await customerOption.waitFor({ state: 'visible', timeout: 5000 })
|
||||
await customerOption.click()
|
||||
} else if (config.customerId !== undefined && config.customerId !== '') {
|
||||
const customerOption = this.page.getByTestId(`team-customer-option-${config.customerId}`)
|
||||
await customerOption.waitFor({ state: 'visible', timeout: 5000 })
|
||||
await customerOption.click()
|
||||
}
|
||||
}
|
||||
|
||||
if (config.budget?.maxLimit !== undefined) {
|
||||
const budgetInput = this.page.getByTestId('budget-max-limit-input')
|
||||
await budgetInput.fill(String(config.budget.maxLimit))
|
||||
}
|
||||
|
||||
const saveBtn = this.teamDialog.getByRole('button', { name: /Create Team/i })
|
||||
await expect(saveBtn).toBeEnabled()
|
||||
await saveBtn.click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect(this.teamDialog).not.toBeVisible({ timeout: 10000 })
|
||||
}
|
||||
|
||||
async deleteTeam(name: string): Promise<void> {
|
||||
const deleteBtn = this.page.getByTestId(`team-delete-btn-${name}`)
|
||||
await deleteBtn.click()
|
||||
|
||||
const confirmDialog = this.page.locator('[role="alertdialog"]')
|
||||
await confirmDialog.getByRole('button', { name: /Delete/i }).click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect.poll(() => this.teamExists(name), { timeout: 10000 }).toBe(false)
|
||||
}
|
||||
|
||||
async closeTeamDialog(): Promise<void> {
|
||||
if (await this.teamDialog.isVisible().catch(() => false)) {
|
||||
await this.teamDialog.getByRole('button', { name: /Cancel/i }).click()
|
||||
await expect(this.teamDialog).not.toBeVisible({ timeout: 10000 })
|
||||
}
|
||||
}
|
||||
|
||||
getCustomerRow(name: string): Locator {
|
||||
return this.customersTable.getByTestId(`customer-row-${name}`)
|
||||
}
|
||||
|
||||
async customerExists(name: string): Promise<boolean> {
|
||||
const row = this.getCustomerRow(name)
|
||||
return (await row.count()) > 0
|
||||
}
|
||||
|
||||
async createCustomer(config: CustomerConfig): Promise<void> {
|
||||
await this.customersCreateBtn.click()
|
||||
await expect(this.customerDialog).toBeVisible({ timeout: 5000 })
|
||||
await this.waitForSheetAnimation()
|
||||
|
||||
await this.customerNameInput.fill(config.name)
|
||||
|
||||
if (config.budget?.maxLimit !== undefined) {
|
||||
const budgetInput = this.page.getByTestId('budget-max-limit-input')
|
||||
await budgetInput.fill(String(config.budget.maxLimit))
|
||||
}
|
||||
|
||||
const saveBtn = this.customerDialog.getByRole('button', { name: /Create Customer/i })
|
||||
await expect(saveBtn).toBeEnabled()
|
||||
await saveBtn.click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect(this.customerDialog).not.toBeVisible({ timeout: 10000 })
|
||||
}
|
||||
|
||||
async deleteCustomer(name: string): Promise<void> {
|
||||
const row = this.getCustomerRow(name)
|
||||
const deleteBtn = row.locator('[data-testid^="customer-button-delete-"]')
|
||||
await deleteBtn.click()
|
||||
|
||||
const confirmBtn = this.page.getByTestId('customer-button-delete-confirm')
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 5000 })
|
||||
await confirmBtn.click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect.poll(() => this.customerExists(name), { timeout: 10000 }).toBe(false)
|
||||
}
|
||||
|
||||
async editTeam(name: string, updates: Partial<TeamConfig>): Promise<void> {
|
||||
const editBtn = this.page.getByTestId(`team-edit-btn-${name}`)
|
||||
await editBtn.click()
|
||||
await expect(this.teamDialog).toBeVisible({ timeout: 5000 })
|
||||
await this.waitForSheetAnimation()
|
||||
|
||||
if (updates.name) {
|
||||
await this.teamNameInput.clear()
|
||||
await this.teamNameInput.fill(updates.name)
|
||||
}
|
||||
|
||||
if (updates.customerId !== undefined) {
|
||||
const trigger = this.page.getByTestId('team-customer-select-trigger')
|
||||
await trigger.click()
|
||||
if (updates.customerId === '') {
|
||||
await this.page.getByTestId('team-customer-option-none').click()
|
||||
} else {
|
||||
await this.page.getByTestId(`team-customer-option-${updates.customerId}`).click()
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.budget?.maxLimit !== undefined) {
|
||||
const budgetInput = this.page.getByTestId('budget-max-limit-input')
|
||||
await budgetInput.clear()
|
||||
await budgetInput.fill(String(updates.budget.maxLimit))
|
||||
}
|
||||
|
||||
const saveBtn = this.teamDialog.getByRole('button', { name: /Save|Update/i })
|
||||
await expect(saveBtn).toBeEnabled()
|
||||
await saveBtn.click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect(this.teamDialog).not.toBeVisible({ timeout: 10000 })
|
||||
}
|
||||
|
||||
async editCustomer(name: string, updates: Partial<CustomerConfig>): Promise<void> {
|
||||
const row = this.getCustomerRow(name)
|
||||
const editBtn = row.locator('[data-testid^="customer-button-edit-"]')
|
||||
await editBtn.click()
|
||||
await expect(this.customerDialog).toBeVisible({ timeout: 5000 })
|
||||
await this.waitForSheetAnimation()
|
||||
|
||||
if (updates.name) {
|
||||
await this.customerNameInput.clear()
|
||||
await this.customerNameInput.fill(updates.name)
|
||||
}
|
||||
|
||||
const saveBtn = this.customerDialog.getByRole('button', { name: /Save|Update/i })
|
||||
await expect(saveBtn).toBeEnabled()
|
||||
await saveBtn.click()
|
||||
await this.waitForSuccessToast()
|
||||
await expect(this.customerDialog).not.toBeVisible({ timeout: 10000 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user