lotr-sut/tests/e2e/steps/npc-chat.steps.ts
Fellowship Scholar f6a5823439 init commit
2026-03-29 20:07:56 +00:00

231 lines
8.5 KiB
TypeScript

import { Given, When, Then, expect } from '../fixtures/bdd-fixtures';
Given('I open the NPC chat panel', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
if (chatPanel && typeof chatPanel.open === 'function') {
await chatPanel.open();
}
await page.waitForTimeout(300);
});
Given('the chat initializes with {string}', async ({ page }, characterName: string) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter(characterName);
await page.waitForTimeout(500);
});
When('I select {string} from the character selector', async ({ page }, characterName: string) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter(characterName);
await page.waitForTimeout(500);
});
When('I send a message {string}', async ({ page }, message: string) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.sendMessage(message);
await page.waitForTimeout(500);
});
When('I send another message {string}', async ({ page }, message: string) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.sendMessage(message);
await page.waitForTimeout(500);
});
When('I click the reset conversation button', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
if (typeof chatPanel.resetConversation === 'function') {
await chatPanel.resetConversation();
await page.waitForTimeout(500);
}
});
When('I chat with {string}', async ({ page }, characterName: string) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter(characterName);
await page.waitForTimeout(500);
});
When('I chat with Frodo', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Frodo');
await page.waitForTimeout(500);
});
When('I chat with Sam', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Sam');
await page.waitForTimeout(500);
});
When('I chat with Gandalf', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Gandalf');
await page.waitForTimeout(500);
});
Then('the chat should initialize with {string}', async ({ page }, characterName: string) => {
const testContext = global.fixtures.testContext;
expect(testContext).toBeDefined();
});
Then('an opening message should appear from {string}', async ({ page }, _character: string) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThan(0);
});
Then('the opening message from {string} should be one of:', async ({ page }, _character: string) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
const firstMessage = messages[0];
expect(firstMessage).toBeDefined();
});
Then('I should receive another reply from {string}', async ({ page }, _character: string) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThanOrEqual(3);
const lastMessage = messages[messages.length - 1];
expect(lastMessage).toBeDefined();
});
Then('I should receive a reply from {string}', async ({ page }, _character: string) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThan(1);
const lastMessage = messages[messages.length - 1];
expect(lastMessage).toBeDefined();
});
Then('the conversation should flow coherently across multiple turns', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThanOrEqual(2);
for (const msg of messages) {
expect(msg.length).toBeGreaterThan(0);
}
});
Then('the NPC response should include a suggested action', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
// Last message should be from NPC and contain some suggested action text
expect(messages.length).toBeGreaterThan(0);
const lastMsg = messages[messages.length - 1];
expect(lastMsg).toBeDefined();
expect(lastMsg.length).toBeGreaterThan(0);
});
Then('the suggested action should point to a valid in-app route', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const actions = await chatPanel.getAvailableActions();
expect(actions.length).toBeGreaterThan(0);
});
Then('a fresh opening message should appear', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBe(1);
});
Then('the previous conversation history should be cleared', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeLessThanOrEqual(1);
});
When('Frodo responds to my message, the tone should be:', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Frodo');
await chatPanel.sendMessage('Hello');
await page.waitForTimeout(500);
const lastMessage = await chatPanel.getLastNPCMessage();
expect(lastMessage.length).toBeGreaterThan(0);
});
When('Sam responds to my message, the tone should be:', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Sam');
await chatPanel.sendMessage('Hello');
await page.waitForTimeout(500);
const lastMessage = await chatPanel.getLastNPCMessage();
expect(lastMessage.length).toBeGreaterThan(0);
});
When('Gandalf responds to my message, the tone should be:', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Gandalf');
await chatPanel.sendMessage('Hello');
await page.waitForTimeout(500);
const lastMessage = await chatPanel.getLastNPCMessage();
expect(lastMessage.length).toBeGreaterThan(0);
});
Given('the Azure AI service is unavailable', async ({ page }) => {
const testContext = global.fixtures.testContext;
(testContext as any).azureServiceUnavailable = true;
});
Given('the Azure service returns an out-of-character response', async ({ page }) => {
const testContext = global.fixtures.testContext;
(testContext as any).azureReturnsOOC = true;
});
Then('the chat should still function', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThan(0);
});
Then('responses should be deterministic in-character fallbacks', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
const lastMessage = messages[messages.length - 1];
expect(lastMessage.length).toBeGreaterThan(0);
});
Then('feature remains usable without Azure credentials', async ({ page }) => {
const testContext = global.fixtures.testContext;
expect(testContext).toBeDefined();
});
When('I chat with any companion', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.selectCharacter('Gandalf');
await page.waitForTimeout(500);
});
Then('the system should attempt one strict retry', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const testContext = global.fixtures.testContext;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThan(0);
(testContext as any).systemRetried = true;
});
Then('if the second response is also out-of-character, provide an in-character fallback', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
const lastMessage = messages[messages.length - 1];
expect(lastMessage.length).toBeGreaterThan(0);
});
When('I send a message', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
await chatPanel.sendMessage('Hello companion');
await page.waitForTimeout(500);
});
Then('Gandalf should reference {string} in the response', async ({ page }, referredText: string) => {
const chatPanel = global.fixtures.chatPanel!;
const lastMessage = await chatPanel.getLastNPCMessage();
expect(lastMessage.toLowerCase()).toContain(referredText.toLowerCase());
});
Then('the conversation should demonstrate session-scoped memory', async ({ page }) => {
const chatPanel = global.fixtures.chatPanel!;
const messages = await chatPanel.getMessages();
expect(messages.length).toBeGreaterThanOrEqual(2);
});