fix: multiple bug fixes
All checks were successful
Queue Release Build / prepare (push) Successful in 15s
Deploy Web Apps / deploy (push) Successful in 6m54s
Queue Release Build / build-windows (push) Successful in 16m6s
Queue Release Build / build-linux (push) Successful in 30m58s
Queue Release Build / finalize (push) Successful in 44s

isolated users, db backup, weird disconnect issues for long voice sessions,
This commit is contained in:
2026-04-24 22:19:57 +02:00
parent 44588e8789
commit 1656b8a17f
42 changed files with 1671 additions and 88 deletions

View File

@@ -18,6 +18,81 @@ const DELETED_MESSAGE_CONTENT = '[Message deleted]';
test.describe('Chat messaging features', () => {
test.describe.configure({ timeout: 180_000 });
test('shows per-server channel lists on first saved-server click', async ({ createClient }) => {
const scenario = await createSingleClientChatScenario(createClient);
const alphaServerName = `Alpha Server ${uniqueName('rail')}`;
const betaServerName = `Beta Server ${uniqueName('rail')}`;
const alphaChannelName = uniqueName('alpha-updates');
const betaChannelName = uniqueName('beta-plans');
const channelsPanel = scenario.room.channelsSidePanel;
await test.step('Create first saved server with a unique text channel', async () => {
await createServerAndOpenRoom(scenario.search, scenario.client.page, alphaServerName, 'Rail switch alpha server');
await scenario.room.ensureTextChannelExists(alphaChannelName);
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${alphaChannelName}"]`)
).toBeVisible({ timeout: 20_000 });
});
await test.step('Create second saved server with a different text channel', async () => {
await createServerAndOpenRoom(scenario.search, scenario.client.page, betaServerName, 'Rail switch beta server');
await scenario.room.ensureTextChannelExists(betaChannelName);
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${betaChannelName}"]`)
).toBeVisible({ timeout: 20_000 });
});
await test.step('Opening first server once restores only its channels', async () => {
await openSavedRoomByName(scenario.client.page, alphaServerName);
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${alphaChannelName}"]`)
).toBeVisible({ timeout: 20_000 });
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${betaChannelName}"]`)
).toHaveCount(0);
});
await test.step('Opening second server once restores only its channels', async () => {
await openSavedRoomByName(scenario.client.page, betaServerName);
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${betaChannelName}"]`)
).toBeVisible({ timeout: 20_000 });
await expect(
channelsPanel.locator(`button[data-channel-type="text"][data-channel-name="${alphaChannelName}"]`)
).toHaveCount(0);
});
});
test('shows local room history on first saved-server click', async ({ createClient }) => {
const scenario = await createSingleClientChatScenario(createClient);
const alphaServerName = `History Alpha ${uniqueName('rail')}`;
const betaServerName = `History Beta ${uniqueName('rail')}`;
const alphaMessage = `Alpha history message ${uniqueName('msg')}`;
const betaMessage = `Beta history message ${uniqueName('msg')}`;
await test.step('Create first server and send a local message', async () => {
await createServerAndOpenRoom(scenario.search, scenario.client.page, alphaServerName, 'Rail history alpha server');
await scenario.messages.sendMessage(alphaMessage);
await expect(scenario.messages.getMessageItemByText(alphaMessage)).toBeVisible({ timeout: 20_000 });
});
await test.step('Create second server and send a different local message', async () => {
await createServerAndOpenRoom(scenario.search, scenario.client.page, betaServerName, 'Rail history beta server');
await scenario.messages.sendMessage(betaMessage);
await expect(scenario.messages.getMessageItemByText(betaMessage)).toBeVisible({ timeout: 20_000 });
});
await test.step('Opening first server once restores its history immediately', async () => {
await openSavedRoomByName(scenario.client.page, alphaServerName);
await expect(scenario.messages.getMessageItemByText(alphaMessage)).toBeVisible({ timeout: 20_000 });
});
await test.step('Opening second server once restores its history immediately', async () => {
await openSavedRoomByName(scenario.client.page, betaServerName);
await expect(scenario.messages.getMessageItemByText(betaMessage)).toBeVisible({ timeout: 20_000 });
});
});
test('syncs messages in a newly created text channel', async ({ createClient }) => {
const scenario = await createChatScenario(createClient);
const channelName = uniqueName('updates');
@@ -143,6 +218,43 @@ interface ChatScenario {
bobMessages: ChatMessagesPage;
}
interface SingleClientChatScenario {
client: Client;
messages: ChatMessagesPage;
room: ChatRoomPage;
search: ServerSearchPage;
}
async function createSingleClientChatScenario(createClient: () => Promise<Client>): Promise<SingleClientChatScenario> {
const suffix = uniqueName('solo');
const client = await createClient();
const credentials = {
username: `solo_${suffix}`,
displayName: 'Solo',
password: 'TestPass123!'
};
await installChatFeatureMocks(client.page);
const registerPage = new RegisterPage(client.page);
await registerPage.goto();
await registerPage.register(
credentials.username,
credentials.displayName,
credentials.password
);
await expect(client.page).toHaveURL(/\/search/, { timeout: 15_000 });
return {
client,
messages: new ChatMessagesPage(client.page),
room: new ChatRoomPage(client.page),
search: new ServerSearchPage(client.page)
};
}
async function createChatScenario(createClient: () => Promise<Client>): Promise<ChatScenario> {
const suffix = uniqueName('chat');
const serverName = `Chat Server ${suffix}`;
@@ -217,6 +329,52 @@ async function createChatScenario(createClient: () => Promise<Client>): Promise<
};
}
async function createServerAndOpenRoom(
searchPage: ServerSearchPage,
page: Page,
serverName: string,
description: string
): Promise<void> {
await searchPage.createServer(serverName, { description });
await expect(page).toHaveURL(/\/room\//, { timeout: 15_000 });
await waitForCurrentRoomName(page, serverName);
}
async function openSavedRoomByName(page: Page, roomName: string): Promise<void> {
const roomButton = page.locator(`button[title="${roomName}"]`);
await expect(roomButton).toBeVisible({ timeout: 20_000 });
await roomButton.click();
await expect(page).toHaveURL(/\/room\//, { timeout: 20_000 });
await expect(page.locator('app-rooms-side-panel').first()).toBeVisible({ timeout: 20_000 });
await waitForCurrentRoomName(page, roomName);
}
async function waitForCurrentRoomName(page: Page, roomName: string, timeout = 20_000): Promise<void> {
await page.waitForFunction(
(expectedRoomName) => {
interface RoomShape { name?: string }
interface AngularDebugApi {
getComponent: (element: Element) => Record<string, unknown>;
}
const host = document.querySelector('app-rooms-side-panel');
const debugApi = (window as { ng?: AngularDebugApi }).ng;
if (!host || !debugApi?.getComponent) {
return false;
}
const component = debugApi.getComponent(host);
const currentRoom = (component['currentRoom'] as (() => RoomShape | null) | undefined)?.() ?? null;
return currentRoom?.name === expectedRoomName;
},
roomName,
{ timeout }
);
}
async function installChatFeatureMocks(page: Page): Promise<void> {
await page.route('**/api/klipy/config', async (route) => {
await route.fulfill({