feat: dashboard

This commit is contained in:
2026-06-05 01:25:16 +02:00
parent 147858de2f
commit 2f6c52e73c
73 changed files with 3490 additions and 1061 deletions

View File

@@ -7,72 +7,71 @@ import {
export class ServerSearchPage {
readonly searchInput: Locator;
readonly createServerButton: Locator;
readonly railCreateServerButton: Locator;
readonly searchCreateServerButton: Locator;
readonly railDashboardButton: Locator;
readonly settingsButton: Locator;
// Create server dialog
// Create server page
readonly serverNameInput: Locator;
readonly serverDescriptionInput: Locator;
readonly serverTopicInput: Locator;
readonly signalEndpointSelect: Locator;
readonly advancedSettingsToggle: Locator;
readonly privateCheckbox: Locator;
readonly serverPasswordInput: Locator;
readonly dialogCreateButton: Locator;
readonly dialogCancelButton: Locator;
readonly createSubmitButton: Locator;
readonly cancelButton: Locator;
constructor(private page: Page) {
this.searchInput = page.getByPlaceholder('Search servers and users...');
this.railCreateServerButton = page.locator('button[title="Create Server"]');
this.searchCreateServerButton = page.getByRole('button', { name: 'Create New Server' });
this.createServerButton = this.searchCreateServerButton;
// Server discovery lives on /servers via <app-server-browser>.
this.searchInput = page.getByPlaceholder('Search servers...');
this.railDashboardButton = page.locator('button[title="Dashboard"]');
// Dashboard "Create Server" entry point.
this.createServerButton = page.getByRole('link', { name: 'Create Server' }).first();
this.settingsButton = page.locator('button[title="Settings"]');
// Create dialog elements
// Create-server page elements.
this.serverNameInput = page.locator('#create-server-name');
this.serverDescriptionInput = page.locator('#create-server-description');
this.serverTopicInput = page.locator('#create-server-topic');
this.signalEndpointSelect = page.locator('#create-server-signal-endpoint');
this.privateCheckbox = page.locator('#private');
this.advancedSettingsToggle = page.getByRole('button', { name: 'Advanced settings' });
this.privateCheckbox = page.locator('#create-server-private');
this.serverPasswordInput = page.locator('#create-server-password');
this.dialogCreateButton = page.locator('div[role="dialog"]').getByRole('button', { name: 'Create' });
this.dialogCancelButton = page.locator('div[role="dialog"]').getByRole('button', { name: 'Cancel' });
this.createSubmitButton = page.locator('#create-server-submit');
this.cancelButton = page.locator('#create-server-cancel');
}
async goto() {
await this.page.goto('/search');
await this.page.goto('/servers');
}
async createServer(name: string, options?: { description?: string; topic?: string; sourceId?: string }) {
if (!await this.serverNameInput.isVisible()) {
if (await this.searchCreateServerButton.isVisible()) {
await this.searchCreateServerButton.click();
} else {
await this.railCreateServerButton.click();
await this.page.goto('/create-server', { waitUntil: 'domcontentloaded' });
if (!await this.serverNameInput.isVisible()) {
await expect(this.searchCreateServerButton).toBeVisible({ timeout: 10_000 });
await this.searchCreateServerButton.click();
}
}
}
await expect(this.serverNameInput).toBeVisible();
await expect(this.serverNameInput).toBeVisible({ timeout: 10_000 });
await this.serverNameInput.fill(name);
if (options?.description) {
await this.serverDescriptionInput.fill(options.description);
}
if (options?.topic) {
await this.serverTopicInput.fill(options.topic);
if (options?.topic || options?.sourceId) {
if (!await this.serverTopicInput.isVisible()) {
await this.advancedSettingsToggle.click();
}
await expect(this.serverTopicInput).toBeVisible({ timeout: 10_000 });
if (options?.topic) {
await this.serverTopicInput.fill(options.topic);
}
if (options?.sourceId) {
await this.signalEndpointSelect.selectOption(options.sourceId);
}
}
if (options?.sourceId) {
await this.signalEndpointSelect.selectOption(options.sourceId);
}
await this.dialogCreateButton.click();
await this.createSubmitButton.click();
}
async joinSavedRoom(name: string) {
@@ -80,6 +79,8 @@ export class ServerSearchPage {
}
async joinServerFromSearch(name: string, options: { acceptPluginDownloads?: boolean } = {}) {
await this.page.goto('/servers', { waitUntil: 'domcontentloaded' });
await expect(this.searchInput).toBeVisible({ timeout: 15_000 });
await this.searchInput.fill(name);
const serverCard = this.page.locator('div[title]', { hasText: name }).first();