Mining/ui/e2e/page-objects/main-layout.page.ts

113 lines
3.4 KiB
TypeScript

import { Page, Locator } from '@playwright/test';
export class MainLayoutPage {
readonly page: Page;
// Shadow DOM root
readonly shadowHost: Locator;
// Sidebar elements
readonly sidebar: Locator;
readonly sidebarLogo: Locator;
readonly collapseButton: Locator;
readonly workersNavBtn: Locator;
readonly graphsNavBtn: Locator;
readonly consoleNavBtn: Locator;
readonly poolsNavBtn: Locator;
readonly profilesNavBtn: Locator;
readonly minersNavBtn: Locator;
readonly miningStatus: Locator;
// Stats panel elements
readonly statsPanel: Locator;
readonly hashratestat: Locator;
readonly sharesStat: Locator;
readonly uptimeStat: Locator;
readonly poolStat: Locator;
readonly workersStat: Locator;
constructor(page: Page) {
this.page = page;
this.shadowHost = page.locator('snider-mining');
// Sidebar - use button role with exact name for navigation (to avoid matching "All Workers" in switcher)
this.sidebar = page.locator('app-sidebar');
this.sidebarLogo = page.locator('.logo-text');
this.collapseButton = page.locator('button.collapse-btn');
this.workersNavBtn = page.getByRole('button', { name: 'Workers', exact: true });
this.graphsNavBtn = page.getByRole('button', { name: 'Graphs', exact: true });
this.consoleNavBtn = page.getByRole('button', { name: 'Console', exact: true });
this.poolsNavBtn = page.getByRole('button', { name: 'Pools', exact: true });
this.profilesNavBtn = page.getByRole('button', { name: 'Profiles', exact: true });
this.minersNavBtn = page.getByRole('button', { name: 'Miners', exact: true });
this.miningStatus = page.getByText('Mining Active');
// Stats panel
this.statsPanel = page.locator('app-stats-panel');
this.hashratestat = page.getByText('H/s').first();
this.sharesStat = page.locator('.stat-card').nth(1);
this.uptimeStat = page.locator('.stat-card').nth(2);
this.poolStat = page.getByText('Not connected');
this.workersStat = page.locator('.stat-card').nth(4);
}
async goto() {
await this.page.goto('/');
await this.page.waitForLoadState('networkidle');
}
async waitForLayoutLoad() {
await this.shadowHost.waitFor({ state: 'visible' });
// Wait for either main layout or setup wizard
await this.page.waitForTimeout(1000);
}
async isMainLayoutVisible(): Promise<boolean> {
try {
const mainLayout = this.page.locator('app-main-layout');
return await mainLayout.isVisible({ timeout: 2000 });
} catch {
return false;
}
}
async navigateToWorkers() {
await this.workersNavBtn.click();
}
async navigateToGraphs() {
await this.graphsNavBtn.click();
}
async navigateToConsole() {
await this.consoleNavBtn.click();
}
async navigateToPools() {
await this.poolsNavBtn.click();
}
async navigateToProfiles() {
await this.profilesNavBtn.click();
}
async navigateToMiners() {
await this.minersNavBtn.click();
}
async toggleSidebarCollapse() {
await this.collapseButton.click();
}
async isSidebarCollapsed(): Promise<boolean> {
const sidebar = this.page.locator('.sidebar');
const classes = await sidebar.getAttribute('class');
return classes?.includes('collapsed') ?? false;
}
async getActiveNavItem(): Promise<string> {
const activeBtn = this.page.locator('.nav-item.active');
const label = activeBtn.locator('.nav-label');
return await label.textContent() ?? '';
}
}