Skip to content

Commit

Permalink
Merge branch 'development' into feat/remove-empty-chat-settings
Browse files Browse the repository at this point in the history
  • Loading branch information
irinakartun authored Jun 25, 2024
2 parents a6ceeec + 62751b0 commit 316d033
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 15 deletions.
24 changes: 20 additions & 4 deletions apps/chat-e2e/src/testData/conversationHistory/conversationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ export class ConversationData extends FolderData {
return this.conversationBuilder.build();
}

public prepareConversationWithCodeContent(
public prepareConversationWithTextContent(
responseContent: string,
model?: string | DialAIEntityModel,
) {
const conversation = this.prepareDefaultConversation(model);
Expand All @@ -272,21 +273,36 @@ export class ConversationData extends FolderData {
};
const userMessage: Message = {
role: Role.User,
content: 'provide an example of interface declaration in Java',
content: 'request',
model: conversation.model,
settings: messageSettings,
};
const assistantMessage: Message = {
role: Role.Assistant,
content:
'Here is an example of an interface declaration in Java:\n\n```java\npublic interface Animal {\n void eat();\n void sleep();\n void makeSound();\n}\n```\n\nIn this example, `Animal` is an interface that declares three methods: `eat()`, `sleep()`, and `makeSound()`. Any class that implements the `Animal` interface will need to provide implementations for these three methods.',
content: responseContent,
model: conversation.model,
settings: messageSettings,
};
conversation.messages = [userMessage, assistantMessage];
return this.conversationBuilder.build();
}

public prepareConversationWithCodeContent(
model?: string | DialAIEntityModel,
) {
const responseContent =
'Here is an example of an interface declaration in Java:\n\n```java\npublic interface Animal {\n void eat();\n void sleep();\n void makeSound();\n}\n```\n\nIn this example, `Animal` is an interface that declares three methods: `eat()`, `sleep()`, and `makeSound()`. Any class that implements the `Animal` interface will need to provide implementations for these three methods.';
return this.prepareConversationWithTextContent(responseContent, model);
}

public prepareConversationWithMdTableContent(
model?: string | DialAIEntityModel,
) {
const responseContent =
'| Country | Capital |\n| ------------- |-------------|\n| Canada | Ottawa |\n| United States | Washington, D.C. |\n';
return this.prepareConversationWithTextContent(responseContent, model);
}

public prepareAssistantConversation(
assistant: DialAIEntityModel,
addons: string[],
Expand Down
3 changes: 3 additions & 0 deletions apps/chat-e2e/src/testData/expectedConstants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import config from '../../config/playwright.config';

import { CopyTableType } from '@/chat/types/chat';
import path from 'path';

export const ExpectedConstants = {
Expand Down Expand Up @@ -129,6 +130,8 @@ export const ExpectedConstants = {
endDotFilenameError: (filename: string) =>
`Using a dot at the end of a name is not permitted. Please rename or delete them from uploading files list: ${filename}`,
allFilesRoot: 'All files',
copyTableTooltip: (copyType: CopyTableType) =>
`Copy as ${copyType.toUpperCase()}`,
};

export enum Groups {
Expand Down
10 changes: 10 additions & 0 deletions apps/chat-e2e/src/testData/expectedMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,14 @@ export enum ExpectedMessages {
uploadToPathIsTruncated = 'Upload to path is truncated',
folderCheckboxIsNotVisible = 'Folder check-box is not visible',
stopPlaybackButtonNotVisible = '"Stop playback" button is not visible',
tableIsVisible = 'Table is visible in chat message',
tableControlIconsNotVisible = 'Table control icons are not visible',
tableCopyAsCsvIconIsVisible = 'Table Copy As Csv icon is available',
tableCopyAsTxtIconIsVisible = 'Table Copy As Txt icon is available',
tableCopyAsMdIconIsVisible = 'Table Copy As MD icon is available',
tableColumnsCountIsValid = 'Table columns count is valid',
tableRowsCountIsValid = 'Table rows count is valid',
tableEntityBackgroundColorIsValid = 'Table entity background color is valid',
tableControlTooltipIsVisible = 'Table control tooltip is visible',
copiedContentIsValid = 'Copied content is valid',
}
235 changes: 235 additions & 0 deletions apps/chat-e2e/src/tests/mdTableModelResponse.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import { Conversation, CopyTableType } from '@/chat/types/chat';
import dialTest from '@/src/core/dialFixtures';
import {
ExpectedConstants,
ExpectedMessages,
ModelIds,
Theme,
} from '@/src/testData';
import { Colors } from '@/src/ui/domData';
import { GeneratorUtil } from '@/src/utils';
import { Locator, expect } from '@playwright/test';

const expectedChatMessageIndex = 2;

dialTest(
'Check md table in response.\n' +
'Copy md table as CSV.\n' +
'Copy md table as TXT.\n' +
'Copy md table as MD',
async ({
dialHomePage,
setTestIds,
chatMessages,
tooltip,
sendMessage,
localStorageManager,
conversationData,
dataInjector,
}) => {
setTestIds('EPMRTC-1153', 'EPMRTC-3124', 'EPMRTC-3125', 'EPMRTC-3126');
let theme: string;
let tableConversation: Conversation;
let copyAsCsvIcon: Locator;
let copyAsTxtIcon: Locator;
let copyAsMdIcon: Locator;
let copyIcons: Locator[] = [];

const expectedTableDimensions = 2;
const expectedCopyIconTooltips = [
ExpectedConstants.copyTableTooltip(CopyTableType.CSV),
ExpectedConstants.copyTableTooltip(CopyTableType.TXT),
ExpectedConstants.copyTableTooltip(CopyTableType.MD),
];
const expectedCopiedContent = [
'"Country","Capital"\n' +
'"Canada","Ottawa"\n' +
'"United States","Washington, D.C."',
'Country\tCapital\n' +
'Canada\tOttawa\n' +
'United States\tWashington, D.C.',
'| Country | Capital |\n' +
'| :-- | :-- |\n' +
'| Canada | Ottawa |\n' +
'| United States | Washington, D.C. |',
];

await dialTest.step('Set random application theme', async () => {
theme = GeneratorUtil.randomArrayElement(Object.keys(Theme));
await localStorageManager.setSettings(theme);
});

await dialTest.step(
'Prepare conversation with table response',
async () => {
tableConversation =
conversationData.prepareConversationWithMdTableContent();
await dataInjector.createConversations([tableConversation]);
await localStorageManager.setSelectedConversation(tableConversation);
},
);

await dialTest.step(
'Verify table data is correctly displayed',
async () => {
await dialHomePage.openHomePage();
await dialHomePage.waitForPageLoaded();
await expect
.soft(
chatMessages.getChatMessageTable(expectedChatMessageIndex),
ExpectedMessages.tableIsVisible,
)
.toBeVisible();

copyAsCsvIcon = chatMessages.getChatMessageTableCopyAsCsvIcon(
expectedChatMessageIndex,
);
await expect
.soft(copyAsCsvIcon, ExpectedMessages.tableCopyAsCsvIconIsVisible)
.toBeVisible();

copyAsTxtIcon = chatMessages.getChatMessageTableCopyAsTxtIcon(
expectedChatMessageIndex,
);
await expect
.soft(copyAsTxtIcon, ExpectedMessages.tableCopyAsTxtIconIsVisible)
.toBeVisible();

copyAsMdIcon = chatMessages.getChatMessageTableCopyAsMdIcon(
expectedChatMessageIndex,
);
await expect
.soft(copyAsMdIcon, ExpectedMessages.tableCopyAsMdIconIsVisible)
.toBeVisible();
expect
.soft(
await chatMessages.getChatMessageTableHeaderColumnsCount(
expectedChatMessageIndex,
),
ExpectedMessages.tableColumnsCountIsValid,
)
.toBe(expectedTableDimensions);
expect
.soft(
await chatMessages.getChatMessageTableRowsCount(
expectedChatMessageIndex,
),
ExpectedMessages.tableRowsCountIsValid,
)
.toBe(expectedTableDimensions * expectedTableDimensions);
},
);

await dialTest.step(
'Verify table rows background color is correct',
async () => {
const tableHeaderBackgroundColor =
await chatMessages.getChatMessageTableHeadersBackgroundColor(
expectedChatMessageIndex,
);
expect
.soft(
tableHeaderBackgroundColor[0],
ExpectedMessages.tableEntityBackgroundColorIsValid,
)
.toBe(
theme === Theme.dark
? Colors.backgroundLayer4Dark
: Colors.backgroundLayer4Light,
);

const tableRowBackgroundColor =
await chatMessages.getChatMessageTableRowsBackgroundColor(
expectedChatMessageIndex,
);
expect
.soft(
tableRowBackgroundColor[0],
ExpectedMessages.tableEntityBackgroundColorIsValid,
)
.toBe(
theme === Theme.dark
? Colors.backgroundLayer3Dark
: Colors.backgroundLayer3Light,
);
},
);

await dialTest.step(
'Verify tooltip is shown on hover over table controls, valid content is copied by click on controls',
async () => {
copyIcons = [copyAsCsvIcon, copyAsTxtIcon, copyAsMdIcon];
for (let i = 0; i < copyIcons.length; i++) {
await copyIcons[i].hover();
await expect
.soft(
tooltip.getElementLocator(),
ExpectedMessages.tableControlTooltipIsVisible,
)
.toBeVisible();
expect
.soft(
await tooltip.getContent(),
ExpectedMessages.tooltipContentIsValid,
)
.toBe(expectedCopyIconTooltips[i]);

await copyIcons[i].click();
await sendMessage.pasteDataIntoMessageInput();
expect
.soft(
await sendMessage.getMessage(),
ExpectedMessages.copiedContentIsValid,
)
.toBe(expectedCopiedContent[i]);
await sendMessage.clearMessageInput();
}
},
);
},
);

dialTest(
'Copy buttons are not shown in MD table if the response is being generated',
async ({
dialHomePage,
setTestIds,
chatMessages,
chat,
localStorageManager,
conversationData,
dataInjector,
}) => {
setTestIds('EPMRTC-3123');
let tableConversation: Conversation;

await dialTest.step('Prepare empty conversation', async () => {
tableConversation = conversationData.prepareEmptyConversation(
ModelIds.GPT_4,
);
await dataInjector.createConversations([tableConversation]);
await localStorageManager.setSelectedConversation(tableConversation);
});

await dialTest.step(
'Send request to generate MD table and verify copy icons are not available while response is generating',
async () => {
await dialHomePage.openHomePage();
await dialHomePage.waitForPageLoaded();
await chat.sendRequestWithButton(
'Create md table with all countries, its capitals and population',
false,
);
await chatMessages
.getChatMessageTable(expectedChatMessageIndex)
.waitFor();
await expect
.soft(
chatMessages.getChatMessageTableControls(expectedChatMessageIndex),
ExpectedMessages.tableControlIconsNotVisible,
)
.toBeHidden();
},
);
},
);
5 changes: 5 additions & 0 deletions apps/chat-e2e/src/ui/domData/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ export enum Colors {
defaultBackground = 'rgba(0, 0, 0, 0)',
textPermanent = 'rgb(252, 252, 252)',
backgroundAccentPrimaryAlpha = 'rgba(92, 141, 234, 0.17)',
backgroundLayer4Dark = 'rgb(51, 57, 66)',
backgroundLayer4Light = 'rgb(221, 225, 230)',
backgroundLayer3Dark = 'rgb(34, 41, 50)',
// eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
backgroundLayer3Light = 'rgb(252, 252, 252)',
}
5 changes: 5 additions & 0 deletions apps/chat-e2e/src/ui/domData/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ export enum Tags {
a = 'a',
desc = 'desc',
closingTag = '/>',
table = 'table',
thead = 'thead',
th = 'th',
tbody = 'tbody',
td = 'td',
}
8 changes: 8 additions & 0 deletions apps/chat-e2e/src/ui/selectors/chatSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,11 @@ export const ChatSelectors = {
messageSpinner: '[data-qa="message-input-spinner"]',
plotlyContainer: '.plot-container',
};

export const TableSelectors = {
tableContainer: '[data-qa="table"]',
tableControls: '[data-qa="table-controls"]',
copyAsCsvIcon: '[data-qa="csv-icon"]',
copyAsTxtIcon: '[data-qa="txt-icon"]',
copyAsMdIcon: '[data-qa="md-icon"]',
};
Loading

0 comments on commit 316d033

Please sign in to comment.