Add private chat to multiplayer rooms

This commit is contained in:
2026-10-08 10:22:19 +05:00
parent 1307436e65
commit 36e8d11eb4
14 changed files with 810 additions and 4 deletions

View File

@@ -57,6 +57,7 @@ try {
waitUntil: "domcontentloaded",
timeout: 60000,
});
await expect(friend.getByRole("button", { name: /^Chat/ })).toHaveCount(0);
await friend.getByLabel("Your player name").fill("Browser Friend");
await friend.getByRole("button", { name: "Join room", exact: true }).click();
await expect(
@@ -67,6 +68,29 @@ try {
await expect(
host.getByRole("button", { name: "Start multiplayer match", exact: true }),
).toBeEnabled({ timeout: 20000 });
await host.getByRole("button", { name: /^Chat/ }).click();
await host
.getByLabel("Message", { exact: true })
.fill("Hello from the lobby (: <script>window.chatInjected=true</script>");
await host.getByRole("button", { name: "Send message", exact: true }).click();
await expect(host.getByRole("log")).toContainText("Hello from the lobby");
await expect(friend.locator(".room-chat-unread")).toHaveText("1", {
timeout: 15000,
});
await friend.getByRole("button", { name: /^Chat/ }).click();
await expect(friend.getByRole("log")).toContainText("Hello from the lobby");
assert.equal(
await friend.evaluate(() => window.chatInjected),
undefined,
"chat renders HTML as plain text",
);
await friend
.getByLabel("Message", { exact: true })
.fill("Привет с телефона!");
await friend.getByLabel("Message", { exact: true }).press("Enter");
await expect(host.getByRole("log")).toContainText("Привет с телефона!", {
timeout: 15000,
});
fs.mkdirSync("artifacts/multiplayer", { recursive: true });
await host.screenshot({
path: "artifacts/multiplayer/desktop-lobby.png",
@@ -85,6 +109,11 @@ try {
await host
.getByRole("button", { name: "Start multiplayer match", exact: true })
.click();
await expect(friend.getByRole("log")).toContainText("Hello from the lobby", {
timeout: 15000,
});
await friend.getByRole("button", { name: "Close chat", exact: true }).click();
await host.getByRole("button", { name: "Close chat", exact: true }).click();
for (let round = 0; round < 5; round++) {
await Promise.all([
expect(host.locator(".game-info strong").first()).toHaveText(
@@ -107,6 +136,36 @@ try {
await expect(host.locator(".game-loading")).toHaveCount(0, {
timeout: 45000,
});
await host.getByRole("button", { name: /^Chat/ }).click();
await expect(host.getByRole("log")).toContainText("Привет с телефона!");
await host
.getByLabel("Message", { exact: true })
.fill("Good luck this round!");
await host
.getByRole("button", { name: "Send message", exact: true })
.click();
await expect(friend.locator(".room-chat-unread")).toHaveText("1", {
timeout: 15000,
});
await friend.getByRole("button", { name: /^Chat/ }).click();
await expect(friend.getByRole("log")).toContainText(
"Good luck this round!",
);
await friend.screenshot({
path: "artifacts/multiplayer/mobile-chat.png",
});
await host.screenshot({ path: "artifacts/multiplayer/desktop-chat.png" });
assert.ok(
await friend.evaluate(
() => document.documentElement.scrollWidth <= innerWidth,
),
"mobile chat fits the viewport",
);
await friend.getByLabel("Message", { exact: true }).press("Escape");
await expect(friend.getByRole("button", { name: /^Chat/ })).toBeFocused();
await host
.getByRole("button", { name: "Close chat", exact: true })
.click();
}
await friend
.getByRole("button", { name: "Open guess map", exact: true })
@@ -150,6 +209,17 @@ try {
friend.getByRole("heading", { name: "Final standings", exact: true }),
).toBeVisible({ timeout: 20000 });
assert.equal(await host.locator(".multiplayer-final tbody tr").count(), 2);
await friend.getByRole("button", { name: /^Chat/ }).click();
await friend
.getByLabel("Message", { exact: true })
.fill("GG, thanks for playing!");
await friend
.getByRole("button", { name: "Send message", exact: true })
.click();
await host.getByRole("button", { name: /^Chat/ }).click();
await expect(host.getByRole("log")).toContainText("GG, thanks for playing!", {
timeout: 15000,
});
await host.screenshot({
path: "artifacts/multiplayer/desktop-results.png",
fullPage: true,
@@ -166,7 +236,7 @@ try {
);
assert.deepEqual(pageErrors, []);
console.log(
"Desktop/mobile browser multiplayer passed: create, invite, join, reconnect, five shared rounds, map guesses, and final standings. No page errors.",
"Desktop/mobile browser multiplayer passed: lobby and in-game chat, unread badges, plain-text rendering, keyboard controls, reconnect, five shared rounds, map guesses, and final standings chat. No page errors.",
);
} finally {
await browser.close();