feat: Add user statuses and cards
This commit is contained in:
@@ -3,7 +3,7 @@ import { type BrowserContext, type Page } from '@playwright/test';
|
||||
const SERVER_ENDPOINTS_STORAGE_KEY = 'metoyou_server_endpoints';
|
||||
const REMOVED_DEFAULT_KEYS_STORAGE_KEY = 'metoyou_removed_default_server_keys';
|
||||
|
||||
type SeededEndpointStorageState = {
|
||||
interface SeededEndpointStorageState {
|
||||
key: string;
|
||||
removedKey: string;
|
||||
endpoints: {
|
||||
@@ -14,7 +14,7 @@ type SeededEndpointStorageState = {
|
||||
isDefault: boolean;
|
||||
status: string;
|
||||
}[];
|
||||
};
|
||||
}
|
||||
|
||||
function buildSeededEndpointStorageState(
|
||||
port: number = Number(process.env.TEST_SERVER_PORT) || 3099
|
||||
@@ -40,7 +40,11 @@ function applySeededEndpointStorageState(storageState: SeededEndpointStorageStat
|
||||
const storage = window.localStorage;
|
||||
|
||||
storage.setItem(storageState.key, JSON.stringify(storageState.endpoints));
|
||||
storage.setItem(storageState.removedKey, JSON.stringify(['default', 'toju-primary', 'toju-sweden']));
|
||||
storage.setItem(storageState.removedKey, JSON.stringify([
|
||||
'default',
|
||||
'toju-primary',
|
||||
'toju-sweden'
|
||||
]));
|
||||
} catch {
|
||||
// about:blank and some Playwright UI pages deny localStorage access.
|
||||
}
|
||||
@@ -59,7 +63,7 @@ export async function installTestServerEndpoint(
|
||||
* Seed localStorage with a single signal endpoint pointing at the test server.
|
||||
* Must be called AFTER navigating to the app origin (localStorage is per-origin)
|
||||
* but BEFORE the app reads from storage (i.e. before the Angular bootstrap is
|
||||
* relied upon — calling it in the first goto() landing page is fine since the
|
||||
* relied upon - calling it in the first goto() landing page is fine since the
|
||||
* page will re-read on next navigation/reload).
|
||||
*
|
||||
* Typical usage:
|
||||
|
||||
@@ -4,11 +4,11 @@ import {
|
||||
type Page
|
||||
} from '@playwright/test';
|
||||
|
||||
export type ChatDropFilePayload = {
|
||||
export interface ChatDropFilePayload {
|
||||
name: string;
|
||||
mimeType: string;
|
||||
base64: string;
|
||||
};
|
||||
}
|
||||
|
||||
export class ChatMessagesPage {
|
||||
readonly composer: Locator;
|
||||
@@ -115,7 +115,8 @@ export class ChatMessagesPage {
|
||||
getEmbedCardByTitle(title: string): Locator {
|
||||
return this.page.locator('app-chat-link-embed').filter({
|
||||
has: this.page.getByText(title, { exact: true })
|
||||
}).last();
|
||||
})
|
||||
.last();
|
||||
}
|
||||
|
||||
async editOwnMessage(originalText: string, updatedText: string): Promise<void> {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { expect, type Page, type Locator } from '@playwright/test';
|
||||
import {
|
||||
expect,
|
||||
type Page,
|
||||
type Locator
|
||||
} from '@playwright/test';
|
||||
|
||||
export class RegisterPage {
|
||||
readonly usernameInput: Locator;
|
||||
|
||||
@@ -13,7 +13,7 @@ export default defineConfig({
|
||||
trace: 'on-first-retry',
|
||||
screenshot: 'only-on-failure',
|
||||
video: 'on-first-retry',
|
||||
actionTimeout: 15_000,
|
||||
actionTimeout: 15_000
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
@@ -22,18 +22,15 @@ export default defineConfig({
|
||||
...devices['Desktop Chrome'],
|
||||
permissions: ['microphone', 'camera'],
|
||||
launchOptions: {
|
||||
args: [
|
||||
'--use-fake-device-for-media-stream',
|
||||
'--use-fake-ui-for-media-stream',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
args: ['--use-fake-device-for-media-stream', '--use-fake-ui-for-media-stream']
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
webServer: {
|
||||
command: 'cd ../toju-app && npx ng serve',
|
||||
port: 4200,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
timeout: 120_000,
|
||||
},
|
||||
timeout: 120_000
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { type Page } from '@playwright/test';
|
||||
import { test, expect, type Client } from '../../fixtures/multi-client';
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
type Client
|
||||
} from '../../fixtures/multi-client';
|
||||
import { RegisterPage } from '../../pages/register.page';
|
||||
import { ServerSearchPage } from '../../pages/server-search.page';
|
||||
import { ChatRoomPage } from '../../pages/chat-room.page';
|
||||
import {
|
||||
ChatMessagesPage,
|
||||
type ChatDropFilePayload
|
||||
} from '../../pages/chat-messages.page';
|
||||
import { ChatMessagesPage, type ChatDropFilePayload } from '../../pages/chat-messages.page';
|
||||
|
||||
const MOCK_EMBED_URL = 'https://example.test/mock-embed';
|
||||
const MOCK_EMBED_TITLE = 'Mock Embed Title';
|
||||
@@ -133,14 +134,14 @@ test.describe('Chat messaging features', () => {
|
||||
});
|
||||
});
|
||||
|
||||
type ChatScenario = {
|
||||
interface ChatScenario {
|
||||
alice: Client;
|
||||
bob: Client;
|
||||
aliceRoom: ChatRoomPage;
|
||||
bobRoom: ChatRoomPage;
|
||||
aliceMessages: ChatMessagesPage;
|
||||
bobMessages: ChatMessagesPage;
|
||||
};
|
||||
}
|
||||
|
||||
async function createChatScenario(createClient: () => Promise<Client>): Promise<ChatScenario> {
|
||||
const suffix = uniqueName('chat');
|
||||
@@ -170,6 +171,7 @@ async function createChatScenario(createClient: () => Promise<Client>): Promise<
|
||||
aliceCredentials.displayName,
|
||||
aliceCredentials.password
|
||||
);
|
||||
|
||||
await expect(alice.page).toHaveURL(/\/search/, { timeout: 15_000 });
|
||||
|
||||
await bobRegisterPage.goto();
|
||||
@@ -178,6 +180,7 @@ async function createChatScenario(createClient: () => Promise<Client>): Promise<
|
||||
bobCredentials.displayName,
|
||||
bobCredentials.password
|
||||
);
|
||||
|
||||
await expect(bob.page).toHaveURL(/\/search/, { timeout: 15_000 });
|
||||
|
||||
const aliceSearchPage = new ServerSearchPage(alice.page);
|
||||
@@ -185,6 +188,7 @@ async function createChatScenario(createClient: () => Promise<Client>): Promise<
|
||||
await aliceSearchPage.createServer(serverName, {
|
||||
description: 'E2E chat server for messaging feature coverage'
|
||||
});
|
||||
|
||||
await expect(alice.page).toHaveURL(/\/room\//, { timeout: 15_000 });
|
||||
|
||||
const bobSearchPage = new ServerSearchPage(bob.page);
|
||||
@@ -259,6 +263,7 @@ async function installChatFeatureMocks(page: Page): Promise<void> {
|
||||
siteName: 'Mock Docs'
|
||||
})
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,5 +296,6 @@ function buildMockSvgMarkup(label: string): string {
|
||||
}
|
||||
|
||||
function uniqueName(prefix: string): string {
|
||||
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
return `${prefix}-${Date.now()}-${Math.random().toString(36)
|
||||
.slice(2, 8)}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user