From 92675f7ec73d36c287656eec66dc4a22fbb54d27 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 13:25:12 +0100 Subject: [PATCH 01/19] feat/update-e2e-with-stateful-api: updated tests with stateful api usage --- apps/chat-e2e/README.md | 17 +- apps/chat-e2e/src/core/baseFixtures.ts | 25 + .../src/core/{fixtures.ts => dialFixtures.ts} | 87 +- apps/chat-e2e/src/core/localStorageManager.ts | 4 - apps/chat-e2e/src/hooks/global-setup.ts | 3 + apps/chat-e2e/src/testData/api/index.ts | 1 + .../src/testData/api/itemApiHelper.ts | 94 + .../conversationHistory/conversationData.ts | 1 + .../src/testData/expectedConstants.ts | 8 +- .../chat-e2e/src/testData/expectedMessages.ts | 3 +- .../src/testData/injector/apiInjector.ts | 45 + .../injector/browserStorageInjector.ts | 43 + .../injector/dataInjectorInterface.ts | 23 + .../src/tests/announcementBanner.test.ts | 114 +- .../tests/chatApi/arithmeticRequest.test.ts | 19 +- .../src/tests/chatApi/attachment.test.ts | 23 +- .../src/tests/chatApi/imageGeneration.test.ts | 29 +- .../src/tests/chatBarConversation.test.ts | 1298 +++++++------- .../tests/chatBarFolderConversation.test.ts | 584 ++++--- .../src/tests/chatExportImport.test.ts | 977 ++++++----- apps/chat-e2e/src/tests/chatHeader.test.ts | 155 +- .../src/tests/chatHeaderSettings.test.ts | 78 +- apps/chat-e2e/src/tests/compareMode.test.ts | 1517 +++++++++-------- .../src/tests/defaultModelSettings.test.ts | 296 ++-- apps/chat-e2e/src/tests/desktopAuth.ts | 3 +- apps/chat-e2e/src/tests/entityIcon.test.ts | 187 +- apps/chat-e2e/src/tests/folderPrompts.test.ts | 618 ++++--- apps/chat-e2e/src/tests/listing.test.ts | 2 +- apps/chat-e2e/src/tests/modelSettings.test.ts | 27 +- apps/chat-e2e/src/tests/playBack.test.ts | 414 +++-- .../src/tests/promptExportImport.test.ts | 856 ++++++---- apps/chat-e2e/src/tests/prompts.test.ts | 431 ++--- apps/chat-e2e/src/tests/replay.test.ts | 1202 +++++++------ .../src/tests/sharedChatIcons.test.ts | 348 ++-- .../src/tests/sharedPromptIcons.test.ts | 160 +- .../chat-e2e/src/tests/sideBarFilters.test.ts | 546 +++--- .../tests/sidePanelEntityDragAndDrop.test.ts | 373 ++-- apps/chat-e2e/src/tests/sidePanels.test.ts | 182 +- .../chat-e2e/src/tests/workWithModels.test.ts | 458 ++--- apps/chat-e2e/src/ui/domData/attributes.ts | 1 + apps/chat-e2e/src/ui/pages/auth0Page.ts | 2 +- apps/chat-e2e/src/ui/pages/basePage.ts | 8 +- apps/chat-e2e/src/ui/pages/dialHomePage.ts | 19 +- .../src/ui/selectors/chatSelectors.ts | 2 + .../src/ui/webElements/appContainer.ts | 9 + apps/chat-e2e/src/ui/webElements/chat.ts | 6 +- apps/chat-e2e/src/ui/webElements/chatBar.ts | 10 + .../chat-e2e/src/ui/webElements/chatLoader.ts | 9 + .../src/ui/webElements/chatMessages.ts | 8 +- .../src/ui/webElements/confirmationDialog.ts | 12 +- .../ui/webElements/conversationToCompare.ts | 9 + .../src/ui/webElements/conversations.ts | 13 +- .../src/ui/webElements/folderConversations.ts | 13 + apps/chat-e2e/src/ui/webElements/folders.ts | 36 +- apps/chat-e2e/src/ui/webElements/index.ts | 1 + .../chat-e2e/src/ui/webElements/promptList.ts | 1 + .../src/ui/webElements/promptModalDialog.ts | 8 + apps/chat-e2e/src/ui/webElements/sideBar.ts | 20 + .../src/ui/webElements/sideBarEntities.ts | 30 +- apps/chat-e2e/src/utils/conversationUtil.ts | 13 + apps/chat-e2e/src/utils/index.ts | 1 + 61 files changed, 6638 insertions(+), 4844 deletions(-) create mode 100644 apps/chat-e2e/src/core/baseFixtures.ts rename apps/chat-e2e/src/core/{fixtures.ts => dialFixtures.ts} (84%) create mode 100644 apps/chat-e2e/src/testData/api/itemApiHelper.ts create mode 100644 apps/chat-e2e/src/testData/injector/apiInjector.ts create mode 100644 apps/chat-e2e/src/testData/injector/browserStorageInjector.ts create mode 100644 apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts create mode 100644 apps/chat-e2e/src/ui/webElements/chatLoader.ts create mode 100644 apps/chat-e2e/src/utils/conversationUtil.ts diff --git a/apps/chat-e2e/README.md b/apps/chat-e2e/README.md index b6aea9161d..992fae4fba 100644 --- a/apps/chat-e2e/README.md +++ b/apps/chat-e2e/README.md @@ -59,11 +59,12 @@ CI report includes screenshots for failed tests. The following variables should be placed inside `chat-e2e/.env.local` file in order to run tests locally -| Variable | Required | Description | Available Values | Default values | -|-----------------| -------- |----------------------------------------------------------------------------------------------------------------------------------------------------|------------------| -------------- | -| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | -| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | -| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | -| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | -| `TMS_URL` | No | TMS URL | Any string | | -| `ISSUE_URL` | No | Issue URL | Any string | | +| Variable | Required | Description | Available Values | Default values | +|-----------------| -------- |----------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------| +| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | +| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | +| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | +| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | +| `TMS_URL` | No | TMS URL | Any string | | +| `ISSUE_URL` | No | Issue URL | Any string | | +| `STORAGE_TYPE` | No | Storage type used for e2e tests data | api,browserStorage | api | diff --git a/apps/chat-e2e/src/core/baseFixtures.ts b/apps/chat-e2e/src/core/baseFixtures.ts new file mode 100644 index 0000000000..0ac747bddf --- /dev/null +++ b/apps/chat-e2e/src/core/baseFixtures.ts @@ -0,0 +1,25 @@ +import { LocalStorageManager } from '@/src/core/localStorageManager'; +import { LoginPage } from '@/src/ui/pages'; +import { Auth0Page } from '@/src/ui/pages/auth0Page'; +import { test as base } from '@playwright/test'; + +const test = base.extend<{ + loginPage: LoginPage; + auth0Page: Auth0Page; + localStorageManager: LocalStorageManager; +}>({ + loginPage: async ({ page }, use) => { + const loginPage = new LoginPage(page); + await use(loginPage); + }, + auth0Page: async ({ page }, use) => { + const auth0Page = new Auth0Page(page); + await use(auth0Page); + }, + localStorageManager: async ({ page }, use) => { + const localStorageManager = new LocalStorageManager(page); + await use(localStorageManager); + }, +}); + +export default test; diff --git a/apps/chat-e2e/src/core/fixtures.ts b/apps/chat-e2e/src/core/dialFixtures.ts similarity index 84% rename from apps/chat-e2e/src/core/fixtures.ts rename to apps/chat-e2e/src/core/dialFixtures.ts index d308062986..c9a9f68270 100644 --- a/apps/chat-e2e/src/core/fixtures.ts +++ b/apps/chat-e2e/src/core/dialFixtures.ts @@ -1,10 +1,11 @@ -import { DialHomePage, LoginPage } from '../ui/pages'; +import { DialHomePage } from '../ui/pages'; import { Chat, ChatBar, ChatHeader, ChatMessages, ConversationSettings, + ConversationToCompare, Conversations, EntitySelector, ModelsDialog, @@ -13,22 +14,27 @@ import { RecentEntities, SendMessage, } from '../ui/webElements'; -import { LocalStorageManager } from './localStorageManager'; +import test from '@/src/core/baseFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { ConversationData } from '@/src/testData'; import { ChatApiHelper, FileApiHelper, IconApiHelper, } from '@/src/testData/api'; +import { ItemApiHelper } from '@/src/testData/api/itemApiHelper'; +import { ApiInjector } from '@/src/testData/injector/apiInjector'; +import { BrowserStorageInjector } from '@/src/testData/injector/browserStorageInjector'; +import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface'; import { PromptData } from '@/src/testData/prompts/promptData'; -import { Auth0Page } from '@/src/ui/pages/auth0Page'; import { AccountSettings } from '@/src/ui/webElements/accountSettings'; import { Addons } from '@/src/ui/webElements/addons'; import { AddonsDialog } from '@/src/ui/webElements/addonsDialog'; import { AppContainer } from '@/src/ui/webElements/appContainer'; import { Banner } from '@/src/ui/webElements/banner'; import { ChatInfoTooltip } from '@/src/ui/webElements/chatInfoTooltip'; +import { ChatLoader } from '@/src/ui/webElements/chatLoader'; import { Compare } from '@/src/ui/webElements/compare'; import { ConfirmationDialog } from '@/src/ui/webElements/confirmationDialog'; import { DropdownCheckboxMenu } from '@/src/ui/webElements/dropdownCheckboxMenu'; @@ -50,7 +56,6 @@ import { ShareModal } from '@/src/ui/webElements/shareModal'; import { TemperatureSlider } from '@/src/ui/webElements/temperatureSlider'; import { Tooltip } from '@/src/ui/webElements/tooltip'; import { VariableModalDialog } from '@/src/ui/webElements/variableModalDialog'; -import { test as base } from '@playwright/test'; import { allure } from 'allure-playwright'; import path from 'path'; @@ -64,13 +69,13 @@ interface ReportAttributes { setIssueIds: (...issueIds: string[]) => void; } -const test = base.extend< +const dialTest = test.extend< ReportAttributes & { + beforeTestCleanup: string; dialHomePage: DialHomePage; - loginPage: LoginPage; - auth0Page: Auth0Page; appContainer: AppContainer; chatBar: ChatBar; + chatLoader: ChatLoader; header: Header; accountSettings: AccountSettings; accountDropdownMenu: DropdownMenu; @@ -93,7 +98,6 @@ const test = base.extend< addonsDialog: AddonsDialog; conversationData: ConversationData; promptData: PromptData; - localStorageManager: LocalStorageManager; conversationDropdownMenu: DropdownMenu; folderDropdownMenu: DropdownMenu; promptDropdownMenu: DropdownMenu; @@ -106,6 +110,7 @@ const test = base.extend< chatInfoTooltip: ChatInfoTooltip; compare: Compare; compareConversationSelector: ModelSelector; + compareConversation: ConversationToCompare; rightConversationSettings: ConversationSettings; leftConversationSettings: ConversationSettings; rightChatHeader: ChatHeader; @@ -125,6 +130,10 @@ const test = base.extend< iconApiHelper: IconApiHelper; chatApiHelper: ChatApiHelper; fileApiHelper: FileApiHelper; + itemApiHelper: ItemApiHelper; + browserStorageInjector: BrowserStorageInjector; + apiInjector: ApiInjector; + dataInjector: DataInjectorInterface; } >({ // eslint-disable-next-line no-empty-pattern @@ -141,23 +150,26 @@ const test = base.extend< const callback = (...issueIds: string[]) => { for (const issueId of issueIds) { allure.issue(issueId, `${process.env.ISSUE_URL}/${issueId}`); - test.skip(); + dialTest.skip(); } }; await use(callback); }, + beforeTestCleanup: [ + async ({ dataInjector }, use) => { + await dataInjector.deleteAllData(); + await use('beforeTestCleanup'); + }, + { scope: 'test', auto: true }, + ], + // eslint-disable-next-line no-empty-pattern + storageState: async ({}, use) => { + await use(stateFilePath); + }, dialHomePage: async ({ page }, use) => { const dialHomePage = new DialHomePage(page); await use(dialHomePage); }, - loginPage: async ({ page }, use) => { - const loginPage = new LoginPage(page); - await use(loginPage); - }, - auth0Page: async ({ page }, use) => { - const auth0Page = new Auth0Page(page); - await use(auth0Page); - }, appContainer: async ({ dialHomePage }, use) => { const appContainer = dialHomePage.getAppContainer(); await use(appContainer); @@ -166,6 +178,10 @@ const test = base.extend< const chatBar = appContainer.getChatBar(); await use(chatBar); }, + chatLoader: async ({ appContainer }, use) => { + const chatLoader = appContainer.getChatLoader(); + await use(chatLoader); + }, header: async ({ appContainer }, use) => { const header = appContainer.getHeader(); await use(header); @@ -316,10 +332,6 @@ const test = base.extend< const promptData = new PromptData(); await use(promptData); }, - localStorageManager: async ({ page }, use) => { - const localStorageManager = new LocalStorageManager(page); - await use(localStorageManager); - }, chatInfoTooltip: async ({ page }, use) => { const chatInfoTooltip = new ChatInfoTooltip(page); await use(chatInfoTooltip); @@ -328,10 +340,13 @@ const test = base.extend< const compare = chat.getCompare(); await use(compare); }, - compareConversationSelector: async ({ compare }, use) => { - const compareConversationSelector = compare - .getConversationToCompare() - .getConversationSelector(); + compareConversation: async ({ compare }, use) => { + const compareConversation = compare.getConversationToCompare(); + await use(compareConversation); + }, + compareConversationSelector: async ({ compareConversation }, use) => { + const compareConversationSelector = + compareConversation.getConversationSelector(); await use(compareConversationSelector); }, rightConversationSettings: async ({ compare }, use) => { @@ -386,6 +401,26 @@ const test = base.extend< const fileApiHelper = new FileApiHelper(request); await use(fileApiHelper); }, + itemApiHelper: async ({ request }, use) => { + const conversationApiHelper = new ItemApiHelper(request); + await use(conversationApiHelper); + }, + apiInjector: async ({ itemApiHelper }, use) => { + const apiInjector = new ApiInjector(itemApiHelper); + await use(apiInjector); + }, + browserStorageInjector: async ({ localStorageManager }, use) => { + const browserStorageInjector = new BrowserStorageInjector( + localStorageManager, + ); + await use(browserStorageInjector); + }, + dataInjector: async ({ apiInjector, browserStorageInjector }, use) => { + const dataInjector = isApiStorageType + ? apiInjector + : browserStorageInjector; + await use(dataInjector); + }, }); -export default test; +export default dialTest; diff --git a/apps/chat-e2e/src/core/localStorageManager.ts b/apps/chat-e2e/src/core/localStorageManager.ts index 4480ea9d40..193ff22e71 100644 --- a/apps/chat-e2e/src/core/localStorageManager.ts +++ b/apps/chat-e2e/src/core/localStorageManager.ts @@ -27,10 +27,6 @@ export class LocalStorageManager { window.localStorage.setItem('selectedConversationIds', selected); }; - setOpenedFoldersIdsKey = () => (folders: string) => { - window.localStorage.setItem('openedFoldersIds', folders); - }; - setSettingsKey = () => (settings: string) => { window.localStorage.setItem('settings', settings); }; diff --git a/apps/chat-e2e/src/hooks/global-setup.ts b/apps/chat-e2e/src/hooks/global-setup.ts index 18cd61e01f..592d36b44c 100644 --- a/apps/chat-e2e/src/hooks/global-setup.ts +++ b/apps/chat-e2e/src/hooks/global-setup.ts @@ -2,6 +2,9 @@ import { ResultFolder } from '@/src/testData'; import { FileUtil } from '@/src/utils'; import path from 'path'; +export const isApiStorageType = + process.env.STORAGE_TYPE === 'api' || process.env.STORAGE_TYPE === undefined; + export const ExecutionResults = { allureReportPath: path.resolve( __dirname, diff --git a/apps/chat-e2e/src/testData/api/index.ts b/apps/chat-e2e/src/testData/api/index.ts index 9407b09f32..1f1e52fe5c 100644 --- a/apps/chat-e2e/src/testData/api/index.ts +++ b/apps/chat-e2e/src/testData/api/index.ts @@ -2,3 +2,4 @@ export * from './baseApiHelper'; export * from './chatApiHelper'; export * from './fileApiHelper'; export * from './iconApiHelper'; +export * from './itemApiHelper'; diff --git a/apps/chat-e2e/src/testData/api/itemApiHelper.ts b/apps/chat-e2e/src/testData/api/itemApiHelper.ts new file mode 100644 index 0000000000..4ed4dbb3bb --- /dev/null +++ b/apps/chat-e2e/src/testData/api/itemApiHelper.ts @@ -0,0 +1,94 @@ +import { Conversation } from '@/chat/types/chat'; +import { BackendDataEntity, BackendDataNodeType } from '@/chat/types/common'; +import { FolderInterface } from '@/chat/types/folder'; +import { Prompt } from '@/chat/types/prompt'; +import { API } from '@/src/testData'; +import { BaseApiHelper } from '@/src/testData/api/baseApiHelper'; +import { BucketUtil, ConversationUtil } from '@/src/utils'; +import { expect } from '@playwright/test'; + +export class ItemApiHelper extends BaseApiHelper { + public async deleteAllData() { + const conversations = await this.listItems(API.conversationsListingHost()); + const prompts = await this.listItems(API.promptsListingHost()); + await this.deleteBackendItem(...conversations, ...prompts); + } + + public async listItems(url: string) { + const response = await this.request.get(url, { + params: { + filter: BackendDataNodeType.ITEM, + bucket: BucketUtil.getBucket(), + recursive: true, + }, + }); + const entities = (await response.json()) as BackendDataEntity[]; + expect( + response.status(), + `Received items: ${JSON.stringify(entities)}`, + ).toBe(200); + return entities; + } + + public async deleteBackendItem(...items: BackendDataEntity[]) { + for (const item of items) { + const url = `/api/${item.url}`; + const response = await this.request.delete(url); + expect( + response.status(), + `Backend item with id: ${item.name} was successfully deleted`, + ).toBe(200); + } + } + + public async createConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ) { + for (const conversation of conversations) { + const path = await this.getItemPath(conversation, ...folders); + conversation.id = + path.length === 0 + ? ConversationUtil.getApiConversationId(conversation) + : `${path}/${ConversationUtil.getApiConversationId(conversation)}`; + await this.createItem(API.conversationsHost, conversation); + } + } + + public async createPrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + for (const prompt of prompts) { + const path = await this.getItemPath(prompt, ...folders); + prompt.id = path.length === 0 ? prompt.name : `${path}/${prompt.name}`; + await this.createItem(API.promptsHost, prompt); + } + } + + private async createItem(host: string, item: Prompt | Conversation) { + const url = `${host}/${BucketUtil.getBucket()}/${item.id}`; + const response = await this.request.put(url, { + data: item, + }); + expect( + response.status(), + `Item created with data: ${JSON.stringify(item)}`, + ).toBe(200); + } + + private async getItemPath( + item: Prompt | Conversation, + ...folders: FolderInterface[] + ) { + let path = ''; + const itemFolderId = item.folderId; + if (itemFolderId) { + let itemFolder = folders.find((f) => f.id === itemFolderId); + path = itemFolder!.name; + while (itemFolder!.folderId) { + itemFolder = folders.find((f) => f.id === itemFolder?.folderId); + path = `${itemFolder?.name}/${path}`; + } + item.folderId = path; + } + return path; + } +} diff --git a/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts b/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts index e6b071e844..d4feefe14c 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts @@ -41,6 +41,7 @@ export class ConversationData extends FolderData { const userMessage: Message = { role: Role.User, content: 'test request', + model: { id: modelToUse.id }, }; const assistantMessage: Message = { role: Role.Assistant, diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts index 4e46e4e7f3..e2c96723e2 100644 --- a/apps/chat-e2e/src/testData/expectedConstants.ts +++ b/apps/chat-e2e/src/testData/expectedConstants.ts @@ -5,6 +5,8 @@ export const ExpectedConstants = { newPromptTitle: (index: number) => `Prompt ${index}`, promptPlaceholder: (variable: string) => `Enter a value for ${variable}...`, newFolderTitle: 'New folder', + newFolderWithIndexTitle: (index: number) => + `${ExpectedConstants.newFolderTitle} ${index}`, emptyString: '', defaultTemperature: '1', signInButtonTitle: 'Sign in with Credentials', @@ -102,7 +104,11 @@ export const API = { chatHost: '/api/chat', sessionHost: '/api/auth/session', defaultIconHost: '/api/themes/image?name=default-model', - bucketHost: '/api/files/bucket', + bucketHost: '/api/bucket', + conversationsHost: '/api/conversations', + promptsHost: '/api/prompts', + conversationsListingHost: () => `${API.conversationsHost}/listing`, + promptsListingHost: () => `${API.promptsHost}/listing`, fileHost: '/api/files/file', uploadedFileHost: () => `${API.fileHost}/files`, }; diff --git a/apps/chat-e2e/src/testData/expectedMessages.ts b/apps/chat-e2e/src/testData/expectedMessages.ts index 2f88b26911..ea7b987500 100644 --- a/apps/chat-e2e/src/testData/expectedMessages.ts +++ b/apps/chat-e2e/src/testData/expectedMessages.ts @@ -14,8 +14,7 @@ export enum ExpectedMessages { newFolderCreated = 'New folder is created', folderCollapsed = 'Folder is collapsed', folderExpanded = 'Folder is expanded', - folderCaretIsVisible = 'Folder caret is visible', - folderCaretIsNotVisible = 'Folder caret is not visible', + folderCaretIsExpanded = 'Folder caret is visible and expanded', folderNameUpdated = 'Folder name is updated', folderNameNotUpdated = 'Folder name is not updated', folderDeleted = 'Folder is deleted', diff --git a/apps/chat-e2e/src/testData/injector/apiInjector.ts b/apps/chat-e2e/src/testData/injector/apiInjector.ts new file mode 100644 index 0000000000..cc255c4044 --- /dev/null +++ b/apps/chat-e2e/src/testData/injector/apiInjector.ts @@ -0,0 +1,45 @@ +import { Conversation } from '@/chat/types/chat'; +import { FolderInterface } from '@/chat/types/folder'; +import { Prompt } from '@/chat/types/prompt'; +import { ItemApiHelper } from '@/src/testData/api'; +import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface'; + +export class ApiInjector implements DataInjectorInterface { + private itemApiHelper: ItemApiHelper; + + constructor(conversationApiHelper: ItemApiHelper) { + this.itemApiHelper = conversationApiHelper; + } + + async createPrompts( + prompts: Prompt[], + ...folders: FolderInterface[] + ): Promise { + await this.itemApiHelper.createPrompts(prompts, ...folders); + } + + async updateConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ): Promise { + await this.itemApiHelper.createConversations(conversations, ...folders); + } + + async updatePrompts( + prompts: Prompt[], + ...folders: FolderInterface[] + ): Promise { + await this.itemApiHelper.createPrompts(prompts, ...folders); + } + + async createConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ) { + await this.itemApiHelper.createConversations(conversations, ...folders); + } + + async deleteAllData() { + await this.itemApiHelper.deleteAllData(); + } +} diff --git a/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts b/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts new file mode 100644 index 0000000000..2009c5efc4 --- /dev/null +++ b/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts @@ -0,0 +1,43 @@ +import { Conversation } from '@/chat/types/chat'; +import { FolderInterface } from '@/chat/types/folder'; +import { Prompt } from '@/chat/types/prompt'; +import { LocalStorageManager } from '@/src/core/localStorageManager'; +import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface'; + +export class BrowserStorageInjector implements DataInjectorInterface { + private readonly localStorageManager: LocalStorageManager; + + constructor(localStorageManager: LocalStorageManager) { + this.localStorageManager = localStorageManager; + } + + async createConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ): Promise { + await this.localStorageManager.setFolders(...folders); + await this.localStorageManager.setConversationHistory(...conversations); + } + + async updateConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ) { + await this.localStorageManager.updateConversationHistory(...conversations); + await this.localStorageManager.updateFolders(...folders); + } + + async createPrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + await this.localStorageManager.setFolders(...folders); + await this.localStorageManager.setPrompts(...prompts); + } + + async updatePrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + await this.localStorageManager.updatePrompts(...prompts); + await this.localStorageManager.updateFolders(...folders); + } + + async deleteAllData() { + return Promise.resolve(); + } +} diff --git a/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts b/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts new file mode 100644 index 0000000000..be419ed46a --- /dev/null +++ b/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts @@ -0,0 +1,23 @@ +import { Conversation } from '@/chat/types/chat'; +import { FolderInterface } from '@/chat/types/folder'; +import { Prompt } from '@/chat/types/prompt'; + +export interface DataInjectorInterface { + createConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ): Promise; + updateConversations( + conversations: Conversation[], + ...folders: FolderInterface[] + ): Promise; + createPrompts( + prompts: Prompt[], + ...folders: FolderInterface[] + ): Promise; + updatePrompts( + prompts: Prompt[], + ...folders: FolderInterface[] + ): Promise; + deleteAllData(): Promise; +} diff --git a/apps/chat-e2e/src/tests/announcementBanner.test.ts b/apps/chat-e2e/src/tests/announcementBanner.test.ts index d459fe9b91..bba1fe1707 100644 --- a/apps/chat-e2e/src/tests/announcementBanner.test.ts +++ b/apps/chat-e2e/src/tests/announcementBanner.test.ts @@ -1,41 +1,41 @@ import { Conversation } from '@/chat/types/chat'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { AccountMenuOptions, ExpectedMessages } from '@/src/testData'; import { expect } from '@playwright/test'; -test.describe('Announcement banner tests', () => { - test.use({ storageState: stateFilePath }); - test( - 'Banner is shown.\n' + - 'Banner text contains html link.\n' + - "Banner doesn't appear if to close it", - async ({ - dialHomePage, - conversationData, - localStorageManager, - chatBar, - promptBar, - conversations, - banner, - header, - appContainer, - accountSettings, - accountDropdownMenu, - confirmationDialog, - loginPage, - setTestIds, - }) => { - setTestIds('EPMRTC-1576', 'EPMRTC-1580', 'EPMRTC-1577'); - let conversation: Conversation; - let chatBarBounding; - let promptBarBounding; +dialTest( + 'Banner is shown.\n' + + 'Banner text contains html link.\n' + + "Banner doesn't appear if to close it", + async ({ + dialHomePage, + conversationData, + dataInjector, + chatBar, + promptBar, + conversations, + banner, + header, + appContainer, + accountSettings, + accountDropdownMenu, + confirmationDialog, + loginPage, + setTestIds, + }) => { + setTestIds('EPMRTC-1576', 'EPMRTC-1580', 'EPMRTC-1577'); + let conversation: Conversation; + let chatBarBounding; + let promptBarBounding; - await test.step('Prepare any conversation', async () => { - conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); - }); + await dialTest.step('Prepare any conversation', async () => { + conversation = conversationData.prepareDefaultConversation(); + await dataInjector.createConversations([conversation]); + }); - await test.step('Open app and verify announcement banner is shown between side panels', async () => { + await dialTest.step( + 'Open app and verify announcement banner is shown between side panels', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -67,9 +67,12 @@ test.describe('Announcement banner tests', () => { ExpectedMessages.bannerWidthIsValid, ) .toBeTruthy(); - }); + }, + ); - await test.step('Select conversation in chat panel and verify announcement banner is shown between side panels', async () => { + await dialTest.step( + 'Select conversation in chat panel and verify announcement banner is shown between side panels', + async () => { await conversations.selectConversation(conversation.name); const bannerBounding = await banner.getElementBoundingBox(); expect @@ -84,9 +87,12 @@ test.describe('Announcement banner tests', () => { ExpectedMessages.bannerWidthIsValid, ) .toBeTruthy(); - }); + }, + ); - await test.step('Hide side panels and verify announcement banner is shown on full window width', async () => { + await dialTest.step( + 'Hide side panels and verify announcement banner is shown on full window width', + async () => { await header.chatPanelToggle.click(); await header.promptsPanelToggle.click(); const appBounding = await appContainer.getElementBoundingBox(); @@ -97,33 +103,45 @@ test.describe('Announcement banner tests', () => { ExpectedMessages.bannerWidthIsValid, ) .toBeTruthy(); - }); + }, + ); - await test.step('Click on banner message link and verify new page is opened', async () => { + await dialTest.step( + 'Click on banner message link and verify new page is opened', + async () => { const newPage = await dialHomePage.getNewPage(() => banner.bannerMessageLink.click(), ); expect .soft(newPage !== undefined, ExpectedMessages.newPageIsOpened) .toBeTruthy(); - }); + }, + ); - await test.step('Click on close on banner and verify it is not shown', async () => { + await dialTest.step( + 'Click on close on banner and verify it is not shown', + async () => { await dialHomePage.bringPageToFront(); await banner.closeButton.click(); expect .soft(await banner.isVisible(), ExpectedMessages.bannerIsClosed) .toBeFalsy(); - }); + }, + ); - await test.step('Refresh page and verify banner is not shown', async () => { + await dialTest.step( + 'Refresh page and verify banner is not shown', + async () => { await dialHomePage.reloadPage(); expect .soft(await banner.isVisible(), ExpectedMessages.bannerIsClosed) .toBeFalsy(); - }); + }, + ); - await test.step('Re-login to app and verify banner is not shown', async () => { + await dialTest.step( + 'Re-login to app and verify banner is not shown', + async () => { await accountSettings.openAccountDropdownMenu(); await accountDropdownMenu.selectMenuOption(AccountMenuOptions.logout); await confirmationDialog.confirm(); @@ -131,7 +149,7 @@ test.describe('Announcement banner tests', () => { expect .soft(await banner.isVisible(), ExpectedMessages.bannerIsClosed) .toBeFalsy(); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts index 927d334ccd..ca6a48ebde 100644 --- a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts @@ -1,4 +1,4 @@ -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, ModelIds } from '@/src/testData'; import { expect } from '@playwright/test'; @@ -34,13 +34,10 @@ const modelsForArithmeticRequest: { { modelId: ModelIds.GEMINI_PRO, isSysPromptAllowed: true }, ); -test.describe('Chat API arithmetic request tests', () => { - test.use({ storageState: stateFilePath }); - for (const modelToUse of modelsForArithmeticRequest) { - test(`Generate arithmetic response for model: ${modelToUse.modelId}`, async ({ - conversationData, - chatApiHelper, - }) => { +for (const modelToUse of modelsForArithmeticRequest) { + dialTest( + `Generate arithmetic response for model: ${modelToUse.modelId}`, + async ({ conversationData, chatApiHelper }) => { const conversation = conversationData.prepareModelConversation( 0, modelToUse.isSysPromptAllowed @@ -69,6 +66,6 @@ test.describe('Chat API arithmetic request tests', () => { `${ExpectedMessages.responseTextIsValid}${modelToUse.modelId}`, ) .toMatch(/\s?3\.?/); - }); - } -}); + }, + ); +} diff --git a/apps/chat-e2e/src/tests/chatApi/attachment.test.ts b/apps/chat-e2e/src/tests/chatApi/attachment.test.ts index b53fbaba9f..b1d28fda75 100644 --- a/apps/chat-e2e/src/tests/chatApi/attachment.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/attachment.test.ts @@ -1,4 +1,4 @@ -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { Attachment, ExpectedConstants, @@ -16,17 +16,14 @@ const modelsForRequestWithAttachment: { ); let imageUrl: string; -test.beforeEach(async ({ fileApiHelper }) => { +dialTest.beforeEach(async ({ fileApiHelper }) => { imageUrl = await fileApiHelper.putFile(Attachment.sunImageName); }); -test.describe('Chat API request with attachments tests', () => { - test.use({ storageState: stateFilePath }); - for (const modelToUse of modelsForRequestWithAttachment) { - test(`Generate response on request with attachment for model: ${modelToUse.modelId}`, async ({ - conversationData, - chatApiHelper, - }) => { +for (const modelToUse of modelsForRequestWithAttachment) { + dialTest( + `Generate response on request with attachment for model: ${modelToUse.modelId}`, + async ({ conversationData, chatApiHelper }) => { const conversation = conversationData.prepareConversationWithAttachment( imageUrl, modelToUse.modelId, @@ -50,10 +47,10 @@ test.describe('Chat API request with attachments tests', () => { `${ExpectedMessages.responseTextIsValid}${modelToUse.modelId}`, ) .toMatch(new RegExp('.*sun.*', 'i')); - }); - } -}); + }, + ); +} -test.afterEach(async ({ fileApiHelper }) => { +dialTest.afterEach(async ({ fileApiHelper }) => { await fileApiHelper.deleteUploadedFile(Attachment.sunImageName); }); diff --git a/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts b/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts index 5a4508e4b4..365210218c 100644 --- a/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts @@ -1,4 +1,4 @@ -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, ModelIds } from '@/src/testData'; import { expect } from '@playwright/test'; @@ -8,15 +8,12 @@ const modelsForImageGeneration = Array.of( ModelIds.IMAGE_GENERATION_005, ); -test.describe('Chat API request for image generation tests', () => { - test.use({ storageState: stateFilePath }); - let imageUrl: string | undefined; +let imageUrl: string | undefined; - for (const modelToUse of modelsForImageGeneration) { - test(`Generate image for model: ${modelToUse}`, async ({ - conversationData, - chatApiHelper, - }) => { +for (const modelToUse of modelsForImageGeneration) { + dialTest( + `Generate image for model: ${modelToUse}`, + async ({ conversationData, chatApiHelper }) => { const conversation = conversationData.prepareModelConversationBasedOnRequests(modelToUse, [ 'draw smiling emoticon', @@ -37,12 +34,12 @@ test.describe('Chat API request for image generation tests', () => { `${ExpectedMessages.imageUrlReturnedInResponse}${modelToUse}`, ) .toMatch(ExpectedConstants.responseFileUrlContentPattern(modelToUse)); - }); - } + }, + ); +} - test.afterEach(async ({ fileApiHelper }) => { - if (imageUrl) { - await fileApiHelper.deleteAppDataFile(imageUrl); - } - }); +dialTest.afterEach(async ({ fileApiHelper }) => { + if (imageUrl) { + await fileApiHelper.deleteAppDataFile(imageUrl); + } }); diff --git a/apps/chat-e2e/src/tests/chatBarConversation.test.ts b/apps/chat-e2e/src/tests/chatBarConversation.test.ts index 92f265f8eb..db85315b0c 100644 --- a/apps/chat-e2e/src/tests/chatBarConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarConversation.test.ts @@ -1,7 +1,8 @@ import { Conversation } from '@/chat/types/chat'; import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { Chronology, ExpectedConstants, @@ -10,7 +11,7 @@ import { ModelIds, } from '@/src/testData'; import { Colors, Overflow, Styles } from '@/src/ui/domData'; -import { BucketUtil, GeneratorUtil } from '@/src/utils'; +import { GeneratorUtil } from '@/src/utils'; import { ModelsUtil } from '@/src/utils/modelsUtil'; import { expect } from '@playwright/test'; @@ -18,75 +19,71 @@ let gpt35Model: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; let bisonModel: OpenAIEntityModel; -const request = 'What is epam official name?'; +const request = 'What is epam official name'; const notMatchingSearchTerm = 'abc'; const secondSearchTerm = 'epam official'; const matchingConversationName = `${secondSearchTerm} name`; -const specialSymbolsName = 'Chat_!@#$%^&*()+=\':",.<>'; +const specialSymbolsName = '_!@$epam official^&()_{}[]"\'.<>-`~'; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { gpt35Model = ModelsUtil.getDefaultModel()!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; bisonModel = ModelsUtil.getModel(ModelIds.BISON_001)!; }); -test.describe('Chat bar conversations tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Chat name equals to the first message\n' + - 'Chat sorting. Today for newly created chat', - async ({ dialHomePage, conversations, chat, setTestIds }) => { - setTestIds('EPMRTC-583', 'EPMRTC-776'); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - const messageToSend = 'Hi'; - await chat.sendRequestWithButton(messageToSend); - expect - .soft( - await conversations.getConversationByName(messageToSend).isVisible(), - ExpectedMessages.conversationRenamed, - ) - .toBeTruthy(); +dialTest( + 'Chat name equals to the first message\n' + + 'Chat sorting. Today for newly created chat', + async ({ dialHomePage, conversations, chat, setTestIds }) => { + setTestIds('EPMRTC-583', 'EPMRTC-776'); + await dialHomePage.openHomePage({ + iconsToBeLoaded: [ModelsUtil.getDefaultModel()!.iconUrl], + }); + await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); + const messageToSend = 'Hi'; + await chat.sendRequestWithButton(messageToSend); + await conversations.getConversationByName(messageToSend).waitFor(); - const todayConversations = await conversations.getTodayConversations(); - expect - .soft( - todayConversations.includes(messageToSend), - ExpectedMessages.conversationOfToday, - ) - .toBeTruthy(); - }, - ); - - test( - 'Rename chat. Cancel.\n' + - 'Long Chat name is cut. Named automatically by the system.\n' + - 'Long chat name while delete and edit', - async ({ - dialHomePage, - conversations, - conversationDropdownMenu, - conversationData, - localStorageManager, - setTestIds, - }) => { - setTestIds('EPMRTC-588', 'EPMRTC-816', 'EPMRTC-1494'); - const newName = 'new name to cancel'; - let conversation: Conversation; - const conversationName = GeneratorUtil.randomString(70); - - await test.step('Prepare conversation with long name', async () => { - conversation = conversationData.prepareDefaultConversation( - gpt35Model, - conversationName, - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + const todayConversations = await conversations.getTodayConversations(); + expect + .soft( + todayConversations.includes(messageToSend), + ExpectedMessages.conversationOfToday, + ) + .toBeTruthy(); + }, +); + +dialTest( + 'Rename chat. Cancel.\n' + + 'Long Chat name is cut. Named automatically by the system.\n' + + 'Long chat name while delete and edit', + async ({ + dialHomePage, + conversations, + conversationDropdownMenu, + conversationData, + localStorageManager, + dataInjector, + setTestIds, + }) => { + setTestIds('EPMRTC-588', 'EPMRTC-816', 'EPMRTC-1494'); + const newName = 'new name to cancel'; + let conversation: Conversation; + const conversationName = GeneratorUtil.randomString(70); - await test.step('Open app and verify conversation name is truncated in the side panel', async () => { + await dialTest.step('Prepare conversation with long name', async () => { + conversation = conversationData.prepareDefaultConversation( + gpt35Model, + conversationName, + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }); + + await dialTest.step( + 'Open app and verify conversation name is truncated in the side panel', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); const chatNameOverflow = await conversations @@ -95,9 +92,12 @@ test.describe('Chat bar conversations tests', () => { expect .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Hover over conversation name and verify it is truncated when menu dots appear', async () => { + await dialTest.step( + 'Hover over conversation name and verify it is truncated when menu dots appear', + async () => { await conversations.getConversationByName(conversationName).hover(); const chatNameOverflow = await conversations .getConversationName(conversationName) @@ -105,9 +105,12 @@ test.describe('Chat bar conversations tests', () => { expect .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Select "Rename" from chat menu and verify it is truncated, cursor set at the end', async () => { + await dialTest.step( + 'Select "Rename" from chat menu and verify it is truncated, cursor set at the end', + async () => { await conversations.openConversationDropdownMenu(conversationName); await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); const chatNameOverflow = await conversations @@ -116,9 +119,12 @@ test.describe('Chat bar conversations tests', () => { expect .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) .toBe(undefined); - }); + }, + ); - await test.step('Set new conversation name, cancel edit and verify conversation with initial name shown', async () => { + await dialTest.step( + 'Set new conversation name, cancel edit and verify conversation with initial name shown', + async () => { const nameInput = await conversations.openEditConversationNameMode( conversation.name, newName, @@ -130,9 +136,12 @@ test.describe('Chat bar conversations tests', () => { ExpectedMessages.conversationNameNotUpdated, ) .toBeFalsy(); - }); + }, + ); - await test.step('Select "Delete" from conversation menu and verify its name is truncated when menu dots appear', async () => { + await dialTest.step( + 'Select "Delete" from conversation menu and verify its name is truncated when menu dots appear', + async () => { await conversations.openConversationDropdownMenu(conversationName); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); const chatNameOverflow = await conversations @@ -141,130 +150,134 @@ test.describe('Chat bar conversations tests', () => { expect .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) .toBe(Overflow.ellipsis); - }); - }, - ); - - test( - 'Rename chat before starting the conversation.\n' + - 'Long Chat name is cut. Named manually', - async ({ - dialHomePage, - conversations, - conversationDropdownMenu, - chat, - setTestIds, - }) => { - setTestIds('EPMRTC-584', 'EPMRTC-819'); - const newName = GeneratorUtil.randomString(70); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await conversations.openConversationDropdownMenu( - ExpectedConstants.newConversationTitle, - ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); - await conversations.editConversationNameWithTick( - ExpectedConstants.newConversationTitle, - newName, - ); - expect - .soft( - await conversations.getConversationByName(newName).isVisible(), - ExpectedMessages.conversationNameUpdated, - ) - .toBeTruthy(); + }, + ); + }, +); - const chatNameOverflow = await conversations - .getConversationName(newName) - .getComputedStyleProperty(Styles.text_overflow); - expect - .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) - .toBe(Overflow.ellipsis); +dialTest( + 'Rename chat before starting the conversation.\n' + + 'Long Chat name is cut. Named manually', + async ({ + dialHomePage, + conversations, + conversationDropdownMenu, + chat, + setTestIds, + }) => { + setTestIds('EPMRTC-584', 'EPMRTC-819'); + const newName = GeneratorUtil.randomString(70); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); + await conversations.openConversationDropdownMenu( + ExpectedConstants.newConversationTitle, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); + await conversations.editConversationNameWithTick( + ExpectedConstants.newConversationTitle, + newName, + ); + expect + .soft( + await conversations.getConversationByName(newName).isVisible(), + ExpectedMessages.conversationNameUpdated, + ) + .toBeTruthy(); - await chat.sendRequestWithButton('one more test message'); - expect - .soft( - await conversations.getConversationByName(newName).isVisible(), - ExpectedMessages.conversationNameUpdated, - ) - .toBeTruthy(); - }, - ); - - test( - 'Rename chat after starting the conversation.\n' + - 'Long Chat name is cut in chat header. Named manually.\n' + - 'Tooltip shows full long chat name in chat header. Named manually.\n' + - 'Long chat name is cut in chat header. Named automatically by the system.\n' + - 'Tooltip shows full long chat name in chat header. Named automatically by the system', - async ({ - dialHomePage, - conversations, - conversationDropdownMenu, - conversationData, - localStorageManager, - chatHeader, - tooltip, - setTestIds, - errorPopup, - }) => { - setTestIds( - 'EPMRTC-585', - 'EPMRTC-821', - 'EPMRTC-822', - 'EPMRTC-818', - 'EPMRTC-820', - ); - const newName = GeneratorUtil.randomString(60); - const conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); + const chatNameOverflow = await conversations + .getConversationName(newName) + .getComputedStyleProperty(Styles.text_overflow); + expect + .soft(chatNameOverflow[0], ExpectedMessages.chatNameIsTruncated) + .toBe(Overflow.ellipsis); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations.openConversationDropdownMenu(conversation.name); - await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); - await conversations.editConversationNameWithEnter( - conversation.name, - newName, - ); - expect - .soft( - await conversations.getConversationByName(newName).isVisible(), - ExpectedMessages.conversationNameUpdated, - ) - .toBeTruthy(); + await chat.sendRequestWithButton('one more test message'); + expect + .soft( + await conversations.getConversationByName(newName).isVisible(), + ExpectedMessages.conversationNameUpdated, + ) + .toBeTruthy(); + }, +); + +dialTest( + 'Rename chat after starting the conversation.\n' + + 'Long Chat name is cut in chat header. Named manually.\n' + + 'Tooltip shows full long chat name in chat header. Named manually.\n' + + 'Long chat name is cut in chat header. Named automatically by the system.\n' + + 'Tooltip shows full long chat name in chat header. Named automatically by the system', + async ({ + dialHomePage, + conversations, + conversationDropdownMenu, + conversationData, + dataInjector, + localStorageManager, + chatHeader, + tooltip, + setTestIds, + errorPopup, + }) => { + setTestIds( + 'EPMRTC-585', + 'EPMRTC-821', + 'EPMRTC-822', + 'EPMRTC-818', + 'EPMRTC-820', + ); + const newName = GeneratorUtil.randomString(60); + const conversation = conversationData.prepareDefaultConversation(); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); - const isChatHeaderTitleTruncated = - await chatHeader.chatTitle.isElementWidthTruncated(); - expect - .soft( - isChatHeaderTitleTruncated, - ExpectedMessages.chatHeaderTitleTruncated, - ) - .toBeTruthy(); - await errorPopup.cancelPopup(); - await chatHeader.chatTitle.hoverOver(); - const tooltipChatHeaderTitle = await tooltip.getContent(); - expect - .soft( - tooltipChatHeaderTitle, - ExpectedMessages.headerTitleCorrespondRequest, - ) - .toBe(newName); - - const isTooltipChatHeaderTitleTruncated = - await tooltip.isElementWidthTruncated(); - expect - .soft( - isTooltipChatHeaderTitleTruncated, - ExpectedMessages.headerTitleIsFullyVisible, - ) - .toBeFalsy(); - }, - ); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.openConversationDropdownMenu(conversation.name); + await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); + await conversations.editConversationNameWithEnter( + conversation.name, + newName, + ); + expect + .soft( + await conversations.getConversationByName(newName).isVisible(), + ExpectedMessages.conversationNameUpdated, + ) + .toBeTruthy(); + + const isChatHeaderTitleTruncated = + await chatHeader.chatTitle.isElementWidthTruncated(); + expect + .soft( + isChatHeaderTitleTruncated, + ExpectedMessages.chatHeaderTitleTruncated, + ) + .toBeTruthy(); + await errorPopup.cancelPopup(); + await chatHeader.chatTitle.hoverOver(); + const tooltipChatHeaderTitle = await tooltip.getContent(); + expect + .soft( + tooltipChatHeaderTitle, + ExpectedMessages.headerTitleCorrespondRequest, + ) + .toBe(newName); - test('Menu for New conversation', async ({ + const isTooltipChatHeaderTitleTruncated = + await tooltip.isElementWidthTruncated(); + expect + .soft( + isTooltipChatHeaderTitleTruncated, + ExpectedMessages.headerTitleIsFullyVisible, + ) + .toBeFalsy(); + }, +); + +dialTest( + 'Menu for New conversation', + async ({ dialHomePage, conversations, conversationDropdownMenu, @@ -288,80 +301,82 @@ test.describe('Chat bar conversations tests', () => { MenuOptions.publish, MenuOptions.delete, ]); - }); - - test( - 'Menu for conversation with history.\n' + - 'Special characters are allowed in chat name', - async ({ - dialHomePage, - conversations, - conversationDropdownMenu, - conversationData, - localStorageManager, - setTestIds, - }) => { - setTestIds('EPMRTC-595', 'EPMRTC-1276'); - const conversation = conversationData.prepareDefaultConversation( - gpt35Model, - '!@#$%^&()_{}[]:;"\',./<>?/-`~', - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); + }, +); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations.getConversationByName(conversation.name).waitFor(); - await conversations.openConversationDropdownMenu(conversation.name); - const menuOptions = await conversationDropdownMenu.getAllMenuOptions(); - expect - .soft(menuOptions, ExpectedMessages.contextMenuOptionsValid) - .toEqual([ - MenuOptions.rename, - MenuOptions.compare, - MenuOptions.replay, - MenuOptions.playback, - MenuOptions.export, - MenuOptions.moveTo, - MenuOptions.share, - MenuOptions.publish, - MenuOptions.delete, - ]); - }, - ); +dialTest( + 'Menu for conversation with history.\n' + + 'Special characters are allowed in chat name', + async ({ + dialHomePage, + conversations, + conversationDropdownMenu, + conversationData, + localStorageManager, + dataInjector, + setTestIds, + }) => { + setTestIds('EPMRTC-595', 'EPMRTC-1276'); + const conversation = conversationData.prepareDefaultConversation( + gpt35Model, + '!@$^&()_{}[]"\'.<>-`~', + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); - test('Delete chat in the folder', async ({ + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.getConversationByName(conversation.name).waitFor(); + await conversations.openConversationDropdownMenu(conversation.name); + const menuOptions = await conversationDropdownMenu.getAllMenuOptions(); + expect + .soft(menuOptions, ExpectedMessages.contextMenuOptionsValid) + .toEqual([ + MenuOptions.rename, + MenuOptions.compare, + MenuOptions.replay, + MenuOptions.playback, + MenuOptions.export, + MenuOptions.moveTo, + MenuOptions.share, + MenuOptions.publish, + MenuOptions.delete, + ]); + }, +); + +dialTest( + 'Delete chat in the folder', + async ({ dialHomePage, folderConversations, conversationData, - localStorageManager, + dataInjector, conversationDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-607'); const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); - await localStorageManager.setFolders(conversationInFolder.folders); - await localStorageManager.setConversationHistory( - conversationInFolder.conversations[0], - ); - await localStorageManager.setSelectedConversation( - conversationInFolder.conversations[0], + await dataInjector.createConversations( + conversationInFolder.conversations, + conversationInFolder.folders, ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await folderConversations.openFolderEntityDropdownMenu( conversationInFolder.folders.name, conversationInFolder.conversations[0].name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await folderConversations - .getFolderConversationInput(conversationInFolder.conversations[0].name) - .clickTickButton(); + await folderConversations.deleteConversation( + conversationInFolder.conversations[0].name, + ); expect .soft( await folderConversations.isFolderEntityVisible( @@ -371,19 +386,23 @@ test.describe('Chat bar conversations tests', () => { ExpectedMessages.folderConversationDeleted, ) .toBeFalsy(); - }); + }, +); - test('Delete chat located in the root', async ({ +dialTest( + 'Delete chat located in the root', + async ({ dialHomePage, conversations, conversationDropdownMenu, conversationData, + dataInjector, localStorageManager, setTestIds, }) => { setTestIds('EPMRTC-608'); const conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); await dialHomePage.openHomePage(); @@ -401,115 +420,125 @@ test.describe('Chat bar conversations tests', () => { ExpectedMessages.conversationDeleted, ) .toBeFalsy(); - }); - - test( - 'Chat sorting. Yesterday.\n' + - 'Chat sorting. Last 7 days when chat with lastActivityDate is the day before yesterday.\n' + - 'Chat sorting. Last 30 days when chat with lastActivityDate is the 8th day.\n' + - 'Chat sorting. Yesterday chat is moved to Today section after regenerate response.\n' + - 'Chat sorting. Last 7 Days chat is moved to Today section after editing already answered message', - async ({ - dialHomePage, - conversations, - chat, - chatMessages, - conversationData, - localStorageManager, - setTestIds, - }) => { - setTestIds( - 'EPMRTC-775', - 'EPMRTC-796', - 'EPMRTC-798', - 'EPMRTC-777', - 'EPMRTC-780', - ); - const yesterdayConversation = - conversationData.prepareYesterdayConversation(gpt35Model, 'yesterday'); - conversationData.resetData(); - const lastWeekConversation = conversationData.prepareLastWeekConversation( - gpt35Model, - 'last week', - ); - conversationData.resetData(); - const lastMonthConversation = - conversationData.prepareLastMonthConversation(gpt35Model, 'last month'); - await localStorageManager.setConversationHistory( - yesterdayConversation, - lastWeekConversation, - lastMonthConversation, - ); - await localStorageManager.setSelectedConversation(yesterdayConversation); + }, +); + +//TODO: enable when item modification date is implemented on backend +dialTest.skip( + 'Chat sorting. Yesterday.\n' + + 'Chat sorting. Last 7 days when chat with lastActivityDate is the day before yesterday.\n' + + 'Chat sorting. Last 30 days when chat with lastActivityDate is the 8th day.\n' + + 'Chat sorting. Yesterday chat is moved to Today section after regenerate response.\n' + + 'Chat sorting. Last 7 Days chat is moved to Today section after editing already answered message', + async ({ + dialHomePage, + conversations, + chat, + chatMessages, + conversationData, + dataInjector, + localStorageManager, + setTestIds, + }) => { + setTestIds( + 'EPMRTC-775', + 'EPMRTC-796', + 'EPMRTC-798', + 'EPMRTC-777', + 'EPMRTC-780', + ); + const yesterdayConversation = conversationData.prepareYesterdayConversation( + gpt35Model, + 'yesterday', + ); + conversationData.resetData(); + const lastWeekConversation = conversationData.prepareLastWeekConversation( + gpt35Model, + 'last week', + ); + conversationData.resetData(); + const lastMonthConversation = conversationData.prepareLastMonthConversation( + gpt35Model, + 'last month', + ); + await dataInjector.createConversations([ + yesterdayConversation, + lastWeekConversation, + lastMonthConversation, + ]); + await localStorageManager.setSelectedConversation(yesterdayConversation); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - const yesterdayConversations = - await conversations.getYesterdayConversations(); - expect - .soft( - yesterdayConversations.includes(yesterdayConversation.name), - ExpectedMessages.conversationOfYesterday, - ) - .toBeTruthy(); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + const yesterdayConversations = + await conversations.getYesterdayConversations(); + expect + .soft( + yesterdayConversations.includes(yesterdayConversation.name), + ExpectedMessages.conversationOfYesterday, + ) + .toBeTruthy(); - const lastWeekConversations = - await conversations.getLastWeekConversations(); - expect - .soft( - lastWeekConversations.includes(lastWeekConversation.name), - ExpectedMessages.conversationOfLastWeek, - ) - .toBeTruthy(); + const lastWeekConversations = + await conversations.getLastWeekConversations(); + expect + .soft( + lastWeekConversations.includes(lastWeekConversation.name), + ExpectedMessages.conversationOfLastWeek, + ) + .toBeTruthy(); - const lastMonthConversations = - await conversations.getLastMonthConversations(); - expect - .soft( - lastMonthConversations.includes(lastMonthConversation.name), - ExpectedMessages.conversationOfLastMonth, - ) - .toBeTruthy(); + const lastMonthConversations = + await conversations.getLastMonthConversations(); + expect + .soft( + lastMonthConversations.includes(lastMonthConversation.name), + ExpectedMessages.conversationOfLastMonth, + ) + .toBeTruthy(); - await chat.regenerateResponse(); - let todayConversations = await conversations.getTodayConversations(); - expect - .soft(todayConversations.length, ExpectedMessages.conversationOfToday) - .toBe(1); - - const messageToEdit = lastWeekConversation.messages[0].content; - await conversations.selectConversation(lastWeekConversation.name); - await chatMessages.openEditMessageMode(messageToEdit); - await chatMessages.editMessage(messageToEdit, 'updated message'); - todayConversations = await conversations.getTodayConversations(); - expect - .soft(todayConversations.length, ExpectedMessages.conversationOfToday) - .toBe(2); + await chat.regenerateResponse(); + let todayConversations = await conversations.getTodayConversations(); + expect + .soft(todayConversations.length, ExpectedMessages.conversationOfToday) + .toBe(1); + + const messageToEdit = lastWeekConversation.messages[0].content; + await conversations.selectConversation(lastWeekConversation.name); + await chatMessages.openEditMessageMode(messageToEdit); + await chatMessages.editMessage(messageToEdit, 'updated message'); + todayConversations = await conversations.getTodayConversations(); + expect + .soft(todayConversations.length, ExpectedMessages.conversationOfToday) + .toBe(2); - await conversations.selectConversation(lastMonthConversation.name); - await chat.sendRequestWithButton('one more test message'); - todayConversations = await conversations.getTodayConversations(); - expect - .soft( - todayConversations.includes(lastMonthConversation.name), - ExpectedMessages.conversationOfToday, - ) - .toBeTruthy(); - }, - ); + await conversations.selectConversation(lastMonthConversation.name); + await chat.sendRequestWithButton('one more test message'); + todayConversations = await conversations.getTodayConversations(); + expect + .soft( + todayConversations.includes(lastMonthConversation.name), + ExpectedMessages.conversationOfToday, + ) + .toBeTruthy(); + }, +); - test('Chat is moved to folder created from Move to', async ({ +dialTest( + 'Chat is moved to folder created from Move to', + async ({ dialHomePage, conversations, conversationDropdownMenu, conversationData, + dataInjector, localStorageManager, folderConversations, setTestIds, }) => { setTestIds('EPMRTC-864'); const conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); await dialHomePage.openHomePage(); @@ -519,11 +548,12 @@ test.describe('Chat bar conversations tests', () => { await conversationDropdownMenu.selectMenuOption(MenuOptions.newFolder); await folderConversations.expandCollapseFolder( - ExpectedConstants.newFolderTitle, + ExpectedConstants.newFolderWithIndexTitle(1), + { isHttpMethodTriggered: true }, ); const isFolderConversationVisible = await folderConversations.isFolderEntityVisible( - ExpectedConstants.newFolderTitle, + ExpectedConstants.newFolderWithIndexTitle(1), conversation.name, ); expect @@ -534,42 +564,58 @@ test.describe('Chat bar conversations tests', () => { .toBeTruthy(); const folderNameColor = await folderConversations.getFolderNameColor( - ExpectedConstants.newFolderTitle, + ExpectedConstants.newFolderWithIndexTitle(1), ); expect .soft(folderNameColor[0], ExpectedMessages.folderNameColorIsValid) .toBe(Colors.textAccentSecondary); - }); - - test( - 'Chat is moved to folder from Move to list.\n' + - 'Long folder name is cut in Move to menu', - async ({ - dialHomePage, - conversations, - conversationDropdownMenu, - conversationData, - localStorageManager, - folderConversations, - setTestIds, - }) => { - setTestIds('EPMRTC-863', 'EPMRTC-942'); - const folderName = GeneratorUtil.randomString(70); - let conversation: Conversation; - let folderToMoveIn: FolderInterface; - - await test.step('Prepare conversation and folder with long name to move conversation in', async () => { - folderToMoveIn = conversationData.prepareFolder(folderName); + }, +); + +dialTest( + 'Chat is moved to folder from Move to list.\n' + + 'Long folder name is cut in Move to menu', + async ({ + dialHomePage, + conversations, + conversationDropdownMenu, + conversationData, + localStorageManager, + dataInjector, + folderConversations, + folderDropdownMenu, + chatBar, + setTestIds, + }) => { + setTestIds('EPMRTC-863', 'EPMRTC-942'); + const folderName = GeneratorUtil.randomString(70); + let conversation: Conversation; + + await dialTest.step( + 'Prepare conversation and folder with long name to move conversation in', + async () => { conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setFolders(folderToMoveIn); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); - await test.step('Open "Move to" menu option for conversation and verify folder name is truncated', async () => { + await dialTest.step( + 'Open "Move to" menu option for conversation and verify folder name is truncated', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await folderConversations.expandCollapseFolder(folderToMoveIn.name); + await chatBar.createNewFolder(); + await folderConversations.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + 1, + ); + await folderDropdownMenu.selectMenuOption(MenuOptions.rename); + await folderConversations.editFolderNameWithEnter( + ExpectedConstants.newFolderWithIndexTitle(1), + folderName, + ); + await conversations.openConversationDropdownMenu(conversation.name); await conversationDropdownMenu.selectMenuOption(MenuOptions.moveTo); @@ -581,10 +627,16 @@ test.describe('Chat bar conversations tests', () => { expect .soft(moveToFolderOverflow[0], ExpectedMessages.folderNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Select folder name from menu and conversation is moved into folder', async () => { - await conversationDropdownMenu.selectMenuOption(folderName); + await dialTest.step( + 'Select folder name from menu and conversation is moved into folder', + async () => { + await conversations.selectMoveToMenuOption(folderName); + await folderConversations.expandCollapseFolder(folderName, { + isHttpMethodTriggered: true, + }); const isFolderConversationVisible = await folderConversations.isFolderEntityVisible( folderName, @@ -596,40 +648,40 @@ test.describe('Chat bar conversations tests', () => { ExpectedMessages.conversationMovedToFolder, ) .toBeTruthy(); - }); - }, - ); + }, + ); + }, +); - test('Delete all conversations. Cancel', async ({ +dialTest( + 'Delete all conversations. Cancel', + async ({ dialHomePage, conversations, conversationData, - localStorageManager, folderConversations, chatBar, confirmationDialog, + dataInjector, setTestIds, }) => { setTestIds('EPMRTC-610'); - const emptyFolder = conversationData.prepareFolder(); conversationData.resetData(); const singleConversation = conversationData.prepareDefaultConversation(); conversationData.resetData(); const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); - await localStorageManager.setConversationHistory( - singleConversation, - conversationInFolder.conversations[0], - ); - await localStorageManager.setFolders( - emptyFolder, + await dataInjector.createConversations( + [singleConversation, ...conversationInFolder.conversations], conversationInFolder.folders, ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); + await chatBar.createNewFolder(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await chatBar.deleteAllEntities(); await confirmationDialog.cancelDialog(); @@ -647,7 +699,7 @@ test.describe('Chat bar conversations tests', () => { .toBeTruthy(); const isFolderVisible = await folderConversations - .getFolderByName(emptyFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .isVisible(); expect .soft(isFolderVisible, ExpectedMessages.folderNotDeleted) @@ -662,66 +714,73 @@ test.describe('Chat bar conversations tests', () => { ExpectedMessages.conversationNotDeleted, ) .toBeTruthy(); - }); + }, +); - test('Delete all conversations. Clear', async ({ +dialTest( + 'Delete all conversations. Clear', + async ({ dialHomePage, conversations, conversationData, promptData, - localStorageManager, + dataInjector, folderConversations, chatBar, confirmationDialog, folderPrompts, prompts, + promptBar, setTestIds, }) => { setTestIds('EPMRTC-611'); - const emptyFolder = conversationData.prepareFolder(); - conversationData.resetData(); const singleConversation = conversationData.prepareDefaultConversation(); conversationData.resetData(); const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); conversationData.resetData(); - const nestedFolders = conversationData.prepareNestedFolder(3); - - const emptyPromptFolder = promptData.prepareFolder(); - promptData.resetData(); const promptInFolder = promptData.prepareDefaultPromptInFolder(); promptData.resetData(); const singlePrompt = promptData.prepareDefaultPrompt(); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await localStorageManager.updateConversationHistory( - singleConversation, - conversationInFolder.conversations[0], - ); - await localStorageManager.updatePrompts( - singlePrompt, - promptInFolder.prompts[0], - ); - await localStorageManager.updateFolders( - emptyFolder, + await dataInjector.updateConversations( + [singleConversation, ...conversationInFolder.conversations], conversationInFolder.folders, - emptyPromptFolder, + ); + await dataInjector.updatePrompts( + [singlePrompt, ...promptInFolder.prompts], promptInFolder.folders, - ...nestedFolders, ); await dialHomePage.reloadPage(); await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); + await promptBar.createNewFolder(); + for (let i = 1; i <= 4; i++) { + await chatBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await chatBar.dragAndDropEntityToFolder( + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); } + await folderConversations.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + ); + await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await chatBar.deleteAllEntities(); - await confirmationDialog.confirm(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); let i = 2; while (i > 0) { @@ -735,13 +794,13 @@ test.describe('Chat bar conversations tests', () => { .toBeFalsy(); const isFolderVisible = await folderConversations - .getFolderByName(emptyFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(4)) .isVisible(); expect.soft(isFolderVisible, ExpectedMessages.folderDeleted).toBeFalsy(); - for (const nestedFolder of nestedFolders) { + for (let i = 1; i <= 3; i++) { const isNestedFolderVisible = await folderConversations - .getFolderByName(nestedFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) .isVisible(); expect .soft(isNestedFolderVisible, ExpectedMessages.folderDeleted) @@ -755,12 +814,9 @@ test.describe('Chat bar conversations tests', () => { .soft(isSingleConversationVisible, ExpectedMessages.conversationDeleted) .toBeFalsy(); - const isNewConversationVisible = await conversations + await conversations .getConversationByName(ExpectedConstants.newConversationTitle) - .isVisible(); - expect - .soft(isNewConversationVisible, ExpectedMessages.newConversationCreated) - .toBeTruthy(); + .waitFor(); if (i === 1) { await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); @@ -774,11 +830,15 @@ test.describe('Chat bar conversations tests', () => { .toBeTruthy(); const isPromptFolderVisible = await folderPrompts - .getFolderByName(emptyPromptFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .isVisible(); - expect - .soft(isPromptFolderVisible, ExpectedMessages.folderNotDeleted) - .toBeTruthy(); + i === 1 + ? expect + .soft(isPromptFolderVisible, ExpectedMessages.folderNotDeleted) + .toBeFalsy() + : expect + .soft(isPromptFolderVisible, ExpectedMessages.folderNotDeleted) + .toBeTruthy(); const isSinglePromptVisible = await prompts .getPromptByName(singlePrompt.name) @@ -793,9 +853,13 @@ test.describe('Chat bar conversations tests', () => { } i--; } - }); + }, +); - test('Chat sorting. Sections can be collapsed and expanded', async ({ +//TODO: enable when item modification date is implemented on backend +dialTest.skip( + 'Chat sorting. Sections can be collapsed and expanded', + async ({ dialHomePage, conversations, conversationData, @@ -803,65 +867,76 @@ test.describe('Chat bar conversations tests', () => { setTestIds, }) => { setTestIds('EPMRTC-1313'); - await test.step('Prepare conversations for all available chronologies', async () => { - const yesterdayConversation = - conversationData.prepareYesterdayConversation(gpt35Model); - conversationData.resetData(); - const lastWeekConversation = - conversationData.prepareLastWeekConversation(gpt35Model); - conversationData.resetData(); - const lastMonthConversation = - conversationData.prepareLastMonthConversation(gpt35Model); - conversationData.resetData(); - const otherConversation = - conversationData.prepareOlderConversation(gpt35Model); - await localStorageManager.setConversationHistory( - yesterdayConversation, - lastWeekConversation, - lastMonthConversation, - otherConversation, - ); - }); + await dialTest.step( + 'Prepare conversations for all available chronologies', + async () => { + const yesterdayConversation = + conversationData.prepareYesterdayConversation(gpt35Model); + conversationData.resetData(); + const lastWeekConversation = + conversationData.prepareLastWeekConversation(gpt35Model); + conversationData.resetData(); + const lastMonthConversation = + conversationData.prepareLastMonthConversation(gpt35Model); + conversationData.resetData(); + const otherConversation = + conversationData.prepareOlderConversation(gpt35Model); + await localStorageManager.setConversationHistory( + yesterdayConversation, + lastWeekConversation, + lastMonthConversation, + otherConversation, + ); + }, + ); - await test.step('Verify it is possible to expand/collapse random chronology', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); + await dialTest.step( + 'Verify it is possible to expand/collapse random chronology', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + + const randomChronology = GeneratorUtil.randomArrayElement([ + Chronology.today, + Chronology.yesterday, + Chronology.lastSevenDays, + Chronology.lastThirtyDays, + Chronology.older, + ]); + await conversations.chronologyByTitle(randomChronology).click(); - const randomChronology = GeneratorUtil.randomArrayElement([ - Chronology.today, - Chronology.yesterday, - Chronology.lastSevenDays, - Chronology.lastThirtyDays, - Chronology.older, - ]); - await conversations.chronologyByTitle(randomChronology).click(); + let chronologyConversations = + await conversations.getChronologyConversations(randomChronology); + expect + .soft( + chronologyConversations.length, + ExpectedMessages.chronologyMessageCountIsCorrect, + ) + .toBe(0); - let chronologyConversations = - await conversations.getChronologyConversations(randomChronology); - expect - .soft( - chronologyConversations.length, - ExpectedMessages.chronologyMessageCountIsCorrect, - ) - .toBe(0); - - await conversations.chronologyByTitle(randomChronology).click(); - chronologyConversations = - await conversations.getChronologyConversations(randomChronology); - expect - .soft( - chronologyConversations.length, - ExpectedMessages.chronologyMessageCountIsCorrect, - ) - .toBe(1); - }); - }); + await conversations.chronologyByTitle(randomChronology).click(); + chronologyConversations = + await conversations.getChronologyConversations(randomChronology); + expect + .soft( + chronologyConversations.length, + ExpectedMessages.chronologyMessageCountIsCorrect, + ) + .toBe(1); + }, + ); + }, +); - test('Search conversation when no folders', async ({ +dialTest( + 'Search conversation when no folders', + async ({ dialHomePage, conversations, conversationData, - localStorageManager, + dataInjector, chatBar, chatBarSearch, setTestIds, @@ -869,77 +944,88 @@ test.describe('Chat bar conversations tests', () => { setTestIds('EPMRTC-1188'); const firstSearchTerm = 'EPAM'; const specialSymbolsSearchTerm = '@'; + const specialSymbolName = 'test' + specialSymbolsSearchTerm + 'chat'; - await test.step('Prepare conversations with different content', async () => { - const firstConversation = - conversationData.prepareModelConversationBasedOnRequests(gpt35Model, [ - request, - ]); - conversationData.resetData(); - - const secondConversation = - conversationData.prepareModelConversationBasedOnRequests( + await dialTest.step( + 'Prepare conversations with different content', + async () => { + const firstConversation = conversationData.prepareDefaultConversation( gpt4Model, - ['What is AI?'], matchingConversationName, ); - conversationData.resetData(); + conversationData.resetData(); - const thirdConversation = - conversationData.prepareModelConversationBasedOnRequests( + const secondConversation = conversationData.prepareDefaultConversation( bisonModel, - [request], - specialSymbolsName, + specialSymbolName, ); - await localStorageManager.setConversationHistory( - firstConversation, - secondConversation, - thirdConversation, - ); - }); - - await test.step('Type not matching search term is "Search chat..." field and verify no results found', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await chatBarSearch.setSearchValue(notMatchingSearchTerm); - const noResult = await chatBar.noResultFoundIcon.getElementInnerContent(); - expect - .soft(noResult, ExpectedMessages.noResultsFound) - .toBe(ExpectedConstants.noResults); - }); + await dataInjector.createConversations([ + firstConversation, + secondConversation, + ]); + }, + ); - await test.step('Clear search field and verify all conversations are displayed', async () => { - await chatBarSearch.setSearchValue(''); - const results = await conversations.getTodayConversations(); - expect - .soft(results.length, ExpectedMessages.searchResultCountIsValid) - .toBe(4); - }); + await dialTest.step( + 'Type not matching search term is "Search chat..." field and verify no results found', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await chatBarSearch.setSearchValue(notMatchingSearchTerm); + const noResult = + await chatBar.noResultFoundIcon.getElementInnerContent(); + expect + .soft(noResult, ExpectedMessages.noResultsFound) + .toBe(ExpectedConstants.noResults); + }, + ); - await test.step('Search by first term and verify search results are correct', async () => { - for (const term of [firstSearchTerm, secondSearchTerm]) { - await chatBarSearch.setSearchValue(term); + await dialTest.step( + 'Clear search field and verify all conversations are displayed', + async () => { + await chatBarSearch.setSearchValue(''); const results = await conversations.getTodayConversations(); expect .soft(results.length, ExpectedMessages.searchResultCountIsValid) .toBe(3); - } - }); + }, + ); - await test.step('Search by special symbol and verify search results are correct', async () => { - await chatBarSearch.setSearchValue(specialSymbolsSearchTerm); - const results = await conversations.getTodayConversations(); - expect - .soft(results.length, ExpectedMessages.searchResultCountIsValid) - .toBe(1); - }); - }); + await dialTest.step( + 'Search by first term and verify search results are correct', + async () => { + for (const term of [firstSearchTerm, secondSearchTerm]) { + await chatBarSearch.setSearchValue(term); + const results = await conversations.getTodayConversations(); + expect + .soft(results.length, ExpectedMessages.searchResultCountIsValid) + .toBe(1); + } + }, + ); + + await dialTest.step( + 'Search by special symbol and verify search results are correct', + async () => { + await chatBarSearch.setSearchValue(specialSymbolsSearchTerm); + const results = await conversations.getTodayConversations(); + expect + .soft(results.length, ExpectedMessages.searchResultCountIsValid) + .toBe(1); + }, + ); + }, +); - test('Search conversation located in folders', async ({ +dialTest( + 'Search conversation located in folders', + async ({ dialHomePage, conversationData, - localStorageManager, + dataInjector, chatBar, folderConversations, chatBarSearch, @@ -949,90 +1035,104 @@ test.describe('Chat bar conversations tests', () => { let firstFolder: FolderInterface; let secondFolder: FolderInterface; - let thirdFolder: FolderInterface; - - await test.step('Prepare conversations in folders with different content', async () => { - firstFolder = conversationData.prepareFolder(); - conversationData.resetData(); - - const firstConversation = - conversationData.prepareModelConversationBasedOnRequests(gpt35Model, [ - request, - ]); - firstConversation.folderId = firstFolder.id; - conversationData.resetData(); - const secondConversation = conversationData.prepareDefaultConversation( - gpt4Model, - matchingConversationName, - ); - secondConversation.folderId = firstFolder.id; - conversationData.resetData(); + await dialTest.step( + 'Prepare conversations in folders with different content', + async () => { + firstFolder = conversationData.prepareFolder(); + conversationData.resetData(); - secondFolder = conversationData.prepareFolder(); - conversationData.resetData(); + const firstConversation = + conversationData.prepareModelConversationBasedOnRequests(gpt35Model, [ + request, + ]); + firstConversation.folderId = firstFolder.id; + conversationData.resetData(); - const thirdConversation = - conversationData.prepareModelConversationBasedOnRequests( - bisonModel, - [request], - specialSymbolsName, + const secondConversation = conversationData.prepareDefaultConversation( + gpt4Model, + matchingConversationName, ); - thirdConversation.folderId = secondFolder.id; - conversationData.resetData(); - - const fourthConversation = - conversationData.prepareDefaultConversation(gpt35Model); - fourthConversation.folderId = secondFolder.id; - conversationData.resetData(); + secondConversation.folderId = firstFolder.id; + conversationData.resetData(); - thirdFolder = conversationData.prepareFolder(); + secondFolder = conversationData.prepareFolder(); + conversationData.resetData(); - await localStorageManager.setConversationHistory( - firstConversation, - secondConversation, - thirdConversation, - fourthConversation, - ); - await localStorageManager.setFolders( - firstFolder, - secondFolder, - thirdFolder, - ); - }); + const thirdConversation = + conversationData.prepareModelConversationBasedOnRequests( + bisonModel, + [request], + specialSymbolsName, + ); + thirdConversation.folderId = secondFolder.id; + conversationData.resetData(); + + const fourthConversation = + conversationData.prepareDefaultConversation(gpt35Model); + fourthConversation.folderId = secondFolder.id; + conversationData.resetData(); + + await dataInjector.createConversations( + [ + firstConversation, + secondConversation, + thirdConversation, + fourthConversation, + ], + firstFolder, + secondFolder, + ); + }, + ); - await test.step('Type not matching search term is "Search chat..." field and verify no results found', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await chatBarSearch.setSearchValue(notMatchingSearchTerm); - const noResult = await chatBar.noResultFoundIcon.getElementInnerContent(); - expect - .soft(noResult, ExpectedMessages.noResultsFound) - .toBe(ExpectedConstants.noResults); - }); + await dialTest.step( + 'Type not matching search term is "Search chat..." field and verify no results found', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await chatBar.createNewFolder(); + await chatBarSearch.setSearchValue(notMatchingSearchTerm); + const noResult = + await chatBar.noResultFoundIcon.getElementInnerContent(); + expect + .soft(noResult, ExpectedMessages.noResultsFound) + .toBe(ExpectedConstants.noResults); + }, + ); - await test.step('Clear search field and verify all conversations are displayed', async () => { - await chatBarSearch.setSearchValue(''); - const results = await folderConversations.getFoldersCount(); - expect.soft(results, ExpectedMessages.searchResultCountIsValid).toBe(3); - }); + await dialTest.step( + 'Clear search field and verify all conversations are displayed', + async () => { + await chatBarSearch.setSearchValue(''); + const results = await folderConversations.getFoldersCount(); + expect.soft(results, ExpectedMessages.searchResultCountIsValid).toBe(3); + }, + ); - await test.step('Search by search term and verify search results are correct, empty folder is not shown', async () => { - await chatBarSearch.setSearchValue(secondSearchTerm); - let results = await folderConversations.getFolderEntitiesCount( - firstFolder.name, - ); - results += await folderConversations.getFolderEntitiesCount( - secondFolder.name, - ); - expect.soft(results, ExpectedMessages.searchResultCountIsValid).toBe(3); + await dialTest.step( + 'Search by search term and verify search results are correct, empty folder is not shown', + async () => { + await chatBarSearch.setSearchValue(secondSearchTerm); + let results = await folderConversations.getFolderEntitiesCount( + firstFolder.name, + ); + results += await folderConversations.getFolderEntitiesCount( + secondFolder.name, + ); + expect + .soft(results, ExpectedMessages.searchResultCountIsValid) + .toBe(isApiStorageType ? 2 : 3); - const isEmptyFolderVisible = await folderConversations - .getFolderByName(thirdFolder.name) - .isVisible(); - expect - .soft(isEmptyFolderVisible, ExpectedMessages.folderIsNotVisible) - .toBeFalsy(); - }); - }); -}); + const isEmptyFolderVisible = await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .isVisible(); + expect + .soft(isEmptyFolderVisible, ExpectedMessages.folderIsNotVisible) + .toBeFalsy(); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts index de62ef58c6..eca8faf949 100644 --- a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts @@ -1,26 +1,19 @@ import { Conversation } from '@/chat/types/chat'; import { FolderInterface } from '@/chat/types/folder'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, FolderConversation, MenuOptions, } from '@/src/testData'; -import { Attributes, Overflow, Styles } from '@/src/ui/domData'; +import { Overflow, Styles } from '@/src/ui/domData'; import { GeneratorUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -test.describe('Chat bar folder conversations tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Create new chat folder', async ({ - dialHomePage, - chatBar, - folderConversations, - setTestIds, - }) => { +dialTest( + 'Create new chat folder', + async ({ dialHomePage, chatBar, folderConversations, setTestIds }) => { setTestIds('EPMRTC-569'); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); @@ -28,121 +21,144 @@ test.describe('Chat bar folder conversations tests', () => { expect .soft( await folderConversations - .getFolderByName(ExpectedConstants.newFolderTitle) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .isVisible(), ExpectedMessages.newFolderCreated, ) .toBeTruthy(); - }); + }, +); - test( - `Rename chat folder when it's empty using Enter.\n` + - 'Rename folders on nested levels', - async ({ - dialHomePage, - conversationData, - folderConversations, - localStorageManager, - folderDropdownMenu, - setTestIds, - }) => { - setTestIds('EPMRTC-571', 'EPMRTC-1371'); - const nestedFolders = conversationData.prepareNestedFolder(3); - await localStorageManager.setFolders(...nestedFolders); +dialTest( + `Rename chat folder when it's empty using Enter.\n` + + 'Rename folders on nested levels', + async ({ + dialHomePage, + folderConversations, + folderDropdownMenu, + chatBar, + setTestIds, + }) => { + setTestIds('EPMRTC-571', 'EPMRTC-1371'); + const newName = 'updated folder name'; + const randomFolderIndex = GeneratorUtil.randomNumberInRange(2) + 1; - const newName = 'updated folder name'; - const randomFolder = GeneratorUtil.randomArrayElement(nestedFolders); - const randomFolderIndex = nestedFolders.indexOf(randomFolder); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - await folderConversations.openFolderDropdownMenu(randomFolder.name); - await folderDropdownMenu.selectMenuOption(MenuOptions.rename); - await folderConversations.editFolderNameWithEnter( - randomFolder.name, - newName, + for (let i = 1; i <= 3; i++) { + await chatBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await chatBar.dragAndDropEntityToFolder( + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), ); - expect - .soft( - await folderConversations.getFolderByName(newName).isVisible(), - ExpectedMessages.folderNameUpdated, - ) - .toBeTruthy(); + } + await folderConversations.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + { isHttpMethodTriggered: true }, + ); - for (let i = 0; i < nestedFolders.length; i++) { - if (i !== randomFolderIndex) { - expect - .soft( - await folderConversations - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderNameNotUpdated, - ) - .toBeTruthy(); - } + await folderConversations.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(randomFolderIndex), + ); + await folderDropdownMenu.selectMenuOption(MenuOptions.rename); + await folderConversations.editFolderNameWithEnter( + ExpectedConstants.newFolderWithIndexTitle(randomFolderIndex), + newName, + ); + expect + .soft( + await folderConversations.getFolderByName(newName).isVisible(), + ExpectedMessages.folderNameUpdated, + ) + .toBeTruthy(); + + for (let i = 1; i <= 3; i++) { + if (i !== randomFolderIndex) { + expect + .soft( + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) + .isVisible(), + ExpectedMessages.folderNameNotUpdated, + ) + .toBeTruthy(); } - }, - ); + } + }, +); - test(`Cancel folder renaming on "x"`, async ({ +dialTest( + `Cancel folder renaming on "x"`, + async ({ dialHomePage, - conversationData, folderConversations, - localStorageManager, conversationDropdownMenu, + chatBar, setTestIds, }) => { setTestIds('EPMRTC-572'); const newName = 'updated folder name'; - const folder = conversationData.prepareDefaultFolder(); - await localStorageManager.setFolders(folder); - await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await folderConversations.openFolderDropdownMenu(folder.name); + await chatBar.createNewFolder(); + await folderConversations.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); await conversationDropdownMenu.selectMenuOption(MenuOptions.rename); const folderInput = await folderConversations.editFolderName( - folder.name, + ExpectedConstants.newFolderWithIndexTitle(1), newName, ); await folderInput.clickCancelButton(); expect .soft( - await folderConversations.getFolderByName(folder.name).isVisible(), + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .isVisible(), ExpectedMessages.folderNameNotUpdated, ) .toBeTruthy(); - }); + }, +); - test( - 'Rename chat folder when chats are inside using check button\n' + - 'Long Folder name is cut', - async ({ - dialHomePage, - conversationData, - folderConversations, - localStorageManager, - folderDropdownMenu, - setTestIds, - }) => { - setTestIds('EPMRTC-573', 'EPMRTC-574'); - const folderName = GeneratorUtil.randomString(70); - const newConversationName = 'updated folder name'; +dialTest( + 'Rename chat folder when chats are inside using check button\n' + + 'Long Folder name is cut', + async ({ + dialHomePage, + conversationData, + folderConversations, + dataInjector, + folderDropdownMenu, + setTestIds, + }) => { + setTestIds('EPMRTC-573', 'EPMRTC-574'); + const folderName = GeneratorUtil.randomString(70); + const newConversationName = 'updated folder name'; - await test.step('Prepare folder with long name and conversation inside folder', async () => { + await dialTest.step( + 'Prepare folder with long name and conversation inside folder', + async () => { const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); conversationInFolder.folders.name = folderName; - await localStorageManager.setFolders(conversationInFolder.folders); - await localStorageManager.setConversationHistory( - conversationInFolder.conversations[0], + await dataInjector.createConversations( + conversationInFolder.conversations, + conversationInFolder.folders, ); - }); + }, + ); - await test.step('Open app and verify folder name is truncated in the side panel', async () => { + await dialTest.step( + 'Open app and verify folder name is truncated in the side panel', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -153,9 +169,12 @@ test.describe('Chat bar folder conversations tests', () => { expect .soft(folderNameOverflow[0], ExpectedMessages.folderNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Hover over folder name and verify it is truncated when menu dots appear', async () => { + await dialTest.step( + 'Hover over folder name and verify it is truncated when menu dots appear', + async () => { await folderConversations.getFolderByName(folderName).hover(); const folderNameOverflow = await folderConversations .getFolderName(folderName) @@ -163,9 +182,12 @@ test.describe('Chat bar folder conversations tests', () => { expect .soft(folderNameOverflow[0], ExpectedMessages.folderNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Open edit folder name mode and verify it is truncated', async () => { + await dialTest.step( + 'Open edit folder name mode and verify it is truncated', + async () => { await folderConversations.openFolderDropdownMenu(folderName); await folderDropdownMenu.selectMenuOption(MenuOptions.rename); const folderInputOverflow = await folderConversations @@ -174,9 +196,12 @@ test.describe('Chat bar folder conversations tests', () => { expect .soft(folderInputOverflow[0], ExpectedMessages.folderNameIsTruncated) .toBe(Overflow.ellipsis); - }); + }, + ); - await test.step('Edit folder name using tick button and verify it is renamed', async () => { + await dialTest.step( + 'Edit folder name using tick button and verify it is renamed', + async () => { await folderConversations.editFolderNameWithTick( folderName, newConversationName, @@ -189,127 +214,133 @@ test.describe('Chat bar folder conversations tests', () => { ExpectedMessages.folderNameUpdated, ) .toBeTruthy(); - }); - }, - ); + }, + ); + }, +); - test( - 'Folders can expand and collapse.\n' + - '[UI] Expand/collapse icon near chat folder appears if there is any chat inside', - async ({ - dialHomePage, - conversationData, - folderConversations, - localStorageManager, - setTestIds, - }) => { - setTestIds('EPMRTC-579', 'EPMRTC-1365'); - let firstConversationInFolder: FolderConversation; - let secondConversationInFolder: FolderConversation; - let emptyFolder: FolderInterface; +dialTest( + 'Folders can expand and collapse.\n', + async ({ + dialHomePage, + conversationData, + folderConversations, + dataInjector, + setTestIds, + }) => { + setTestIds('EPMRTC-579'); + let conversationInFolder: FolderConversation; - await test.step('Prepare 2 conversations inside folders and one empty folder', async () => { - firstConversationInFolder = - conversationData.prepareFolderWithConversations(1); - conversationData.resetData(); - secondConversationInFolder = - conversationData.prepareFolderWithConversations(1); - conversationData.resetData(); - emptyFolder = conversationData.prepareFolder(); - await localStorageManager.setFolders( - firstConversationInFolder.folders, - secondConversationInFolder.folders, - emptyFolder, - ); - await localStorageManager.setConversationHistory( - firstConversationInFolder.conversations[0], - secondConversationInFolder.conversations[0], - ); - }); - await test.step('Hover over folder with conversation and verify it has blue arrow', async () => { + await dialTest.step('Prepare conversation inside folder', async () => { + conversationInFolder = conversationData.prepareFolderWithConversations(1); + await dataInjector.createConversations( + conversationInFolder.conversations, + conversationInFolder.folders, + ); + }); + await dialTest.step( + 'Verify folder arrow icon is changes on expand/collapse folder', + async () => { await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await folderConversations - .getFolderByName(firstConversationInFolder.folders.name) - .hover(); - const firstFolderCaret = await folderConversations.getFolderCaret( - firstConversationInFolder.folders.name, - ); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + let isFolderCaretExpanded = + await folderConversations.isFolderCaretExpanded( + conversationInFolder.folders.name, + ); expect - .soft(firstFolderCaret, ExpectedMessages.folderCaretIsVisible) - .toBe(Attributes.visible); + .soft(isFolderCaretExpanded, ExpectedMessages.folderCaretIsExpanded) + .toBeFalsy(); - await folderConversations.getFolderByName(emptyFolder.name).hover(); - const emptyFolderCaret = await folderConversations.getFolderCaret( - emptyFolder.name, + await folderConversations.expandCollapseFolder( + conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, + ); + isFolderCaretExpanded = await folderConversations.isFolderCaretExpanded( + conversationInFolder.folders.name, ); expect - .soft(emptyFolderCaret, ExpectedMessages.folderCaretIsNotVisible) - .toBe(Attributes.invisible); - }); - }, - ); + .soft(isFolderCaretExpanded, ExpectedMessages.folderCaretIsExpanded) + .toBeTruthy(); + }, + ); + }, +); - test( - 'Delete folder. Cancel.\n' + 'Delete root folder with nested folders', - async ({ - dialHomePage, - conversationData, - folderConversations, - localStorageManager, - conversationDropdownMenu, - confirmationDialog, - setTestIds, - }) => { - setTestIds('EPMRTC-606', 'EPMRTC-1373'); - const nestedFolders = conversationData.prepareNestedFolder(3); - await localStorageManager.setFolders(...nestedFolders); +dialTest( + 'Delete folder. Cancel.\n' + 'Delete root folder with nested folders', + async ({ + dialHomePage, + folderConversations, + conversationDropdownMenu, + confirmationDialog, + chatBar, + setTestIds, + }) => { + setTestIds('EPMRTC-606', 'EPMRTC-1373'); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - await folderConversations.openFolderDropdownMenu(nestedFolders[0].name); - await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - expect - .soft( - await confirmationDialog.getConfirmationMessage(), - ExpectedMessages.confirmationMessageIsValid, - ) - .toBe(ExpectedConstants.deleteFolderMessage); + for (let i = 1; i <= 3; i++) { + await chatBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await chatBar.dragAndDropEntityToFolder( + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); + } + await folderConversations.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + { isHttpMethodTriggered: true }, + ); - await confirmationDialog.cancelDialog(); - expect - .soft( - await folderConversations - .getFolderByName(nestedFolders[0].name) - .isVisible(), - ExpectedMessages.folderNotDeleted, - ) - .toBeTruthy(); + await folderConversations.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); + expect + .soft( + await confirmationDialog.getConfirmationMessage(), + ExpectedMessages.confirmationMessageIsValid, + ) + .toBe(ExpectedConstants.deleteFolderMessage); - await folderConversations.openFolderDropdownMenu(nestedFolders[0].name); - await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); - for (const nestedFolder of nestedFolders) { - expect - .soft( - await folderConversations - .getFolderByName(nestedFolder.name) - .isVisible(), - ExpectedMessages.folderDeleted, - ) - .toBeFalsy(); - } - }, - ); + await confirmationDialog.cancelDialog(); + expect + .soft( + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .isVisible(), + ExpectedMessages.folderNotDeleted, + ) + .toBeTruthy(); + + await folderConversations.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); + await confirmationDialog.confirm(); + for (let i = 2; i <= 3; i++) { + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) + .waitFor({ state: 'hidden' }); + } + }, +); - test('Delete folder when there are some chats inside', async ({ +dialTest( + 'Delete folder when there are some chats inside', + async ({ dialHomePage, conversationData, folderConversations, - localStorageManager, + dataInjector, conversationDropdownMenu, conversations, confirmationDialog, @@ -318,18 +349,18 @@ test.describe('Chat bar folder conversations tests', () => { setTestIds('EPMRTC-605'); const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); - await localStorageManager.setFolders(conversationInFolder.folders); - await localStorageManager.setConversationHistory( - conversationInFolder.conversations[0], + await dataInjector.createConversations( + conversationInFolder.conversations, + conversationInFolder.folders, ); await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); + await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); await folderConversations.openFolderDropdownMenu( conversationInFolder.folders.name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); expect .soft( await folderConversations @@ -346,13 +377,16 @@ test.describe('Chat bar folder conversations tests', () => { ExpectedMessages.conversationOfToday, ) .toBeFalsy(); - }); + }, +); - test('Delete nested folder with chat', async ({ +dialTest( + 'Delete nested folder with chat', + async ({ dialHomePage, conversationData, folderConversations, - localStorageManager, + dataInjector, conversationDropdownMenu, conversations, confirmationDialog, @@ -364,66 +398,76 @@ test.describe('Chat bar folder conversations tests', () => { let nestedFolders: FolderInterface[]; let nestedConversations: Conversation[] = []; - await test.step('Prepare nested folders with conversations inside each one', async () => { - nestedFolders = conversationData.prepareNestedFolder(levelsCount); - nestedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory(...nestedConversations); - }); + await dialTest.step( + 'Prepare nested folders with conversations inside each one', + async () => { + nestedFolders = conversationData.prepareNestedFolder(levelsCount); + nestedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); + await dataInjector.createConversations( + nestedConversations, + ...nestedFolders, + ); + }, + ); - await test.step('Delete 2nd level folder and verify all nested content is deleted as well', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - await folderConversations.openFolderDropdownMenu( - nestedFolders[levelToDelete].name, - ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); + await dialTest.step( + 'Delete 2nd level folder and verify all nested content is deleted as well', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } + await folderConversations.openFolderDropdownMenu( + nestedFolders[levelToDelete].name, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); - for (let i = levelToDelete; i <= levelsCount; i++) { - expect - .soft( - await folderConversations - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderDeleted, - ) - .toBeFalsy(); - expect - .soft( - await conversations - .getConversationByName(nestedConversations[i].name) - .isVisible(), - ExpectedMessages.conversationDeleted, - ) - .toBeFalsy(); - } + for (let i = levelToDelete; i <= levelsCount; i++) { + expect + .soft( + await folderConversations + .getFolderByName(nestedFolders[i].name) + .isVisible(), + ExpectedMessages.folderDeleted, + ) + .toBeFalsy(); + expect + .soft( + await conversations + .getConversationByName(nestedConversations[i].name) + .isVisible(), + ExpectedMessages.conversationDeleted, + ) + .toBeFalsy(); + } - for (let i = 0; i <= levelsCount - levelToDelete; i++) { - expect - .soft( - await folderConversations - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderNotDeleted, - ) - .toBeTruthy(); - expect - .soft( - await folderConversations - .getFolderEntity( - nestedFolders[i].name, - nestedConversations[i].name, - ) - .isVisible(), - ExpectedMessages.conversationNotDeleted, - ) - .toBeTruthy(); - } - }); - }); -}); + for (let i = 0; i <= levelsCount - levelToDelete; i++) { + expect + .soft( + await folderConversations + .getFolderByName(nestedFolders[i].name) + .isVisible(), + ExpectedMessages.folderNotDeleted, + ) + .toBeTruthy(); + expect + .soft( + await folderConversations + .getFolderEntity( + nestedFolders[i].name, + nestedConversations[i].name, + ) + .isVisible(), + ExpectedMessages.conversationNotDeleted, + ) + .toBeTruthy(); + } + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/chatExportImport.test.ts b/apps/chat-e2e/src/tests/chatExportImport.test.ts index 0f3aae39d7..940c57517d 100644 --- a/apps/chat-e2e/src/tests/chatExportImport.test.ts +++ b/apps/chat-e2e/src/tests/chatExportImport.test.ts @@ -1,7 +1,7 @@ import { Conversation } from '@/chat/types/chat'; import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, @@ -28,58 +28,67 @@ const updatedExportedConversations: UploadDownloadData[] = []; let gpt35Model: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { gpt35Model = ModelsUtil.getDefaultModel()!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -test.describe('Chat export/import tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Export and import one chat in a folder.\n' + - `Export and import one chat in a folder when folder doesn't exist`, - async ({ - dialHomePage, - folderConversations, - setTestIds, - conversationData, - localStorageManager, - chatBar, - folderDropdownMenu, - conversationDropdownMenu, - confirmationDialog, - conversations, - }) => { - setTestIds('EPMRTC-908', 'EPMRTC-909'); - let conversationInFolder: FolderConversation; - let exportedData: UploadDownloadData; - await test.step('Prepare exported conversation inside folder and another conversation outside folders', async () => { +dialTest.skip( + 'Export and import one chat in a folder.\n' + + `Export and import one chat in a folder when folder doesn't exist`, + async ({ + dialHomePage, + folderConversations, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + chatBar, + folderDropdownMenu, + conversationDropdownMenu, + confirmationDialog, + }) => { + setTestIds('EPMRTC-908', 'EPMRTC-909'); + let conversationInFolder: FolderConversation; + let exportedData: UploadDownloadData; + await dialTest.step( + 'Prepare exported conversation inside folder and another conversation outside folders', + async () => { conversationInFolder = conversationData.prepareDefaultConversationInFolder(); conversationData.resetData(); const conversationOutsideFolder = conversationData.prepareDefaultConversation(); - await localStorageManager.setFolders(conversationInFolder.folders); - await localStorageManager.setConversationHistory( - conversationInFolder.conversations[0], - conversationOutsideFolder, + await dataInjector.createConversations( + [...conversationInFolder.conversations, conversationOutsideFolder], + conversationInFolder.folders, ); await localStorageManager.setSelectedConversation( conversationInFolder.conversations[0], ); - }); + }, + ); - await test.step('Export conversation inside folder using chat bar conversation menu', async () => { + await dialTest.step( + 'Export conversation inside folder using chat bar conversation menu', + async () => { await dialHomePage.openHomePage({ iconsToBeLoaded: [gpt35Model!.iconUrl], }); await dialHomePage.waitForPageLoaded(); - await folderConversations.expandCollapseFolder( - conversationInFolder.folders.name, - ); + + const isFolderExpanded = + await folderConversations.isFolderCaretExpanded( + conversationInFolder.folders.name, + ); + if (!isFolderExpanded) { + await folderConversations.expandCollapseFolder( + conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, + ); + } + await folderConversations.openFolderEntityDropdownMenu( conversationInFolder.folders.name, conversationInFolder.conversations[0].name, @@ -90,17 +99,21 @@ test.describe('Chat export/import tests', () => { MenuOptions.withoutAttachments, ), ); - }); + }, + ); - await test.step('Delete conversation inside folder, re-import it again and verify it displayed inside folder', async () => { + await dialTest.step( + 'Delete conversation inside folder, re-import it again and verify it displayed inside folder', + async () => { await folderConversations.openFolderEntityDropdownMenu( conversationInFolder.folders.name, conversationInFolder.conversations[0].name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await conversations - .getConversationInput(conversationInFolder.conversations[0].name) - .clickTickButton(); + await folderConversations.deleteConversation( + conversationInFolder.conversations[0].name, + ); + await dialHomePage.uploadData(exportedData, () => chatBar.importButton.click(), ); @@ -111,14 +124,17 @@ test.describe('Chat export/import tests', () => { conversationInFolder.conversations[0].name, ) .waitFor(); - }); + }, + ); - await test.step('Delete folder with the conversation inside, re-import it again and verify it displayed inside folder', async () => { + await dialTest.step( + 'Delete folder with the conversation inside, re-import it again and verify it displayed inside folder', + async () => { await folderConversations.openFolderDropdownMenu( conversationInFolder.folders.name, ); await folderDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); await dialHomePage.uploadData(exportedData, () => chatBar.importButton.click(), @@ -130,84 +146,99 @@ test.describe('Chat export/import tests', () => { conversationInFolder.conversations[0].name, ) .waitFor(); - }); - }, - ); - - test('Export and import chat structure with all conversations', async ({ + }, + ); + }, +); + +dialTest.skip( + 'Export and import chat structure with all conversations', + async ({ dialHomePage, folderConversations, setTestIds, conversationData, - localStorageManager, + dataInjector, conversations, chatBar, confirmationDialog, }) => { setTestIds('EPMRTC-907'); - let emptyFolder: FolderInterface; let nestedFolders: FolderInterface[]; let conversationOutsideFolder: Conversation; let nestedConversations: Conversation[] = []; let exportedData: UploadDownloadData; - await test.step('Prepare empty folder, 3 level nested folders with conversations and conversation outside folder', async () => { - emptyFolder = conversationData.prepareFolder(); - conversationData.resetData(); - - conversationOutsideFolder = conversationData.prepareDefaultConversation(); - conversationData.resetData(); - nestedFolders = conversationData.prepareNestedFolder(levelsCount); - nestedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); + await dialTest.step( + 'Prepare empty folder, 3 level nested folders with conversations and conversation outside folder', + async () => { + conversationOutsideFolder = + conversationData.prepareDefaultConversation(); + conversationData.resetData(); - await localStorageManager.setFolders(emptyFolder, ...nestedFolders); - await localStorageManager.setConversationHistory( - conversationOutsideFolder, - ...nestedConversations, - ); - await localStorageManager.setSelectedConversation( - conversationOutsideFolder, - ); - }); + nestedFolders = conversationData.prepareNestedFolder(levelsCount); + nestedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); - await test.step('Export all conversations using chat bar Export button', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - exportedData = await dialHomePage.downloadData(() => - chatBar.exportButton.click(), - ); - }); + await dataInjector.createConversations( + [...nestedConversations, conversationOutsideFolder], + ...nestedFolders, + ); + }, + ); - await test.step('Delete all conversations and folders, re-import again and verify they are displayed', async () => { - await chatBar.deleteAllEntities(); - await confirmationDialog.confirm(); - await dialHomePage.uploadData(exportedData, () => - chatBar.importButton.click(), - ); + await dialTest.step( + 'Export all conversations using chat bar Export button', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await chatBar.createNewFolder(); + await chatBar.createNewConversation(); + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } + exportedData = await dialHomePage.downloadData(() => + chatBar.exportButton.click(), + ); + }, + ); - await folderConversations.getFolderByName(emptyFolder.name).waitFor(); - await conversations - .getConversationByName(conversationOutsideFolder.name) - .waitFor(); + await dialTest.step( + 'Delete all conversations and folders, re-import again and verify they are displayed', + async () => { + await chatBar.deleteAllEntities(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); + await dialHomePage.uploadData(exportedData, () => + chatBar.importButton.click(), + ); - for (let i = 0; i <= levelsCount; i++) { await folderConversations - .getFolderEntity(nestedFolders[i].name, nestedConversations[i].name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .waitFor(); + await conversations + .getConversationByName(conversationOutsideFolder.name) .waitFor(); - } - }); - }); - test('Existed chats stay after import', async ({ + for (let i = 0; i <= levelsCount; i++) { + await folderConversations + .getFolderEntity(nestedFolders[i].name, nestedConversations[i].name) + .waitFor(); + } + }, + ); + }, +); + +dialTest.skip( + 'Existed chats stay after import', + async ({ dialHomePage, folderConversations, setTestIds, conversationData, - localStorageManager, + dataInjector, conversations, chatBar, chatHeader, @@ -219,129 +250,158 @@ test.describe('Chat export/import tests', () => { let importedRootConversation: Conversation; let importedNewFolderConversation: FolderConversation; - await test.step('Prepare conversations inside folder and another conversation outside folder', async () => { - conversationsInFolder = - conversationData.prepareFolderWithConversations(2); - conversationData.resetData(); + await dialTest.step( + 'Prepare conversations inside folder and another conversation outside folder', + async () => { + conversationsInFolder = + conversationData.prepareFolderWithConversations(2); + conversationData.resetData(); - conversationOutsideFolder = conversationData.prepareDefaultConversation(); - conversationData.resetData(); + conversationOutsideFolder = + conversationData.prepareDefaultConversation(); + conversationData.resetData(); - await localStorageManager.setFolders(conversationsInFolder.folders); - await localStorageManager.setConversationHistory( - ...conversationsInFolder.conversations, - conversationOutsideFolder, - ); - }); + await dataInjector.createConversations( + [...conversationsInFolder.conversations, conversationOutsideFolder], + conversationsInFolder.folders, + ); + }, + ); - await test.step('Prepare conversation inside existing folder to import, conversation inside new folder to import and conversation inside root', async () => { - importedFolderConversation = - conversationData.prepareDefaultConversation(); - folderConversationData = ImportConversation.prepareConversationFile( - importedFolderConversation, - conversationsInFolder, - ); - conversationData.resetData(); + await dialTest.step( + 'Prepare conversation inside existing folder to import, conversation inside new folder to import and conversation inside root', + async () => { + importedFolderConversation = + conversationData.prepareDefaultConversation(); + folderConversationData = ImportConversation.prepareConversationFile( + importedFolderConversation, + conversationsInFolder, + ); + conversationData.resetData(); - importedRootConversation = conversationData.prepareDefaultConversation(); - rootConversationData = ImportConversation.prepareConversationFile( - importedRootConversation, - ); - conversationData.resetData(); + importedRootConversation = + conversationData.prepareDefaultConversation(); + rootConversationData = ImportConversation.prepareConversationFile( + importedRootConversation, + ); + conversationData.resetData(); - importedNewFolderConversation = - conversationData.prepareDefaultConversationInFolder(); - newFolderConversationData = ImportConversation.prepareConversationFile( - importedNewFolderConversation.conversations[0], - importedNewFolderConversation, - ); - }); + importedNewFolderConversation = + conversationData.prepareDefaultConversationInFolder(); + newFolderConversationData = ImportConversation.prepareConversationFile( + importedNewFolderConversation.conversations[0], + importedNewFolderConversation, + ); + }, + ); - await test.step('Import conversation inside existing folder and verify it is imported and existing conversations remain inside folder', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await dialHomePage.uploadData(folderConversationData, () => - chatBar.importButton.click(), - ); - await folderConversations.expandCollapseFolder( - conversationsInFolder.folders.name, - ); - expect - .soft( - await chatHeader.chatTitle.getElementInnerContent(), - ExpectedMessages.headerTitleCorrespondRequest, - ) - .toBe(importedFolderConversation.name); - expect - .soft( - await folderConversations.isFolderEntityVisible( + await dialTest.step( + 'Import conversation inside existing folder and verify it is imported and existing conversations remain inside folder', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await dialHomePage.uploadData(folderConversationData, () => + chatBar.importButton.click(), + ); + + const isFolderExpanded = + await folderConversations.isFolderCaretExpanded( conversationsInFolder.folders.name, - conversationsInFolder.conversations[0].name, - ), - ExpectedMessages.conversationIsVisible, - ) - .toBeTruthy(); - expect - .soft( - await folderConversations.isFolderEntityVisible( + ); + if (!isFolderExpanded) { + await folderConversations.expandCollapseFolder( conversationsInFolder.folders.name, - conversationsInFolder.conversations[1].name, - ), - ExpectedMessages.conversationIsVisible, - ) - .toBeTruthy(); - }); + { isHttpMethodTriggered: true }, + ); + } + expect + .soft( + await chatHeader.chatTitle.getElementInnerContent(), + ExpectedMessages.headerTitleCorrespondRequest, + ) + .toBe(importedFolderConversation.name); + expect + .soft( + await folderConversations.isFolderEntityVisible( + conversationsInFolder.folders.name, + conversationsInFolder.conversations[0].name, + ), + ExpectedMessages.conversationIsVisible, + ) + .toBeTruthy(); + expect + .soft( + await folderConversations.isFolderEntityVisible( + conversationsInFolder.folders.name, + conversationsInFolder.conversations[1].name, + ), + ExpectedMessages.conversationIsVisible, + ) + .toBeTruthy(); + }, + ); - await test.step('Import root conversation and verify it is imported and existing root conversations remain', async () => { - await dialHomePage.uploadData(rootConversationData, () => - chatBar.importButton.click(), - ); - await conversations - .getConversationByName(importedRootConversation.name) - .waitFor(); - expect - .soft( - await conversations - .getConversationByName(conversationOutsideFolder.name) - .isVisible(), - ExpectedMessages.conversationIsVisible, - ) - .toBeTruthy(); - }); + await dialTest.step( + 'Import root conversation and verify it is imported and existing root conversations remain', + async () => { + await dialHomePage.uploadData(rootConversationData, () => + chatBar.importButton.click(), + ); + await conversations + .getConversationByName(importedRootConversation.name) + .waitFor(); + expect + .soft( + await conversations + .getConversationByName(conversationOutsideFolder.name) + .isVisible(), + ExpectedMessages.conversationIsVisible, + ) + .toBeTruthy(); + }, + ); - await test.step('Import conversation inside new folder and verify it is imported', async () => { - await dialHomePage.uploadData(newFolderConversationData, () => - chatBar.importButton.click(), - ); - await folderConversations - .getFolderByName(importedNewFolderConversation.folders.name) - .waitFor(); - expect - .soft( - await chatHeader.chatTitle.getElementInnerContent(), - ExpectedMessages.headerTitleCorrespondRequest, - ) - .toBe(importedNewFolderConversation.conversations[0].name); - }); - }); + await dialTest.step( + 'Import conversation inside new folder and verify it is imported', + async () => { + await dialHomePage.uploadData(newFolderConversationData, () => + chatBar.importButton.click(), + ); + await folderConversations + .getFolderByName(importedNewFolderConversation.folders.name) + .waitFor(); + expect + .soft( + await chatHeader.chatTitle.getElementInnerContent(), + ExpectedMessages.headerTitleCorrespondRequest, + ) + .toBe(importedNewFolderConversation.conversations[0].name); + }, + ); + }, +); + +dialTest.skip( + 'Continue working with imported file. Regenerate response.\n' + + 'Continue working with imported file. Send a message.\n' + + 'Continue working with imported file. Edit a message', + async ({ + dialHomePage, + setTestIds, + conversationData, + chatMessages, + chat, + chatBar, + }) => { + setTestIds('EPMRTC-923', 'EPMRTC-924', 'EPMRTC-925'); + let importedRootConversation: Conversation; + const requests = ['1+2=', '2+3=', '3+4=']; - test( - 'Continue working with imported file. Regenerate response.\n' + - 'Continue working with imported file. Send a message.\n' + - 'Continue working with imported file. Edit a message', - async ({ - dialHomePage, - setTestIds, - conversationData, - chatMessages, - chat, - chatBar, - }) => { - setTestIds('EPMRTC-923', 'EPMRTC-924', 'EPMRTC-925'); - let importedRootConversation: Conversation; - const requests = ['1+2=', '2+3=', '3+4=']; - - await test.step('Prepare conversation with several messages to import', async () => { + await dialTest.step( + 'Prepare conversation with several messages to import', + async () => { importedRootConversation = conversationData.prepareModelConversationBasedOnRequests( gpt35Model, @@ -350,9 +410,12 @@ test.describe('Chat export/import tests', () => { threeConversationsData = ImportConversation.prepareConversationFile( importedRootConversation, ); - }); + }, + ); - await test.step('Import conversation, regenerate the response and verify last response is regenerated', async () => { + await dialTest.step( + 'Import conversation, regenerate the response and verify last response is regenerated', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -366,9 +429,12 @@ test.describe('Chat export/import tests', () => { expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(requests.length * 2); - }); + }, + ); - await test.step('Send new request in chat and verify response is received', async () => { + await dialTest.step( + 'Send new request in chat and verify response is received', + async () => { const newRequest = '4+5='; await chat.sendRequestWithButton(newRequest); const messagesCount = @@ -376,9 +442,12 @@ test.describe('Chat export/import tests', () => { expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(requests.length * 2 + 2); - }); + }, + ); - await test.step('Edit 1st request in chat and verify 1st response is regenerated', async () => { + await dialTest.step( + 'Edit 1st request in chat and verify 1st response is regenerated', + async () => { const updatedMessage = '6+7='; await chatMessages.openEditMessageMode(1); await chatMessages.editMessage(requests[0], updatedMessage); @@ -387,27 +456,30 @@ test.describe('Chat export/import tests', () => { expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(2); - }); - }, - ); - - test( - 'Import file from 1.4 DIAL milestone to conversations and continue working with it.\n' + - 'Chat sorting. Other chat is moved to Today section after sending a message', - async ({ - dialHomePage, - chatBar, - setTestIds, - folderConversations, - prompts, - chatMessages, - conversations, - chat, - iconApiHelper, - conversationSettings, - }) => { - setTestIds('EPMRTC-906', 'EPMRTC-779'); - await test.step('Import conversation from 1.4 app version and verify folder with Gpt-3.5 chat and its history is visible', async () => { + }, + ); + }, +); + +dialTest.skip( + 'Import file from 1.4 DIAL milestone to conversations and continue working with it.\n' + + 'Chat sorting. Other chat is moved to Today section after sending a message', + async ({ + dialHomePage, + chatBar, + setTestIds, + folderConversations, + prompts, + chatMessages, + conversations, + chat, + iconApiHelper, + conversationSettings, + }) => { + setTestIds('EPMRTC-906', 'EPMRTC-779'); + await dialTest.step( + 'Import conversation from 1.4 app version and verify folder with Gpt-3.5 chat and its history is visible', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -419,6 +491,7 @@ test.describe('Chat export/import tests', () => { await folderConversations.expandCollapseFolder( Import.oldVersionAppFolderName, + { isHttpMethodTriggered: true }, ); expect .soft( @@ -439,9 +512,12 @@ test.describe('Chat export/import tests', () => { expect .soft(folderChatMessagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(2); - }); + }, + ); - await test.step('Verify New conversation with Gpt-4 icon is imported', async () => { + await dialTest.step( + 'Verify New conversation with Gpt-4 icon is imported', + async () => { await conversations .getConversationByName(ExpectedConstants.newConversationTitle, 2) .waitFor(); @@ -453,9 +529,12 @@ test.describe('Chat export/import tests', () => { expect .soft(newGpt4ConversationIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedModelIcon); - }); + }, + ); - await test.step('Verify Bison conversation with default icon is imported', async () => { + await dialTest.step( + 'Verify Bison conversation with default icon is imported', + async () => { await conversations .getConversationByName(Import.v14AppBisonChatName) .waitFor(); @@ -470,14 +549,17 @@ test.describe('Chat export/import tests', () => { ExpectedMessages.chatBarConversationIconIsDefault, ) .toBe(defaultIcon); - }); + }, + ); - await test.step('Verify no prompts are imported', async () => { - const promptsCount = await prompts.getPromptsCount(); - expect.soft(promptsCount, ExpectedMessages.noPromptsImported).toBe(0); - }); + await dialTest.step('Verify no prompts are imported', async () => { + const promptsCount = await prompts.getPromptsCount(); + expect.soft(promptsCount, ExpectedMessages.noPromptsImported).toBe(0); + }); - await test.step('Send new request in Gpr-3.5 and verify response is received', async () => { + await dialTest.step( + 'Send new request in Gpr-3.5 and verify response is received', + async () => { const newRequest = '1+2='; await chat.sendRequestWithButton(newRequest); const lastResponseContent = await chatMessages.getLastMessageContent(); @@ -487,9 +569,12 @@ test.describe('Chat export/import tests', () => { ExpectedMessages.messageContentIsValid, ) .toBeTruthy(); - }); + }, + ); - await test.step('Send new request in imported "New Conversation" and verify it was moved into Today section', async () => { + await dialTest.step( + 'Send new request in imported "New Conversation" and verify it was moved into Today section', + async () => { await conversations.selectConversation( ExpectedConstants.newConversationTitle, 2, @@ -500,48 +585,57 @@ test.describe('Chat export/import tests', () => { expect .soft(todayConversations.length, ExpectedMessages.conversationOfToday) .toBe(2); - }); - }, - ); - - test( - `Export and import single chat in nested folders when folders structure doesn't exist.\n` + - `Export and import single chat in nested folders when it's folder doesn't exist.\n` + - `Export and import single chat in nested folders when parent folder doesn't exist`, - async ({ - dialHomePage, - folderConversations, - setTestIds, - conversationData, - localStorageManager, - chatBar, - confirmationDialog, - conversationDropdownMenu, - folderDropdownMenu, - }) => { - setTestIds('EPMRTC-1359', 'EPMRTC-1368', 'EPMRTC-1369'); - let nestedFolders: FolderInterface[]; - let nestedConversations: Conversation[] = []; - let exportedData: UploadDownloadData; - await test.step('Prepare 3 level nested folders with conversations in each folder', async () => { + }, + ); + }, +); + +dialTest.skip( + `Export and import single chat in nested folders when folders structure doesn't exist.\n` + + `Export and import single chat in nested folders when it's folder doesn't exist.\n` + + `Export and import single chat in nested folders when parent folder doesn't exist`, + async ({ + dialHomePage, + folderConversations, + setTestIds, + conversationData, + dataInjector, + localStorageManager, + chatBar, + confirmationDialog, + conversationDropdownMenu, + folderDropdownMenu, + }) => { + setTestIds('EPMRTC-1359', 'EPMRTC-1368', 'EPMRTC-1369'); + let nestedFolders: FolderInterface[]; + let nestedConversations: Conversation[] = []; + let exportedData: UploadDownloadData; + await dialTest.step( + 'Prepare 3 level nested folders with conversations in each folder', + async () => { nestedFolders = conversationData.prepareNestedFolder(levelsCount); nestedConversations = conversationData.prepareConversationsForNestedFolders(nestedFolders); - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory( - ...nestedConversations, + await dataInjector.createConversations( + nestedConversations, + ...nestedFolders, ); await localStorageManager.setSelectedConversation( nestedConversations[levelsCount], ); - }); + }, + ); - await test.step('Export single conversations inside last nested folder', async () => { + await dialTest.step( + 'Export single conversations inside last nested folder', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); } await folderConversations.openFolderEntityDropdownMenu( @@ -554,9 +648,12 @@ test.describe('Chat export/import tests', () => { MenuOptions.withoutAttachments, ), ); - }); + }, + ); - await test.step('Delete all conversations and folders, re-import exported file and verify only last nested conversation with folders structure imported', async () => { + await dialTest.step( + 'Delete all conversations and folders, re-import exported file and verify only last nested conversation with folders structure imported', + async () => { await chatBar.deleteAllEntities(); await confirmationDialog.confirm(); await dialHomePage.uploadData(exportedData, () => @@ -587,9 +684,12 @@ test.describe('Chat export/import tests', () => { ) .toBeFalsy(); } - }); + }, + ); - await test.step('Delete last folder with its conversation, re-import exported file and verify last nested folder with its conversation imported', async () => { + await dialTest.step( + 'Delete last folder with its conversation, re-import exported file and verify last nested folder with its conversation imported', + async () => { await folderConversations.openFolderDropdownMenu( nestedFolders[levelsCount].name, ); @@ -606,9 +706,12 @@ test.describe('Chat export/import tests', () => { nestedConversations[levelsCount].name, ) .waitFor(); - }); + }, + ); - await test.step('Delete 2nd level folder with its nested content, re-import exported file and verify 2nd level folder with its nested content imported', async () => { + await dialTest.step( + 'Delete 2nd level folder with its nested content, re-import exported file and verify 2nd level folder with its nested content imported', + async () => { await folderConversations.openFolderDropdownMenu( nestedFolders[levelsCount - 1].name, ); @@ -629,16 +732,20 @@ test.describe('Chat export/import tests', () => { await folderConversations .getFolderByName(nestedFolders[levelsCount - 1].name) .waitFor(); - }); - }, - ); - - test('Import a chat in nested folder', async ({ + }, + ); + }, +); + +dialTest.skip( + 'Import a chat in nested folder', + async ({ dialHomePage, folderConversations, setTestIds, conversationData, localStorageManager, + dataInjector, chatBar, conversationDropdownMenu, }) => { @@ -647,108 +754,129 @@ test.describe('Chat export/import tests', () => { let nestedConversations: Conversation[] = []; const updatedConversationNames: string[] = []; - await test.step('Prepare 3 level nested folders with conversations in each folder', async () => { - nestedFolders = conversationData.prepareNestedFolder(levelsCount); - nestedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); - - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory(...nestedConversations); - await localStorageManager.setSelectedConversation( - nestedConversations[levelsCount], - ); - }); - - await test.step('Export single conversations from root folder and single conversation from 2nd level folder', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } + await dialTest.step( + 'Prepare 3 level nested folders with conversations in each folder', + async () => { + nestedFolders = conversationData.prepareNestedFolder(levelsCount); + nestedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); - for (let i = 0; i <= 2; i = i + 2) { - await folderConversations.openFolderEntityDropdownMenu( - nestedFolders[i].name, - nestedConversations[i].name, - ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.export); - const exportedData = await dialHomePage.downloadData( - () => - conversationDropdownMenu.selectMenuOption( - MenuOptions.withoutAttachments, - ), - `${i}.json`, + await localStorageManager.setFolders(...nestedFolders); + await dataInjector.createConversations( + nestedConversations, + ...nestedFolders, ); - exportedConversations.push(exportedData); - } - }); - - await test.step('Update id and name of exported conversations and import them again', async () => { - for (const exportedData of exportedConversations) { - const exportedContent = FileUtil.readFileData(exportedData.path); - const conversation = exportedContent.history[0]; - conversation.id = uuidv4(); - conversation.name = GeneratorUtil.randomString(10); - const updatedExportedConversation = { - path: FileUtil.writeDataToFile(exportedContent), - isDownloadedData: false, - }; - updatedExportedConversations.push(updatedExportedConversation); - await dialHomePage.uploadData(updatedExportedConversation, () => - chatBar.importButton.click(), + await localStorageManager.setSelectedConversation( + nestedConversations[levelsCount], ); - updatedConversationNames.push(conversation.name); - } - }); + }, + ); - await test.step('Verify new conversations are added to root and 2nd level folders, folders structure remains the same', async () => { - for (let i = 0; i <= levelsCount; i++) { - await folderConversations - .getFolderByName(nestedFolders[i].name) - .waitFor(); - } + await dialTest.step( + 'Export single conversations from root folder and single conversation from 2nd level folder', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } - for (let i = 0; i < levelsCount; i++) { - expect - .soft( - await folderConversations.isFolderEntityVisible( - nestedFolders[i].name, - nestedConversations[i].name, - ), - ExpectedMessages.conversationIsVisible, - ) - .toBeTruthy(); - if (i === 0) { - expect - .soft( - await folderConversations.isFolderEntityVisible( - nestedFolders[i].name, - updatedConversationNames[0], + for (let i = 0; i <= 2; i = i + 2) { + await folderConversations.openFolderEntityDropdownMenu( + nestedFolders[i].name, + nestedConversations[i].name, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.export); + const exportedData = await dialHomePage.downloadData( + () => + conversationDropdownMenu.selectMenuOption( + MenuOptions.withoutAttachments, ), - ExpectedMessages.conversationIsVisible, - ) - .toBeTruthy(); - } else if (i === 2) { + `${i}.json`, + ); + exportedConversations.push(exportedData); + } + }, + ); + + await dialTest.step( + 'Update id and name of exported conversations and import them again', + async () => { + for (const exportedData of exportedConversations) { + const exportedContent = FileUtil.readFileData(exportedData.path); + const conversation = exportedContent.history[0]; + conversation.id = uuidv4(); + conversation.name = GeneratorUtil.randomString(10); + const updatedExportedConversation = { + path: FileUtil.writeDataToFile(exportedContent), + isDownloadedData: false, + }; + updatedExportedConversations.push(updatedExportedConversation); + await dialHomePage.uploadData(updatedExportedConversation, () => + chatBar.importButton.click(), + ); + updatedConversationNames.push(conversation.name); + } + }, + ); + + await dialTest.step( + 'Verify new conversations are added to root and 2nd level folders, folders structure remains the same', + async () => { + for (let i = 0; i <= levelsCount; i++) { + await folderConversations + .getFolderByName(nestedFolders[i].name) + .waitFor(); + } + + for (let i = 0; i < levelsCount; i++) { expect .soft( await folderConversations.isFolderEntityVisible( nestedFolders[i].name, - updatedConversationNames[1], + nestedConversations[i].name, ), ExpectedMessages.conversationIsVisible, ) .toBeTruthy(); + if (i === 0) { + expect + .soft( + await folderConversations.isFolderEntityVisible( + nestedFolders[i].name, + updatedConversationNames[0], + ), + ExpectedMessages.conversationIsVisible, + ) + .toBeTruthy(); + } else if (i === 2) { + expect + .soft( + await folderConversations.isFolderEntityVisible( + nestedFolders[i].name, + updatedConversationNames[1], + ), + ExpectedMessages.conversationIsVisible, + ) + .toBeTruthy(); + } } - } - }); - }); - - test('Import a chat from nested folder which was moved to another place', async ({ + }, + ); + }, +); + +dialTest.skip( + 'Import a chat from nested folder which was moved to another place', + async ({ dialHomePage, folderConversations, setTestIds, conversationData, localStorageManager, + dataInjector, chatBar, conversationDropdownMenu, }) => { @@ -757,26 +885,31 @@ test.describe('Chat export/import tests', () => { let thirdLevelFolderConversation: Conversation; let exportedData: UploadDownloadData; - await test.step('Prepare 3 level nested folders and conversation inside the 3rd level folder', async () => { - nestedFolders = conversationData.prepareNestedFolder(levelsCount); - thirdLevelFolderConversation = - conversationData.prepareDefaultConversation(); - thirdLevelFolderConversation.folderId = nestedFolders[levelsCount].id; + await dialTest.step( + 'Prepare 3 level nested folders and conversation inside the 3rd level folder', + async () => { + nestedFolders = conversationData.prepareNestedFolder(levelsCount); + thirdLevelFolderConversation = + conversationData.prepareDefaultConversation(); + thirdLevelFolderConversation.folderId = nestedFolders[levelsCount].id; - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory( - thirdLevelFolderConversation, - ); - await localStorageManager.setSelectedConversation( - thirdLevelFolderConversation, - ); - }); + await dataInjector.createConversations( + [thirdLevelFolderConversation], + ...nestedFolders, + ); + await localStorageManager.setSelectedConversation( + thirdLevelFolderConversation, + ); + }, + ); - await test.step('Export 3rd level folder conversation', async () => { + await dialTest.step('Export 3rd level folder conversation', async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); } await folderConversations.openFolderEntityDropdownMenu( nestedFolders[levelsCount].name, @@ -790,42 +923,52 @@ test.describe('Chat export/import tests', () => { ); }); - await test.step('Move 3rd level folder on the root folder level and import exported conversation', async () => { - nestedFolders[levelsCount].folderId = undefined; - await localStorageManager.setFolders(...nestedFolders); - await dialHomePage.reloadPage(); - await dialHomePage.waitForPageLoaded(); - await dialHomePage.uploadData(exportedData, () => - chatBar.importButton.click(), - ); - }); + await dialTest.step( + 'Move 3rd level folder on the root folder level and import exported conversation', + async () => { + nestedFolders[levelsCount].folderId = undefined; + await localStorageManager.setFolders(...nestedFolders); + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + await dialHomePage.uploadData(exportedData, () => + chatBar.importButton.click(), + ); + }, + ); - await test.step('Verify imported conversations is in 3rd level folder on the root level', async () => { - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - await folderConversations - .getFolderEntity( - nestedFolders[levelsCount].name, - thirdLevelFolderConversation.name, - ) - .waitFor(); - - const foldersCount = await folderConversations.getFoldersCount(); - expect - .soft(foldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(levelsCount + 1); - - const conversationsCount = - await folderConversations.getFolderEntitiesCount(nestedFolders[0].name); - expect - .soft(conversationsCount, ExpectedMessages.conversationsCountIsValid) - .toBe(0); - }); - }); -}); + await dialTest.step( + 'Verify imported conversations is in 3rd level folder on the root level', + async () => { + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } + await folderConversations + .getFolderEntity( + nestedFolders[levelsCount].name, + thirdLevelFolderConversation.name, + ) + .waitFor(); -test.afterAll(async () => { + const foldersCount = await folderConversations.getFoldersCount(); + expect + .soft(foldersCount, ExpectedMessages.foldersCountIsValid) + .toBe(levelsCount + 1); + + const conversationsCount = + await folderConversations.getFolderEntitiesCount( + nestedFolders[0].name, + ); + expect + .soft(conversationsCount, ExpectedMessages.conversationsCountIsValid) + .toBe(0); + }, + ); + }, +); + +dialTest.afterAll(async () => { const importFilesToDelete: UploadDownloadData[] = [ folderConversationData, rootConversationData, diff --git a/apps/chat-e2e/src/tests/chatHeader.test.ts b/apps/chat-e2e/src/tests/chatHeader.test.ts index a75fc23979..1bae3b381d 100644 --- a/apps/chat-e2e/src/tests/chatHeader.test.ts +++ b/apps/chat-e2e/src/tests/chatHeader.test.ts @@ -1,6 +1,6 @@ import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages } from '@/src/testData'; import { ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; @@ -9,48 +9,50 @@ let allAddons: OpenAIEntityModel[]; let addonIds: string[]; let defaultModel: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { allAddons = ModelsUtil.getAddons(); addonIds = allAddons.map((a) => a.id); defaultModel = ModelsUtil.getDefaultModel()!; }); -test.describe('Chat header tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Check chat header for Model with three addons, temp = 0.\n' + - 'Message is send on Enter', - async ({ - dialHomePage, - chat, - setTestIds, - conversationData, - localStorageManager, - chatHeader, - chatInfoTooltip, - errorPopup, - iconApiHelper, - }) => { - setTestIds('EPMRTC-1115', 'EPMRTC-473'); - let conversation: Conversation; - const temp = 0; - const request = 'This is a test request'; - const expectedModelIcon = await iconApiHelper.getEntityIcon(defaultModel); - - await test.step('Prepare model conversation with all available addons and temperature', async () => { +dialTest( + 'Check chat header for Model with three addons, temp = 0.\n' + + 'Message is send on Enter', + async ({ + dialHomePage, + chat, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + chatHeader, + chatInfoTooltip, + errorPopup, + iconApiHelper, + }) => { + setTestIds('EPMRTC-1115', 'EPMRTC-473'); + let conversation: Conversation; + const temp = 0; + const request = 'This is a test request'; + const expectedModelIcon = await iconApiHelper.getEntityIcon(defaultModel); + + await dialTest.step( + 'Prepare model conversation with all available addons and temperature', + async () => { conversation = conversationData.prepareModelConversation( temp, '', addonIds, defaultModel, ); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); - await test.step('Send new request in chat and verify request is sent with valid data', async () => { + await dialTest.step( + 'Send new request in chat and verify request is sent with valid data', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); const requestsData = await chat.sendRequestWithKeyboard(request, false); @@ -70,9 +72,12 @@ test.describe('Chat header tests', () => { ExpectedMessages.requestSelectedAddonsAreValid, ) .toEqual(conversation.selectedAddons); - }); + }, + ); - await test.step('Verify chat icons are updated with model, temperature and addons in the header', async () => { + await dialTest.step( + 'Verify chat icons are updated with model, temperature and addons in the header', + async () => { const headerModelIcon = await chatHeader.getHeaderModelIcon(); expect .soft( @@ -105,9 +110,12 @@ test.describe('Chat header tests', () => { .toBe(expectedAddonIcon); } } - }); + }, + ); - await test.step('Hover over chat header and verify chat settings are correct on tooltip', async () => { + await dialTest.step( + 'Hover over chat header and verify chat settings are correct on tooltip', + async () => { await errorPopup.cancelPopup(); await chatHeader.chatModel.hoverOver(); const modelInfo = await chatInfoTooltip.getModelInfo(); @@ -150,36 +158,40 @@ test.describe('Chat header tests', () => { ) .toBe(expectedAddonIcon); } - }); - }, - ); - - test( - 'Clear conversations using button in chat. Cancel.\n' + - 'Clear conversation using button in chat. Ok', - async ({ - dialHomePage, - setTestIds, - chatMessages, - conversationData, - localStorageManager, - chatHeader, - conversationSettings, - confirmationDialog, - }) => { - setTestIds('EPMRTC-490', 'EPMRTC-491'); - let conversation: Conversation; - await test.step('Prepare conversation with history', async () => { - conversation = - await conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - ['first request', 'second request', 'third request'], - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); + }, +); + +dialTest( + 'Clear conversations using button in chat. Cancel.\n' + + 'Clear conversation using button in chat. Ok', + async ({ + dialHomePage, + setTestIds, + chatMessages, + conversationData, + localStorageManager, + dataInjector, + chatHeader, + conversationSettings, + confirmationDialog, + }) => { + setTestIds('EPMRTC-490', 'EPMRTC-491'); + let conversation: Conversation; + await dialTest.step('Prepare conversation with history', async () => { + conversation = + await conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + ['first request', 'second request', 'third request'], + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }); - await test.step('Try to clear conversation messages using header button but cancel clearing and verify no messages deleted', async () => { + await dialTest.step( + 'Try to clear conversation messages using header button but cancel clearing and verify no messages deleted', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await chatHeader.clearConversation.click(); @@ -190,11 +202,14 @@ test.describe('Chat header tests', () => { expect .soft(messagesCount, ExpectedMessages.messageContentIsValid) .toBe(conversation.messages.length); - }); + }, + ); - await test.step('Clear conversation messages using header button and verify messages deleted, setting are shown', async () => { + await dialTest.step( + 'Clear conversation messages using header button and verify messages deleted, setting are shown', + async () => { await chatHeader.clearConversation.click(); - await confirmationDialog.confirm(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'PUT' }); const isConversationSettingsVisible = await conversationSettings.isVisible(); @@ -204,7 +219,7 @@ test.describe('Chat header tests', () => { ExpectedMessages.conversationSettingsVisible, ) .toBeTruthy(); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts b/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts index 378bd48572..9e3e174763 100644 --- a/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts +++ b/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts @@ -1,21 +1,19 @@ import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages } from '@/src/testData'; import { GeneratorUtil, ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; let defaultModel: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { defaultModel = ModelsUtil.getDefaultModel()!; }); -test.describe('Chat header settings tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Model settings opened in chat are the same as on New chat defaults', async ({ +dialTest( + 'Model settings opened in chat are the same as on New chat defaults', + async ({ dialHomePage, chatHeader, entitySettings, @@ -25,6 +23,7 @@ test.describe('Chat header settings tests', () => { setTestIds, conversationData, localStorageManager, + dataInjector, }) => { setTestIds('EPMRTC-449'); let conversation: Conversation; @@ -33,33 +32,42 @@ test.describe('Chat header settings tests', () => { allModels.filter((m) => m.id !== defaultModel.id), ); - await test.step('Prepare conversation with default model and settings', async () => { - conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + await dialTest.step( + 'Prepare conversation with default model and settings', + async () => { + conversation = conversationData.prepareDefaultConversation(); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }, + ); - await test.step('Open conversation settings and change model', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await chatHeader.openConversationSettingsPopup(); - await talkToSelector.selectModel(randomModel.name); - }); + await dialTest.step( + 'Open conversation settings and change model', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await chatHeader.openConversationSettingsPopup(); + await talkToSelector.selectModel(randomModel.name); + }, + ); - await test.step('Verify conversation settings are the same as for initial model', async () => { - const systemPrompt = await entitySettings.getSystemPrompt(); - expect - .soft(systemPrompt, ExpectedMessages.defaultSystemPromptIsEmpty) - .toBe(conversation.prompt); - const temperature = await temperatureSlider.getTemperature(); - expect - .soft(temperature, ExpectedMessages.defaultTemperatureIsOne) - .toBe(conversation.temperature.toString()); - const modelAddons = defaultModel.selectedAddons ?? []; - const selectedAddons = await addons.getSelectedAddons(); - expect - .soft(selectedAddons, ExpectedMessages.noAddonsSelected) - .toEqual(modelAddons); - }); - }); -}); + await dialTest.step( + 'Verify conversation settings are the same as for initial model', + async () => { + const systemPrompt = await entitySettings.getSystemPrompt(); + expect + .soft(systemPrompt, ExpectedMessages.defaultSystemPromptIsEmpty) + .toBe(conversation.prompt); + const temperature = await temperatureSlider.getTemperature(); + expect + .soft(temperature, ExpectedMessages.defaultTemperatureIsOne) + .toBe(conversation.temperature.toString()); + const modelAddons = defaultModel.selectedAddons ?? []; + const selectedAddons = await addons.getSelectedAddons(); + expect + .soft(selectedAddons, ExpectedMessages.noAddonsSelected) + .toEqual(modelAddons); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/compareMode.test.ts b/apps/chat-e2e/src/tests/compareMode.test.ts index c7ca96301d..167faf538a 100644 --- a/apps/chat-e2e/src/tests/compareMode.test.ts +++ b/apps/chat-e2e/src/tests/compareMode.test.ts @@ -1,6 +1,7 @@ import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { API, ExpectedConstants, @@ -20,97 +21,107 @@ let defaultModel: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; let bisonModel: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { defaultModel = ModelsUtil.getDefaultModel()!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; bisonModel = ModelsUtil.getModel(ModelIds.BISON_001)!; }); -test.describe('Compare mode tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Compare mode button creates two new chats and opens them in compare mode', async ({ +dialTest( + 'Compare mode button creates two new chats and opens them in compare mode', + async ({ dialHomePage, setTestIds, chatBar, conversations, compare }) => { + setTestIds('EPMRTC-537'); + await dialTest.step( + 'Click on compare button on bottom of chat bar and verify compare mode is opened for new two chats', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await chatBar.openCompareMode(); + await compare.waitForState(); + const chatsCount = await compare.getConversationsCount(); + expect.soft(chatsCount, ExpectedMessages.compareModeOpened).toBe(2); + + const todayConversations = await conversations.getTodayConversations(); + expect + .soft(todayConversations.length, ExpectedMessages.conversationOfToday) + .toBe(3); + + todayConversations.forEach((value) => + expect + .soft(value, ExpectedMessages.conversationOfToday) + .toContain(ExpectedConstants.newConversationTitle), + ); + }, + ); + }, +); + +dialTest( + 'Check the list of available conversations.\n' + + 'Chat icon is shown in Select conversation drop down list in compare mode', + async ({ dialHomePage, setTestIds, - chatBar, + conversationDropdownMenu, conversations, + conversationData, + localStorageManager, + dataInjector, compare, + compareConversationSelector, + iconApiHelper, }) => { - setTestIds('EPMRTC-537'); - await test.step('Click on compare button on bottom of chat bar and verify compare mode is opened for new two chats', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await chatBar.openCompareMode(); - await compare.waitForState(); - const chatsCount = await compare.getConversationsCount(); - expect.soft(chatsCount, ExpectedMessages.compareModeOpened).toBe(2); - - const todayConversations = await conversations.getTodayConversations(); - expect - .soft(todayConversations.length, ExpectedMessages.conversationOfToday) - .toBe(3); - - todayConversations.forEach((value) => - expect - .soft(value, ExpectedMessages.conversationOfToday) - .toContain(ExpectedConstants.newConversationTitle), + setTestIds('EPMRTC-546', 'EPMRTC-383'); + let firstModelConversation: Conversation; + let secondModelConversation: Conversation; + let modelConversationInFolder: FolderConversation; + let thirdModelConversation: Conversation; + const conversationName = GeneratorUtil.randomString(7); + + await dialTest.step('Prepare three conversations to compare', async () => { + firstModelConversation = conversationData.prepareDefaultConversation( + defaultModel, + conversationName, ); - }); - }); - - test( - 'Check the list of available conversations.\n' + - 'Chat icon is shown in Select conversation drop down list in compare mode', - async ({ - dialHomePage, - setTestIds, - conversationDropdownMenu, - conversations, - conversationData, - localStorageManager, - compare, - compareConversationSelector, - iconApiHelper, - }) => { - setTestIds('EPMRTC-546', 'EPMRTC-383'); - let firstModelConversation: Conversation; - let secondModelConversation: Conversation; - let modelConversationInFolder: FolderConversation; - let thirdModelConversation: Conversation; - - await test.step('Prepare three conversations to compare', async () => { - firstModelConversation = conversationData.prepareDefaultConversation( - defaultModel, - ExpectedConstants.newConversationTitle, + const request = firstModelConversation.messages.find( + (m) => m.role === 'user', + )?.content; + conversationData.resetData(); + secondModelConversation = + conversationData.prepareModelConversationBasedOnRequests( + gpt4Model, + [request!], + conversationName, ); - const request = firstModelConversation.messages.find( - (m) => m.role === 'user', - )?.content; - conversationData.resetData(); - secondModelConversation = - conversationData.prepareModelConversationBasedOnRequests(gpt4Model, [ - request!, - ]); - conversationData.resetData(); - modelConversationInFolder = - conversationData.prepareDefaultConversationInFolder(bisonModel); - conversationData.resetData(); - thirdModelConversation = - conversationData.prepareDefaultConversation(bisonModel); - await localStorageManager.setFolders(modelConversationInFolder.folders); - await localStorageManager.setConversationHistory( + conversationData.resetData(); + modelConversationInFolder = + conversationData.prepareDefaultConversationInFolder( + bisonModel, + conversationName, + ); + conversationData.resetData(); + thirdModelConversation = conversationData.prepareDefaultConversation( + bisonModel, + conversationName, + ); + + await dataInjector.createConversations( + [ firstModelConversation, secondModelConversation, thirdModelConversation, - modelConversationInFolder.conversations[0], - ); - await localStorageManager.setSelectedConversation( - thirdModelConversation, - ); - }); + ...modelConversationInFolder.conversations, + ], + modelConversationInFolder.folders, + ); + await localStorageManager.setSelectedConversation(thirdModelConversation); + }); - await test.step('Open compare mode from 1st chat dropdown menu and verify chats with valid icons available for comparison', async () => { + await dialTest.step( + 'Open compare mode from 1st chat dropdown menu and verify chats with valid icons available for comparison', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu( @@ -164,50 +175,69 @@ test.describe('Compare mode tests', () => { .soft(actualOptionIcon.icon, ExpectedMessages.entityIconIsValid) .toBe(expectedModelIcon); } - }); - }, - ); - - test( - 'Check replay chats are not included in Select conversation drop down list.\n' + - 'Compare mode is closed if to switch to another chat', - async ({ - dialHomePage, - setTestIds, - conversationDropdownMenu, - conversations, - conversationData, - localStorageManager, - compareConversationSelector, - compare, - }) => { - setTestIds('EPMRTC-1133', 'EPMRTC-541'); - let modelConversation: Conversation; - let replayConversation: Conversation; - let firstEmptyConversation: Conversation; - let secondEmptyConversation: Conversation; - - await test.step('Prepare one conversation with replay conversation and two empty conversations', async () => { - modelConversation = conversationData.prepareDefaultConversation(); + }, + ); + }, +); + +dialTest( + 'Check replay chats are not included in Select conversation drop down list.\n' + + 'Compare mode is closed if to switch to another chat', + async ({ + dialHomePage, + setTestIds, + conversationDropdownMenu, + conversations, + conversationData, + localStorageManager, + dataInjector, + compareConversationSelector, + compare, + }) => { + setTestIds('EPMRTC-1133', 'EPMRTC-541'); + let modelConversation: Conversation; + let replayConversation: Conversation; + let firstEmptyConversation: Conversation; + let secondEmptyConversation: Conversation; + const conversationName = GeneratorUtil.randomString(7); + + await dialTest.step( + 'Prepare one conversation with replay conversation and two empty conversations', + async () => { + modelConversation = conversationData.prepareDefaultConversation( + defaultModel, + conversationName, + ); replayConversation = conversationData.prepareDefaultReplayConversation(modelConversation); conversationData.resetData(); - firstEmptyConversation = conversationData.prepareEmptyConversation(); + firstEmptyConversation = conversationData.prepareEmptyConversation( + defaultModel, + `${conversationName} 1`, + ); conversationData.resetData(); - secondEmptyConversation = conversationData.prepareEmptyConversation(); - await localStorageManager.setConversationHistory( + secondEmptyConversation = conversationData.prepareEmptyConversation( + defaultModel, + `${conversationName} 2`, + ); + await dataInjector.createConversations([ modelConversation, replayConversation, firstEmptyConversation, secondEmptyConversation, - ); + ]); await localStorageManager.setSelectedConversation( firstEmptyConversation, ); - }); - - await test.step('Open compare mode for the 1st empty chat and verify only one empty chat is available for comparison', async () => { - await dialHomePage.openHomePage(); + }, + ); + + await dialTest.step( + 'Open compare mode for the 1st empty chat and verify only one empty chat is available for comparison', + async () => { + await dialHomePage.openHomePage({ + iconsToBeLoaded: [defaultModel.iconUrl], + }); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu( firstEmptyConversation.name, @@ -216,55 +246,68 @@ test.describe('Compare mode tests', () => { await compareConversationSelector.click(); const conversationsList = await compareConversationSelector.getListOptions(); + const expectedCompareConversations = isApiStorageType + ? [modelConversation.name, secondEmptyConversation.name] + : [secondEmptyConversation.name]; expect .soft( conversationsList, ExpectedMessages.conversationsToCompareOptionsValid, ) - .toEqual([secondEmptyConversation.name]); - }); + .toEqual(expectedCompareConversations); + }, + ); - await test.step('Open another conversation and verify compare mode is closed', async () => { + await dialTest.step( + 'Open another conversation and verify compare mode is closed', + async () => { await conversations.selectConversation(modelConversation.name); const isCompareModeOn = await compare.isVisible(); expect .soft(isCompareModeOn, ExpectedMessages.compareModeClosed) .toBeFalsy(); - }); - }, - ); - - test( - `Compare mode is closed on "x" button in chat1.\n` + - 'Compare mode is closed on "x" button in chat2', - async ({ - dialHomePage, - setTestIds, - conversationData, - localStorageManager, - compare, - rightChatHeader, - leftChatHeader, - }) => { - setTestIds('EPMRTC-544', 'EPMRTC-545'); - let firstConversation: Conversation; - let secondConversation: Conversation; - - await test.step('Prepare two conversations in compare mode', async () => { + }, + ); + }, +); + +dialTest( + `Compare mode is closed on "x" button in chat1.\n` + + 'Compare mode is closed on "x" button in chat2', + async ({ + dialHomePage, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + compare, + rightChatHeader, + leftChatHeader, + }) => { + setTestIds('EPMRTC-544', 'EPMRTC-545'); + let firstConversation: Conversation; + let secondConversation: Conversation; + + await dialTest.step( + 'Prepare two conversations in compare mode', + async () => { firstConversation = conversationData.prepareDefaultConversation(); conversationData.resetData(); secondConversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ firstConversation, secondConversation, - ); + ]); await localStorageManager.setSelectedConversation( firstConversation, secondConversation, ); - }); + }, + ); - await test.step('Remove 1st conversation from compare mode using Close btn in the header', async () => { + await dialTest.step( + 'Remove 1st conversation from compare mode using Close btn in the header', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); const randomSide = GeneratorUtil.randomArrayElement( @@ -289,15 +332,19 @@ test.describe('Compare mode tests', () => { expect .soft(activeChatHeader, ExpectedMessages.headerTitleIsValid) .toBe(activeChat); - }); - }, - ); - - test('Check the list of No conversations available', async ({ + }, + ); + }, +); + +dialTest( + 'Check the list of No conversations available', + async ({ dialHomePage, setTestIds, conversationData, localStorageManager, + dataInjector, conversations, compareConversationSelector, conversationDropdownMenu, @@ -312,124 +359,136 @@ test.describe('Compare mode tests', () => { let forthConversation: Conversation; let fifthConversation: Conversation; - await test.step('Prepare five conversations with requests combination', async () => { - firstConversation = - conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - [firstRequest, secondRequest], - 'firstConv', - ); - conversationData.resetData(); - secondConversation = - conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - [secondRequest, firstRequest], - 'secondConv', - ); - conversationData.resetData(); - thirdConversation = - conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - [firstRequest], - 'thirdConv', - ); - conversationData.resetData(); - forthConversation = - conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - [firstRequest, thirdRequest], - 'forthConv', - ); - conversationData.resetData(); - fifthConversation = - conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - [firstRequest.toLowerCase(), secondRequest], - 'fifthConv', + await dialTest.step( + 'Prepare five conversations with requests combination', + async () => { + firstConversation = + conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + [firstRequest, secondRequest], + 'firstConv', + ); + conversationData.resetData(); + secondConversation = + conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + [secondRequest, firstRequest], + 'secondConv', + ); + conversationData.resetData(); + thirdConversation = + conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + [firstRequest], + 'thirdConv', + ); + conversationData.resetData(); + forthConversation = + conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + [firstRequest, thirdRequest], + 'forthConv', + ); + conversationData.resetData(); + fifthConversation = + conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + [firstRequest.toLowerCase(), secondRequest], + 'fifthConv', + ); + + await dataInjector.createConversations([ + firstConversation, + secondConversation, + thirdConversation, + forthConversation, + fifthConversation, + ]); + await localStorageManager.setSelectedConversation(firstConversation); + }, + ); + + await dialTest.step( + 'Open compare mode for the 1st conversation and verify no options are available for comparison', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.openConversationDropdownMenu( + firstConversation.name, ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); - await localStorageManager.setConversationHistory( + await compareConversationSelector.click(); + const selectorPlaceholder = + await compareConversationSelector.getSelectorPlaceholder(); + expect + .soft(selectorPlaceholder, ExpectedMessages.noConversationsAvailable) + .toBe(ExpectedConstants.noConversationsAvailable); + + const conversationsList = + await compareConversationSelector.getListOptions(); + expect + .soft( + conversationsList, + ExpectedMessages.conversationsToCompareOptionsValid, + ) + .toEqual([]); + }, + ); + }, +); + +dialTest( + 'Generate new response for two chats in compare mode. GPT models.\n' + + 'Likes/Dislikes set in compare mode are stored in both chats', + async ({ + dialHomePage, + chat, + chatMessages, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + compare, + conversations, + }) => { + setTestIds('EPMRTC-552', 'EPMRTC-558'); + + let firstConversation: Conversation; + let secondConversation: Conversation; + + const firstPrompt = 'repeat the same text'; + const firstTemp = 1; + const secondPrompt = 'repeat the same text again'; + const secondTemp = 0; + + await dialTest.step('Prepare two conversations for comparing', async () => { + firstConversation = conversationData.prepareModelConversation( + firstTemp, + firstPrompt, + [], + defaultModel, + ); + conversationData.resetData(); + secondConversation = conversationData.prepareModelConversation( + secondTemp, + secondPrompt, + [], + gpt4Model, + ); + await dataInjector.createConversations([ + firstConversation, + secondConversation, + ]); + await localStorageManager.setSelectedConversation( firstConversation, secondConversation, - thirdConversation, - forthConversation, - fifthConversation, ); - await localStorageManager.setSelectedConversation(firstConversation); - }); - - await test.step('Open compare mode for the 1st conversation and verify no options are available for comparison', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations.openConversationDropdownMenu(firstConversation.name); - await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); - - await compareConversationSelector.click(); - const selectorPlaceholder = - await compareConversationSelector.getSelectorPlaceholder(); - expect - .soft(selectorPlaceholder, ExpectedMessages.noConversationsAvailable) - .toBe(ExpectedConstants.noConversationsAvailable); - - const conversationsList = - await compareConversationSelector.getListOptions(); - expect - .soft( - conversationsList, - ExpectedMessages.conversationsToCompareOptionsValid, - ) - .toEqual([]); }); - }); - - test( - 'Generate new response for two chats in compare mode. GPT models.\n' + - 'Likes/Dislikes set in compare mode are stored in both chats', - async ({ - dialHomePage, - chat, - chatMessages, - setTestIds, - conversationData, - localStorageManager, - compare, - conversations, - }) => { - setTestIds('EPMRTC-552', 'EPMRTC-558'); - - let firstConversation: Conversation; - let secondConversation: Conversation; - - const firstPrompt = 'repeat the same text'; - const firstTemp = 1; - const secondPrompt = 'repeat the same text again'; - const secondTemp = 0; - - await test.step('Prepare two conversations for comparing', async () => { - firstConversation = conversationData.prepareModelConversation( - firstTemp, - firstPrompt, - [], - defaultModel, - ); - conversationData.resetData(); - secondConversation = conversationData.prepareModelConversation( - secondTemp, - secondPrompt, - [], - gpt4Model, - ); - await localStorageManager.setConversationHistory( - firstConversation, - secondConversation, - ); - await localStorageManager.setSelectedConversation( - firstConversation, - secondConversation, - ); - }); - await test.step('Send new message in compare chat and verify response is displayed for both and API requests are correct', async () => { + await dialTest.step( + 'Send new message in compare chat and verify response is displayed for both and API requests are correct', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await compare.waitForComparedConversationsLoaded(); @@ -491,9 +550,12 @@ test.describe('Compare mode tests', () => { ExpectedMessages.requestTempIsValid, ) .toBe(secondTemp); - }); + }, + ); - await test.step('Put like/dislike for compared chat, open this chat and verify like/dislike saved', async () => { + await dialTest.step( + 'Put like/dislike for compared chat, open this chat and verify like/dislike saved', + async () => { const rate = GeneratorUtil.randomArrayElement(Object.values(Rate)); await chatMessages.rateCompareRowMessage(Side.left, rate); const isComparedMessageRated = @@ -503,54 +565,57 @@ test.describe('Compare mode tests', () => { .toBeTruthy(); await conversations.selectConversation(firstConversation.name); - await chatMessages .getChatMessageRate(firstConversation.messages.length + 2, rate) .waitFor(); - }); - }, - ); - - test( - 'Generate new response for two chats in compare mode. Bison and GPT-4-32 which have different response time.\n' + - 'Regenerate response in compare mode', - async ({ - dialHomePage, - chat, - chatMessages, - setTestIds, - conversationData, - localStorageManager, - page, - }) => { - setTestIds('EPMRTC-553', 'EPMRTC-555'); - const request = ['beautiful']; - let firstConversation: Conversation; - let secondConversation: Conversation; - - await test.step('Prepare two conversations for comparing', async () => { - firstConversation = - conversationData.prepareModelConversationBasedOnRequests( - bisonModel, - request, - ); - conversationData.resetData(); - secondConversation = - conversationData.prepareModelConversationBasedOnRequests( - ModelsUtil.getModel(ModelIds.GPT_4_32K)!, - request, - ); - await localStorageManager.setConversationHistory( - firstConversation, - secondConversation, + }, + ); + }, +); + +dialTest( + 'Generate new response for two chats in compare mode. Bison and GPT-4-32 which have different response time.\n' + + 'Regenerate response in compare mode', + async ({ + dialHomePage, + chat, + chatMessages, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + page, + }) => { + setTestIds('EPMRTC-553', 'EPMRTC-555'); + const request = ['beautiful']; + let firstConversation: Conversation; + let secondConversation: Conversation; + + await dialTest.step('Prepare two conversations for comparing', async () => { + firstConversation = + conversationData.prepareModelConversationBasedOnRequests( + bisonModel, + request, ); - await localStorageManager.setSelectedConversation( - firstConversation, - secondConversation, + conversationData.resetData(); + secondConversation = + conversationData.prepareModelConversationBasedOnRequests( + ModelsUtil.getModel(ModelIds.GPT_4_32K)!, + request, ); - }); + await dataInjector.createConversations([ + firstConversation, + secondConversation, + ]); + await localStorageManager.setSelectedConversation( + firstConversation, + secondConversation, + ); + }); - await test.step('Send new message in compare chat and verify regenerate is not available until both responses received', async () => { + await dialTest.step( + 'Send new message in compare chat and verify regenerate is not available until both responses received', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -590,9 +655,12 @@ test.describe('Compare mode tests', () => { expect .soft(isStopButtonVisible, ExpectedMessages.stopGeneratingAvailable) .toBeTruthy(); - }); + }, + ); - await test.step('Click "Regenerate" button and verify last response is regenerated for both chats', async () => { + await dialTest.step( + 'Click "Regenerate" button and verify last response is regenerated for both chats', + async () => { await chat.regenerate.waitForState(); const requestsData = await chat.regenerateResponseInCompareMode({ @@ -612,15 +680,19 @@ test.describe('Compare mode tests', () => { ExpectedMessages.requestModeIdIsValid, ) .toBe(secondConversation.model.id); - }); - }, - ); - - test('Apply changes with new settings for both chats in compare mode and check chat headers', async ({ + }, + ); + }, +); + +dialTest( + 'Apply changes with new settings for both chats in compare mode and check chat headers', + async ({ dialHomePage, chat, setTestIds, conversationData, + dataInjector, localStorageManager, leftChatHeader, rightChatHeader, @@ -631,7 +703,7 @@ test.describe('Compare mode tests', () => { errorPopup, iconApiHelper, }) => { - test.slow(); + dialTest.slow(); setTestIds('EPMRTC-1021'); let firstConversation: Conversation; let secondConversation: Conversation; @@ -651,167 +723,185 @@ test.describe('Compare mode tests', () => { const expectedFirstUpdatedRandomModelIcon = await iconApiHelper.getEntityIcon(firstUpdatedRandomModel); - await test.step('Prepare two model conversations for comparing', async () => { - firstConversation = conversationData.prepareModelConversation( - 1, - 'prompt', - [], - initRandomModel, - ); + await dialTest.step( + 'Prepare two model conversations for comparing', + async () => { + firstConversation = conversationData.prepareModelConversation( + 1, + 'prompt', + [], + initRandomModel, + ); + conversationData.resetData(); + secondConversation = + conversationData.prepareDefaultConversation(initRandomModel); + await dataInjector.createConversations([ + firstConversation, + secondConversation, + ]); + await localStorageManager.setSelectedConversation( + firstConversation, + secondConversation, + ); + }, + ); + + await dialTest.step( + 'Open chat settings and update them for both models', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await leftChatHeader.openConversationSettingsPopup(); + await leftConversationSettings + .getTalkToSelector() + .selectModel(firstUpdatedRandomModel.name); + const leftEntitySettings = leftConversationSettings.getEntitySettings(); + await leftEntitySettings.setSystemPrompt(firstUpdatedPrompt); + await leftEntitySettings + .getTemperatureSlider() + .setTemperature(firstUpdatedTemp); + + await rightConversationSettings + .getTalkToSelector() + .selectModel(secondUpdatedRandomModel.name); + const rightEntitySettings = + rightConversationSettings.getEntitySettings(); + await rightEntitySettings.setSystemPrompt(secondUpdatedPrompt); + await rightEntitySettings + .getTemperatureSlider() + .setTemperature(secondUpdatedTemp); + await chat.applyNewEntity( + firstUpdatedRandomModel.iconUrl, + secondUpdatedRandomModel.iconUrl, + ); + }, + ); + + await dialTest.step( + 'Verify chat icons are updated with new model and addons in the header and chat bar', + async () => { + const rightHeaderModelIcon = await rightChatHeader.getHeaderModelIcon(); + expect + .soft( + rightHeaderModelIcon, + `${ExpectedMessages.entityIconIsValid} for ${secondUpdatedRandomModel.name}`, + ) + .toBe(expectedSecondUpdatedRandomModelIcon); + + const leftHeaderModelIcon = await leftChatHeader.getHeaderModelIcon(); + expect + .soft( + leftHeaderModelIcon, + `${ExpectedMessages.entityIconIsValid} for ${firstUpdatedRandomModel.name}`, + ) + .toBe(expectedFirstUpdatedRandomModelIcon); + + const firstConversationIcon = await conversations.getConversationIcon( + firstConversation.name, + ); + expect + .soft(firstConversationIcon, ExpectedMessages.entityIconIsValid) + .toBe(expectedFirstUpdatedRandomModelIcon); + + const secondConversationIcon = await conversations.getConversationIcon( + secondConversation.name, + ); + expect + .soft(secondConversationIcon, ExpectedMessages.entityIconIsValid) + .toBe(expectedSecondUpdatedRandomModelIcon); + }, + ); + + await dialTest.step( + 'Hover over chat headers and verify chat settings updated on tooltip', + async () => { + await errorPopup.cancelPopup(); + await rightChatHeader.chatModel.hoverOver(); + const rightModelInfo = await chatInfoTooltip.getModelInfo(); + expect + .soft(rightModelInfo, ExpectedMessages.chatInfoModelIsValid) + .toBe(secondUpdatedRandomModel.name); + + const rightModelInfoIcon = await chatInfoTooltip.getModelIcon(); + expect + .soft(rightModelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) + .toBe(expectedSecondUpdatedRandomModelIcon); + + const rightPromptInfo = await chatInfoTooltip.getPromptInfo(); + expect + .soft(rightPromptInfo, ExpectedMessages.chatInfoPromptIsValid) + .toBe(secondUpdatedPrompt); + + const rightTempInfo = await chatInfoTooltip.getTemperatureInfo(); + expect + .soft(rightTempInfo, ExpectedMessages.chatInfoTemperatureIsValid) + .toBe(secondUpdatedTemp.toString()); + + await errorPopup.cancelPopup(); + await leftChatHeader.chatModel.hoverOver(); + const leftModelInfo = await chatInfoTooltip.getModelInfo(); + expect + .soft(leftModelInfo, ExpectedMessages.chatInfoModelIsValid) + .toBe(firstUpdatedRandomModel.name); + + const leftModelInfoIcon = await chatInfoTooltip.getModelIcon(); + expect + .soft(leftModelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) + .toBe(expectedFirstUpdatedRandomModelIcon); + + const leftPromptInfo = await chatInfoTooltip.getPromptInfo(); + expect + .soft(leftPromptInfo, ExpectedMessages.chatInfoPromptIsValid) + .toBe(firstUpdatedPrompt); + + const leftTempInfo = await chatInfoTooltip.getTemperatureInfo(); + expect + .soft(leftTempInfo, ExpectedMessages.chatInfoTemperatureIsValid) + .toBe(firstUpdatedTemp.toString()); + }, + ); + }, +); + +dialTest( + 'Stop regenerating in compare mode.\n' + + 'Both "Talk to" item icons are jumping while generating an answer in Compare mode', + async ({ + dialHomePage, + chat, + chatMessages, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + compare, + iconApiHelper, + }) => { + dialTest.slow(); + setTestIds('EPMRTC-556', 'EPMRTC-1134'); + let firstConversation: Conversation; + let secondConversation: Conversation; + const sides = Object.values(Side); + + await dialTest.step('Prepare two conversations for comparing', async () => { + firstConversation = + conversationData.prepareDefaultConversation(defaultModel); conversationData.resetData(); secondConversation = - conversationData.prepareDefaultConversation(initRandomModel); - await localStorageManager.setConversationHistory( + conversationData.prepareDefaultConversation(defaultModel); + await dataInjector.createConversations([ firstConversation, secondConversation, - ); + ]); await localStorageManager.setSelectedConversation( firstConversation, secondConversation, ); }); - await test.step('Open chat settings and update them for both models', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await leftChatHeader.openConversationSettingsPopup(); - await leftConversationSettings - .getTalkToSelector() - .selectModel(firstUpdatedRandomModel.name); - const leftEntitySettings = leftConversationSettings.getEntitySettings(); - await leftEntitySettings.setSystemPrompt(firstUpdatedPrompt); - await leftEntitySettings - .getTemperatureSlider() - .setTemperature(firstUpdatedTemp); - - await rightConversationSettings - .getTalkToSelector() - .selectModel(secondUpdatedRandomModel.name); - const rightEntitySettings = rightConversationSettings.getEntitySettings(); - await rightEntitySettings.setSystemPrompt(secondUpdatedPrompt); - await rightEntitySettings - .getTemperatureSlider() - .setTemperature(secondUpdatedTemp); - await chat.applyNewEntity( - firstUpdatedRandomModel.iconUrl, - secondUpdatedRandomModel.iconUrl, - ); - }); - - await test.step('Verify chat icons are updated with new model and addons in the header and chat bar', async () => { - const rightHeaderModelIcon = await rightChatHeader.getHeaderModelIcon(); - expect - .soft( - rightHeaderModelIcon, - `${ExpectedMessages.entityIconIsValid} for ${secondUpdatedRandomModel.name}`, - ) - .toBe(expectedSecondUpdatedRandomModelIcon); - - const leftHeaderModelIcon = await leftChatHeader.getHeaderModelIcon(); - expect - .soft( - leftHeaderModelIcon, - `${ExpectedMessages.entityIconIsValid} for ${firstUpdatedRandomModel.name}`, - ) - .toBe(expectedFirstUpdatedRandomModelIcon); - - const firstConversationIcon = await conversations.getConversationIcon( - firstConversation.name, - ); - expect - .soft(firstConversationIcon, ExpectedMessages.entityIconIsValid) - .toBe(expectedFirstUpdatedRandomModelIcon); - - const secondConversationIcon = await conversations.getConversationIcon( - secondConversation.name, - ); - expect - .soft(secondConversationIcon, ExpectedMessages.entityIconIsValid) - .toBe(expectedSecondUpdatedRandomModelIcon); - }); - - await test.step('Hover over chat headers and verify chat settings updated on tooltip', async () => { - await errorPopup.cancelPopup(); - await rightChatHeader.chatModel.hoverOver(); - const rightModelInfo = await chatInfoTooltip.getModelInfo(); - expect - .soft(rightModelInfo, ExpectedMessages.chatInfoModelIsValid) - .toBe(secondUpdatedRandomModel.name); - - const rightModelInfoIcon = await chatInfoTooltip.getModelIcon(); - expect - .soft(rightModelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) - .toBe(expectedSecondUpdatedRandomModelIcon); - - const rightPromptInfo = await chatInfoTooltip.getPromptInfo(); - expect - .soft(rightPromptInfo, ExpectedMessages.chatInfoPromptIsValid) - .toBe(secondUpdatedPrompt); - - const rightTempInfo = await chatInfoTooltip.getTemperatureInfo(); - expect - .soft(rightTempInfo, ExpectedMessages.chatInfoTemperatureIsValid) - .toBe(secondUpdatedTemp.toString()); - - await errorPopup.cancelPopup(); - await leftChatHeader.chatModel.hoverOver(); - const leftModelInfo = await chatInfoTooltip.getModelInfo(); - expect - .soft(leftModelInfo, ExpectedMessages.chatInfoModelIsValid) - .toBe(firstUpdatedRandomModel.name); - - const leftModelInfoIcon = await chatInfoTooltip.getModelIcon(); - expect - .soft(leftModelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) - .toBe(expectedFirstUpdatedRandomModelIcon); - - const leftPromptInfo = await chatInfoTooltip.getPromptInfo(); - expect - .soft(leftPromptInfo, ExpectedMessages.chatInfoPromptIsValid) - .toBe(firstUpdatedPrompt); - - const leftTempInfo = await chatInfoTooltip.getTemperatureInfo(); - expect - .soft(leftTempInfo, ExpectedMessages.chatInfoTemperatureIsValid) - .toBe(firstUpdatedTemp.toString()); - }); - }); - - test( - 'Stop regenerating in compare mode.\n' + - 'Both "Talk to" item icons are jumping while generating an answer in Compare mode', - async ({ - dialHomePage, - chat, - chatMessages, - setTestIds, - conversationData, - localStorageManager, - compare, - iconApiHelper, - }) => { - setTestIds('EPMRTC-556', 'EPMRTC-1134'); - let firstConversation: Conversation; - let secondConversation: Conversation; - const sides = Object.values(Side); - - await test.step('Prepare two conversations for comparing', async () => { - firstConversation = - conversationData.prepareDefaultConversation(defaultModel); - conversationData.resetData(); - secondConversation = - conversationData.prepareDefaultConversation(defaultModel); - await localStorageManager.setConversationHistory( - firstConversation, - secondConversation, - ); - await localStorageManager.setSelectedConversation( - firstConversation, - secondConversation, - ); - }); - - await test.step('Send new message in compare chat, verify both chat icons are jumping while responding and then stop generation', async () => { + await dialTest.step( + 'Send new message in compare chat, verify both chat icons are jumping while responding and then stop generation', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await compare.waitForComparedConversationsLoaded(); @@ -829,9 +919,12 @@ test.describe('Compare mode tests', () => { } await chat.stopGenerating.click(); - }); + }, + ); - await test.step('Verify response is not received by both chats, stop is done immediately, valid model icons are displayed', async () => { + await dialTest.step( + 'Verify response is not received by both chats, stop is done immediately, valid model icons are displayed', + async () => { const isResponseLoading = await chatMessages.isResponseLoading(); expect .soft(isResponseLoading, ExpectedMessages.responseLoadingStopped) @@ -850,38 +943,43 @@ test.describe('Compare mode tests', () => { .soft(messageIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedModelIcon); } - }); - }, - ); - - test( - 'Search chat in Select conversation drop down.\n' + - 'Select chat from search results in Select conversation drop down', - async ({ - dialHomePage, - setTestIds, - conversationDropdownMenu, - conversations, - conversationData, - localStorageManager, - compareConversationSelector, - rightChatHeader, - }) => { - setTestIds('EPMRTC-536', 'EPMRTC-1168'); - const request = 'What is epam official name?'; - const firstSearchTerm = 'epam'; - const secondSearchTerm = 'systems'; - const thirdSearchTerm = 'epam official'; - const underscoreSearchTerm = '_'; - const noResultSearchTerm = 'epaQ'; - - let firstConversation: Conversation; - let secondConversation: Conversation; - let thirdConversation: Conversation; - let fourthConversation: Conversation; - const matchedConversations: string[] = []; - - await test.step('Prepare 4 conversations with the same request but different names', async () => { + }, + ); + }, +); + +dialTest( + 'Search chat in Select conversation drop down.\n' + + 'Select chat from search results in Select conversation drop down', + async ({ + dialHomePage, + setTestIds, + conversationDropdownMenu, + conversations, + conversationData, + localStorageManager, + dataInjector, + compareConversationSelector, + rightChatHeader, + compareConversation, + }) => { + setTestIds('EPMRTC-536', 'EPMRTC-1168'); + const request = 'What is epam official name'; + const firstSearchTerm = 'epam'; + const secondSearchTerm = 'systems'; + const thirdSearchTerm = 'epam official'; + const underscoreSearchTerm = '_'; + const noResultSearchTerm = 'epaQ'; + + let firstConversation: Conversation; + let secondConversation: Conversation; + let thirdConversation: Conversation; + let fourthConversation: Conversation; + const matchedConversations: string[] = []; + + await dialTest.step( + 'Prepare 4 conversations with the same request but different names', + async () => { firstConversation = conversationData.prepareModelConversationBasedOnRequests( defaultModel, @@ -893,7 +991,7 @@ test.describe('Compare mode tests', () => { conversationData.prepareModelConversationBasedOnRequests( defaultModel, [request], - request, + 'When was epam officially founded', ); conversationData.resetData(); thirdConversation = @@ -907,68 +1005,82 @@ test.describe('Compare mode tests', () => { conversationData.prepareModelConversationBasedOnRequests( defaultModel, [request], - 'epam_systems !@#$%^&*()+=\':",.<>', + 'epam_systems', ); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ firstConversation, secondConversation, thirdConversation, fourthConversation, - ); + ]); await localStorageManager.setSelectedConversation(firstConversation); matchedConversations.push( - secondConversation.name, thirdConversation.name, + secondConversation.name, fourthConversation.name, ); - }); + matchedConversations.sort(); + }, + ); - await test.step('Open compare mode for the 1st chat and verify all chats are available for comparison in dropdown list', async () => { + await dialTest.step( + 'Open compare mode for the 1st chat and verify all chats are available for comparison in dropdown list', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu( firstConversation.name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); + await compareConversation.checkShowAllConversations(); await compareConversationSelector.click(); const conversationsList = await compareConversationSelector.getListOptions(); expect .soft( - conversationsList, + conversationsList.sort(), ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual(matchedConversations); - }); + }, + ); - await test.step('Type first search term and verify all chats are available for comparison in dropdown list', async () => { + await dialTest.step( + 'Type first search term and verify all chats are available for comparison in dropdown list', + async () => { for (const term of [firstSearchTerm, firstSearchTerm.toUpperCase()]) { await compareConversationSelector.fillInput(term); const conversationsList = await compareConversationSelector.getListOptions(); expect .soft( - conversationsList, + conversationsList.sort(), ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual(matchedConversations); } - }); + }, + ); - await test.step('Type second search term and verify chat 3 and 4 are available for comparison in dropdown list', async () => { + await dialTest.step( + 'Type second search term and verify chat 3 and 4 are available for comparison in dropdown list', + async () => { await compareConversationSelector.fillInput(secondSearchTerm); const conversationsList = await compareConversationSelector.getListOptions(); expect .soft( - conversationsList, + conversationsList.sort(), ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual([thirdConversation.name, fourthConversation.name]); - }); + }, + ); - await test.step('Type third search term and verify chat 2 is available for comparison in dropdown list', async () => { + await dialTest.step( + 'Type third search term and verify chat 2 is available for comparison in dropdown list', + async () => { await compareConversationSelector.fillInput(thirdSearchTerm); const conversationsList = await compareConversationSelector.getListOptions(); @@ -978,9 +1090,12 @@ test.describe('Compare mode tests', () => { ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual([secondConversation.name]); - }); + }, + ); - await test.step('Type underscore and verify chat 4 is available for comparison in dropdown list', async () => { + await dialTest.step( + 'Type underscore and verify chat 4 is available for comparison in dropdown list', + async () => { await compareConversationSelector.fillInput(underscoreSearchTerm); const conversationsList = await compareConversationSelector.getListOptions(); @@ -990,9 +1105,12 @@ test.describe('Compare mode tests', () => { ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual([fourthConversation.name]); - }); + }, + ); - await test.step('Type not matching search term and verify no chats available for comparison in dropdown list', async () => { + await dialTest.step( + 'Type not matching search term and verify no chats available for comparison in dropdown list', + async () => { await compareConversationSelector.fillInput(noResultSearchTerm); const conversationsList = await compareConversationSelector.getListOptions(); @@ -1002,21 +1120,27 @@ test.describe('Compare mode tests', () => { ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual([]); - }); + }, + ); - await test.step('Delete search term and verify all chats are available for comparison in dropdown list', async () => { + await dialTest.step( + 'Delete search term and verify all chats are available for comparison in dropdown list', + async () => { await compareConversationSelector.fillInput(''); const conversationsList = await compareConversationSelector.getListOptions(); expect .soft( - conversationsList, + conversationsList.sort(), ExpectedMessages.conversationsToCompareOptionsValid, ) .toEqual(matchedConversations); - }); + }, + ); - await test.step('Select any chat and verify it shown in the input, dropdown list is closed', async () => { + await dialTest.step( + 'Select any chat and verify it shown in the input, dropdown list is closed', + async () => { const chatToSelect = GeneratorUtil.randomArrayElement(matchedConversations); await compareConversationSelector.selectModel(chatToSelect, true); @@ -1028,33 +1152,37 @@ test.describe('Compare mode tests', () => { expect .soft(rightHeaderTitle, ExpectedMessages.headerTitleCorrespondRequest) .toBe(chatToSelect); - }); - }, - ); - - test( - 'Compare mode is closed if to create new chat.\n' + - 'Compare mode is closed if to click on chat which is used in compare mode.\n' + - 'Check chat header in compare mode with long chat names.\n' + - 'Long chat names in Select conversations drop down list', - async ({ - dialHomePage, - setTestIds, - conversationData, - localStorageManager, - compare, - conversations, - chatBar, - chatHeader, - compareConversationSelector, - conversationDropdownMenu, - leftChatHeader, - }) => { - setTestIds('EPMRTC-542', 'EPMRTC-543', 'EPMRTC-548', 'EPMRTC-828'); - let firstConversation: Conversation; - let secondConversation: Conversation; - - await test.step('Prepare two conversations for compare mode', async () => { + }, + ); + }, +); + +dialTest( + 'Compare mode is closed if to create new chat.\n' + + 'Compare mode is closed if to click on chat which is used in compare mode.\n' + + 'Check chat header in compare mode with long chat names.\n' + + 'Long chat names in Select conversations drop down list', + async ({ + dialHomePage, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + compare, + conversations, + chatBar, + chatHeader, + compareConversationSelector, + conversationDropdownMenu, + leftChatHeader, + }) => { + setTestIds('EPMRTC-542', 'EPMRTC-543', 'EPMRTC-548', 'EPMRTC-828'); + let firstConversation: Conversation; + let secondConversation: Conversation; + + await dialTest.step( + 'Prepare two conversations for compare mode', + async () => { firstConversation = conversationData.prepareDefaultConversation( defaultModel, GeneratorUtil.randomString(70), @@ -1070,35 +1198,46 @@ test.describe('Compare mode tests', () => { secondConversationName, ); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ firstConversation, secondConversation, - ); + ]); await localStorageManager.setSelectedConversation( firstConversation, secondConversation, ); - }); - - await test.step('Open compare mode and verify long chat name is cut', async () => { - await dialHomePage.openHomePage(); + }, + ); + + await dialTest.step( + 'Open compare mode and verify long chat name is cut', + async () => { + await dialHomePage.openHomePage({ + iconsToBeLoaded: [defaultModel.iconUrl], + }); await dialHomePage.waitForPageLoaded(); const isTitleTruncated = await chatHeader.chatTitle.isElementWidthTruncated(); expect .soft(isTitleTruncated, ExpectedMessages.chatHeaderTitleTruncated) .toBeTruthy(); - }); + }, + ); - await test.step('Create new chat and verify Compare mode is closed', async () => { + await dialTest.step( + 'Create new chat and verify Compare mode is closed', + async () => { await chatBar.createNewConversation(); const isCompareModeOn = await compare.isVisible(); expect .soft(isCompareModeOn, ExpectedMessages.compareModeClosed) .toBeFalsy(); - }); + }, + ); - await test.step('Open compare mode again, switch to comparing conversation and verify Compare mode is closed', async () => { + await dialTest.step( + 'Open compare mode again, switch to comparing conversation and verify Compare mode is closed', + async () => { await dialHomePage.reloadPage(); await compare.waitForState(); await conversations.selectConversation(firstConversation.name); @@ -1106,9 +1245,12 @@ test.describe('Compare mode tests', () => { expect .soft(isCompareModeOn, ExpectedMessages.compareModeClosed) .toBeFalsy(); - }); + }, + ); - await test.step('Open compare mode for 1st conversation and verify long compare options are shown in different rows', async () => { + await dialTest.step( + 'Open compare mode for 1st conversation and verify long compare options are shown in different rows', + async () => { await conversations.openConversationDropdownMenu( firstConversation.name, ); @@ -1131,17 +1273,20 @@ test.describe('Compare mode tests', () => { expect .soft(overflowProp[0], ExpectedMessages.entityNameIsTruncated) .toBe(Overflow.auto); - }); - }, - ); - - test('Compare two chats located in different folders', async ({ + }, + ); + }, +); + +dialTest( + 'Compare two chats located in different folders', + async ({ dialHomePage, setTestIds, conversationDropdownMenu, folderConversations, conversationData, - localStorageManager, + dataInjector, compare, compareConversationSelector, chat, @@ -1149,112 +1294,125 @@ test.describe('Compare mode tests', () => { setTestIds('EPMRTC-557'); let firstFolderConversation: FolderConversation; let secondFolderConversation: FolderConversation; + const conversationName = GeneratorUtil.randomString(7); - await test.step('Prepare two conversations in folders', async () => { + await dialTest.step('Prepare two conversations in folders', async () => { firstFolderConversation = - conversationData.prepareDefaultConversationInFolder(defaultModel); + conversationData.prepareDefaultConversationInFolder( + defaultModel, + `${conversationName} 1`, + ); conversationData.resetData(); secondFolderConversation = - conversationData.prepareDefaultConversationInFolder(bisonModel); - await localStorageManager.setFolders( + conversationData.prepareDefaultConversationInFolder( + bisonModel, + `${conversationName} 2`, + ); + + await dataInjector.createConversations( + [ + firstFolderConversation.conversations[0], + secondFolderConversation.conversations[0], + ], firstFolderConversation.folders, secondFolderConversation.folders, ); - await localStorageManager.setConversationHistory( - firstFolderConversation.conversations[0], - secondFolderConversation.conversations[0], - ); - await localStorageManager.setSelectedConversation( - firstFolderConversation.conversations[0], - ); - }); - - await test.step('Open compare mode from 1st chat dropdown menu and verify one chat is available for comparison', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await folderConversations.expandCollapseFolder( - firstFolderConversation.folders.name, - ); - await folderConversations.expandCollapseFolder( - secondFolderConversation.folders.name, - ); - await folderConversations.openFolderEntityDropdownMenu( - firstFolderConversation.folders.name, - firstFolderConversation.conversations[0].name, - ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); - await compare.waitForState(); - await compareConversationSelector.click(); - const conversationsList = - await compareConversationSelector.getListOptions(); - expect - .soft( - conversationsList, - ExpectedMessages.conversationsToCompareOptionsValid, - ) - .toEqual([secondFolderConversation.conversations[0].name]); }); - await test.step('Select folder conversation for comparison, send new request and verify response generated for both chats', async () => { - await compareConversationSelector.selectModel( - secondFolderConversation.conversations[0].name, - true, - ); - const requestsData = await chat.sendRequestInCompareMode( - 'repeat the same response', - { - rightEntity: firstFolderConversation.conversations[0].model.id, - leftEntity: secondFolderConversation.conversations[0].model.id, - }, - ); - expect - .soft( - requestsData.rightRequest.modelId, - ExpectedMessages.requestModeIdIsValid, - ) - .toBe(firstFolderConversation.conversations[0].model.id); - expect - .soft( - requestsData.leftRequest.modelId, - ExpectedMessages.requestModeIdIsValid, - ) - .toBe(secondFolderConversation.conversations[0].model.id); - }); - }); - - test( - 'In compare mode delete any message in chat2.\n' + - 'In compare mode copy answer.\n' + - 'In compare mode save&sumbit any message in chat1.\n' + - 'In compare mode edit chat name.\n' + - 'In compare mode delete a chat', - async ({ - dialHomePage, - setTestIds, - conversationData, - localStorageManager, - chatMessages, - confirmationDialog, - page, - conversations, - leftChatHeader, - conversationDropdownMenu, - compare, - }) => { - setTestIds( - 'EPMRTC-560', - 'EPMRTC-562', - 'EPMRTC-559', - 'EPMRTC-563', - 'EPMRTC-564', - ); - let firstConversation: Conversation; - let secondConversation: Conversation; - const firstConversationRequests = ['1+2=', '2+3=', '3+4=']; - const secondConversationRequests = ['1+2=', '4+5=', '5+6=']; - let updatedRequestContent: string; + await dialTest.step( + 'Open compare mode from 1st chat dropdown menu and verify one chat is available for comparison', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await folderConversations.expandCollapseFolder( + firstFolderConversation.folders.name, + { isHttpMethodTriggered: true }, + ); + await folderConversations.openFolderEntityDropdownMenu( + firstFolderConversation.folders.name, + firstFolderConversation.conversations[0].name, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); + await compare.waitForState(); + await compareConversationSelector.click(); + const conversationsList = + await compareConversationSelector.getListOptions(); + expect + .soft( + conversationsList, + ExpectedMessages.conversationsToCompareOptionsValid, + ) + .toEqual([secondFolderConversation.conversations[0].name]); + }, + ); + + await dialTest.step( + 'Select folder conversation for comparison, send new request and verify response generated for both chats', + async () => { + await compareConversationSelector.selectModel( + secondFolderConversation.conversations[0].name, + true, + ); + const requestsData = await chat.sendRequestInCompareMode( + 'repeat the same response', + { + rightEntity: firstFolderConversation.conversations[0].model.id, + leftEntity: secondFolderConversation.conversations[0].model.id, + }, + ); + expect + .soft( + requestsData.rightRequest.modelId, + ExpectedMessages.requestModeIdIsValid, + ) + .toBe(firstFolderConversation.conversations[0].model.id); + expect + .soft( + requestsData.leftRequest.modelId, + ExpectedMessages.requestModeIdIsValid, + ) + .toBe(secondFolderConversation.conversations[0].model.id); + }, + ); + }, +); + +dialTest( + 'In compare mode delete any message in chat2.\n' + + 'In compare mode copy answer.\n' + + 'In compare mode save&sumbit any message in chat1.\n' + + 'In compare mode edit chat name.\n' + + 'In compare mode delete a chat', + async ({ + dialHomePage, + setTestIds, + conversationData, + localStorageManager, + dataInjector, + chatMessages, + confirmationDialog, + page, + conversations, + leftChatHeader, + conversationDropdownMenu, + compare, + }) => { + setTestIds( + 'EPMRTC-560', + 'EPMRTC-562', + 'EPMRTC-559', + 'EPMRTC-563', + 'EPMRTC-564', + ); + let firstConversation: Conversation; + let secondConversation: Conversation; + const firstConversationRequests = ['1+2', '2+3', '3+4']; + const secondConversationRequests = ['1+2', '4+5', '5+6']; + let updatedRequestContent: string; - await test.step('Prepare two conversations for compare mode', async () => { + await dialTest.step( + 'Prepare two conversations for compare mode', + async () => { firstConversation = conversationData.prepareModelConversationBasedOnRequests( defaultModel, @@ -1268,17 +1426,20 @@ test.describe('Compare mode tests', () => { secondConversationRequests, ); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ firstConversation, secondConversation, - ); + ]); await localStorageManager.setSelectedConversation( firstConversation, secondConversation, ); - }); + }, + ); - await test.step('Delete 1st message from the left conversation and verify only 1st row deleted for both chats', async () => { + await dialTest.step( + 'Delete 1st message from the left conversation and verify only 1st row deleted for both chats', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await chatMessages.openDeleteCompareRowMessageDialog(Side.left, 1); @@ -1300,9 +1461,12 @@ test.describe('Compare mode tests', () => { ExpectedMessages.messageContentIsValid, ) .toBe(firstConversationRequests[1]); - }); + }, + ); - await test.step('Copy last response from the right conversation and edit the 1st request for the left chat with copied message', async () => { + await dialTest.step( + 'Copy last response from the right conversation and edit the 1st request for the left chat with copied message', + async () => { await chatMessages.copyCompareRowMessage( Side.right, (firstConversationRequests.length - 1) * 2, @@ -1312,9 +1476,12 @@ test.describe('Compare mode tests', () => { await page.keyboard.press(keys.ctrlPlusV); await chatMessages.saveAndSubmit.click(); await chatMessages.waitForResponseReceived(); - }); + }, + ); - await test.step('Verify both first requests updated, messages below are deleted', async () => { + await dialTest.step( + 'Verify both first requests updated, messages below are deleted', + async () => { updatedRequestContent = secondConversation.messages[secondConversation.messages.length - 1] .content; @@ -1336,9 +1503,12 @@ test.describe('Compare mode tests', () => { ) .toBe(updatedRequestContent); } - }); + }, + ); - await test.step('Edit left chat title and verify it is updated in the header', async () => { + await dialTest.step( + 'Edit left chat title and verify it is updated in the header', + async () => { const newLeftChatName = GeneratorUtil.randomString(7); await conversations.openConversationDropdownMenu( updatedRequestContent, @@ -1354,9 +1524,12 @@ test.describe('Compare mode tests', () => { expect .soft(chatTitle, ExpectedMessages.headerTitleCorrespondRequest) .toBe(chatTitle); - }); + }, + ); - await test.step('Delete right chat and compare mode closed, left chat is active', async () => { + await dialTest.step( + 'Delete right chat and compare mode closed, left chat is active', + async () => { await conversations.openConversationDropdownMenu(updatedRequestContent); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); await conversations @@ -1375,7 +1548,7 @@ test.describe('Compare mode tests', () => { expect .soft(isCompareModeOpened, ExpectedMessages.compareModeClosed) .toBeFalsy(); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/defaultModelSettings.test.ts b/apps/chat-e2e/src/tests/defaultModelSettings.test.ts index 4d686b9f0a..fe2e01d5fe 100644 --- a/apps/chat-e2e/src/tests/defaultModelSettings.test.ts +++ b/apps/chat-e2e/src/tests/defaultModelSettings.test.ts @@ -1,4 +1,4 @@ -import test, { stateFilePath } from '../core/fixtures'; +import dialTest from '../core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, ModelIds } from '../testData'; import { Colors, Cursors, Styles } from '../ui/domData'; @@ -13,7 +13,7 @@ let recentAddonIds: string[]; let recentModelIds: string[]; let allEntities: OpenAIEntityModel[]; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { defaultModel = ModelsUtil.getDefaultModel()!; bison = ModelsUtil.getModel(ModelIds.BISON_001)!; recentAddonIds = ModelsUtil.getRecentAddonIds(); @@ -21,29 +21,27 @@ test.beforeAll(async () => { allEntities = ModelsUtil.getOpenAIEntities(); }); -test.describe('Chat default settings tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Create new conversation.\n' + - 'Default settings in new chat with cleared site data.\n' + - '"Talk to" icon is set in recent list on default screen for new chat.\n' + - 'Addon icon is set in recent and selected list on default screen for new chat', - async ({ - dialHomePage, - chatBar, - conversations, - recentEntities, - entitySettings, - temperatureSlider, - addons, - iconApiHelper, - setTestIds, - }) => { - setTestIds('EPMRTC-933', 'EPMRTC-398', 'EPMRTC-376', 'EPMRTC-1030'); - const expectedAddons = ModelsUtil.getAddons(); - await test.step('Create new conversation and verify it is moved under Today section in chat bar', async () => { +dialTest( + 'Create new conversation.\n' + + 'Default settings in new chat with cleared site data.\n' + + '"Talk to" icon is set in recent list on default screen for new chat.\n' + + 'Addon icon is set in recent and selected list on default screen for new chat', + async ({ + dialHomePage, + chatBar, + conversations, + recentEntities, + entitySettings, + temperatureSlider, + addons, + iconApiHelper, + setTestIds, + }) => { + setTestIds('EPMRTC-933', 'EPMRTC-398', 'EPMRTC-376', 'EPMRTC-1030'); + const expectedAddons = ModelsUtil.getAddons(); + await dialTest.step( + 'Create new conversation and verify it is moved under Today section in chat bar', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -64,9 +62,12 @@ test.describe('Chat default settings tests', () => { expect.stringContaining(ExpectedConstants.newConversationTitle), ); } - }); + }, + ); - await test.step('Verify default model is selected by default', async () => { + await dialTest.step( + 'Verify default model is selected by default', + async () => { await recentEntities.waitForState(); const modelBorderColors = await recentEntities .getRecentEntity(defaultModel.name) @@ -78,9 +79,12 @@ test.describe('Chat default settings tests', () => { .toBe(Colors.controlsBackgroundAccent); }); }); - }); + }, + ); - await test.step('Verify the list of recent entities and default settings for default model', async () => { + await dialTest.step( + 'Verify the list of recent entities and default settings for default model', + async () => { const expectedDefaultRecentEntities = []; for (const entity of recentModelIds) { expectedDefaultRecentEntities.push( @@ -121,9 +125,12 @@ test.describe('Chat default settings tests', () => { expect .soft(recentAddons, ExpectedMessages.recentAddonsVisible) .toEqual(expectedDefaultRecentAddons); - }); + }, + ); - await test.step('Verify recent entities icons are displayed and valid', async () => { + await dialTest.step( + 'Verify recent entities icons are displayed and valid', + async () => { const recentEntitiesIcons = await recentEntities.getRecentEntitiesIcons(); expect @@ -147,9 +154,12 @@ test.describe('Chat default settings tests', () => { ) .toBe(expectedEntityIcon); } - }); + }, + ); - await test.step('Verify recent addon icons are displayed and valid', async () => { + await dialTest.step( + 'Verify recent addon icons are displayed and valid', + async () => { const recentAddonsIcons = await addons.getRecentAddonsIcons(); expect .soft( @@ -172,31 +182,34 @@ test.describe('Chat default settings tests', () => { ) .toBe(expectedAddonIcon); } - }); - }, - ); - - test( - 'Default model in new chat is set as in previous chat.\n' + - 'Send button is disabled if the message box is empty.\n' + - 'Chat name is shown in chat header.\n' + - `It's impossible to send a message with spaces only`, - async ({ - dialHomePage, - chatBar, - recentEntities, - talkToSelector, - chat, - sendMessage, - chatHeader, - tooltip, - chatMessages, - page, - setTestIds, - }) => { - setTestIds('EPMRTC-400', 'EPMRTC-474', 'EPMRTC-817', 'EPMRTC-1568'); - const request = 'test'; - await test.step('Verify Send button is disabled if no request message set and tooltip is shown on button hover', async () => { + }, + ); + }, +); + +dialTest( + 'Default model in new chat is set as in previous chat.\n' + + 'Send button is disabled if the message box is empty.\n' + + 'Chat name is shown in chat header.\n' + + `It's impossible to send a message with spaces only`, + async ({ + dialHomePage, + chatBar, + recentEntities, + talkToSelector, + chat, + sendMessage, + chatHeader, + tooltip, + chatMessages, + page, + setTestIds, + }) => { + setTestIds('EPMRTC-400', 'EPMRTC-474', 'EPMRTC-817', 'EPMRTC-1568'); + const request = 'test'; + await dialTest.step( + 'Verify Send button is disabled if no request message set and tooltip is shown on button hover', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -217,9 +230,12 @@ test.describe('Chat default settings tests', () => { expect .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.sendMessageTooltip); - }); + }, + ); - await test.step('Set spaces in the message input and Send button is disabled, tooltip is shown on hover, no message send on hit Enter', async () => { + await dialTest.step( + 'Set spaces in the message input and Send button is disabled, tooltip is shown on hover, no message send on hit Enter', + async () => { for (let i = 1; i <= 2; i++) { if (i === 2) { const messagesCountBefore = @@ -261,17 +277,23 @@ test.describe('Chat default settings tests', () => { .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.sendMessageTooltip); } - }); + }, + ); - await test.step('Send new request and verify it is reflected in chat header', async () => { + await dialTest.step( + 'Send new request and verify it is reflected in chat header', + async () => { await chat.sendRequestWithButton(request); const chatTitle = await chatHeader.chatTitle.getElementInnerContent(); expect .soft(chatTitle, ExpectedMessages.headerTitleCorrespondRequest) .toBe(request); - }); + }, + ); - await test.step('Create new conversation and verify previous model is preselected and highlighted', async () => { + await dialTest.step( + 'Create new conversation and verify previous model is preselected and highlighted', + async () => { await chatBar.createNewConversation(); const modelBorderColors = await recentEntities .getRecentEntity(bison.name) @@ -288,11 +310,14 @@ test.describe('Chat default settings tests', () => { expect .soft(recentTalkTo[0], ExpectedMessages.recentEntitiesIsOnTop) .toBe(bison.name); - }); - }, - ); + }, + ); + }, +); - test('Settings on default screen are saved in local storage when temperature = 0', async ({ +dialTest( + 'Settings on default screen are saved in local storage when temperature = 0', + async ({ dialHomePage, recentEntities, entitySettings, @@ -339,9 +364,12 @@ test.describe('Chat default settings tests', () => { const selectedAddons = await addons.getSelectedAddons(); expect.soft(selectedAddons, ExpectedMessages.noAddonsSelected).toEqual([]); - }); + }, +); - test('Recent "Talk to" list is updated', async ({ +dialTest( + 'Recent "Talk to" list is updated', + async ({ dialHomePage, chatBar, recentEntities, @@ -372,9 +400,12 @@ test.describe('Chat default settings tests', () => { expect .soft(recentTalkTo[0], ExpectedMessages.talkToEntityIsSelected) .toBe(bison.name); - }); + }, +); - test('Search "Talk to" item in "See full list..."', async ({ +dialTest( + 'Search "Talk to" item in "See full list..."', + async ({ dialHomePage, chatBar, talkToSelector, @@ -396,59 +427,74 @@ test.describe('Chat default settings tests', () => { a.name.toLowerCase().includes(searchTerm.toLowerCase()), ); - await test.step('Create new conversation and click "See full list.." link', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await chatBar.createNewConversation(); - await talkToSelector.seeFullList(); - }); + await dialTest.step( + 'Create new conversation and click "See full list.." link', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await chatBar.createNewConversation(); + await talkToSelector.seeFullList(); + }, + ); - await test.step('Type first search term and verify search result is correct', async () => { - await modelsDialog.searchInput.fillInInput(searchTerm); - const resultsCount = await modelsDialog.groupEntity.getElementsCount(); - expect - .soft(resultsCount, ExpectedMessages.searchResultCountIsValid) - .toBe( - matchedModels.length + - matchedApplications.length + - matchedAssistants.length, - ); - }); + await dialTest.step( + 'Type first search term and verify search result is correct', + async () => { + await modelsDialog.searchInput.fillInInput(searchTerm); + const resultsCount = await modelsDialog.groupEntity.getElementsCount(); + expect + .soft(resultsCount, ExpectedMessages.searchResultCountIsValid) + .toBe( + matchedModels.length + + matchedApplications.length + + matchedAssistants.length, + ); + }, + ); - await test.step('Click on entity tabs one by one and verify search results are correct', async () => { - await modelsDialog.modelsTab.click(); - const assistantsPlusAppResultsCount = - await modelsDialog.groupEntity.getElementsCount(); - expect - .soft( - assistantsPlusAppResultsCount, - ExpectedMessages.searchResultCountIsValid, - ) - .toBe(matchedApplications.length + matchedAssistants.length); - - await modelsDialog.assistantsTab.click(); - const appResultsCount = await modelsDialog.groupEntity.getElementsCount(); - expect - .soft(appResultsCount, ExpectedMessages.searchResultCountIsValid) - .toBe(matchedApplications.length); - - await modelsDialog.applicationsTab.click(); - const noResult = - await modelsDialog.noResultFoundIcon.getElementInnerContent(); - expect - .soft(noResult, ExpectedMessages.noResultsFound) - .toBe(ExpectedConstants.noResults); - }); + await dialTest.step( + 'Click on entity tabs one by one and verify search results are correct', + async () => { + await modelsDialog.modelsTab.click(); + const assistantsPlusAppResultsCount = + await modelsDialog.groupEntity.getElementsCount(); + expect + .soft( + assistantsPlusAppResultsCount, + ExpectedMessages.searchResultCountIsValid, + ) + .toBe(matchedApplications.length + matchedAssistants.length); - await test.step('Clear search input and verify all entities are displayed', async () => { - await modelsDialog.searchInput.fillInInput(''); - await modelsDialog.modelsTab.click(); - await modelsDialog.assistantsTab.click(); - await modelsDialog.applicationsTab.click(); - const resultsCount = await modelsDialog.groupEntity.getElementsCount(); - expect - .soft(resultsCount, ExpectedMessages.searchResultCountIsValid) - .toBe(ModelsUtil.getOpenAIEntities().length); - }); - }); -}); + await modelsDialog.assistantsTab.click(); + const appResultsCount = + await modelsDialog.groupEntity.getElementsCount(); + expect + .soft(appResultsCount, ExpectedMessages.searchResultCountIsValid) + .toBe(matchedApplications.length); + + await modelsDialog.applicationsTab.click(); + const noResult = + await modelsDialog.noResultFoundIcon.getElementInnerContent(); + expect + .soft(noResult, ExpectedMessages.noResultsFound) + .toBe(ExpectedConstants.noResults); + }, + ); + + await dialTest.step( + 'Clear search input and verify all entities are displayed', + async () => { + await modelsDialog.searchInput.fillInInput(''); + await modelsDialog.modelsTab.click(); + await modelsDialog.assistantsTab.click(); + await modelsDialog.applicationsTab.click(); + const resultsCount = await modelsDialog.groupEntity.getElementsCount(); + expect + .soft(resultsCount, ExpectedMessages.searchResultCountIsValid) + .toBe(ModelsUtil.getOpenAIEntities().length); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/desktopAuth.ts b/apps/chat-e2e/src/tests/desktopAuth.ts index da9ec3c295..5b32ee5470 100644 --- a/apps/chat-e2e/src/tests/desktopAuth.ts +++ b/apps/chat-e2e/src/tests/desktopAuth.ts @@ -1,6 +1,7 @@ import config from '../../config/playwright.config'; -import test, { stateFilePath } from '../core/fixtures'; +import { stateFilePath } from '../core/dialFixtures'; +import test from '@/src/core/baseFixtures'; import { API } from '@/src/testData'; const usernames = process.env diff --git a/apps/chat-e2e/src/tests/entityIcon.test.ts b/apps/chat-e2e/src/tests/entityIcon.test.ts index db4f713ec3..d776b490e3 100644 --- a/apps/chat-e2e/src/tests/entityIcon.test.ts +++ b/apps/chat-e2e/src/tests/entityIcon.test.ts @@ -1,4 +1,4 @@ -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, @@ -8,61 +8,62 @@ import { import { GeneratorUtil, ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -test.describe('Chat entity icons tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - '"Talk to" icons on See full list screen.\n' + - 'Addon icons on See full addons screen.\n' + - 'Chat icon is changed in the tree according to selected "Talk to" item on default new chat screen', - async ({ - dialHomePage, - talkToSelector, - modelsDialog, - addons, - addonsDialog, - conversations, - iconApiHelper, - setTestIds, - }) => { - test.slow(); - setTestIds('EPMRTC-1036', 'EPMRTC-1038', 'EPMRTC-378'); - await test.step('Open initial screen and click "See full list" to view all available entities', async () => { +dialTest( + '"Talk to" icons on See full list screen.\n' + + 'Addon icons on See full addons screen.\n' + + 'Chat icon is changed in the tree according to selected "Talk to" item on default new chat screen', + async ({ + dialHomePage, + talkToSelector, + modelsDialog, + addons, + addonsDialog, + conversations, + iconApiHelper, + setTestIds, + }) => { + dialTest.slow(); + setTestIds('EPMRTC-1036', 'EPMRTC-1038', 'EPMRTC-378'); + await dialTest.step( + 'Open initial screen and click "See full list" to view all available entities', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, }); await talkToSelector.seeFullList(); - }); + }, + ); - await test.step('Verify all entities have valid icons', async () => { - const allExpectedEntities = ModelsUtil.getOpenAIEntities(); - const actualEntitiesIcons = await modelsDialog.getEntitiesIcons(); - expect - .soft( - actualEntitiesIcons.length, - ExpectedMessages.entitiesIconsCountIsValid, - ) - .toBe(allExpectedEntities.length); + await dialTest.step('Verify all entities have valid icons', async () => { + const allExpectedEntities = ModelsUtil.getOpenAIEntities(); + const actualEntitiesIcons = await modelsDialog.getEntitiesIcons(); + expect + .soft( + actualEntitiesIcons.length, + ExpectedMessages.entitiesIconsCountIsValid, + ) + .toBe(allExpectedEntities.length); - const randomEntity = - GeneratorUtil.randomArrayElement(allExpectedEntities); - const actualEntity = actualEntitiesIcons.find( - (e) => e.entityName === randomEntity.name, - )!; - const expectedEntityIcon = - await iconApiHelper.getEntityIcon(randomEntity); - expect - .soft( - actualEntity.icon, - `${ExpectedMessages.entityIconIsValid} for ${randomEntity.name}`, - ) - .toBe(expectedEntityIcon); - await modelsDialog.closeDialog(); - }); + const randomEntity = + GeneratorUtil.randomArrayElement(allExpectedEntities); + const actualEntity = actualEntitiesIcons.find( + (e) => e.entityName === randomEntity.name, + )!; + const expectedEntityIcon = + await iconApiHelper.getEntityIcon(randomEntity); + expect + .soft( + actualEntity.icon, + `${ExpectedMessages.entityIconIsValid} for ${randomEntity.name}`, + ) + .toBe(expectedEntityIcon); + await modelsDialog.closeDialog(); + }); - await test.step('Click "See all addons" and verify all addons have valid icons', async () => { + await dialTest.step( + 'Click "See all addons" and verify all addons have valid icons', + async () => { const expectedAddons = ModelsUtil.getAddons(); await addons.seeAllAddons(); const actualAddonsIcons = await addonsDialog.getAddonsIcons(); @@ -86,9 +87,12 @@ test.describe('Chat entity icons tests', () => { ) .toBe(expectedAddonIcon); await addonsDialog.closeDialog(); - }); + }, + ); - await test.step('Verify default model icon is displayed on chat bar panel', async () => { + await dialTest.step( + 'Verify default model icon is displayed on chat bar panel', + async () => { const defaultConversationIcon = await conversations.getConversationIcon( ExpectedConstants.newConversationTitle, ); @@ -98,9 +102,12 @@ test.describe('Chat entity icons tests', () => { expect .soft(defaultConversationIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedDefaultIcon); - }); + }, + ); - await test.step('Select any entity and verify corresponding icon is displayed on chat bar panel', async () => { + await dialTest.step( + 'Select any entity and verify corresponding icon is displayed on chat bar panel', + async () => { const randomEntity = GeneratorUtil.randomArrayElement( ModelsUtil.getModels(), ); @@ -114,44 +121,52 @@ test.describe('Chat entity icons tests', () => { expect .soft(conversationIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedIcon); - }); - }, - ); + }, + ); + }, +); - test('"Talk to" item icon is jumping while generating an answer', async ({ - dialHomePage, - talkToSelector, - chat, - setTestIds, - chatMessages, - }) => { +dialTest( + '"Talk to" item icon is jumping while generating an answer', + async ({ dialHomePage, talkToSelector, chat, setTestIds, chatMessages }) => { setTestIds('EPMRTC-386'); const model = ModelsUtil.getModel(ModelIds.GPT_4_32K)!; - await test.step('Create a new conversation based on default model and send a request', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await talkToSelector.selectModel(model.name); - await chat.sendRequestWithButton('write down 15 adjectives', false); - }); + await dialTest.step( + 'Create a new conversation based on default model and send a request', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await talkToSelector.selectModel(model.name); + await chat.sendRequestWithButton('write down 15 adjectives', false); + }, + ); - await test.step('Verify app icon is jumping in chat while responding', async () => { - const jumpingIcon = await chatMessages.getMessageJumpingIcon(); - await jumpingIcon.waitFor(); - }); + await dialTest.step( + 'Verify app icon is jumping in chat while responding', + async () => { + const jumpingIcon = await chatMessages.getMessageJumpingIcon(); + await jumpingIcon.waitFor(); + }, + ); - await test.step('Send one more request and verify model icon size remained the same', async () => { - const initialMessageIconSize = await chatMessages.getMessageIconSize(); - await chat.regenerate.waitForState(); + await dialTest.step( + 'Send one more request and verify model icon size remained the same', + async () => { + const initialMessageIconSize = await chatMessages.getMessageIconSize(); + await chat.regenerate.waitForState(); - await chat.sendRequestWithButton('1+2=', false); - const lastMessageIconSize = await chatMessages.getMessageIconSize(); - expect - .soft( - JSON.stringify(lastMessageIconSize), - ExpectedMessages.iconSizeIsValid, - ) - .toBe(JSON.stringify(initialMessageIconSize)); - }); - }); -}); + await chat.sendRequestWithButton('1+2=', false); + const lastMessageIconSize = await chatMessages.getMessageIconSize(); + expect + .soft( + JSON.stringify(lastMessageIconSize), + ExpectedMessages.iconSizeIsValid, + ) + .toBe(JSON.stringify(initialMessageIconSize)); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/folderPrompts.test.ts b/apps/chat-e2e/src/tests/folderPrompts.test.ts index 8b22704f16..b0265050cf 100644 --- a/apps/chat-e2e/src/tests/folderPrompts.test.ts +++ b/apps/chat-e2e/src/tests/folderPrompts.test.ts @@ -1,6 +1,7 @@ import { FolderInterface } from '@/chat/types/folder'; import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { ExpectedConstants, ExpectedMessages, @@ -10,16 +11,9 @@ import { import { GeneratorUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -test.describe('Prompt bar folder tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Create new prompt folder', async ({ - dialHomePage, - promptBar, - folderPrompts, - setTestIds, - }) => { +dialTest( + 'Create new prompt folder', + async ({ dialHomePage, promptBar, folderPrompts, setTestIds }) => { setTestIds('EPMRTC-944'); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); @@ -27,24 +21,29 @@ test.describe('Prompt bar folder tests', () => { expect .soft( await folderPrompts - .getFolderByName(ExpectedConstants.newFolderTitle) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .isVisible(), ExpectedMessages.newFolderCreated, ) .toBeTruthy(); - }); + }, +); - test('Prompt folder can expand and collapse', async ({ +dialTest( + 'Prompt folder can expand and collapse', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, setTestIds, }) => { setTestIds('EPMRTC-946'); const promptInFolder = promptData.prepareDefaultPromptInFolder(); - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(promptInFolder.prompts[0]); + await dataInjector.createPrompts( + promptInFolder.prompts, + promptInFolder.folders, + ); const folderName = promptInFolder.folders.name; await dialHomePage.openHomePage(); @@ -62,98 +61,122 @@ test.describe('Prompt bar folder tests', () => { promptInFolder.prompts[0].name, ); expect.soft(isPromptVisible, ExpectedMessages.folderCollapsed).toBeFalsy(); - }); - - test( - 'Rename prompt folder on Enter.\n' + - 'Rename prompt folders on nested levels', - async ({ - dialHomePage, - promptData, - folderPrompts, - localStorageManager, - folderDropdownMenu, - setTestIds, - }) => { - setTestIds('EPMRTC-948', 'EPMRTC-1382'); - const newName = 'updated folder name'; - const nestedFolders = promptData.prepareNestedFolder(3); - const randomFolder = GeneratorUtil.randomArrayElement(nestedFolders); - const randomFolderIndex = nestedFolders.indexOf(randomFolder); - await localStorageManager.setFolders(...nestedFolders); - - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts.openFolderDropdownMenu(randomFolder.name); - await folderDropdownMenu.selectMenuOption(MenuOptions.rename); - await folderPrompts.editFolderNameWithEnter(randomFolder.name, newName); - expect - .soft( - await folderPrompts.getFolderByName(newName).isVisible(), - ExpectedMessages.folderNameUpdated, - ) - .toBeTruthy(); + }, +); - for (let i = 0; i < nestedFolders.length; i++) { - if (i !== randomFolderIndex) { - expect - .soft( - await folderPrompts - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderNameNotUpdated, - ) - .toBeTruthy(); - } +dialTest( + 'Rename prompt folder on Enter.\n' + 'Rename prompt folders on nested levels', + async ({ + dialHomePage, + promptBar, + folderPrompts, + folderDropdownMenu, + setTestIds, + }) => { + setTestIds('EPMRTC-948', 'EPMRTC-1382'); + const newName = 'updated folder name'; + const randomFolderIndex = GeneratorUtil.randomNumberInRange(2) + 1; + + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + + for (let i = 1; i <= 3; i++) { + await promptBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await promptBar.dragAndDropEntityToFolder( + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); + } + await folderPrompts.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + ); + + await folderPrompts.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(randomFolderIndex), + ); + await folderDropdownMenu.selectMenuOption(MenuOptions.rename); + await folderPrompts.editFolderNameWithEnter( + ExpectedConstants.newFolderWithIndexTitle(randomFolderIndex), + newName, + ); + expect + .soft( + await folderPrompts.getFolderByName(newName).isVisible(), + ExpectedMessages.folderNameUpdated, + ) + .toBeTruthy(); + + for (let i = 1; i <= 3; i++) { + if (i !== randomFolderIndex) { + expect + .soft( + await folderPrompts + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) + .isVisible(), + ExpectedMessages.folderNameNotUpdated, + ) + .toBeTruthy(); } - }, - ); + } + }, +); - test('Cancel folder renaming on "x"', async ({ +dialTest( + 'Cancel folder renaming on "x"', + async ({ dialHomePage, - promptData, + promptBar, folderPrompts, - localStorageManager, folderDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-949'); const newName = 'updated folder name'; - const folder = promptData.prepareFolder(); - await localStorageManager.setFolders(folder); - await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await folderPrompts.openFolderDropdownMenu(folder.name); + await promptBar.createNewFolder(); + await folderPrompts.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); await folderDropdownMenu.selectMenuOption(MenuOptions.rename); const folderInput = await folderPrompts.editFolderName( - folder.name, + ExpectedConstants.newFolderWithIndexTitle(1), newName, ); await folderInput.clickCancelButton(); expect .soft( - await folderPrompts.getFolderByName(folder.name).isVisible(), + await folderPrompts + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .isVisible(), ExpectedMessages.folderNameNotUpdated, ) .toBeTruthy(); - }); + }, +); - test('Rename prompt folder when prompts are inside using check button', async ({ +dialTest( + 'Rename prompt folder when prompts are inside using check button', + async ({ dialHomePage, promptData, + dataInjector, folderPrompts, - localStorageManager, folderDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-950'); const promptInFolder = promptData.prepareDefaultPromptInFolder(); - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(promptInFolder.prompts[0]); + await dataInjector.createPrompts( + promptInFolder.prompts, + promptInFolder.folders, + ); const newName = 'updated folder name'; await dialHomePage.openHomePage(); @@ -170,20 +193,23 @@ test.describe('Prompt bar folder tests', () => { ExpectedMessages.folderNameUpdated, ) .toBeTruthy(); - }); + }, +); - test('Prompt is moved to folder created from Move to', async ({ +dialTest( + 'Prompt is moved to folder created from Move to', + async ({ dialHomePage, prompts, promptDropdownMenu, promptData, - localStorageManager, + dataInjector, folderPrompts, setTestIds, }) => { setTestIds('EPMRTC-962'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -199,45 +225,54 @@ test.describe('Prompt bar folder tests', () => { expect .soft(isFolderPromptVisible, ExpectedMessages.promptMovedToFolder) .toBeTruthy(); - }); + }, +); - test('Prompt is moved to folder from Move to list', async ({ +dialTest( + 'Prompt is moved to folder from Move to list', + async ({ dialHomePage, prompts, promptDropdownMenu, promptData, - localStorageManager, + dataInjector, folderPrompts, + promptBar, setTestIds, }) => { setTestIds('EPMRTC-963'); - const folderToMoveIn = promptData.prepareFolder(); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); - await localStorageManager.setFolders(folderToMoveIn); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await folderPrompts.expandCollapseFolder(folderToMoveIn.name); + await promptBar.createNewFolder(); + await folderPrompts.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(1), + ); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.moveTo); - await promptDropdownMenu.selectMenuOption(folderToMoveIn.name); - + await prompts.selectMoveToMenuOption( + ExpectedConstants.newFolderWithIndexTitle(1), + ); const isFolderPromptVisible = await folderPrompts.isFolderEntityVisible( - folderToMoveIn.name, + ExpectedConstants.newFolderWithIndexTitle(1), prompt.name, ); expect .soft(isFolderPromptVisible, ExpectedMessages.promptMovedToFolder) .toBeTruthy(); - }); + }, +); - test('Delete folder when there are some prompts inside', async ({ +dialTest( + 'Delete folder when there are some prompts inside', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, promptDropdownMenu, prompts, confirmationDialog, @@ -245,8 +280,10 @@ test.describe('Prompt bar folder tests', () => { }) => { setTestIds('EPMRTC-966'); const promptInFolder = promptData.prepareDefaultPromptInFolder(); - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(promptInFolder.prompts[0]); + await dataInjector.createPrompts( + promptInFolder.prompts, + promptInFolder.folders, + ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -266,73 +303,93 @@ test.describe('Prompt bar folder tests', () => { .getPromptByName(promptInFolder.prompts[0].name) .isVisible(); expect.soft(isPromptVisible, ExpectedMessages.promptIsVisible).toBeFalsy(); - }); - - test( - 'Delete folder. Cancel.\n' + - 'Delete root prompt folder with nested folders', - async ({ - dialHomePage, - promptData, - folderPrompts, - localStorageManager, - promptDropdownMenu, - confirmationDialog, - setTestIds, - }) => { - setTestIds('EPMRTC-967', 'EPMRTC-1383'); - const nestedFolders = promptData.prepareNestedFolder(3); - await localStorageManager.setFolders(...nestedFolders); - - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts.openFolderDropdownMenu(nestedFolders[0].name); - await promptDropdownMenu.selectMenuOption(MenuOptions.delete); - expect - .soft( - await confirmationDialog.getConfirmationMessage(), - ExpectedMessages.confirmationMessageIsValid, - ) - .toBe(ExpectedConstants.deleteFolderMessage); - await confirmationDialog.cancelDialog(); + }, +); + +dialTest( + 'Delete folder. Cancel.\n' + 'Delete root prompt folder with nested folders', + async ({ + dialHomePage, + folderPrompts, + promptBar, + promptDropdownMenu, + confirmationDialog, + setTestIds, + }) => { + setTestIds('EPMRTC-967', 'EPMRTC-1383'); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + for (let i = 1; i <= 3; i++) { + await promptBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await promptBar.dragAndDropEntityToFolder( + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); + } + await folderPrompts.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + ); + + await folderPrompts.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + await promptDropdownMenu.selectMenuOption(MenuOptions.delete); + expect + .soft( + await confirmationDialog.getConfirmationMessage(), + ExpectedMessages.confirmationMessageIsValid, + ) + .toBe(ExpectedConstants.deleteFolderMessage); + await confirmationDialog.cancelDialog(); + expect + .soft( + await folderPrompts + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .isVisible(), + ExpectedMessages.folderNotDeleted, + ) + .toBeTruthy(); + + await folderPrompts.openFolderDropdownMenu( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + await promptDropdownMenu.selectMenuOption(MenuOptions.delete); + await confirmationDialog.confirm(); + for (let i = 1; i <= 3; i++) { expect .soft( await folderPrompts - .getFolderByName(nestedFolders[0].name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) .isVisible(), - ExpectedMessages.folderNotDeleted, + ExpectedMessages.folderDeleted, ) - .toBeTruthy(); - - await folderPrompts.openFolderDropdownMenu(nestedFolders[0].name); - await promptDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); - for (const nestedFolder of nestedFolders) { - expect - .soft( - await folderPrompts.getFolderByName(nestedFolder.name).isVisible(), - ExpectedMessages.folderDeleted, - ) - .toBeFalsy(); - } - }, - ); - - test('Delete prompt in the folder', async ({ + .toBeFalsy(); + } + }, +); + +dialTest( + 'Delete prompt in the folder', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, promptDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-968'); const promptInFolder = promptData.prepareDefaultPromptInFolder(); - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(promptInFolder.prompts[0]); + await dataInjector.createPrompts( + promptInFolder.prompts, + promptInFolder.folders, + ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -356,12 +413,15 @@ test.describe('Prompt bar folder tests', () => { ExpectedMessages.promptDeleted, ) .toBeFalsy(); - }); + }, +); - test('Delete nested prompt folder with prompt', async ({ +dialTest( + 'Delete nested prompt folder with prompt', + async ({ dialHomePage, folderPrompts, - localStorageManager, + dataInjector, conversationDropdownMenu, prompts, confirmationDialog, @@ -374,71 +434,79 @@ test.describe('Prompt bar folder tests', () => { let nestedFolders: FolderInterface[]; const nestedPrompts: Prompt[] = []; - await test.step('Prepare nested folders with prompts inside each one', async () => { - nestedFolders = promptData.prepareNestedFolder(levelsCount); - for (let i = 0; i <= levelsCount; i++) { - const nestedPrompt = promptData.prepareDefaultPrompt(); - nestedPrompts.push(nestedPrompt); - nestedPrompt.folderId = nestedFolders[i].id; - promptData.resetData(); - } - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setPrompts(...nestedPrompts); - }); - - await test.step('Delete 2nd level folder and verify all nested content is deleted as well', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts.openFolderDropdownMenu( - nestedFolders[levelToDelete].name, - ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await confirmationDialog.confirm(); + await dialTest.step( + 'Prepare nested folders with prompts inside each one', + async () => { + nestedFolders = promptData.prepareNestedFolder(levelsCount); + for (let i = 0; i <= levelsCount; i++) { + const nestedPrompt = promptData.prepareDefaultPrompt(); + nestedPrompts.push(nestedPrompt); + nestedPrompt.folderId = nestedFolders[i].id; + promptData.resetData(); + } + await dataInjector.createPrompts(nestedPrompts, ...nestedFolders); + }, + ); - for (let i = levelToDelete; i <= levelsCount; i++) { - expect - .soft( - await folderPrompts - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderDeleted, - ) - .toBeFalsy(); - expect - .soft( - await prompts.getPromptByName(nestedPrompts[i].name).isVisible(), - ExpectedMessages.promptDeleted, - ) - .toBeFalsy(); - } + await dialTest.step( + 'Delete 2nd level folder and verify all nested content is deleted as well', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + for (const nestedFolder of nestedFolders) { + await folderPrompts.expandCollapseFolder(nestedFolder.name); + } + await folderPrompts.openFolderDropdownMenu( + nestedFolders[levelToDelete].name, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); - for (let i = 0; i <= levelsCount - levelToDelete; i++) { - expect - .soft( - await folderPrompts - .getFolderByName(nestedFolders[i].name) - .isVisible(), - ExpectedMessages.folderNotDeleted, - ) - .toBeTruthy(); - expect - .soft( - await folderPrompts - .getFolderEntity(nestedFolders[i].name, nestedPrompts[i].name) - .isVisible(), - ExpectedMessages.promptNotDeleted, - ) - .toBeTruthy(); - } - }); - }); + for (let i = levelToDelete; i <= levelsCount; i++) { + expect + .soft( + await folderPrompts + .getFolderByName(nestedFolders[i].name) + .isVisible(), + ExpectedMessages.folderDeleted, + ) + .toBeFalsy(); + expect + .soft( + await prompts.getPromptByName(nestedPrompts[i].name).isVisible(), + ExpectedMessages.promptDeleted, + ) + .toBeFalsy(); + } - test('Search prompt located in folders', async ({ + for (let i = 0; i <= levelsCount - levelToDelete; i++) { + expect + .soft( + await folderPrompts + .getFolderByName(nestedFolders[i].name) + .isVisible(), + ExpectedMessages.folderNotDeleted, + ) + .toBeTruthy(); + expect + .soft( + await folderPrompts + .getFolderEntity(nestedFolders[i].name, nestedPrompts[i].name) + .isVisible(), + ExpectedMessages.promptNotDeleted, + ) + .toBeTruthy(); + } + }, + ); + }, +); + +dialTest( + 'Search prompt located in folders', + async ({ dialHomePage, - localStorageManager, + dataInjector, promptData, folderPrompts, promptBarSearch, @@ -451,59 +519,77 @@ test.describe('Prompt bar folder tests', () => { const promptContent = 'Prompt search test'; const searchTerm = 'test'; - await test.step('Prepare prompts in folders with different content', async () => { - firstFolderPrompt = promptData.prepareDefaultPromptInFolder(); - firstFolderPrompt.prompts[0].name = promptContent; - promptData.resetData(); + await dialTest.step( + 'Prepare prompts in folders with different content', + async () => { + firstFolderPrompt = promptData.prepareDefaultPromptInFolder(); + firstFolderPrompt.prompts[0].name = promptContent; + promptData.resetData(); - secondFolderPrompts = promptData.preparePromptsInFolder(3); - secondFolderPrompts.prompts[0].description = promptContent; - secondFolderPrompts.prompts[1].content = promptContent; + secondFolderPrompts = promptData.preparePromptsInFolder(3); + secondFolderPrompts.prompts[0].description = promptContent; + secondFolderPrompts.prompts[1].content = promptContent; - await localStorageManager.setFolders( - firstFolderPrompt.folders, - secondFolderPrompts.folders, - ); - await localStorageManager.setPrompts( - ...firstFolderPrompt.prompts, - ...secondFolderPrompts.prompts, - ); - }); - - await test.step('Type search term in the field and verify all prompts displayed', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await promptBarSearch.setSearchValue(searchTerm); - const firstFolderResultCount = await folderPrompts.getFolderEntitiesCount( - firstFolderPrompt.folders.name, - ); - const secondFolderResultCount = - await folderPrompts.getFolderEntitiesCount( - secondFolderPrompts.folders.name, + await dataInjector.createPrompts( + [...firstFolderPrompt.prompts, ...secondFolderPrompts.prompts], + firstFolderPrompt.folders, + secondFolderPrompts.folders, ); - expect - .soft( - firstFolderResultCount + secondFolderResultCount, - ExpectedMessages.searchResultCountIsValid, - ) - .toBe(3); - }); + }, + ); - await test.step('Clear search field and verify all prompts displayed', async () => { - await promptBarSearch.setSearchValue(''); - const firstFolderResultCount = await folderPrompts.getFolderEntitiesCount( - secondFolderPrompts.folders.name, - ); - const secondFolderResultCount = - await folderPrompts.getFolderEntitiesCount( - firstFolderPrompt.folders.name, + await dialTest.step( + 'Type search term in the field and verify all prompts displayed', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await promptBarSearch.setSearchValue(searchTerm); + const firstFolderResultCount = + await folderPrompts.getFolderEntitiesCount( + firstFolderPrompt.folders.name, + ); + const secondFolderResultCount = + await folderPrompts.getFolderEntitiesCount( + secondFolderPrompts.folders.name, + ); + expect + .soft( + firstFolderResultCount + secondFolderResultCount, + ExpectedMessages.searchResultCountIsValid, + ) + .toBe(isApiStorageType ? 1 : 3); + }, + ); + + await dialTest.step( + 'Clear search field and verify all prompts displayed', + async () => { + await promptBarSearch.setSearchValue(''); + const isFolderExpanded = await folderPrompts.isFolderCaretExpanded( + secondFolderPrompts.folders.name, ); - expect - .soft( - firstFolderResultCount + secondFolderResultCount, - ExpectedMessages.searchResultCountIsValid, - ) - .toBe(4); - }); - }); -}); + if (!isFolderExpanded) { + await folderPrompts.expandCollapseFolder( + secondFolderPrompts.folders.name, + ); + } + const firstFolderResultCount = + await folderPrompts.getFolderEntitiesCount( + secondFolderPrompts.folders.name, + ); + const secondFolderResultCount = + await folderPrompts.getFolderEntitiesCount( + firstFolderPrompt.folders.name, + ); + expect + .soft( + firstFolderResultCount + secondFolderResultCount, + ExpectedMessages.searchResultCountIsValid, + ) + .toBe(4); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/listing.test.ts b/apps/chat-e2e/src/tests/listing.test.ts index aec7c9e4aa..e82a79c7eb 100644 --- a/apps/chat-e2e/src/tests/listing.test.ts +++ b/apps/chat-e2e/src/tests/listing.test.ts @@ -1,4 +1,4 @@ -import test from '@/src/core/fixtures'; +import test from '@/src/core/baseFixtures'; import { AddonIds, ExpectedMessages, ModelIds } from '@/src/testData'; import { ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; diff --git a/apps/chat-e2e/src/tests/modelSettings.test.ts b/apps/chat-e2e/src/tests/modelSettings.test.ts index a364fc6e1a..7dc60c300e 100644 --- a/apps/chat-e2e/src/tests/modelSettings.test.ts +++ b/apps/chat-e2e/src/tests/modelSettings.test.ts @@ -1,5 +1,5 @@ import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages } from '@/src/testData'; import { Colors } from '@/src/ui/domData'; import { GeneratorUtil, ModelsUtil } from '@/src/utils'; @@ -11,16 +11,14 @@ const temp = 0.8; let models: OpenAIEntityModel[]; let defaultModel: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { models = ModelsUtil.getModels(); defaultModel = ModelsUtil.getDefaultModel()!; }); -test.describe('Chat model settings tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Selected settings are saved if to switch from Model1 to Model2', async ({ +dialTest( + 'Selected settings are saved if to switch from Model1 to Model2', + async ({ dialHomePage, recentEntities, entitySettings, @@ -65,13 +63,12 @@ test.describe('Chat model settings tests', () => { expect .soft(selectedAddons, ExpectedMessages.selectedAddonsValid) .toEqual([]); - }); + }, +); - test('System prompt contains combinations with :', async ({ - dialHomePage, - entitySettings, - setTestIds, - }) => { +dialTest( + 'System prompt contains combinations with :', + async ({ dialHomePage, entitySettings, setTestIds }) => { setTestIds('EPMRTC-1084'); const prompts = [ 'test:', @@ -90,5 +87,5 @@ test.describe('Chat model settings tests', () => { .toBe(prompt); await entitySettings.clearSystemPrompt(); } - }); -}); + }, +); diff --git a/apps/chat-e2e/src/tests/playBack.test.ts b/apps/chat-e2e/src/tests/playBack.test.ts index 47856003fe..b6fc863a69 100644 --- a/apps/chat-e2e/src/tests/playBack.test.ts +++ b/apps/chat-e2e/src/tests/playBack.test.ts @@ -1,6 +1,6 @@ import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, @@ -15,45 +15,43 @@ import { expect } from '@playwright/test'; let defaultModel: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { defaultModel = ModelsUtil.getDefaultModel()!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -test.describe('Chat playback tests', () => { - test.use({ - storageState: stateFilePath, - }); - // TODO: redo after new changes in playback - test.skip( - 'Playback: first screen.\n' + - 'Playback: move to the next using next button.\n' + - 'Playback: move to the previous using back button', - async ({ - dialHomePage, - localStorageManager, - conversationData, - conversations, - conversationDropdownMenu, - playback, - playbackControl, - chat, - chatMessages, - chatHeader, - setTestIds, - iconApiHelper, - }) => { - setTestIds('EPMRTC-1417', 'EPMRTC-1418', 'EPMRTC-1422'); - let conversation: Conversation; - const conversationModels = [defaultModel, gpt4Model]; - let playbackConversationName: string; - - const expectedDefaultModelIcon = - await iconApiHelper.getEntityIcon(defaultModel); - const expectedSecondModelIcon = - await iconApiHelper.getEntityIcon(gpt4Model); - - await test.step('Prepare conversation to playback based on different models', async () => { +// TODO: redo after new changes in playback +dialTest.skip( + 'Playback: first screen.\n' + + 'Playback: move to the next using next button.\n' + + 'Playback: move to the previous using back button', + async ({ + dialHomePage, + localStorageManager, + conversationData, + conversations, + conversationDropdownMenu, + playback, + playbackControl, + chat, + chatMessages, + chatHeader, + setTestIds, + iconApiHelper, + }) => { + setTestIds('EPMRTC-1417', 'EPMRTC-1418', 'EPMRTC-1422'); + let conversation: Conversation; + const conversationModels = [defaultModel, gpt4Model]; + let playbackConversationName: string; + + const expectedDefaultModelIcon = + await iconApiHelper.getEntityIcon(defaultModel); + const expectedSecondModelIcon = + await iconApiHelper.getEntityIcon(gpt4Model); + + await dialTest.step( + 'Prepare conversation to playback based on different models', + async () => { conversation = conversationData.prepareConversationWithDifferentModels( conversationModels, @@ -63,9 +61,12 @@ test.describe('Chat playback tests', () => { const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); await localStorageManager.setSettings(theme); - }); + }, + ); - await test.step('Select Playback option from conversation dropdown menu and verify new Playback chat is created and button are available at the bottom of main screen', async () => { + await dialTest.step( + 'Select Playback option from conversation dropdown menu and verify new Playback chat is created and button are available at the bottom of main screen', + async () => { playbackConversationName = `[${MenuOptions.playback}] ${conversation.name}`; await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -109,9 +110,12 @@ test.describe('Chat playback tests', () => { expect .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) .toBe(ExpectedConstants.emptyPlaybackMessage); - }); + }, + ); - await test.step('Click on Next button and verify text content updated', async () => { + await dialTest.step( + 'Click on Next button and verify text content updated', + async () => { await chat.playNextChatMessage(); const isPlaybackNextBtnEnabled = @@ -136,9 +140,12 @@ test.describe('Chat playback tests', () => { expect .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) .toBe(conversation.messages[0].content); - }); + }, + ); - await test.step('Click on Next button and verify chat header, history and bottom controls are updated', async () => { + await dialTest.step( + 'Click on Next button and verify chat header, history and bottom controls are updated', + async () => { await chat.playNextChatMessage(); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -196,9 +203,12 @@ test.describe('Chat playback tests', () => { ExpectedMessages.chatBarConversationIconIsPlayback, ) .toBeTruthy(); - }); + }, + ); - await test.step('Click on Next button again twice and verify chat header icon updated, history contains all messages and Next button disabled on bottom controls', async () => { + await dialTest.step( + 'Click on Next button again twice and verify chat header icon updated, history contains all messages and Next button disabled on bottom controls', + async () => { await chat.playNextChatMessage(); const playBackMessage = await playbackControl.playbackMessage.getElementContent(); @@ -264,9 +274,12 @@ test.describe('Chat playback tests', () => { ExpectedMessages.chatBarConversationIconIsPlayback, ) .toBeTruthy(); - }); + }, + ); - await test.step('Click on Back button and verify chat header icon updated, history contains first request/response, Next button is enabled on bottom controls', async () => { + await dialTest.step( + 'Click on Back button and verify chat header icon updated, history contains first request/response, Next button is enabled on bottom controls', + async () => { await chat.playPreviousChatMessage(); const isPlaybackNextBtnEnabled = await playbackControl.playbackNextButton.isElementEnabled(); @@ -291,8 +304,11 @@ test.describe('Chat playback tests', () => { expect .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) .toBe(ExpectedConstants.emptyPlaybackMessage); - }); - await test.step('Click on Back button and verify chat header icon updated, history contains first request/response, Next button is enabled on bottom controls', async () => { + }, + ); + await dialTest.step( + 'Click on Back button and verify chat header icon updated, history contains first request/response, Next button is enabled on bottom controls', + async () => { await chat.playPreviousChatMessage(); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -350,9 +366,12 @@ test.describe('Chat playback tests', () => { ExpectedMessages.chatBarConversationIconIsPlayback, ) .toBeTruthy(); - }); + }, + ); - await test.step('Click on Back button again twice and verify chat header icon updated, history is empty and Back button is disabled on bottom controls', async () => { + await dialTest.step( + 'Click on Back button again twice and verify chat header icon updated, history is empty and Back button is disabled on bottom controls', + async () => { await chat.playPreviousChatMessage(); let playBackMessage = await playbackControl.playbackMessage.getElementContent(); @@ -403,42 +422,45 @@ test.describe('Chat playback tests', () => { ExpectedMessages.chatBarConversationIconIsPlayback, ) .toBeTruthy(); - }); - }, - ); - // TODO: redo after new changes in playback - test.skip( - 'Playback: move to the next using hot keys.\n' + - 'Playback: move to the previous using hot keys', - async ({ - dialHomePage, - localStorageManager, - conversationData, - conversations, - playbackControl, - chat, - chatMessages, - page, - chatHeader, - setTestIds, - }) => { - setTestIds('EPMRTC-1420', 'EPMRTC-1421'); - let conversation: Conversation; - let playbackConversation: Conversation; - const playNextKeys = [ - keys.space, - keys.enter, - keys.arrowDown, - keys.arrowRight, - ]; - const playPreviousKeys = [ - keys.arrowUp, - keys.arrowLeft, - keys.arrowUp, - keys.arrowLeft, - ]; - - await test.step('Prepare playback conversation based on 4 requests', async () => { + }, + ); + }, +); +// TODO: redo after new changes in playback +dialTest.skip( + 'Playback: move to the next using hot keys.\n' + + 'Playback: move to the previous using hot keys', + async ({ + dialHomePage, + localStorageManager, + conversationData, + conversations, + playbackControl, + chat, + chatMessages, + page, + chatHeader, + setTestIds, + }) => { + setTestIds('EPMRTC-1420', 'EPMRTC-1421'); + let conversation: Conversation; + let playbackConversation: Conversation; + const playNextKeys = [ + keys.space, + keys.enter, + keys.arrowDown, + keys.arrowRight, + ]; + const playPreviousKeys = [ + keys.arrowUp, + keys.arrowLeft, + keys.arrowUp, + keys.arrowLeft, + ]; + + await dialTest.step( + 'Prepare playback conversation based on 4 requests', + async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( defaultModel, ['1st request', '2nd request', '3rd request', '4th request'], @@ -452,9 +474,12 @@ test.describe('Chat playback tests', () => { playbackConversation, ); await localStorageManager.setSelectedConversation(playbackConversation); - }); + }, + ); - await test.step('Play Next message using hot keys and verify chat messages replayed, bottom playback controls are updated', async () => { + await dialTest.step( + 'Play Next message using hot keys and verify chat messages replayed, bottom playback controls are updated', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await conversations @@ -523,9 +548,12 @@ test.describe('Chat playback tests', () => { .toBe(''); } } - }); + }, + ); - await test.step('Press again Play Next message hot key and verify no updates happen', async () => { + await dialTest.step( + 'Press again Play Next message hot key and verify no updates happen', + async () => { await page.keyboard.press(playNextKeys[0]); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -557,9 +585,12 @@ test.describe('Chat playback tests', () => { expect .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) .toBe(''); - }); + }, + ); - await test.step('Play Previous message using hot keys and verify chat messages replayed back, bottom playback controls are updated', async () => { + await dialTest.step( + 'Play Previous message using hot keys and verify chat messages replayed back, bottom playback controls are updated', + async () => { for (let i = playPreviousKeys.length - 1; i >= 0; i--) { await chat.playChatMessageWithKey(playPreviousKeys[i]); const messagesCount = @@ -614,9 +645,12 @@ test.describe('Chat playback tests', () => { .toBeFalsy(); } } - }); + }, + ); - await test.step('Press again Play Previous message hot key and verify no updates happen', async () => { + await dialTest.step( + 'Press again Play Previous message hot key and verify no updates happen', + async () => { await page.keyboard.press(playPreviousKeys[0]); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -648,11 +682,14 @@ test.describe('Chat playback tests', () => { expect .soft(playBackMessage, ExpectedMessages.playbackChatMessageIsValid) .toBe(conversation.messages[0].content); - }); - }, - ); - // TODO: redo after new changes in playback - test.skip('Playback: exit the mode at the end of playback', async ({ + }, + ); + }, +); +// TODO: redo after new changes in playback +dialTest.skip( + 'Playback: exit the mode at the end of playback', + async ({ dialHomePage, localStorageManager, conversationData, @@ -668,70 +705,81 @@ test.describe('Chat playback tests', () => { let conversation: Conversation; let playbackConversation: Conversation; - await test.step('Prepare playback conversation based on 2 requests and played back till the last message', async () => { - conversation = conversationData.prepareModelConversationBasedOnRequests( - defaultModel, - ['1+2=', '2+3='], - ); - conversationData.resetData(); - playbackConversation = - conversationData.prepareDefaultPlaybackConversation( + await dialTest.step( + 'Prepare playback conversation based on 2 requests and played back till the last message', + async () => { + conversation = conversationData.prepareModelConversationBasedOnRequests( + defaultModel, + ['1+2=', '2+3='], + ); + conversationData.resetData(); + playbackConversation = + conversationData.prepareDefaultPlaybackConversation( + conversation, + conversation.messages.length, + ); + + await localStorageManager.setConversationHistory( conversation, - conversation.messages.length, + playbackConversation, ); + await localStorageManager.setSelectedConversation(playbackConversation); + }, + ); - await localStorageManager.setConversationHistory( - conversation, - playbackConversation, - ); - await localStorageManager.setSelectedConversation(playbackConversation); - }); + await dialTest.step( + 'Click Stop Playback and verify chat messages input is available', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations + .getConversationByName(playbackConversation.name) + .waitFor(); + await chatHeader.leavePlaybackMode.click(); + await sendMessage.messageInput.waitForState(); + await chat.sendRequestWithButton('3+4='); - await test.step('Click Stop Playback and verify chat messages input is available', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations - .getConversationByName(playbackConversation.name) - .waitFor(); - await chatHeader.leavePlaybackMode.click(); - await sendMessage.messageInput.waitForState(); - await chat.sendRequestWithButton('3+4='); - - const messagesCount = await chatMessages.chatMessages.getElementsCount(); - expect - .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) - .toBe(conversation.messages.length + 2); - - const expectedModelIcon = await iconApiHelper.getEntityIcon(defaultModel); - const sentMessageIcon = await chatMessages.getIconAttributesForMessage( - conversation.messages.length + 2, - ); - expect - .soft(sentMessageIcon, ExpectedMessages.entityIconIsValid) - .toBe(expectedModelIcon); - }); - }); - // TODO: redo after new changes in playback - test.skip( - 'Playback: auto-scroll.\n' + - 'Playback: huge user-message scrolled in message box.\n' + - 'Playback: response is shown in some time.\n' + - "Playback: it's impossible to click on next button while the answer is in progress", - async ({ - dialHomePage, - localStorageManager, - conversationData, - conversations, - chat, - chatMessages, - playbackControl, - setTestIds, - }) => { - setTestIds('EPMRTC-1427', 'EPMRTC-1470', 'EPMRTC-1473', 'EPMRTC-1428'); - let conversation: Conversation; - let playbackConversation: Conversation; - - await test.step('Prepare playback conversation based on several long requests', async () => { + const messagesCount = + await chatMessages.chatMessages.getElementsCount(); + expect + .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) + .toBe(conversation.messages.length + 2); + + const expectedModelIcon = + await iconApiHelper.getEntityIcon(defaultModel); + const sentMessageIcon = await chatMessages.getIconAttributesForMessage( + conversation.messages.length + 2, + ); + expect + .soft(sentMessageIcon, ExpectedMessages.entityIconIsValid) + .toBe(expectedModelIcon); + }, + ); + }, +); +// TODO: redo after new changes in playback +dialTest.skip( + 'Playback: auto-scroll.\n' + + 'Playback: huge user-message scrolled in message box.\n' + + 'Playback: response is shown in some time.\n' + + "Playback: it's impossible to click on next button while the answer is in progress", + async ({ + dialHomePage, + localStorageManager, + conversationData, + conversations, + chat, + chatMessages, + playbackControl, + setTestIds, + }) => { + setTestIds('EPMRTC-1427', 'EPMRTC-1470', 'EPMRTC-1473', 'EPMRTC-1428'); + let conversation: Conversation; + let playbackConversation: Conversation; + + await dialTest.step( + 'Prepare playback conversation based on several long requests', + async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( defaultModel, [GeneratorUtil.randomString(3000), GeneratorUtil.randomString(2000)], @@ -745,24 +793,27 @@ test.describe('Chat playback tests', () => { playbackConversation, ); await localStorageManager.setSelectedConversation(playbackConversation); - }); + }, + ); - await test.step('Verify playback next message has scroll', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations - .getConversationByName(playbackConversation.name) - .waitFor(); + await dialTest.step('Verify playback next message has scroll', async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations + .getConversationByName(playbackConversation.name) + .waitFor(); - const isPlaybackNextMessageScrollable = - await playbackControl.playbackMessage.isElementScrollableVertically(); - expect( - isPlaybackNextMessageScrollable, - ExpectedMessages.playbackNextMessageIsScrollable, - ).toBeTruthy(); - }); + const isPlaybackNextMessageScrollable = + await playbackControl.playbackMessage.isElementScrollableVertically(); + expect( + isPlaybackNextMessageScrollable, + ExpectedMessages.playbackNextMessageIsScrollable, + ).toBeTruthy(); + }); - await test.step('Click Play Next message button and verify Play Next is not visible and cursor is blinking while response is loading, content auto-scrolled to the end of response', async () => { + await dialTest.step( + 'Click Play Next message button and verify Play Next is not visible and cursor is blinking while response is loading, content auto-scrolled to the end of response', + async () => { for (let i = 0; i < 2; i++) { await chat.playNextChatMessage(false); const isPlaybackNextBtnVisible = @@ -794,15 +845,18 @@ test.describe('Chat playback tests', () => { ).toBeTruthy(); } } - }); + }, + ); - await test.step('Click Play Previous message button and verify cursor is not blinking, response is removing immediately', async () => { + await dialTest.step( + 'Click Play Previous message button and verify cursor is not blinking, response is removing immediately', + async () => { await chat.playPreviousChatMessage(); const isResponseLoading = await chatMessages.isResponseLoading(); expect .soft(isResponseLoading, ExpectedMessages.responseIsNotLoading) .toBeFalsy(); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index d3f79cdda3..320f2d6454 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -1,6 +1,6 @@ import { FolderInterface } from '@/chat/types/folder'; import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages, FolderPrompt, @@ -23,34 +23,32 @@ const newDescr = 'test description'; const newValue = 'what is {{A}}'; const levelsCount = 3; -test.describe('Prompt export/import tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Export and import prompt structure with all prompts.\n' + - 'Continue working with imported file. Add imported prompt to a message', - async ({ - dialHomePage, - setTestIds, - localStorageManager, - prompts, - folderPrompts, - promptBar, - confirmationDialog, - promptData, - sendMessage, - }) => { - setTestIds('EPMRTC-883', 'EPMRTC-895'); - let promptsInsideFolder: FolderPrompt; - let emptyFolder: FolderInterface; - let promptOutsideFolder: Prompt; - let nestedFolders: FolderInterface[]; - let nestedPrompts: Prompt[]; - let exportedData: UploadDownloadData; - const promptContent = 'test'; - - await test.step('Prepare empty folder, folder with 2 prompts, another prompt in the root and nested folders with prompts inside', async () => { +dialTest( + 'Export and import prompt structure with all prompts.\n' + + 'Continue working with imported file. Add imported prompt to a message', + async ({ + dialHomePage, + setTestIds, + localStorageManager, + prompts, + folderPrompts, + promptBar, + confirmationDialog, + promptData, + sendMessage, + }) => { + setTestIds('EPMRTC-883', 'EPMRTC-895'); + let promptsInsideFolder: FolderPrompt; + let emptyFolder: FolderInterface; + let promptOutsideFolder: Prompt; + let nestedFolders: FolderInterface[]; + let nestedPrompts: Prompt[]; + let exportedData: UploadDownloadData; + const promptContent = 'test'; + + await dialTest.step( + 'Prepare empty folder, folder with 2 prompts, another prompt in the root and nested folders with prompts inside', + async () => { emptyFolder = promptData.prepareFolder(); promptData.resetData(); @@ -74,9 +72,12 @@ test.describe('Prompt export/import tests', () => { promptOutsideFolder, ...nestedPrompts, ); - }); + }, + ); - await test.step('Export all prompts using prompt bar Export button', async () => { + await dialTest.step( + 'Export all prompts using prompt bar Export button', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -90,9 +91,12 @@ test.describe('Prompt export/import tests', () => { exportedData = await dialHomePage.downloadData(() => promptBar.exportButton.click(), ); - }); + }, + ); - await test.step('Delete all prompts and folders, re-import again and verify they are displayed', async () => { + await dialTest.step( + 'Delete all prompts and folders, re-import again and verify they are displayed', + async () => { await promptBar.deleteAllEntities(); await confirmationDialog.confirm(); await promptBar.deleteEntitiesButton.waitForState({ state: 'hidden' }); @@ -128,9 +132,12 @@ test.describe('Prompt export/import tests', () => { ) .toBeTruthy(); } - }); + }, + ); - await test.step('Type / in chat and verify imported prompt appears', async () => { + await dialTest.step( + 'Type / in chat and verify imported prompt appears', + async () => { await sendMessage.messageInput.fillInInput('/'); await sendMessage .getPromptList() @@ -141,32 +148,35 @@ test.describe('Prompt export/import tests', () => { expect .soft(selectedPromptContent, ExpectedMessages.promptNameValid) .toBe(promptContent); - }); - }, - ); - - test( - 'Export and import one prompt in a folder.\n' + - `Export and import one prompt in a folder when folder doesn't exist.\n` + - 'Continue working with imported file. Edit imported prompt', - async ({ - dialHomePage, - setTestIds, - localStorageManager, - prompts, - folderPrompts, - promptBar, - promptData, - promptDropdownMenu, - promptModalDialog, - confirmationDialog, - }) => { - setTestIds('EPMRTC-884', 'EPMRTC-885', 'EPMRTC-896'); - let promptInsideFolder: FolderPrompt; - let promptOutsideFolder: Prompt; - let exportedData: UploadDownloadData; - - await test.step('Prepare folder with prompt and another prompt in the root', async () => { + }, + ); + }, +); + +dialTest( + 'Export and import one prompt in a folder.\n' + + `Export and import one prompt in a folder when folder doesn't exist.\n` + + 'Continue working with imported file. Edit imported prompt', + async ({ + dialHomePage, + setTestIds, + localStorageManager, + prompts, + folderPrompts, + promptBar, + promptData, + promptDropdownMenu, + promptModalDialog, + confirmationDialog, + }) => { + setTestIds('EPMRTC-884', 'EPMRTC-885', 'EPMRTC-896'); + let promptInsideFolder: FolderPrompt; + let promptOutsideFolder: Prompt; + let exportedData: UploadDownloadData; + + await dialTest.step( + 'Prepare folder with prompt and another prompt in the root', + async () => { promptInsideFolder = promptData.prepareDefaultPromptInFolder(); promptData.resetData(); @@ -177,9 +187,12 @@ test.describe('Prompt export/import tests', () => { ...promptInsideFolder.prompts, promptOutsideFolder, ); - }); + }, + ); - await test.step('Export prompt inside folder using prompt dropdown menu', async () => { + await dialTest.step( + 'Export prompt inside folder using prompt dropdown menu', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -194,9 +207,12 @@ test.describe('Prompt export/import tests', () => { exportedData = await dialHomePage.downloadData(() => promptDropdownMenu.selectMenuOption(MenuOptions.export), ); - }); + }, + ); - await test.step('Delete exported prompt, re-import again and verify it is displayed inside folder', async () => { + await dialTest.step( + 'Delete exported prompt, re-import again and verify it is displayed inside folder', + async () => { await folderPrompts.openFolderEntityDropdownMenu( promptInsideFolder.folders.name, promptInsideFolder.prompts[0].name, @@ -216,9 +232,12 @@ test.describe('Prompt export/import tests', () => { ) .waitFor(); await prompts.getPromptByName(promptOutsideFolder.name).waitFor(); - }); + }, + ); - await test.step('Delete imported prompt with its folder, re-import again and verify it is displayed inside folder', async () => { + await dialTest.step( + 'Delete imported prompt with its folder, re-import again and verify it is displayed inside folder', + async () => { await folderPrompts.openFolderDropdownMenu( promptInsideFolder.folders.name, ); @@ -236,9 +255,12 @@ test.describe('Prompt export/import tests', () => { promptInsideFolder.prompts[0].name, ) .waitFor(); - }); + }, + ); - await test.step('Open imported prompt edit screen, make some updates and verify imported prompt appears', async () => { + await dialTest.step( + 'Open imported prompt edit screen, make some updates and verify imported prompt appears', + async () => { await prompts.openPromptDropdownMenu(promptOutsideFolder.name); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); await promptModalDialog.updatePromptDetails( @@ -261,11 +283,14 @@ test.describe('Prompt export/import tests', () => { ExpectedMessages.promptValueUpdated, ) .toBe(newValue); - }); - }, - ); - - test('Export and import one prompt in hierarchy tree', async ({ + }, + ); + }, +); + +dialTest( + 'Export and import one prompt in hierarchy tree', + async ({ dialHomePage, setTestIds, localStorageManager, @@ -280,43 +305,59 @@ test.describe('Prompt export/import tests', () => { let exportedData: UploadDownloadData; const promptContent = 'test prompt'; - await test.step('Prepare folder with prompt and another prompt in the root', async () => { - promptInsideFolder = promptData.prepareDefaultPromptInFolder(); - promptData.resetData(); - - promptOutsideFolder = promptData.preparePrompt(promptContent); + await dialTest.step( + 'Prepare folder with prompt and another prompt in the root', + async () => { + promptInsideFolder = promptData.prepareDefaultPromptInFolder(); + promptData.resetData(); - await localStorageManager.setFolders(promptInsideFolder.folders); - await localStorageManager.setPrompts( - ...promptInsideFolder.prompts, - promptOutsideFolder, - ); - }); + promptOutsideFolder = promptData.preparePrompt(promptContent); - await test.step('Export prompt in the root using prompt dropdown menu', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await prompts.openPromptDropdownMenu(promptOutsideFolder.name); - exportedData = await dialHomePage.downloadData(() => - promptDropdownMenu.selectMenuOption(MenuOptions.export), - ); - }); + await localStorageManager.setFolders(promptInsideFolder.folders); + await localStorageManager.setPrompts( + ...promptInsideFolder.prompts, + promptOutsideFolder, + ); + }, + ); - await test.step('Delete exported prompt, re-import again and verify it is displayed in the root', async () => { - await prompts.openPromptDropdownMenu(promptOutsideFolder.name); - await promptDropdownMenu.selectMenuOption(MenuOptions.delete); - await prompts.getPromptInput(promptOutsideFolder.name).clickTickButton(); - await prompts - .getPromptByName(promptOutsideFolder.name) - .waitFor({ state: 'hidden' }); - await dialHomePage.uploadData(exportedData, () => - promptBar.importButton.click(), - ); - await prompts.getPromptByName(promptOutsideFolder.name).waitFor(); - }); - }); + await dialTest.step( + 'Export prompt in the root using prompt dropdown menu', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await prompts.openPromptDropdownMenu(promptOutsideFolder.name); + exportedData = await dialHomePage.downloadData(() => + promptDropdownMenu.selectMenuOption(MenuOptions.export), + ); + }, + ); - test('Existed prompts stay after import', async ({ + await dialTest.step( + 'Delete exported prompt, re-import again and verify it is displayed in the root', + async () => { + await prompts.openPromptDropdownMenu(promptOutsideFolder.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.delete); + await prompts + .getPromptInput(promptOutsideFolder.name) + .clickTickButton(); + await prompts + .getPromptByName(promptOutsideFolder.name) + .waitFor({ state: 'hidden' }); + await dialHomePage.uploadData(exportedData, () => + promptBar.importButton.click(), + ); + await prompts.getPromptByName(promptOutsideFolder.name).waitFor(); + }, + ); + }, +); + +dialTest( + 'Existed prompts stay after import', + async ({ dialHomePage, setTestIds, localStorageManager, @@ -332,94 +373,114 @@ test.describe('Prompt export/import tests', () => { let importedRootPrompt: Prompt; let importedNewFolderPrompt: FolderPrompt; - await test.step('Prepare folder with 2 prompts and another prompt in the root', async () => { - promptsInsideFolder = promptData.preparePromptsInFolder(2); - promptData.resetData(); - - promptOutsideFolder = promptData.prepareDefaultPrompt(); - promptData.resetData(); + await dialTest.step( + 'Prepare folder with 2 prompts and another prompt in the root', + async () => { + promptsInsideFolder = promptData.preparePromptsInFolder(2); + promptData.resetData(); - await localStorageManager.setFolders(promptsInsideFolder.folders); - await localStorageManager.setPrompts( - ...promptsInsideFolder.prompts, - promptOutsideFolder, - ); - }); + promptOutsideFolder = promptData.prepareDefaultPrompt(); + promptData.resetData(); - await test.step('Prepare prompt inside existing folder to import, prompt inside new folder to import and prompt inside root', async () => { - importedFolderPrompt = promptData.prepareDefaultPrompt(); - folderPromptData = ImportPrompt.preparePromptFile( - importedFolderPrompt, - promptsInsideFolder, - ); - promptData.resetData(); + await localStorageManager.setFolders(promptsInsideFolder.folders); + await localStorageManager.setPrompts( + ...promptsInsideFolder.prompts, + promptOutsideFolder, + ); + }, + ); + + await dialTest.step( + 'Prepare prompt inside existing folder to import, prompt inside new folder to import and prompt inside root', + async () => { + importedFolderPrompt = promptData.prepareDefaultPrompt(); + folderPromptData = ImportPrompt.preparePromptFile( + importedFolderPrompt, + promptsInsideFolder, + ); + promptData.resetData(); - importedRootPrompt = promptData.prepareDefaultPrompt(); - rootPromptData = ImportPrompt.preparePromptFile(importedRootPrompt); - promptData.resetData(); + importedRootPrompt = promptData.prepareDefaultPrompt(); + rootPromptData = ImportPrompt.preparePromptFile(importedRootPrompt); + promptData.resetData(); - importedNewFolderPrompt = promptData.prepareDefaultPromptInFolder(); - newFolderPromptData = ImportPrompt.preparePromptFile( - importedNewFolderPrompt.prompts[0], - importedNewFolderPrompt, - ); - }); + importedNewFolderPrompt = promptData.prepareDefaultPromptInFolder(); + newFolderPromptData = ImportPrompt.preparePromptFile( + importedNewFolderPrompt.prompts[0], + importedNewFolderPrompt, + ); + }, + ); - await test.step('Import prompt inside existing folder and verify it is imported and existing prompts remain inside folder', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); + await dialTest.step( + 'Import prompt inside existing folder and verify it is imported and existing prompts remain inside folder', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); - await dialHomePage.uploadData(folderPromptData, () => - promptBar.importButton.click(), - ); - await folderPrompts.expandCollapseFolder( - promptsInsideFolder.folders.name, - ); - await folderPrompts - .getFolderEntity( + await dialHomePage.uploadData(folderPromptData, () => + promptBar.importButton.click(), + ); + await folderPrompts.expandCollapseFolder( promptsInsideFolder.folders.name, - importedFolderPrompt.name, - ) - .waitFor(); - for (const existingPrompts of promptsInsideFolder.prompts) { + ); await folderPrompts .getFolderEntity( promptsInsideFolder.folders.name, - existingPrompts.name, + importedFolderPrompt.name, ) .waitFor(); - } - }); + for (const existingPrompts of promptsInsideFolder.prompts) { + await folderPrompts + .getFolderEntity( + promptsInsideFolder.folders.name, + existingPrompts.name, + ) + .waitFor(); + } + }, + ); - await test.step('Import root prompt and verify it is imported and existing root prompt remain', async () => { - await dialHomePage.uploadData(rootPromptData, () => - promptBar.importButton.click(), - ); - await prompts.getPromptByName(importedRootPrompt.name).waitFor(); - await prompts.getPromptByName(promptOutsideFolder.name).waitFor(); - }); + await dialTest.step( + 'Import root prompt and verify it is imported and existing root prompt remain', + async () => { + await dialHomePage.uploadData(rootPromptData, () => + promptBar.importButton.click(), + ); + await prompts.getPromptByName(importedRootPrompt.name).waitFor(); + await prompts.getPromptByName(promptOutsideFolder.name).waitFor(); + }, + ); - await test.step('Import conversation inside new folder and verify it is imported', async () => { - await dialHomePage.uploadData(newFolderPromptData, () => - promptBar.importButton.click(), - ); - await folderPrompts - .getFolderByName(importedNewFolderPrompt.folders.name) - .waitFor(); - const newFolderPrompt = folderPrompts.getFolderEntity( - importedNewFolderPrompt.folders.name, - importedNewFolderPrompt.prompts[0].name, - ); - if (await newFolderPrompt.isHidden()) { - await folderPrompts.expandCollapseFolder( + await dialTest.step( + 'Import conversation inside new folder and verify it is imported', + async () => { + await dialHomePage.uploadData(newFolderPromptData, () => + promptBar.importButton.click(), + ); + await folderPrompts + .getFolderByName(importedNewFolderPrompt.folders.name) + .waitFor(); + const newFolderPrompt = folderPrompts.getFolderEntity( importedNewFolderPrompt.folders.name, + importedNewFolderPrompt.prompts[0].name, ); - await newFolderPrompt.waitFor(); - } - }); - }); - - test('Import file from 1.4 version to prompts and continue working with it', async ({ + if (await newFolderPrompt.isHidden()) { + await folderPrompts.expandCollapseFolder( + importedNewFolderPrompt.folders.name, + ); + await newFolderPrompt.waitFor(); + } + }, + ); + }, +); + +dialTest( + 'Import file from 1.4 version to prompts and continue working with it', + async ({ dialHomePage, promptBar, setTestIds, @@ -431,24 +492,31 @@ test.describe('Prompt export/import tests', () => { }) => { setTestIds('EPMRTC-1135'); const aVariable = 'A'; - await test.step('Import prompt from 1.4 app version and verify folder with prompt is visible', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await dialHomePage.uploadData( - { path: Import.v14AppImportedFilename }, - () => promptBar.importButton.click(), - ); + await dialTest.step( + 'Import prompt from 1.4 app version and verify folder with prompt is visible', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await dialHomePage.uploadData( + { path: Import.v14AppImportedFilename }, + () => promptBar.importButton.click(), + ); - await folderPrompts.expandCollapseFolder(Import.oldVersionAppFolderName); - await folderPrompts - .getFolderEntity( + await folderPrompts.expandCollapseFolder( Import.oldVersionAppFolderName, - Import.v14AppFolderPromptName, - ) - .waitFor(); - }); + ); + await folderPrompts + .getFolderEntity( + Import.oldVersionAppFolderName, + Import.v14AppFolderPromptName, + ) + .waitFor(); + }, + ); - await test.step('Edit imported prompt', async () => { + await dialTest.step('Edit imported prompt', async () => { await folderPrompts.openFolderEntityDropdownMenu( Import.oldVersionAppFolderName, Import.v14AppFolderPromptName, @@ -460,75 +528,84 @@ test.describe('Prompt export/import tests', () => { .waitFor(); }); - await test.step('Enter prompt in the request, set params and verify it is applied in the request field', async () => { - await sendMessage.messageInput.fillInInput('/'); - await sendMessage.getPromptList().selectPrompt(newName); + await dialTest.step( + 'Enter prompt in the request, set params and verify it is applied in the request field', + async () => { + await sendMessage.messageInput.fillInInput('/'); + await sendMessage.getPromptList().selectPrompt(newName); - const promptName = await variableModalDialog.getName(); - expect.soft(promptName, ExpectedMessages.promptNameValid).toBe(newName); + const promptName = await variableModalDialog.getName(); + expect.soft(promptName, ExpectedMessages.promptNameValid).toBe(newName); - const promptDescr = await variableModalDialog.getDescription(); - expect - .soft(promptDescr, ExpectedMessages.promptDescriptionValid) - .toBe(newDescr); + const promptDescr = await variableModalDialog.getDescription(); + expect + .soft(promptDescr, ExpectedMessages.promptDescriptionValid) + .toBe(newDescr); - const variable = '20'; - await variableModalDialog.setVariable(aVariable, variable); + const variable = '20'; + await variableModalDialog.setVariable(aVariable, variable); - const actualMessage = await sendMessage.getMessage(); - expect - .soft(actualMessage, ExpectedMessages.promptApplied) - .toBe(newValue.replace(`{{${aVariable}}}`, variable)); - }); - }); + const actualMessage = await sendMessage.getMessage(); + expect + .soft(actualMessage, ExpectedMessages.promptApplied) + .toBe(newValue.replace(`{{${aVariable}}}`, variable)); + }, + ); + }, +); + +dialTest( + `Export and import single prompt in nested folders when folders structure doesn't exist.\n` + + `Export and import single prompt in nested folders when it's folder doesn't exist.\n` + + `Export and import single prompt in nested folders when parent folder doesn't exist`, + async ({ + dialHomePage, + setTestIds, + localStorageManager, + folderPrompts, + promptBar, + confirmationDialog, + promptData, + promptDropdownMenu, + folderDropdownMenu, + }) => { + setTestIds('EPMRTC-1375', 'EPMRTC-1376', 'EPMRTC-1377'); + let nestedFolders: FolderInterface[]; + let nestedPrompts: Prompt[]; + let exportedData: UploadDownloadData; - test( - `Export and import single prompt in nested folders when folders structure doesn't exist.\n` + - `Export and import single prompt in nested folders when it's folder doesn't exist.\n` + - `Export and import single prompt in nested folders when parent folder doesn't exist`, - async ({ - dialHomePage, - setTestIds, - localStorageManager, - folderPrompts, - promptBar, - confirmationDialog, - promptData, - promptDropdownMenu, - folderDropdownMenu, - }) => { - setTestIds('EPMRTC-1375', 'EPMRTC-1376', 'EPMRTC-1377'); - let nestedFolders: FolderInterface[]; - let nestedPrompts: Prompt[]; - let exportedData: UploadDownloadData; - - await test.step('Prepare nested folders with prompts inside', async () => { + await dialTest.step( + 'Prepare nested folders with prompts inside', + async () => { nestedFolders = promptData.prepareNestedFolder(levelsCount); nestedPrompts = promptData.preparePromptsForNestedFolders(nestedFolders); await localStorageManager.setFolders(...nestedFolders); await localStorageManager.setPrompts(...nestedPrompts); - }); + }, + ); - await test.step('Export prompt from 3rd level folder', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ - isNewConversationVisible: true, - }); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts.openFolderEntityDropdownMenu( - nestedFolders[levelsCount].name, - nestedPrompts[levelsCount].name, - ); - exportedData = await dialHomePage.downloadData(() => - promptDropdownMenu.selectMenuOption(MenuOptions.export), - ); + await dialTest.step('Export prompt from 3rd level folder', async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, }); + for (const nestedFolder of nestedFolders) { + await folderPrompts.expandCollapseFolder(nestedFolder.name); + } + await folderPrompts.openFolderEntityDropdownMenu( + nestedFolders[levelsCount].name, + nestedPrompts[levelsCount].name, + ); + exportedData = await dialHomePage.downloadData(() => + promptDropdownMenu.selectMenuOption(MenuOptions.export), + ); + }); - await test.step('Delete all prompts and folders, import exported prompt and verify folder structure with 3rd level prompt are displayed', async () => { + await dialTest.step( + 'Delete all prompts and folders, import exported prompt and verify folder structure with 3rd level prompt are displayed', + async () => { await promptBar.deleteAllEntities(); await confirmationDialog.confirm(); await dialHomePage.uploadData(exportedData, () => @@ -554,9 +631,12 @@ test.describe('Prompt export/import tests', () => { ExpectedMessages.promptsCountIsValid, ) .toBe(1); - }); + }, + ); - await test.step('Delete last folder with its prompt, re-import exported file again and verify last nested folder with its prompt imported', async () => { + await dialTest.step( + 'Delete last folder with its prompt, re-import exported file again and verify last nested folder with its prompt imported', + async () => { await folderPrompts.openFolderDropdownMenu( nestedFolders[levelsCount].name, ); @@ -573,9 +653,12 @@ test.describe('Prompt export/import tests', () => { nestedPrompts[levelsCount].name, ) .waitFor(); - }); + }, + ); - await test.step('Delete 2nd level folder with its nested content, re-import exported file and verify 2nd/3rd level folders with 3rd level prompt are imported', async () => { + await dialTest.step( + 'Delete 2nd level folder with its nested content, re-import exported file and verify 2nd/3rd level folders with 3rd level prompt are imported', + async () => { await folderPrompts.openFolderDropdownMenu( nestedFolders[levelsCount - 1].name, ); @@ -605,11 +688,14 @@ test.describe('Prompt export/import tests', () => { ExpectedMessages.promptsCountIsValid, ) .toBe(1); - }); - }, - ); - - test('Import a prompt in nested folder', async ({ + }, + ); + }, +); + +dialTest( + 'Import a prompt in nested folder', + async ({ dialHomePage, setTestIds, localStorageManager, @@ -623,15 +709,19 @@ test.describe('Prompt export/import tests', () => { let nestedPrompts: Prompt[]; const updatedPromptNames: string[] = []; - await test.step('Prepare 3 levels nested folders with prompts inside', async () => { - nestedFolders = promptData.prepareNestedFolder(levelsCount); - nestedPrompts = promptData.preparePromptsForNestedFolders(nestedFolders); + await dialTest.step( + 'Prepare 3 levels nested folders with prompts inside', + async () => { + nestedFolders = promptData.prepareNestedFolder(levelsCount); + nestedPrompts = + promptData.preparePromptsForNestedFolders(nestedFolders); - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setPrompts(...nestedPrompts); - }); + await localStorageManager.setFolders(...nestedFolders); + await localStorageManager.setPrompts(...nestedPrompts); + }, + ); - await test.step('Export 2nd and 3rd level folder prompts', async () => { + await dialTest.step('Export 2nd and 3rd level folder prompts', async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); for (const nestedFolder of nestedFolders) { @@ -650,68 +740,77 @@ test.describe('Prompt export/import tests', () => { } }); - await test.step('Update id and name of exported prompts and import them again', async () => { - for (const exportedData of exportedPrompts) { - const exportedContent = FileUtil.readFileData(exportedData.path); - const prompt = exportedContent.prompts[0]; - prompt.id = uuidv4(); - prompt.name = GeneratorUtil.randomString(10); - const updatedExportedPrompt = { - path: FileUtil.writeDataToFile(exportedContent), - isDownloadedData: false, - }; - updatedExportedPrompts.push(updatedExportedPrompt); - await dialHomePage.uploadData(updatedExportedPrompt, () => - promptBar.importButton.click(), - ); - updatedPromptNames.push(prompt.name); - } - }); - - await test.step('Verify new prompts are added to 2nd and 3rd level folders, folders structure remains the same', async () => { - expect - .soft( - await folderPrompts.getFoldersCount(), - ExpectedMessages.foldersCountIsValid, - ) - .toBe(levelsCount + 1); + await dialTest.step( + 'Update id and name of exported prompts and import them again', + async () => { + for (const exportedData of exportedPrompts) { + const exportedContent = FileUtil.readFileData(exportedData.path); + const prompt = exportedContent.prompts[0]; + prompt.id = uuidv4(); + prompt.name = GeneratorUtil.randomString(10); + const updatedExportedPrompt = { + path: FileUtil.writeDataToFile(exportedContent), + isDownloadedData: false, + }; + updatedExportedPrompts.push(updatedExportedPrompt); + await dialHomePage.uploadData(updatedExportedPrompt, () => + promptBar.importButton.click(), + ); + updatedPromptNames.push(prompt.name); + } + }, + ); - for (let i = 0; i < levelsCount; i++) { + await dialTest.step( + 'Verify new prompts are added to 2nd and 3rd level folders, folders structure remains the same', + async () => { expect .soft( - await folderPrompts.isFolderEntityVisible( - nestedFolders[i].name, - nestedPrompts[i].name, - ), - ExpectedMessages.promptIsVisible, + await folderPrompts.getFoldersCount(), + ExpectedMessages.foldersCountIsValid, ) - .toBeTruthy(); - if (i === 1) { - expect - .soft( - await folderPrompts.isFolderEntityVisible( - nestedFolders[i].name, - updatedPromptNames[0], - ), - ExpectedMessages.promptIsVisible, - ) - .toBeTruthy(); - } else if (i === 3) { + .toBe(levelsCount + 1); + + for (let i = 0; i < levelsCount; i++) { expect .soft( await folderPrompts.isFolderEntityVisible( nestedFolders[i].name, - updatedPromptNames[1], + nestedPrompts[i].name, ), ExpectedMessages.promptIsVisible, ) .toBeTruthy(); + if (i === 1) { + expect + .soft( + await folderPrompts.isFolderEntityVisible( + nestedFolders[i].name, + updatedPromptNames[0], + ), + ExpectedMessages.promptIsVisible, + ) + .toBeTruthy(); + } else if (i === 3) { + expect + .soft( + await folderPrompts.isFolderEntityVisible( + nestedFolders[i].name, + updatedPromptNames[1], + ), + ExpectedMessages.promptIsVisible, + ) + .toBeTruthy(); + } } - } - }); - }); - - test('Import a prompt from nested folder which was moved to another place', async ({ + }, + ); + }, +); + +dialTest( + 'Import a prompt from nested folder which was moved to another place', + async ({ dialHomePage, setTestIds, localStorageManager, @@ -725,16 +824,19 @@ test.describe('Prompt export/import tests', () => { let thirdLevelFolderPrompt: Prompt; let exportedData: UploadDownloadData; - await test.step('Prepare 3 levels nested folders and prompt inside the 3rd level folder', async () => { - nestedFolders = promptData.prepareNestedFolder(levelsCount); - thirdLevelFolderPrompt = promptData.prepareDefaultPrompt(); - thirdLevelFolderPrompt.folderId = nestedFolders[levelsCount].id; + await dialTest.step( + 'Prepare 3 levels nested folders and prompt inside the 3rd level folder', + async () => { + nestedFolders = promptData.prepareNestedFolder(levelsCount); + thirdLevelFolderPrompt = promptData.prepareDefaultPrompt(); + thirdLevelFolderPrompt.folderId = nestedFolders[levelsCount].id; - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setPrompts(thirdLevelFolderPrompt); - }); + await localStorageManager.setFolders(...nestedFolders); + await localStorageManager.setPrompts(thirdLevelFolderPrompt); + }, + ); - await test.step('Export 3rd level folder prompt', async () => { + await dialTest.step('Export 3rd level folder prompt', async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); for (const nestedFolder of nestedFolders) { @@ -749,60 +851,66 @@ test.describe('Prompt export/import tests', () => { ); }); - await test.step('Move 3rd level folder on the 1st level folder and import exported prompt', async () => { - nestedFolders[levelsCount].folderId = nestedFolders[1].folderId; - await localStorageManager.setFolders(...nestedFolders); - await dialHomePage.reloadPage(); - await dialHomePage.waitForPageLoaded(); - await dialHomePage.uploadData(exportedData, () => - promptBar.importButton.click(), - ); - }); + await dialTest.step( + 'Move 3rd level folder on the 1st level folder and import exported prompt', + async () => { + nestedFolders[levelsCount].folderId = nestedFolders[1].folderId; + await localStorageManager.setFolders(...nestedFolders); + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + await dialHomePage.uploadData(exportedData, () => + promptBar.importButton.click(), + ); + }, + ); - await test.step('Verify imported prompt is in 3rd level folder on the 1st level', async () => { - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts - .getFolderEntity( - nestedFolders[levelsCount].name, - thirdLevelFolderPrompt.name, - ) - .waitFor(); + await dialTest.step( + 'Verify imported prompt is in 3rd level folder on the 1st level', + async () => { + for (const nestedFolder of nestedFolders) { + await folderPrompts.expandCollapseFolder(nestedFolder.name); + } + await folderPrompts + .getFolderEntity( + nestedFolders[levelsCount].name, + thirdLevelFolderPrompt.name, + ) + .waitFor(); - const thirdLevelFolderPromptsCount = await folderPrompts - .getFolderEntity(nestedFolders[2].name, thirdLevelFolderPrompt.name) - .count(); - expect - .soft( - thirdLevelFolderPromptsCount, - ExpectedMessages.promptsCountIsValid, - ) - .toBe(0); - - const foldersCount = await folderPrompts.getFoldersCount(); - expect - .soft(foldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(levelsCount + 1); - - const promptsCount = await folderPrompts.getFolderEntitiesCount( - nestedFolders[3].name, - ); - expect.soft(promptsCount, ExpectedMessages.promptsCountIsValid).toBe(1); - }); - }); + const thirdLevelFolderPromptsCount = await folderPrompts + .getFolderEntity(nestedFolders[2].name, thirdLevelFolderPrompt.name) + .count(); + expect + .soft( + thirdLevelFolderPromptsCount, + ExpectedMessages.promptsCountIsValid, + ) + .toBe(0); - test.afterAll(async () => { - const importFilesToDelete: UploadDownloadData[] = [ - folderPromptData, - rootPromptData, - newFolderPromptData, - ...updatedExportedPrompts, - ]; - importFilesToDelete.forEach((d) => { - if (d) { - FileUtil.deleteImportFile(d.path); - } - }); + const foldersCount = await folderPrompts.getFoldersCount(); + expect + .soft(foldersCount, ExpectedMessages.foldersCountIsValid) + .toBe(levelsCount + 1); + + const promptsCount = await folderPrompts.getFolderEntitiesCount( + nestedFolders[3].name, + ); + expect.soft(promptsCount, ExpectedMessages.promptsCountIsValid).toBe(1); + }, + ); + }, +); + +dialTest.afterAll(async () => { + const importFilesToDelete: UploadDownloadData[] = [ + folderPromptData, + rootPromptData, + newFolderPromptData, + ...updatedExportedPrompts, + ]; + importFilesToDelete.forEach((d) => { + if (d) { + FileUtil.deleteImportFile(d.path); + } }); }); diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts index 278d1f1a09..9d4ae641dc 100644 --- a/apps/chat-e2e/src/tests/prompts.test.ts +++ b/apps/chat-e2e/src/tests/prompts.test.ts @@ -1,5 +1,6 @@ import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { ExpectedConstants, ExpectedMessages, @@ -12,11 +13,9 @@ const newName = 'test prompt'; const newDescr = 'test description'; const newValue = 'what is {{}}'; -test.describe('Side bar prompt tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Create new prompt', async ({ +dialTest( + 'Create new prompt', + async ({ dialHomePage, promptBar, prompts, @@ -47,19 +46,22 @@ test.describe('Side bar prompt tests', () => { ExpectedMessages.newPromptCreated, ) .toBeTruthy(); - }); + }, +); - test('Prompt menu', async ({ +dialTest( + 'Prompt menu', + async ({ dialHomePage, promptData, prompts, - localStorageManager, + dataInjector, promptDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-952'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -76,13 +78,16 @@ test.describe('Side bar prompt tests', () => { MenuOptions.publish, MenuOptions.delete, ]); - }); + }, +); - test('Edit prompt. Cancel', async ({ +dialTest( + 'Edit prompt. Cancel', + async ({ dialHomePage, promptData, prompts, - localStorageManager, + dataInjector, promptDropdownMenu, promptModalDialog, promptBar, @@ -90,7 +95,7 @@ test.describe('Side bar prompt tests', () => { }) => { setTestIds('EPMRTC-953'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); @@ -110,20 +115,23 @@ test.describe('Side bar prompt tests', () => { expect .soft(isPromptVisible, ExpectedMessages.promptNotUpdated) .toBeTruthy(); - }); + }, +); - test('Edit prompt. Save', async ({ +dialTest( + 'Edit prompt. Save', + async ({ dialHomePage, promptData, prompts, - localStorageManager, + dataInjector, promptDropdownMenu, promptModalDialog, setTestIds, }) => { setTestIds('EPMRTC-954'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -161,80 +169,83 @@ test.describe('Side bar prompt tests', () => { ExpectedMessages.promptValueUpdated, ) .toBe(newValue); - }); - - test( - 'Edit prompt on Enter.\n' + 'Special characters are allowed in prompt name', - async ({ - dialHomePage, - promptData, - prompts, - localStorageManager, - promptDropdownMenu, - promptModalDialog, - setTestIds, - }) => { - setTestIds('EPMRTC-955', 'EPMRTC-1278'); - const nameWithSpecialSymbols = '!@#$%^&*()_+{}[]:;"\',./<>?/*-+`~'; - const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); - - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await prompts.openPromptDropdownMenu(prompt.name); - await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - await promptModalDialog.updatePromptDetailsWithEnter( - nameWithSpecialSymbols, - newDescr, - newValue, - ); + }, +); - const isPromptModalVisible = await promptModalDialog.isVisible(); - await expect - .soft(isPromptModalVisible, ExpectedMessages.promptModalClosed) - .toBeFalsy(); +dialTest( + 'Edit prompt on Enter.\n' + 'Special characters are allowed in prompt name', + async ({ + dialHomePage, + promptData, + prompts, + dataInjector, + promptDropdownMenu, + promptModalDialog, + setTestIds, + }) => { + setTestIds('EPMRTC-955', 'EPMRTC-1278'); + const nameWithSpecialSymbols = '!@$^()_{}[]"\'.<>-`~'; + const prompt = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt]); - const isPromptVisible = await prompts - .getPromptByName(nameWithSpecialSymbols) - .isVisible(); - expect - .soft(isPromptVisible, ExpectedMessages.promptNotUpdated) - .toBeTruthy(); + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await prompts.openPromptDropdownMenu(prompt.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.edit); + await promptModalDialog.updatePromptDetailsWithEnter( + nameWithSpecialSymbols, + newDescr, + newValue, + ); - await prompts.openPromptDropdownMenu(nameWithSpecialSymbols); - await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - expect - .soft( - await promptModalDialog.getName(), - ExpectedMessages.promptNameUpdated, - ) - .toBe(nameWithSpecialSymbols); - expect - .soft( - await promptModalDialog.getDescription(), - ExpectedMessages.promptDescriptionUpdated, - ) - .toBe(newDescr); - expect - .soft( - await promptModalDialog.getPrompt(), - ExpectedMessages.promptValueUpdated, - ) - .toBe(newValue); - }, - ); + const isPromptModalVisible = await promptModalDialog.isVisible(); + await expect + .soft(isPromptModalVisible, ExpectedMessages.promptModalClosed) + .toBeFalsy(); + + const isPromptVisible = await prompts + .getPromptByName(nameWithSpecialSymbols) + .isVisible(); + expect + .soft(isPromptVisible, ExpectedMessages.promptNotUpdated) + .toBeTruthy(); + + await prompts.openPromptDropdownMenu(nameWithSpecialSymbols); + await promptDropdownMenu.selectMenuOption(MenuOptions.edit); + expect + .soft( + await promptModalDialog.getName(), + ExpectedMessages.promptNameUpdated, + ) + .toBe(nameWithSpecialSymbols); + expect + .soft( + await promptModalDialog.getDescription(), + ExpectedMessages.promptDescriptionUpdated, + ) + .toBe(newDescr); + expect + .soft( + await promptModalDialog.getPrompt(), + ExpectedMessages.promptValueUpdated, + ) + .toBe(newValue); + }, +); - test('Delete prompt located in the root', async ({ +dialTest( + 'Delete prompt located in the root', + async ({ dialHomePage, promptData, prompts, - localStorageManager, + dataInjector, promptDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-969'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -247,19 +258,22 @@ test.describe('Side bar prompt tests', () => { ExpectedMessages.promptDeleted, ) .toBeFalsy(); - }); + }, +); - test('Delete prompt. Cancel', async ({ +dialTest( + 'Delete prompt. Cancel', + async ({ dialHomePage, promptData, prompts, - localStorageManager, + dataInjector, promptDropdownMenu, setTestIds, }) => { setTestIds('EPMRTC-970'); const prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -272,14 +286,17 @@ test.describe('Side bar prompt tests', () => { ExpectedMessages.promptNotDeleted, ) .toBeTruthy(); - }); + }, +); - test('Clear prompts. Cancel', async ({ +dialTest( + 'Clear prompts. Cancel', + async ({ dialHomePage, conversations, conversationData, promptData, - localStorageManager, + dataInjector, folderConversations, folderPrompts, promptBar, @@ -288,8 +305,6 @@ test.describe('Side bar prompt tests', () => { setTestIds, }) => { setTestIds('EPMRTC-971'); - const emptyPromptFolder = promptData.prepareFolder(); - promptData.resetData(); const singlePrompt = promptData.prepareDefaultPrompt(); promptData.resetData(); const promptInFolder = promptData.prepareDefaultPromptInFolder(); @@ -299,25 +314,22 @@ test.describe('Side bar prompt tests', () => { const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); - await localStorageManager.setPrompts( - singlePrompt, - promptInFolder.prompts[0], - ); - await localStorageManager.setConversationHistory( - singleConversation, - conversationInFolder.conversations[0], - ); - await localStorageManager.setFolders( - emptyPromptFolder, + await dataInjector.createPrompts( + [singlePrompt, ...promptInFolder.prompts], promptInFolder.folders, + ); + await dataInjector.createConversations( + [singleConversation, ...conversationInFolder.conversations], conversationInFolder.folders, ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); + await promptBar.createNewFolder(); await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await promptBar.deleteAllEntities(); await confirmationDialog.cancelDialog(); @@ -345,7 +357,7 @@ test.describe('Side bar prompt tests', () => { .toBeTruthy(); const isPromptFolderVisible = await folderPrompts - .getFolderByName(emptyPromptFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .isVisible(); expect .soft(isPromptFolderVisible, ExpectedMessages.folderNotDeleted) @@ -365,33 +377,32 @@ test.describe('Side bar prompt tests', () => { expect .soft(isSinglePromptVisible, ExpectedMessages.promptNotDeleted) .toBeTruthy(); - }); + }, +); - test('Clear prompts. Clear', async ({ +dialTest( + 'Clear prompts. Clear', + async ({ dialHomePage, conversations, conversationData, promptData, + dataInjector, localStorageManager, folderConversations, folderPrompts, promptBar, confirmationDialog, prompts, + chatBar, setTestIds, }) => { setTestIds('EPMRTC-972'); let i = 2; - const emptyPromptFolder = promptData.prepareFolder(); - promptData.resetData(); const singlePrompt = promptData.prepareDefaultPrompt(); promptData.resetData(); const promptInFolder = promptData.prepareDefaultPromptInFolder(); promptData.resetData(); - const nestedFolders = promptData.prepareNestedFolder(3); - - const emptyConversationFolder = conversationData.prepareFolder(); - conversationData.resetData(); const singleConversation = conversationData.prepareDefaultConversation(); conversationData.resetData(); const conversationInFolder = @@ -399,60 +410,73 @@ test.describe('Side bar prompt tests', () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await localStorageManager.updatePrompts( - singlePrompt, - promptInFolder.prompts[0], - ); - await localStorageManager.updateConversationHistory( - singleConversation, - conversationInFolder.conversations[0], - ); - await localStorageManager.updateFolders( - emptyPromptFolder, - emptyConversationFolder, + await dataInjector.updatePrompts( + [singlePrompt, ...promptInFolder.prompts], promptInFolder.folders, + ); + await dataInjector.updateConversations( + [singleConversation, ...conversationInFolder.conversations], conversationInFolder.folders, - ...nestedFolders, ); await localStorageManager.updateSelectedConversation(singleConversation); await dialHomePage.reloadPage(); await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); + await chatBar.createNewFolder(); + for (let i = 1; i <= 4; i++) { + await promptBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await promptBar.dragAndDropEntityToFolder( + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); } + await folderPrompts.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + ); await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await conversations .getConversationByName(singleConversation.name) .waitFor(); await promptBar.deleteAllEntities(); - await confirmationDialog.confirm(); + await confirmationDialog.confirm({ triggeredHttpMethod: 'DELETE' }); while (i > 0) { - await folderConversations - .getFolderByName(emptyConversationFolder.name) - .waitFor(); if (i === 1) { + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) + .waitFor({ state: 'hidden' }); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); + } else { await folderConversations - .getFolderEntity( - conversationInFolder.folders.name, - conversationInFolder.conversations[0].name, - ) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(1)) .waitFor(); } + await folderConversations + .getFolderEntity( + conversationInFolder.folders.name, + conversationInFolder.conversations[0].name, + ) + .waitFor(); await conversations .getConversationByName(singleConversation.name) .waitFor(); const isPromptFolderVisible = await folderPrompts - .getFolderByName(emptyPromptFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(4)) .isVisible(); expect .soft(isPromptFolderVisible, ExpectedMessages.folderDeleted) @@ -473,9 +497,9 @@ test.describe('Side bar prompt tests', () => { .soft(isSinglePromptVisible, ExpectedMessages.promptDeleted) .toBeFalsy(); - for (const nestedFolder of nestedFolders) { + for (let i = 1; i <= 3; i++) { const isNestedPromptFolderVisible = await folderPrompts - .getFolderByName(nestedFolder.name) + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) .isVisible(); expect .soft(isNestedPromptFolderVisible, ExpectedMessages.folderDeleted) @@ -488,13 +512,12 @@ test.describe('Side bar prompt tests', () => { } i--; } - }); + }, +); - test(`[UI] Delete all prompts button doesn't exist if not prompts are created`, async ({ - dialHomePage, - promptBar, - setTestIds, - }) => { +dialTest( + `[UI] Delete all prompts button doesn't exist if not prompts are created`, + async ({ dialHomePage, promptBar, setTestIds }) => { setTestIds('EPMRTC-973'); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); @@ -507,19 +530,22 @@ test.describe('Side bar prompt tests', () => { ExpectedMessages.deleteAllPromptsButtonNotVisible, ) .toBeFalsy(); - }); + }, +); - test('Use simple prompt in system prompt', async ({ +dialTest( + 'Use simple prompt in system prompt', + async ({ dialHomePage, promptData, - localStorageManager, + dataInjector, entitySettings, setTestIds, }) => { setTestIds('EPMRTC-1010'); const promptContent = 'prompt content'; const prompt = promptData.preparePrompt(promptContent); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -529,12 +555,15 @@ test.describe('Side bar prompt tests', () => { expect .soft(actualPrompt, ExpectedMessages.systemPromptValid) .toBe(prompt.content); - }); + }, +); - test('Use prompt with parameters', async ({ +dialTest( + 'Use prompt with parameters', + async ({ dialHomePage, promptData, - localStorageManager, + dataInjector, sendMessage, variableModalDialog, setTestIds, @@ -547,7 +576,7 @@ test.describe('Side bar prompt tests', () => { promptContent(`{{${aVariable}}}`), promptDescription, ); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -578,12 +607,15 @@ test.describe('Side bar prompt tests', () => { expect .soft(actualMessage, ExpectedMessages.promptApplied) .toBe(promptContent(variable)); - }); + }, +); - test('Check that all parameters in prompt are required', async ({ +dialTest( + 'Check that all parameters in prompt are required', + async ({ dialHomePage, promptData, - localStorageManager, + dataInjector, sendMessage, variableModalDialog, setTestIds, @@ -596,7 +628,7 @@ test.describe('Side bar prompt tests', () => { const prompt = promptData.preparePrompt( promptContent(`{{${aVariable}}}`, `{{${bVariable}}}`), ); - await localStorageManager.setPrompts(prompt); + await dataInjector.createPrompts([prompt]); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -616,11 +648,14 @@ test.describe('Side bar prompt tests', () => { expect .soft(actualMessage, ExpectedMessages.promptApplied) .toBe(promptContent(firstVariableValue, secondVariableValue)); - }); + }, +); - test('Search prompt when no folders', async ({ +dialTest( + 'Search prompt when no folders', + async ({ dialHomePage, - localStorageManager, + dataInjector, prompts, promptData, promptBar, @@ -638,7 +673,7 @@ test.describe('Side bar prompt tests', () => { const searchTerm = 'test'; const specialSymbolSearchTerm = '@'; - await test.step('Prepare prompts with different content', async () => { + await dialTest.step('Prepare prompts with different content', async () => { firstPrompt = promptData.prepareDefaultPrompt(promptContent); promptData.resetData(); secondPrompt = promptData.preparePrompt('', promptContent); @@ -648,53 +683,67 @@ test.describe('Side bar prompt tests', () => { fourthPrompt = promptData.prepareDefaultPrompt(); promptData.resetData(); fifthPrompt = promptData.prepareDefaultPrompt( - 'Prompt_!@#$%^&*()+=\':",.<>', + 'Prompt_!@$^&()_{}[]"\'.<>-`~', ); - await localStorageManager.setPrompts( + await dataInjector.createPrompts([ firstPrompt, secondPrompt, thirdPrompt, fourthPrompt, fifthPrompt, - ); - }); - - await test.step('Type not matching search term and in "Search prompt.." field and verify no results found', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await promptBarSearch.setSearchValue(notMatchingSearchTerm); - const noResult = - await promptBar.noResultFoundIcon.getElementInnerContent(); - expect - .soft(noResult, ExpectedMessages.noResultsFound) - .toBe(ExpectedConstants.noResults); + ]); }); - await test.step('Clear search field and verify all prompts displayed', async () => { - await promptBarSearch.setSearchValue(''); - const resultCount = await prompts.getPromptsCount(); - expect - .soft(resultCount, ExpectedMessages.searchResultCountIsValid) - .toBe(5); - }); + await dialTest.step( + 'Type not matching search term and in "Search prompt.." field and verify no results found', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await promptBarSearch.setSearchValue(notMatchingSearchTerm); + const noResult = + await promptBar.noResultFoundIcon.getElementInnerContent(); + expect + .soft(noResult, ExpectedMessages.noResultsFound) + .toBe(ExpectedConstants.noResults); + }, + ); - await test.step('Type search term in the field and verify all prompts displayed', async () => { - for (const term of [searchTerm, searchTerm.toUpperCase()]) { - await promptBarSearch.setSearchValue(term); + await dialTest.step( + 'Clear search field and verify all prompts displayed', + async () => { + await promptBarSearch.setSearchValue(''); const resultCount = await prompts.getPromptsCount(); expect .soft(resultCount, ExpectedMessages.searchResultCountIsValid) - .toBe(3); - } - }); + .toBe(5); + }, + ); - await test.step('Type search term in the field and verify all prompts displayed', async () => { - await promptBarSearch.setSearchValue(specialSymbolSearchTerm); - const resultCount = await prompts.getPromptsCount(); - expect - .soft(resultCount, ExpectedMessages.searchResultCountIsValid) - .toBe(1); - }); - }); -}); + await dialTest.step( + 'Type search term in the field and verify all prompts displayed', + async () => { + for (const term of [searchTerm, searchTerm.toUpperCase()]) { + await promptBarSearch.setSearchValue(term); + const resultCount = await prompts.getPromptsCount(); + expect + .soft(resultCount, ExpectedMessages.searchResultCountIsValid) + .toBe(isApiStorageType ? 1 : 3); + } + }, + ); + + await dialTest.step( + 'Type search term in the field and verify all prompts displayed', + async () => { + await promptBarSearch.setSearchValue(specialSymbolSearchTerm); + const resultCount = await prompts.getPromptsCount(); + expect + .soft(resultCount, ExpectedMessages.searchResultCountIsValid) + .toBe(1); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index 381232cbcd..4c7b312584 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -1,7 +1,7 @@ import { ChatBody, Conversation } from '@/chat/types/chat'; import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, @@ -18,42 +18,40 @@ let gpt35Model: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; let bison: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { allModels = ModelsUtil.getModels().filter((m) => m.iconUrl != undefined); gpt35Model = ModelsUtil.getModel(ModelIds.GPT_3_5_TURBO)!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; bison = ModelsUtil.getModel(ModelIds.BISON_001)!; }); -test.describe('Chat replay tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - '[Replay]chat has the same defaults at its parent.\n' + - '"Replay as is" is selected by default in [Replay]chat', - async ({ - dialHomePage, - conversationData, - chat, - localStorageManager, - conversationDropdownMenu, - conversations, - setTestIds, - recentEntities, - replayAsIs, - talkToSelector, - entitySettings, - temperatureSlider, - addons, - }) => { - setTestIds('EPMRTC-501', 'EPMRTC-1264'); - let replayConversation: Conversation; - const replayTemp = 0; - const replayPrompt = 'replay prompt'; - let firstConversation: Conversation; - - await test.step('Prepare two conversation with different settings', async () => { +dialTest( + '[Replay]chat has the same defaults at its parent.\n' + + '"Replay as is" is selected by default in [Replay]chat', + async ({ + dialHomePage, + conversationData, + chat, + dataInjector, + conversationDropdownMenu, + conversations, + setTestIds, + recentEntities, + replayAsIs, + talkToSelector, + entitySettings, + temperatureSlider, + addons, + }) => { + setTestIds('EPMRTC-501', 'EPMRTC-1264'); + let replayConversation: Conversation; + const replayTemp = 0; + const replayPrompt = 'replay prompt'; + let firstConversation: Conversation; + + await dialTest.step( + 'Prepare two conversation with different settings', + async () => { firstConversation = conversationData.prepareModelConversation( 0.5, 'first prompt', @@ -68,13 +66,16 @@ test.describe('Chat replay tests', () => { [], gpt4Model, ); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ firstConversation, replayConversation, - ); - }); + ]); + }, + ); - await test.step('Open Replay drop-down menu for one conversation', async () => { + await dialTest.step( + 'Open Replay drop-down menu for one conversation', + async () => { const modelUrls = allModels .filter( (m) => @@ -90,9 +91,12 @@ test.describe('Chat replay tests', () => { replayConversation!.name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); - }); + }, + ); - await test.step('Verify new Replay conversation is created and Replay button appears', async () => { + await dialTest.step( + 'Verify new Replay conversation is created and Replay button appears', + async () => { expect .soft( await conversations @@ -111,9 +115,12 @@ test.describe('Chat replay tests', () => { ExpectedMessages.startReplayVisible, ) .toBe(ExpectedConstants.startReplayLabel); - }); + }, + ); - await test.step('Verify "Replay as is" option is selected', async () => { + await dialTest.step( + 'Verify "Replay as is" option is selected', + async () => { const modelBorderColors = await recentEntities .getRecentEntity(ExpectedConstants.talkToReply) .getAllBorderColors(); @@ -129,9 +136,12 @@ test.describe('Chat replay tests', () => { expect .soft(replayLabel, ExpectedMessages.replayAsIsLabelIsVisible) .toBe(ExpectedConstants.replayAsIsLabel); - }); + }, + ); - await test.step('Select some model and verify it has the same settings as parent model', async () => { + await dialTest.step( + 'Select some model and verify it has the same settings as parent model', + async () => { await talkToSelector.selectModel(gpt35Model.name); const newModelSystemPrompt = await entitySettings.getSystemPrompt(); @@ -148,15 +158,18 @@ test.describe('Chat replay tests', () => { expect .soft(newModelSelectedAddons, ExpectedMessages.selectedAddonsValid) .toEqual([]); - }); - }, - ); - - test('[Replay]chat is created in the same folder where its parent is located', async ({ + }, + ); + }, +); + +dialTest( + '[Replay]chat is created in the same folder where its parent is located', + async ({ dialHomePage, conversationData, folderConversations, - localStorageManager, + dataInjector, setTestIds, conversationDropdownMenu, }) => { @@ -165,46 +178,65 @@ test.describe('Chat replay tests', () => { let nestedConversations: Conversation[] = []; const nestedLevels = 3; - await test.step('Prepare 3 levels folders hierarchy with chats inside', async () => { - nestedFolders = conversationData.prepareNestedFolder(nestedLevels); - nestedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory(...nestedConversations); - }); - - await test.step('Select Replay from drop-down menu for conversations inside 1st and 3rd level folders', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - for (let i = 0; i < nestedLevels; i = i + 2) { - await folderConversations.openFolderEntityDropdownMenu( - nestedFolders[i + 1].name, - nestedConversations[i + 1].name, + await dialTest.step( + 'Prepare 3 levels folders hierarchy with chats inside', + async () => { + nestedFolders = conversationData.prepareNestedFolder(nestedLevels); + nestedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); + await dataInjector.createConversations( + nestedConversations, + ...nestedFolders, ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); - } - }); - - await test.step('Verify new Replay conversations are created inside 1st and 3rd level folders', async () => { - for (let i = 0; i < nestedLevels; i = i + 2) { - await folderConversations.getFolderEntity( - nestedFolders[i + 1].name, - `${ExpectedConstants.replayConversation}${ - nestedConversations[i + 1].name - }`, - ).waitFor; - } - }); - }); + }, + ); - test('Start replay with the new Model settings', async ({ + await dialTest.step( + 'Select Replay from drop-down menu for conversations inside 1st and 3rd level folders', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } + for (let i = 0; i < nestedLevels; i = i + 2) { + await folderConversations.openFolderEntityDropdownMenu( + nestedFolders[i + 1].name, + nestedConversations[i + 1].name, + ); + await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); + } + }, + ); + + await dialTest.step( + 'Verify new Replay conversations are created inside 1st and 3rd level folders', + async () => { + for (let i = 0; i < nestedLevels; i = i + 2) { + await folderConversations.getFolderEntity( + nestedFolders[i + 1].name, + `${ExpectedConstants.replayConversation}${ + nestedConversations[i + 1].name + }`, + ).waitFor; + } + }, + ); + }, +); + +dialTest( + 'Start replay with the new Model settings', + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, setTestIds, chatHeader, entitySettings, @@ -219,178 +251,215 @@ test.describe('Chat replay tests', () => { const replayPrompt = 'reply the same text'; const replayModel = bison; - await test.step('Prepare conversation to replay', async () => { + await dialTest.step('Prepare conversation to replay', async () => { const conversation = conversationData.prepareDefaultConversation(gpt35Model); const replayConversation = conversationData.prepareDefaultReplayConversation(conversation); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); + ]); await localStorageManager.setSelectedConversation(replayConversation); }); let replayRequest: ChatBody; - await test.step('Change model and settings for replay conversation and press Start replay', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await talkToSelector.selectModel(bison.name); - await entitySettings.setSystemPrompt(replayPrompt); - await temperatureSlider.setTemperature(replayTemp); - replayRequest = await chat.startReplay(); - }); - - await test.step('Verify chat API request is sent with correct settings', async () => { - expect - .soft(replayRequest.modelId, ExpectedMessages.chatRequestModelIsValid) - .toBe(bison.id); - expect - .soft(replayRequest.prompt, ExpectedMessages.chatRequestPromptIsValid) - .toBe(replayPrompt); - expect - .soft( - replayRequest.temperature, - ExpectedMessages.chatRequestTemperatureIsValid, - ) - .toBe(replayTemp); - }); - - await test.step('Verify chat header icons are updated with new model and addon', async () => { - const headerModelIcon = await chatHeader.getHeaderModelIcon(); - const expectedModelIcon = await iconApiHelper.getEntityIcon(bison); - expect - .soft(headerModelIcon, ExpectedMessages.entityIconIsValid) - .toBe(expectedModelIcon); - }); + await dialTest.step( + 'Change model and settings for replay conversation and press Start replay', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await talkToSelector.selectModel(bison.name); + await entitySettings.setSystemPrompt(replayPrompt); + await temperatureSlider.setTemperature(replayTemp); + replayRequest = await chat.startReplay(); + }, + ); + + await dialTest.step( + 'Verify chat API request is sent with correct settings', + async () => { + expect + .soft(replayRequest.modelId, ExpectedMessages.chatRequestModelIsValid) + .toBe(bison.id); + expect + .soft(replayRequest.prompt, ExpectedMessages.chatRequestPromptIsValid) + .toBe(replayPrompt); + expect + .soft( + replayRequest.temperature, + ExpectedMessages.chatRequestTemperatureIsValid, + ) + .toBe(replayTemp); + }, + ); - await test.step('Hover over chat header model and verify chat settings on tooltip', async () => { - await errorPopup.cancelPopup(); - await chatHeader.chatModel.hoverOver(); - const modelInfo = await chatInfoTooltip.getModelInfo(); - expect - .soft(modelInfo, ExpectedMessages.chatInfoModelIsValid) - .toBe(bison.name); + await dialTest.step( + 'Verify chat header icons are updated with new model and addon', + async () => { + const headerModelIcon = await chatHeader.getHeaderModelIcon(); + const expectedModelIcon = await iconApiHelper.getEntityIcon(bison); + expect + .soft(headerModelIcon, ExpectedMessages.entityIconIsValid) + .toBe(expectedModelIcon); + }, + ); - const expectedReplayModelIcon = - await iconApiHelper.getEntityIcon(replayModel); - const modelInfoIcon = await chatInfoTooltip.getModelIcon(); - expect - .soft(modelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) - .toBe(expectedReplayModelIcon); + await dialTest.step( + 'Hover over chat header model and verify chat settings on tooltip', + async () => { + await errorPopup.cancelPopup(); + await chatHeader.chatModel.hoverOver(); + const modelInfo = await chatInfoTooltip.getModelInfo(); + expect + .soft(modelInfo, ExpectedMessages.chatInfoModelIsValid) + .toBe(bison.name); - const promptInfo = await chatInfoTooltip.getPromptInfo(); - expect - .soft(promptInfo, ExpectedMessages.chatInfoPromptIsValid) - .toBe(replayPrompt); + const expectedReplayModelIcon = + await iconApiHelper.getEntityIcon(replayModel); + const modelInfoIcon = await chatInfoTooltip.getModelIcon(); + expect + .soft(modelInfoIcon, ExpectedMessages.chatInfoModelIconIsValid) + .toBe(expectedReplayModelIcon); - const tempInfo = await chatInfoTooltip.getTemperatureInfo(); - expect - .soft(tempInfo, ExpectedMessages.chatInfoTemperatureIsValid) - .toBe(replayTemp.toString()); - }); - }); + const promptInfo = await chatInfoTooltip.getPromptInfo(); + expect + .soft(promptInfo, ExpectedMessages.chatInfoPromptIsValid) + .toBe(replayPrompt); - test('Replay after Stop generating', async ({ + const tempInfo = await chatInfoTooltip.getTemperatureInfo(); + expect + .soft(tempInfo, ExpectedMessages.chatInfoTemperatureIsValid) + .toBe(replayTemp.toString()); + }, + ); + }, +); + +dialTest( + 'Replay after Stop generating', + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, setTestIds, + conversations, chatMessages, }) => { setTestIds('EPMRTC-512'); let conversation: Conversation; + let replayConversation: Conversation; const userRequest = 'write down 100 adjectives'; - await test.step('Prepare model conversation to replay', async () => { + + await dialTest.step('Prepare model conversation to replay', async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( gpt35Model, [userRequest], ); - const replayConversation = + replayConversation = conversationData.preparePartiallyReplayedConversation(conversation); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); - - await test.step('Press Start replay and stop until full response received', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - expect - .soft( - await chat.proceedGenerating.getElementInnerContent(), - ExpectedMessages.proceedReplayIsVisible, - ) - .toBe(ExpectedConstants.continueReplayLabel); - }); - - await test.step('Proceed generating the answer and verify received content is preserved', async () => { - const receivedPartialContent = await chatMessages.getGeneratedChatContent( - conversation.messages.length, - ); - await chat.proceedReplaying(); - const preservedPartialContent = - await chatMessages.getGeneratedChatContent( - conversation.messages.length, - ); - expect - .soft( - preservedPartialContent.includes(receivedPartialContent), - ExpectedMessages.replayContinuesFromReceivedContent, - ) - .toBeTruthy(); + ]); + await localStorageManager.setSelectedConversation(conversation); }); - }); - - test( - 'Restart replay after error appeared on browser refresh.\n' + - 'Restart replay after error appeared on network interruption', - async ({ - dialHomePage, - conversationData, - chat, - localStorageManager, - setTestIds, - chatMessages, - context, - }) => { - setTestIds('EPMRTC-514', 'EPMRTC-1165'); - let conversation: Conversation; - await test.step('Prepare conversation to replay', async () => { - conversation = conversationData.prepareDefaultConversation(gpt35Model); - const replayConversation = - conversationData.prepareDefaultReplayConversation(conversation); - await localStorageManager.setConversationHistory( - conversation, - replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); - await test.step('Press Start replay and interrupt it with network error', async () => { + await dialTest.step( + 'Press Start replay and stop until full response received', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - await context.setOffline(true); - await chat.startReplay(); - }); - - await test.step('Verify error message is displayed', async () => { - const generatedContent = await chatMessages.getLastMessageContent(); - expect - .soft(generatedContent, ExpectedMessages.errorReceivedOnReplay) - .toBe(ExpectedConstants.answerError); + await conversations.selectConversation(replayConversation.name); expect .soft( await chat.proceedGenerating.getElementInnerContent(), ExpectedMessages.proceedReplayIsVisible, ) - .toBe(ExpectedConstants.continueReplayAfterErrorLabel); - }); + .toBe(ExpectedConstants.continueReplayLabel); + }, + ); + + await dialTest.step( + 'Proceed generating the answer and verify received content is preserved', + async () => { + const receivedPartialContent = + await chatMessages.getGeneratedChatContent( + conversation.messages.length, + ); + await chat.proceedReplaying(); + const preservedPartialContent = + await chatMessages.getGeneratedChatContent( + conversation.messages.length, + ); + expect + .soft( + preservedPartialContent.includes(receivedPartialContent), + ExpectedMessages.replayContinuesFromReceivedContent, + ) + .toBeTruthy(); + }, + ); + }, +); + +dialTest( + 'Restart replay after error appeared on browser refresh.\n' + + 'Restart replay after error appeared on network interruption', + async ({ + dialHomePage, + conversationData, + chat, + localStorageManager, + dataInjector, + setTestIds, + chatMessages, + context, + conversations, + }) => { + setTestIds('EPMRTC-514', 'EPMRTC-1165'); + let conversation: Conversation; + let replayConversation: Conversation; + await dialTest.step('Prepare conversation to replay', async () => { + conversation = conversationData.prepareDefaultConversation(gpt35Model); + replayConversation = + conversationData.prepareDefaultReplayConversation(conversation); + await dataInjector.createConversations([ + conversation, + replayConversation, + ]); + await localStorageManager.setSelectedConversation(conversation); + }); + + await dialTest.step( + 'Press Start replay and interrupt it with network error', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); + await context.setOffline(true); + await chat.startReplay(); + }, + ); - await test.step('Proceed replaying and verify response received', async () => { + await dialTest.step('Verify error message is displayed', async () => { + const generatedContent = await chatMessages.getLastMessageContent(); + expect + .soft(generatedContent, ExpectedMessages.errorReceivedOnReplay) + .toBe(ExpectedConstants.answerError); + expect + .soft( + await chat.proceedGenerating.getElementInnerContent(), + ExpectedMessages.proceedReplayIsVisible, + ) + .toBe(ExpectedConstants.continueReplayAfterErrorLabel); + }); + + await dialTest.step( + 'Proceed replaying and verify response received', + async () => { await context.setOffline(false); await chat.proceedReplaying(true); const generatedContent = await chatMessages.getGeneratedChatContent( @@ -404,50 +473,57 @@ test.describe('Chat replay tests', () => { ExpectedMessages.replayContinuesFromReceivedContent, ) .toBeTruthy(); - }); - }, - ); - - test( - '"Replay as is" when chat is based on Model.\n' + - '"Replay as is" when chat is based on Model with addon', - async ({ - dialHomePage, - conversationData, - chat, - localStorageManager, - setTestIds, - chatHeader, - chatInfoTooltip, - errorPopup, - iconApiHelper, - }) => { - setTestIds('EPMRTC-1323', 'EPMRTC-1324'); - const replayTemp = 0.8; - const replayPrompt = 'reply the same text'; - let conversation: Conversation; - const expectedModelIcon = await iconApiHelper.getEntityIcon(gpt35Model); - - await test.step('Prepare conversation to replay', async () => { - conversation = conversationData.prepareModelConversation( - replayTemp, - replayPrompt, - [], - gpt35Model, - ); - const replayConversation = - conversationData.prepareDefaultReplayConversation(conversation); - await localStorageManager.setConversationHistory( - conversation, - replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); + }, + ); + }, +); + +dialTest( + '"Replay as is" when chat is based on Model.\n' + + '"Replay as is" when chat is based on Model with addon', + async ({ + dialHomePage, + conversationData, + chat, + localStorageManager, + dataInjector, + setTestIds, + chatHeader, + chatInfoTooltip, + errorPopup, + iconApiHelper, + conversations, + }) => { + setTestIds('EPMRTC-1323', 'EPMRTC-1324'); + const replayTemp = 0.8; + const replayPrompt = 'reply the same text'; + let conversation: Conversation; + let replayConversation: Conversation; + const expectedModelIcon = await iconApiHelper.getEntityIcon(gpt35Model); + + await dialTest.step('Prepare conversation to replay', async () => { + conversation = conversationData.prepareModelConversation( + replayTemp, + replayPrompt, + [], + gpt35Model, + ); + replayConversation = + conversationData.prepareDefaultReplayConversation(conversation); + await dataInjector.createConversations([ + conversation, + replayConversation, + ]); + await localStorageManager.setSelectedConversation(conversation); + }); - let replayRequest: ChatBody; - await test.step('Replay conversation with "Replay as is" option selected and verify valid request is sent', async () => { + let replayRequest: ChatBody; + await dialTest.step( + 'Replay conversation with "Replay as is" option selected and verify valid request is sent', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); replayRequest = await chat.startReplay( conversation.messages[0].content, ); @@ -463,16 +539,22 @@ test.describe('Chat replay tests', () => { ExpectedMessages.chatRequestTemperatureIsValid, ) .toBe(conversation.temperature); - }); + }, + ); - await test.step('Verify chat header icons are the same as initial model', async () => { + await dialTest.step( + 'Verify chat header icons are the same as initial model', + async () => { const headerModelIcon = await chatHeader.getHeaderModelIcon(); expect .soft(headerModelIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedModelIcon); - }); + }, + ); - await test.step('Hover over chat header model and verify chat settings on tooltip', async () => { + await dialTest.step( + 'Hover over chat header model and verify chat settings on tooltip', + async () => { await errorPopup.cancelPopup(); await chatHeader.chatModel.hoverOver(); const modelInfo = await chatInfoTooltip.getModelInfo(); @@ -494,31 +576,35 @@ test.describe('Chat replay tests', () => { expect .soft(tempInfo, ExpectedMessages.chatInfoTemperatureIsValid) .toBe(conversation.temperature.toString()); - }); - }, - ); - - test( - '"Replay as is" icon is changed to model icon after replaying the chat.\n' + - '"Talk to" item icon is stored in history for previous messages when new model is set', - async ({ - dialHomePage, - conversationData, - chat, - localStorageManager, - chatMessages, - conversations, - iconApiHelper, - setTestIds, - }) => { - setTestIds('EPMRTC-1322', 'EPMRTC-388'); - let replayConversation: Conversation; - let conversation: Conversation; - const firstModel = gpt35Model; - const secondModel = gpt4Model; - const conversationModels = [gpt35Model, gpt4Model]; - - await test.step('Prepare reply conversation with two different models', async () => { + }, + ); + }, +); + +dialTest( + '"Replay as is" icon is changed to model icon after replaying the chat.\n' + + '"Talk to" item icon is stored in history for previous messages when new model is set', + async ({ + dialHomePage, + conversationData, + chat, + localStorageManager, + dataInjector, + chatMessages, + conversations, + iconApiHelper, + setTestIds, + }) => { + setTestIds('EPMRTC-1322', 'EPMRTC-388'); + let replayConversation: Conversation; + let conversation: Conversation; + const firstModel = gpt35Model; + const secondModel = gpt4Model; + const conversationModels = [gpt35Model, gpt4Model]; + + await dialTest.step( + 'Prepare reply conversation with two different models', + async () => { conversation = conversationData.prepareConversationWithDifferentModels( conversationModels, @@ -527,16 +613,20 @@ test.describe('Chat replay tests', () => { replayConversation = conversationData.prepareDefaultReplayConversation(conversation); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); - - await test.step('Send new request with preselected "Replay as is" option and verify message icons correspond models', async () => { + ]); + await localStorageManager.setSelectedConversation(conversation); + }, + ); + + await dialTest.step( + 'Send new request with preselected "Replay as is" option and verify message icons correspond models', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); await chat.startReplayForDifferentModels(); const expectedFirstModelIcon = @@ -562,25 +652,31 @@ test.describe('Chat replay tests', () => { expect .soft(chatBarConversationIcon, ExpectedMessages.entityIconIsValid) .toBe(expectedSecondModelIcon); - }); - }, - ); - - test('Send button is disabled if the chat in replay mode', async ({ + }, + ); + }, +); + +dialTest( + 'Send button is disabled if the chat in replay mode', + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, setTestIds, sendMessage, tooltip, context, chatMessages, + conversations, }) => { setTestIds('EPMRTC-1535'); const message = GeneratorUtil.randomString(10); + let replayConversation: Conversation; - await test.step('Prepare conversation to replay', async () => { + await dialTest.step('Prepare conversation to replay', async () => { const requests: string[] = []; for (let i = 1; i <= 10; i++) { requests.push(GeneratorUtil.randomString(200)); @@ -590,116 +686,139 @@ test.describe('Chat replay tests', () => { gpt35Model, requests, ); - const replayConversation = + replayConversation = conversationData.prepareDefaultReplayConversation(conversation); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); + ]); + await localStorageManager.setSelectedConversation(conversation); }); - await test.step('Type new message while chat is replaying and verify Send button is disabled', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await chat.startReplay(); - await sendMessage.messageInput.fillInInput(message); - - await sendMessage.sendMessageButton.hoverOver(); - const tooltipContent = await tooltip.getContent(); - expect - .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) - .toBe(ExpectedConstants.waitForAssistantAnswerTooltip); + await dialTest.step( + 'Type new message while chat is replaying and verify Send button is disabled', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); + await chat.startReplay(); + await sendMessage.messageInput.fillInInput(message); - const isSendButtonEnabled = - await sendMessage.sendMessageButton.isElementEnabled(); - expect - .soft(isSendButtonEnabled, ExpectedMessages.sendMessageButtonDisabled) - .toBeFalsy(); - }); + await sendMessage.sendMessageButton.hoverOver(); + const tooltipContent = await tooltip.getContent(); + expect + .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) + .toBe(ExpectedConstants.waitForAssistantAnswerTooltip); - await test.step('Stop generating and verify message is preserved, footer is visible and tooltip shown on hover', async () => { - await chat.stopGenerating.click(); - const inputMessage = await sendMessage.messageInput.getElementContent(); - expect - .soft(inputMessage, ExpectedMessages.messageContentIsValid) - .toBe(message); + const isSendButtonEnabled = + await sendMessage.sendMessageButton.isElementEnabled(); + expect + .soft(isSendButtonEnabled, ExpectedMessages.sendMessageButtonDisabled) + .toBeFalsy(); + }, + ); + + await dialTest.step( + 'Stop generating and verify message is preserved, footer is visible and tooltip shown on hover', + async () => { + await chat.stopGenerating.click(); + const inputMessage = await sendMessage.messageInput.getElementContent(); + expect + .soft(inputMessage, ExpectedMessages.messageContentIsValid) + .toBe(message); - await sendMessage.sendMessageButton.hoverOver(); - const tooltipContent = await tooltip.getContent(); - expect - .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) - .toBe(ExpectedConstants.proceedReplayTooltip); + await sendMessage.sendMessageButton.hoverOver(); + const tooltipContent = await tooltip.getContent(); + expect + .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) + .toBe(ExpectedConstants.proceedReplayTooltip); - await chat.footer.waitForState({ state: 'attached' }); - }); + await chat.footer.waitForState({ state: 'attached' }); + }, + ); - await test.step('Continue replaying, refresh page and verify error appears for the least response, message is preserved, footer is visible and tooltip shown on hover', async () => { - await context.setOffline(true); - await chat.proceedReplaying(); + await dialTest.step( + 'Continue replaying, refresh page and verify error appears for the least response, message is preserved, footer is visible and tooltip shown on hover', + async () => { + await context.setOffline(true); + await chat.proceedReplaying(); - const generatedContent = await chatMessages.getLastMessageContent(); - expect - .soft(generatedContent, ExpectedMessages.errorReceivedOnReplay) - .toBe(ExpectedConstants.answerError); + const generatedContent = await chatMessages.getLastMessageContent(); + expect + .soft(generatedContent, ExpectedMessages.errorReceivedOnReplay) + .toBe(ExpectedConstants.answerError); - const inputMessage = await sendMessage.messageInput.getElementContent(); - expect - .soft(inputMessage, ExpectedMessages.messageContentIsValid) - .toBe(message); + const inputMessage = await sendMessage.messageInput.getElementContent(); + expect + .soft(inputMessage, ExpectedMessages.messageContentIsValid) + .toBe(message); - await sendMessage.sendMessageButton.hoverOver(); - const tooltipContent = await tooltip.getContent(); - expect - .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) - .toBe(ExpectedConstants.proceedReplayTooltip); + await sendMessage.sendMessageButton.hoverOver(); + const tooltipContent = await tooltip.getContent(); + expect + .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) + .toBe(ExpectedConstants.proceedReplayTooltip); + + await chat.footer.waitForState({ state: 'attached' }); + }, + ); + }, +); + +dialTest( + 'Replay function is still available if the name was edited.\n' + + 'Start replay works in renamed [Replay]chat.\n' + + 'Regenerate response in already replayed chat.\n' + + 'Continue conversation in already replayed chat', + async ({ + dialHomePage, + conversationData, + chat, + localStorageManager, + dataInjector, + chatMessages, + setTestIds, + conversations, + }) => { + setTestIds('EPMRTC-505', 'EPMRTC-506', 'EPMRTC-515', 'EPMRTC-516'); + let conversation: Conversation; + let replayConversation: Conversation; - await chat.footer.waitForState({ state: 'attached' }); - }); - }); - - test( - 'Replay function is still available if the name was edited.\n' + - 'Start replay works in renamed [Replay]chat.\n' + - 'Regenerate response in already replayed chat.\n' + - 'Continue conversation in already replayed chat', - async ({ - dialHomePage, - conversationData, - chat, - localStorageManager, - chatMessages, - setTestIds, - }) => { - setTestIds('EPMRTC-505', 'EPMRTC-506', 'EPMRTC-515', 'EPMRTC-516'); - let conversation: Conversation; - - await test.step('Prepare conversation to replay with updated name', async () => { + await dialTest.step( + 'Prepare conversation to replay with updated name', + async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( gpt35Model, - ['1+2='], + ['1+2'], ); - const replayConversation = + replayConversation = conversationData.prepareDefaultReplayConversation(conversation); replayConversation.name = GeneratorUtil.randomString(7); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); - - await test.step('Verify "Start Replay" button is available', async () => { + ]); + await localStorageManager.setSelectedConversation(conversation); + }, + ); + + await dialTest.step( + 'Verify "Start Replay" button is available', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); const isStartReplayEnabled = await chat.replay.isElementEnabled(); expect .soft(isStartReplayEnabled, ExpectedMessages.startReplayVisible) .toBeTruthy(); - }); + }, + ); - await test.step('Start replaying and verify replaying is in progress', async () => { + await dialTest.step( + 'Start replaying and verify replaying is in progress', + async () => { const replayRequest = await chat.startReplay( conversation.messages[0].content, true, @@ -707,19 +826,25 @@ test.describe('Chat replay tests', () => { expect .soft(replayRequest.modelId, ExpectedMessages.chatRequestModelIsValid) .toBe(conversation.model.id); - }); + }, + ); - await test.step('Regenerate response and verify it regenerated', async () => { + await dialTest.step( + 'Regenerate response and verify it regenerated', + async () => { await chat.regenerateResponse(); const messagesCount = await chatMessages.chatMessages.getElementsCount(); expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(conversation.messages.length); - }); + }, + ); - await test.step('Send a new message to chat and verify response received', async () => { - const newMessage = '2+3='; + await dialTest.step( + 'Send a new message to chat and verify response received', + async () => { + const newMessage = '2+3'; const newRequest = await chat.sendRequestWithButton(newMessage); expect .soft(newRequest.modelId, ExpectedMessages.chatRequestModelIsValid) @@ -730,118 +855,152 @@ test.describe('Chat replay tests', () => { ExpectedMessages.chatRequestMessageIsValid, ) .toBe(newMessage); - }); - }, - ); - - test('Start replay button appears in [Replay]chat if the parent chat has error in the response', async ({ + }, + ); + }, +); + +dialTest( + 'Start replay button appears in [Replay]chat if the parent chat has error in the response', + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, setTestIds, + conversations, }) => { setTestIds('EPMRTC-1312'); let errorConversation: Conversation; + let replayConversation: Conversation; - await test.step('Prepare errorConversation with error response and replay errorConversation', async () => { - errorConversation = - conversationData.prepareErrorResponseConversation(gpt35Model); - const replayConversation = - conversationData.prepareDefaultReplayConversation(errorConversation); - await localStorageManager.setConversationHistory( - errorConversation, - replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); - - await test.step('Verify "Start Replay" button is available', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - - const isStartReplayEnabled = await chat.replay.isElementEnabled(); - expect - .soft(isStartReplayEnabled, ExpectedMessages.startReplayVisible) - .toBeTruthy(); - }); - }); + await dialTest.step( + 'Prepare errorConversation with error response and replay errorConversation', + async () => { + errorConversation = + conversationData.prepareErrorResponseConversation(gpt35Model); + replayConversation = + conversationData.prepareDefaultReplayConversation(errorConversation); + await dataInjector.createConversations([ + errorConversation, + replayConversation, + ]); + await localStorageManager.setSelectedConversation(errorConversation); + }, + ); + + await dialTest.step( + 'Verify "Start Replay" button is available', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); - test(`"Replay as is" when restricted Model is used in parent chat`, async ({ + const isStartReplayEnabled = await chat.replay.isElementEnabled(); + expect + .soft(isStartReplayEnabled, ExpectedMessages.startReplayVisible) + .toBeTruthy(); + }, + ); + }, +); + +dialTest( + `"Replay as is" when restricted Model is used in parent chat`, + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, talkToSelector, setTestIds, + conversations, }) => { setTestIds('EPMRTC-1328'); let notAllowedModelConversation: Conversation; - - await test.step('Prepare conversation with not allowed model and replay for it', async () => { - notAllowedModelConversation = - conversationData.prepareDefaultConversation('not_allowed_model'); - const replayConversation = - conversationData.prepareDefaultReplayConversation( + let replayConversation: Conversation; + + await dialTest.step( + 'Prepare conversation with not allowed model and replay for it', + async () => { + notAllowedModelConversation = + conversationData.prepareDefaultConversation('not_allowed_model'); + replayConversation = conversationData.prepareDefaultReplayConversation( notAllowedModelConversation, ); - await localStorageManager.setConversationHistory( - notAllowedModelConversation, - replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); - }); + await dataInjector.createConversations([ + notAllowedModelConversation, + replayConversation, + ]); + await localStorageManager.setSelectedConversation( + notAllowedModelConversation, + ); + }, + ); - await test.step('Verify "Start Replay" button is not displayed, error is shown at the bottom', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await talkToSelector.waitForState({ state: 'attached' }); + await dialTest.step( + 'Verify "Start Replay" button is not displayed, error is shown at the bottom', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); - const isStartReplayVisible = await chat.replay.isVisible(); - expect - .soft(isStartReplayVisible, ExpectedMessages.startReplayNotVisible) - .toBeFalsy(); + await talkToSelector.waitForState({ state: 'attached' }); - const notAllowedModelError = - await chat.notAllowedModelLabel.getElementContent(); - expect - .soft( - notAllowedModelError!.trim(), - ExpectedMessages.notAllowedModelErrorDisplayed, - ) - .toBe(ExpectedConstants.notAllowedModelError); - }); + const isStartReplayVisible = await chat.replay.isVisible(); + expect + .soft(isStartReplayVisible, ExpectedMessages.startReplayNotVisible) + .toBeFalsy(); - await test.step('Select any available model and start replaying', async () => { - await talkToSelector.selectModel(gpt35Model.name); - const replayRequest = await chat.startReplay(); - expect - .soft(replayRequest.modelId, ExpectedMessages.chatRequestModelIsValid) - .toBe(gpt35Model.id); - }); - }); - - test( - `"Replay as is" in chat from 1.4 milestone.\n` + - `"Replay as is" in chat from 1.9 milestone`, - async ({ - dialHomePage, - chatBar, - setTestIds, - folderConversations, - conversationDropdownMenu, - chat, - chatHeader, - talkToSelector, - replayAsIs, - }) => { - setTestIds('EPMRTC-1330', 'EPMRTC-1332'); - const filename = GeneratorUtil.randomArrayElement([ - Import.v14AppImportedFilename, - Import.v19AppImportedFilename, - ]); + const notAllowedModelError = + await chat.notAllowedModelLabel.getElementContent(); + expect + .soft( + notAllowedModelError!.trim(), + ExpectedMessages.notAllowedModelErrorDisplayed, + ) + .toBe(ExpectedConstants.notAllowedModelError); + }, + ); - await test.step('Import conversation from old app version and send two new messages based on Titan and gpt-4 models', async () => { + await dialTest.step( + 'Select any available model and start replaying', + async () => { + await talkToSelector.selectModel(gpt35Model.name); + const replayRequest = await chat.startReplay(); + expect + .soft(replayRequest.modelId, ExpectedMessages.chatRequestModelIsValid) + .toBe(gpt35Model.id); + }, + ); + }, +); + +dialTest( + `"Replay as is" in chat from 1.4 milestone.\n` + + `"Replay as is" in chat from 1.9 milestone`, + async ({ + dialHomePage, + chatBar, + setTestIds, + folderConversations, + conversationDropdownMenu, + chat, + chatHeader, + talkToSelector, + replayAsIs, + }) => { + setTestIds('EPMRTC-1330', 'EPMRTC-1332'); + const filename = GeneratorUtil.randomArrayElement([ + Import.v14AppImportedFilename, + Import.v19AppImportedFilename, + ]); + + await dialTest.step( + 'Import conversation from old app version and send two new messages based on Titan and gpt-4 models', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -851,6 +1010,7 @@ test.describe('Chat replay tests', () => { ); await folderConversations.expandCollapseFolder( Import.oldVersionAppFolderName, + { isHttpMethodTriggered: true }, ); await folderConversations.selectFolderEntity( Import.oldVersionAppFolderName, @@ -866,9 +1026,12 @@ test.describe('Chat replay tests', () => { const newMessage = `${i}*2=`; await chat.sendRequestWithButton(newMessage); } - }); + }, + ); - await test.step('Create replay conversation based on imported and verify warning message is displayed under "Replay as is" icon', async () => { + await dialTest.step( + 'Create replay conversation based on imported and verify warning message is displayed under "Replay as is" icon', + async () => { await folderConversations.openFolderEntityDropdownMenu( Import.oldVersionAppFolderName, Import.oldVersionAppFolderChatName, @@ -900,9 +1063,12 @@ test.describe('Chat replay tests', () => { expect .soft(warningColor[0], ExpectedMessages.warningLabelColorIsValid) .toBe(Colors.textError); - }); + }, + ); - await test.step('Start replaying and verify old requests are replayed using gpt-4 model', async () => { + await dialTest.step( + 'Start replaying and verify old requests are replayed using gpt-4 model', + async () => { const requests = await chat.startReplayForDifferentModels(); for (let i = 0; i < requests.length; i++) { const modelId = i === 1 ? ModelIds.BISON_001 : ModelIds.GPT_4; @@ -910,14 +1076,18 @@ test.describe('Chat replay tests', () => { .soft(requests[i].modelId, ExpectedMessages.chatRequestModelIsValid) .toBe(modelId); } - }); - }, - ); - - test('Replay feature does not exist in menu if all the messages were cleared in the chat', async ({ + }, + ); + }, +); + +dialTest( + 'Replay feature does not exist in menu if all the messages were cleared in the chat', + async ({ dialHomePage, conversationData, localStorageManager, + dataInjector, conversations, conversationDropdownMenu, setTestIds, @@ -925,66 +1095,80 @@ test.describe('Chat replay tests', () => { setTestIds('EPMRTC-500'); let conversation: Conversation; - await test.step('Prepare empty conversation', async () => { + await dialTest.step('Prepare empty conversation', async () => { conversation = conversationData.prepareEmptyConversation(); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); }); - await test.step('Open conversation dropdown menu and verify no "Replay" option available', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations.openConversationDropdownMenu(conversation!.name); - const menuOptions = await conversationDropdownMenu.getAllMenuOptions(); - expect - .soft(menuOptions, ExpectedMessages.contextMenuOptionsValid) - .not.toContain(MenuOptions.replay); - }); - }); - - test('Chat is in replay mode if while replaying to clear all messages', async ({ + await dialTest.step( + 'Open conversation dropdown menu and verify no "Replay" option available', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.openConversationDropdownMenu(conversation!.name); + const menuOptions = await conversationDropdownMenu.getAllMenuOptions(); + expect + .soft(menuOptions, ExpectedMessages.contextMenuOptionsValid) + .not.toContain(MenuOptions.replay); + }, + ); + }, +); + +dialTest( + 'Chat is in replay mode if while replaying to clear all messages', + async ({ dialHomePage, conversationData, localStorageManager, + dataInjector, chat, chatHeader, replayAsIs, confirmationDialog, + conversations, setTestIds, }) => { setTestIds('EPMRTC-1542'); let conversation: Conversation; + let replayConversation: Conversation; - await test.step('Prepare partially replayed conversation', async () => { + await dialTest.step('Prepare partially replayed conversation', async () => { conversation = conversationData.prepareConversationWithDifferentModels([ gpt35Model, bison, gpt4Model, ]); - const replayConversation = + replayConversation = conversationData.preparePartiallyReplayedConversation(conversation); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversation, replayConversation, - ); - await localStorageManager.setSelectedConversation(replayConversation); + ]); + await localStorageManager.setSelectedConversation(conversation); }); - await test.step('Clear conversation messages and verify "Replay As Is" option, "Start replay" button are available, ', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await chatHeader.clearConversation.click(); - await confirmationDialog.confirm(); + await dialTest.step( + 'Clear conversation messages and verify "Replay As Is" option, "Start replay" button are available, ', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.selectConversation(replayConversation.name); - const isStartReplayEnabled = await chat.replay.isElementEnabled(); - expect - .soft(isStartReplayEnabled, ExpectedMessages.startReplayVisible) - .toBeTruthy(); + await chatHeader.clearConversation.click(); + await confirmationDialog.confirm(); - const replayLabel = await replayAsIs.getReplayAsIsLabelText(); - expect - .soft(replayLabel, ExpectedMessages.replayAsIsLabelIsVisible) - .toBe(ExpectedConstants.replayAsIsLabel); - }); - }); -}); + const isStartReplayEnabled = await chat.replay.isElementEnabled(); + expect + .soft(isStartReplayEnabled, ExpectedMessages.startReplayVisible) + .toBeTruthy(); + + const replayLabel = await replayAsIs.getReplayAsIsLabelText(); + expect + .soft(replayLabel, ExpectedMessages.replayAsIsLabelIsVisible) + .toBe(ExpectedConstants.replayAsIsLabel); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/sharedChatIcons.test.ts b/apps/chat-e2e/src/tests/sharedChatIcons.test.ts index 6cb0749dc1..43c9ffdc0f 100644 --- a/apps/chat-e2e/src/tests/sharedChatIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedChatIcons.test.ts @@ -1,5 +1,5 @@ import { Conversation } from '@/chat/types/chat'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, @@ -11,34 +11,32 @@ import { keys } from '@/src/ui/keyboard'; import { GeneratorUtil, ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -test.describe('Shared chat icons tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Shared icon appears in chat model icon if to click on copy icon.\n' + - 'Share chat: copy button changes.\n' + - 'Shared icon does not appear in chat model icon if to close the pop-up on X button.\n' + - 'Shared icon does not appear in chat model icon if to close the pop-up on click out of it.\n' + - 'Shared icon appears only once if to click on copy several times', - async ({ - dialHomePage, - conversations, - chatBar, - conversationDropdownMenu, - shareModal, - tooltip, - setTestIds, - }) => { - setTestIds( - 'EPMRTC-1502', - 'EPMRTC-1512', - 'EPMRTC-1505', - 'EPMRTC-1507', - 'EPMRTC-1506', - ); +dialTest.skip( + 'Shared icon appears in chat model icon if to click on copy icon.\n' + + 'Share chat: copy button changes.\n' + + 'Shared icon does not appear in chat model icon if to close the pop-up on X button.\n' + + 'Shared icon does not appear in chat model icon if to close the pop-up on click out of it.\n' + + 'Shared icon appears only once if to click on copy several times', + async ({ + dialHomePage, + conversations, + chatBar, + conversationDropdownMenu, + shareModal, + tooltip, + setTestIds, + }) => { + setTestIds( + 'EPMRTC-1502', + 'EPMRTC-1512', + 'EPMRTC-1505', + 'EPMRTC-1507', + 'EPMRTC-1506', + ); - await test.step('Open conversation dropdown menu and choose "Share" option', async () => { + await dialTest.step( + 'Open conversation dropdown menu and choose "Share" option', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -47,9 +45,12 @@ test.describe('Shared chat icons tests', () => { ExpectedConstants.newConversationTitle, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.share); - }); + }, + ); - await test.step('Hover over "Cancel" and copy buttons and verify they are highlighted with blue color', async () => { + await dialTest.step( + 'Hover over "Cancel" and copy buttons and verify they are highlighted with blue color', + async () => { await shareModal.closeButton.hoverOver(); const closeButtonColor = await shareModal.closeButton.getComputedStyleProperty(Styles.color); @@ -70,9 +71,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(copyLinkTooltip, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.copyUrlTooltip); - }); + }, + ); - await test.step('Click on "Cancel" button in modal window and verify no shared icon appears on model icon', async () => { + await dialTest.step( + 'Click on "Cancel" button in modal window and verify no shared icon appears on model icon', + async () => { await shareModal.closeButton.click(); const isArrowIconVisible = await conversations .getConversationArrowIcon(ExpectedConstants.newConversationTitle) @@ -80,9 +84,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(isArrowIconVisible, ExpectedMessages.conversationIsNotShared) .toBeFalsy(); - }); + }, + ); - await test.step('Open Share modal again, click outside modal window area and verify no shared icon appears on model icon', async () => { + await dialTest.step( + 'Open Share modal again, click outside modal window area and verify no shared icon appears on model icon', + async () => { await conversations.openConversationDropdownMenu( ExpectedConstants.newConversationTitle, ); @@ -99,9 +106,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(isArrowIconVisible, ExpectedMessages.conversationIsNotShared) .toBeFalsy(); - }); + }, + ); - await test.step('Open Share modal again, click on "Copy" button in modal window, close it and verify green shared icon appears on model icon', async () => { + await dialTest.step( + 'Open Share modal again, click on "Copy" button in modal window, close it and verify green shared icon appears on model icon', + async () => { await conversations.openConversationDropdownMenu( ExpectedConstants.newConversationTitle, ); @@ -118,9 +128,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.textAccentSecondary); - }); + }, + ); - await test.step('Open Share modal again, click on "Copy" button in modal window and verify only one green shared icon is shown on model icon', async () => { + await dialTest.step( + 'Open Share modal again, click on "Copy" button in modal window and verify only one green shared icon is shown on model icon', + async () => { await conversations.openConversationDropdownMenu( ExpectedConstants.newConversationTitle, ); @@ -133,59 +146,66 @@ test.describe('Shared chat icons tests', () => { expect .soft(arrowIconsCount, ExpectedMessages.entitiesIconsCountIsValid) .toBe(1); - }); - }, - ); + }, + ); + }, +); - test( - 'Shared icon appears in chat model icon if to copy using Ctrl+A, Ctrl+C.\n' + - 'Shared icon in chat header and response does not appear.\n' + - 'Shared icon stays in chat name if to continue the conversation.\n' + - 'Share chat: tooltip for long chat name.\n' + - 'Share chat: tooltip for URL', - async ({ - dialHomePage, - conversations, - chatHeader, - conversationDropdownMenu, - shareModal, - page, - conversationData, - localStorageManager, - chatMessages, - talkToSelector, - chat, - tooltip, - conversationSettings, - setTestIds, - }) => { - setTestIds( - 'EPMRTC-1503', - 'EPMRTC-1601', - 'EPMRTC-1514', - 'EPMRTC-1508', - 'EPMRTC-1509', - ); - let conversation: Conversation; - const conversationName = GeneratorUtil.randomString(60); +dialTest.skip( + 'Shared icon appears in chat model icon if to copy using Ctrl+A, Ctrl+C.\n' + + 'Shared icon in chat header and response does not appear.\n' + + 'Shared icon stays in chat name if to continue the conversation.\n' + + 'Share chat: tooltip for long chat name.\n' + + 'Share chat: tooltip for URL', + async ({ + dialHomePage, + conversations, + chatHeader, + conversationDropdownMenu, + shareModal, + page, + conversationData, + localStorageManager, + dataInjector, + chatMessages, + talkToSelector, + chat, + tooltip, + conversationSettings, + setTestIds, + }) => { + setTestIds( + 'EPMRTC-1503', + 'EPMRTC-1601', + 'EPMRTC-1514', + 'EPMRTC-1508', + 'EPMRTC-1509', + ); + let conversation: Conversation; + const conversationName = GeneratorUtil.randomString(60); - await test.step('Prepare default conversation', async () => { - conversation = await conversationData.prepareDefaultConversation( - ModelsUtil.getDefaultModel(), - conversationName, - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + await dialTest.step('Prepare default conversation', async () => { + conversation = await conversationData.prepareDefaultConversation( + ModelsUtil.getDefaultModel(), + conversationName, + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }); - await test.step('Open conversation dropdown menu and choose "Share" option', async () => { + await dialTest.step( + 'Open conversation dropdown menu and choose "Share" option', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu(conversation.name); await conversationDropdownMenu.selectMenuOption(MenuOptions.share); - }); + }, + ); - await test.step('Verify chat name is truncated with dots and full name is shown on hover', async () => { + await dialTest.step( + 'Verify chat name is truncated with dots and full name is shown on hover', + async () => { const chatNameOverflowProp = await shareModal.chatName.getComputedStyleProperty( Styles.overflow_wrap, @@ -208,9 +228,12 @@ test.describe('Shared chat icons tests', () => { ExpectedMessages.chatNameIsFullyVisible, ) .toBeFalsy(); - }); + }, + ); - await test.step('Verify URL is truncated with dots and full URL is shown on hover', async () => { + await dialTest.step( + 'Verify URL is truncated with dots and full URL is shown on hover', + async () => { const urlOverflowProp = await shareModal.shareLinkInput.getComputedStyleProperty( Styles.text_overflow, @@ -228,15 +251,21 @@ test.describe('Shared chat icons tests', () => { ExpectedMessages.shareLinkIsFullyVisible, ) .toBeFalsy(); - }); + }, + ); - await test.step('Set cursor in URL input and press Ctrl+A/Ctrl+C', async () => { + await dialTest.step( + 'Set cursor in URL input and press Ctrl+A/Ctrl+C', + async () => { await shareModal.shareLinkInput.click(); await page.keyboard.press(keys.ctrlPlusA); await page.keyboard.press(keys.ctrlPlusC); - }); + }, + ); - await test.step('Close modal window and verify green shared icon appears on model icon', async () => { + await dialTest.step( + 'Close modal window and verify green shared icon appears on model icon', + async () => { await shareModal.closeButton.click(); await conversations .getConversationArrowIcon(conversation.name) @@ -246,9 +275,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.textAccentSecondary); - }); + }, + ); - await test.step('Verify no shared icon shown in chat header and chat response', async () => { + await dialTest.step( + 'Verify no shared icon shown in chat header and chat response', + async () => { const isArrowIconVisibleInHeader = await chatHeader.isArrowIconVisible(); expect @@ -266,100 +298,119 @@ test.describe('Shared chat icons tests', () => { ExpectedMessages.sharedConversationIconIsNotVisible, ) .toBeFalsy(); - }); + }, + ); - await test.step('Change chat model, send a new request and verify share icon is preserved on chat bar', async () => { + await dialTest.step( + 'Change chat model, send a new request and verify share icon is preserved on chat bar', + async () => { const updatedModel = ModelsUtil.getModel(ModelIds.GPT_4)!; await chatHeader.openConversationSettingsPopup(); await talkToSelector.waitForState(); await talkToSelector.selectModel(updatedModel.name); await chat.applyNewEntity(updatedModel.iconUrl); await conversationSettings.waitForState({ state: 'hidden' }); - await chat.sendRequestWithButton('1+2=', false); + await chat.sendRequestWithButton('1+2', false); await conversations .getConversationArrowIcon(conversation.name) .waitFor(); - }); - }, - ); + }, + ); + }, +); - test('Shared icon does not appear in chat model icon if to create replay or playback', async ({ +dialTest.skip( + 'Shared icon does not appear in chat model icon if to create replay or playback', + async ({ dialHomePage, conversations, conversationData, conversationDropdownMenu, localStorageManager, + dataInjector, setTestIds, }) => { setTestIds('EPMRTC-1510'); let conversation: Conversation; - await test.step('Prepare shared conversation', async () => { + await dialTest.step('Prepare shared conversation', async () => { conversation = conversationData.prepareDefaultSharedConversation(); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); }); - await test.step('Create replay and playback conversations based on shared one and verify no arrow icon is shown for them', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await conversations.openConversationDropdownMenu(conversation.name); - await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); - await conversations.openConversationDropdownMenu(conversation.name, 2); - await conversationDropdownMenu.selectMenuOption(MenuOptions.playback); + await dialTest.step( + 'Create replay and playback conversations based on shared one and verify no arrow icon is shown for them', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await conversations.openConversationDropdownMenu(conversation.name); + await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); + await conversations.openConversationDropdownMenu(conversation.name, 2); + await conversationDropdownMenu.selectMenuOption(MenuOptions.playback); - for (const chatName of [ - `${ExpectedConstants.replayConversation}${conversation.name}`, - `${ExpectedConstants.playbackConversation}${conversation.name}`, - ]) { - const isArrowIconVisible = await conversations - .getConversationArrowIcon(chatName) - .isVisible(); - expect - .soft(isArrowIconVisible, ExpectedMessages.conversationIsNotShared) - .toBeFalsy(); - } - }); - }); + for (const chatName of [ + `${ExpectedConstants.replayConversation}${conversation.name}`, + `${ExpectedConstants.playbackConversation}${conversation.name}`, + ]) { + const isArrowIconVisible = await conversations + .getConversationArrowIcon(chatName) + .isVisible(); + expect + .soft(isArrowIconVisible, ExpectedMessages.conversationIsNotShared) + .toBeFalsy(); + } + }, + ); + }, +); - test( - 'Shared icon is blue in Select conversation to compare.\n' + - 'Share chat: tooltip on shared model icon', - async ({ - dialHomePage, - conversations, - conversationData, - conversationDropdownMenu, - localStorageManager, - compareConversationSelector, - tooltip, - setTestIds, - }) => { - setTestIds('EPMRTC-1600', 'EPMRTC-1511'); - let notSharedConversation: Conversation; - let sharedConversation: Conversation; +dialTest.skip( + 'Shared icon is blue in Select conversation to compare.\n' + + 'Share chat: tooltip on shared model icon', + async ({ + dialHomePage, + conversations, + conversationData, + conversationDropdownMenu, + localStorageManager, + dataInjector, + compareConversationSelector, + tooltip, + compareConversation, + setTestIds, + }) => { + setTestIds('EPMRTC-1600', 'EPMRTC-1511'); + let notSharedConversation: Conversation; + let sharedConversation: Conversation; - await test.step('Prepare one shared and one not shared conversations', async () => { + await dialTest.step( + 'Prepare one shared and one not shared conversations', + async () => { notSharedConversation = conversationData.prepareDefaultConversation(); conversationData.resetData(); sharedConversation = conversationData.prepareDefaultSharedConversation(); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ notSharedConversation, sharedConversation, - ); + ]); await localStorageManager.setSelectedConversation( notSharedConversation, ); - }); + }, + ); - await test.step('Open Compare mode for not shared conversation and verify shared conversation has blue arrow in Compare dropdown list', async () => { + await dialTest.step( + 'Open Compare mode for not shared conversation and verify shared conversation has blue arrow in Compare dropdown list', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu( notSharedConversation.name, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); + await compareConversation.checkShowAllConversations(); await compareConversationSelector.click(); await compareConversationSelector .getOptionAdditionalIcon(sharedConversation.name) @@ -371,9 +422,12 @@ test.describe('Shared chat icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.controlsBackgroundAccent); - }); + }, + ); - await test.step('Hover over arrow in the dropdown list option and verify tooltop shown', async () => { + await dialTest.step( + 'Hover over arrow in the dropdown list option and verify tooltip shown', + async () => { await compareConversationSelector .getOptionAdditionalIcon(sharedConversation.name) .hover(); @@ -381,7 +435,7 @@ test.describe('Shared chat icons tests', () => { expect .soft(tooltipChatName, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.sharedConversationTooltip); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts index ed591c5b15..a8003ab5c3 100644 --- a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts @@ -1,47 +1,48 @@ import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages, MenuOptions } from '@/src/testData'; import { Colors } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; import { GeneratorUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -test.describe('Shared prompt icons tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Shared icon appears in prompt icon if to click on copy icon.\n' + - 'Shared icon does not appear in prompt icon if to close the pop-up on X button.\n' + - 'Shared icon does not appear in prompt icon if to close the pop-up on click out of it.\n' + - 'Share icon appears in prompt icon only once if to click on copy several times', - async ({ - dialHomePage, - promptData, - prompts, - localStorageManager, - promptBar, - promptDropdownMenu, - shareModal, - setTestIds, - }) => { - setTestIds('EPMRTC-1517', 'EPMRTC-1520', 'EPMRTC-1521', 'EPMRTC-1523'); - let prompt: Prompt; - await test.step('Prepare a new prompt', async () => { - prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); - }); +dialTest.skip( + 'Shared icon appears in prompt icon if to click on copy icon.\n' + + 'Shared icon does not appear in prompt icon if to close the pop-up on X button.\n' + + 'Shared icon does not appear in prompt icon if to close the pop-up on click out of it.\n' + + 'Share icon appears in prompt icon only once if to click on copy several times', + async ({ + dialHomePage, + promptData, + prompts, + dataInjector, + promptBar, + promptDropdownMenu, + shareModal, + setTestIds, + }) => { + setTestIds('EPMRTC-1517', 'EPMRTC-1520', 'EPMRTC-1521', 'EPMRTC-1523'); + let prompt: Prompt; + await dialTest.step('Prepare a new prompt', async () => { + prompt = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt]); + }); - await test.step('Open prompt dropdown menu and choose "Share" option', async () => { + await dialTest.step( + 'Open prompt dropdown menu and choose "Share" option', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, }); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.share); - }); + }, + ); - await test.step('Click on "Cancel" button in modal window and verify no shared icon appears on prompt icon', async () => { + await dialTest.step( + 'Click on "Cancel" button in modal window and verify no shared icon appears on prompt icon', + async () => { await shareModal.closeButton.click(); const isArrowIconVisible = await prompts .getPromptArrowIcon(prompt.name) @@ -49,9 +50,12 @@ test.describe('Shared prompt icons tests', () => { expect .soft(isArrowIconVisible, ExpectedMessages.promptIsNotShared) .toBeFalsy(); - }); + }, + ); - await test.step('Open Share modal again, click outside modal window area and verify no shared icon appears on prompt icon', async () => { + await dialTest.step( + 'Open Share modal again, click outside modal window area and verify no shared icon appears on prompt icon', + async () => { await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.share); await promptBar.draggableArea.click({ force: true }); @@ -66,9 +70,12 @@ test.describe('Shared prompt icons tests', () => { expect .soft(isArrowIconVisible, ExpectedMessages.promptIsNotShared) .toBeFalsy(); - }); + }, + ); - await test.step('Open Share modal again, click on "Copy" button in modal window, close it and purple shared icon appears on prompt icon', async () => { + await dialTest.step( + 'Open Share modal again, click on "Copy" button in modal window, close it and purple shared icon appears on prompt icon', + async () => { await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.share); await shareModal.copyLinkButton.click(); @@ -80,9 +87,12 @@ test.describe('Shared prompt icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.textSecondary); - }); + }, + ); - await test.step('Open Share modal again, click on "Copy" button in modal window and verify only one purple shared icon is shown on prompt icon', async () => { + await dialTest.step( + 'Open Share modal again, click on "Copy" button in modal window and verify only one purple shared icon is shown on prompt icon', + async () => { await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.share); await shareModal.copyLinkButton.click(); @@ -93,45 +103,54 @@ test.describe('Shared prompt icons tests', () => { expect .soft(arrowIconsCount, ExpectedMessages.entitiesIconsCountIsValid) .toBe(1); - }); - }, - ); + }, + ); + }, +); - test( - 'Shared icon appears in prompt icon if to copy using Ctrl+A, Ctrl+C.\n' + - 'Shared icon stays in prompt icon if to update the prompt.\n', - async ({ - dialHomePage, - prompts, - promptDropdownMenu, - shareModal, - page, - promptData, - localStorageManager, - promptModalDialog, - setTestIds, - }) => { - setTestIds('EPMRTC-1518', 'EPMRTC-1524'); - let prompt: Prompt; - await test.step('Prepare a new prompt', async () => { - prompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setPrompts(prompt); - }); +dialTest.skip( + 'Shared icon appears in prompt icon if to copy using Ctrl+A, Ctrl+C.\n' + + 'Shared icon stays in prompt icon if to update the prompt.\n', + async ({ + dialHomePage, + prompts, + promptDropdownMenu, + shareModal, + page, + promptData, + dataInjector, + promptModalDialog, + setTestIds, + }) => { + setTestIds('EPMRTC-1518', 'EPMRTC-1524'); + let prompt: Prompt; + await dialTest.step('Prepare a new prompt', async () => { + prompt = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt]); + }); - await test.step('Open prompt dropdown menu and choose "Share" option', async () => { + await dialTest.step( + 'Open prompt dropdown menu and choose "Share" option', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.share); - }); + }, + ); - await test.step('Set cursor in URL input and press Ctrl+A/Ctrl+C', async () => { + await dialTest.step( + 'Set cursor in URL input and press Ctrl+A/Ctrl+C', + async () => { await shareModal.shareLinkInput.click(); await page.keyboard.press(keys.ctrlPlusA); await page.keyboard.press(keys.ctrlPlusC); - }); + }, + ); - await test.step('Close modal window and verify purple shared icon appears on prompt icon', async () => { + await dialTest.step( + 'Close modal window and verify purple shared icon appears on prompt icon', + async () => { await shareModal.closeButton.click(); await prompts.getPromptArrowIcon(prompt.name).waitFor(); const arrowIconColor = await prompts.getPromptArrowIconColor( @@ -140,9 +159,12 @@ test.describe('Shared prompt icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.textSecondary); - }); + }, + ); - await test.step('Update prompt details and verify shared icon stays on prompt icon', async () => { + await dialTest.step( + 'Update prompt details and verify shared icon stays on prompt icon', + async () => { const newName = GeneratorUtil.randomString(10); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); @@ -156,7 +178,7 @@ test.describe('Shared prompt icons tests', () => { expect .soft(arrowIconColor[0], ExpectedMessages.sharedIconColorIsValid) .toBe(Colors.textSecondary); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/sideBarFilters.test.ts b/apps/chat-e2e/src/tests/sideBarFilters.test.ts index 7b8ddd193e..ed0b00a3ec 100644 --- a/apps/chat-e2e/src/tests/sideBarFilters.test.ts +++ b/apps/chat-e2e/src/tests/sideBarFilters.test.ts @@ -1,8 +1,9 @@ import { Conversation } from '@/chat/types/chat'; import { FolderInterface } from '@/chat/types/folder'; import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { + ExpectedConstants, ExpectedMessages, FilterMenuOptions, FolderConversation, @@ -11,17 +12,17 @@ import { } from '@/src/testData'; import { expect } from '@playwright/test'; -test.describe('Side panel filter tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Filter "Shared by me" shows only shared chats', async ({ +dialTest.skip( + 'Filter "Shared by me" shows only shared chats', + async ({ dialHomePage, conversations, folderConversations, conversationData, + dataInjector, localStorageManager, chatFilter, + chatBar, chatFilterDropdownMenu, setTestIds, }) => { @@ -29,114 +30,136 @@ test.describe('Side panel filter tests', () => { let nestedFolders: FolderInterface[]; let nestedSharedConversations: Conversation[]; let nestedConversations: Conversation[]; - let emptyFolder: FolderInterface; let folderConversation: FolderConversation; let sharedSingleConversation: Conversation; let singleConversation: Conversation; - await test.step('Prepare nested folders and single shared and not shared conversations', async () => { - nestedFolders = conversationData.prepareNestedFolder(3); - conversationData.resetData(); - nestedSharedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); - nestedSharedConversations.map((c) => (c.isShared = true)); - conversationData.resetData(); - nestedConversations = - conversationData.prepareConversationsForNestedFolders(nestedFolders); - conversationData.resetData(); - emptyFolder = conversationData.prepareFolder(); - conversationData.resetData(); - folderConversation = conversationData.prepareFolderWithConversations(1); - conversationData.resetData(); - sharedSingleConversation = - conversationData.prepareDefaultSharedConversation(); - conversationData.resetData(); - singleConversation = conversationData.prepareDefaultConversation(); - - await localStorageManager.setFolders( - ...nestedFolders, - emptyFolder, - folderConversation.folders, - ); - await localStorageManager.setConversationHistory( - ...nestedSharedConversations, - ...nestedConversations, - ...folderConversation.conversations, - sharedSingleConversation, - singleConversation, - ); - await localStorageManager.setSelectedConversation( - sharedSingleConversation, - ); - }); - - await test.step('Open chat panel filter, check "Shared by me" option and verify only shared conversations and parent folders are shown', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name); - } - await folderConversations.expandCollapseFolder(emptyFolder.name); - await folderConversations.expandCollapseFolder( - folderConversation.folders.name, - ); - await chatFilter.openFilterDropdownMenu(); - await chatFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); + await dialTest.step( + 'Prepare nested folders and single shared and not shared conversations', + async () => { + nestedFolders = conversationData.prepareNestedFolder(3); + conversationData.resetData(); + nestedSharedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); + nestedSharedConversations.map((c) => (c.isShared = true)); + conversationData.resetData(); + nestedConversations = + conversationData.prepareConversationsForNestedFolders(nestedFolders); + conversationData.resetData(); + conversationData.resetData(); + folderConversation = conversationData.prepareFolderWithConversations(1); + conversationData.resetData(); + sharedSingleConversation = + conversationData.prepareDefaultSharedConversation(); + conversationData.resetData(); + singleConversation = conversationData.prepareDefaultConversation(); + await dataInjector.createConversations( + [ + ...nestedSharedConversations, + ...nestedConversations, + ...folderConversation.conversations, + sharedSingleConversation, + singleConversation, + ], + ...nestedFolders, + folderConversation.folders, + ); + await localStorageManager.setSelectedConversation( + sharedSingleConversation, + ); + }, + ); - const actualFilteredFolderConversations = - await folderConversations.getFolderEntitiesCount(nestedFolders[0].name); - const actualFilteredConversations = - await conversations.getTodayConversations(); - expect - .soft( - actualFilteredFolderConversations + - actualFilteredConversations.length, - ExpectedMessages.conversationsCountIsValid, - ) - .toBe(nestedSharedConversations.length + 1); + await dialTest.step( + 'Open chat panel filter, check "Shared by me" option and verify only shared conversations and parent folders are shown', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await chatBar.createNewFolder(); + for (const nestedFolder of nestedFolders) { + await folderConversations.expandCollapseFolder(nestedFolder.name, { + isHttpMethodTriggered: true, + }); + } + await folderConversations.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(1), + { isHttpMethodTriggered: true }, + ); + await folderConversations.expandCollapseFolder( + folderConversation.folders.name, + { isHttpMethodTriggered: true }, + ); + await chatFilter.openFilterDropdownMenu(); + await chatFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, + ); - const actualFilteredFoldersCount = - await folderConversations.getFoldersCount(); - expect - .soft(actualFilteredFoldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(nestedSharedConversations.length); - }); + const actualFilteredFolderConversations = + await folderConversations.getFolderEntitiesCount( + nestedFolders[0].name, + ); + const actualFilteredConversations = + await conversations.getTodayConversations(); + expect + .soft( + actualFilteredFolderConversations + + actualFilteredConversations.length, + ExpectedMessages.conversationsCountIsValid, + ) + .toBe(nestedSharedConversations.length + 1); - await test.step('Uncheck "Shared by me" option and verify all conversations and folders are shown', async () => { - await chatFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); + const actualFilteredFoldersCount = + await folderConversations.getFoldersCount(); + expect + .soft( + actualFilteredFoldersCount, + ExpectedMessages.foldersCountIsValid, + ) + .toBe(nestedSharedConversations.length); + }, + ); - let actualFolderConversationsCount = - await folderConversations.getFolderEntitiesCount(nestedFolders[0].name); - actualFolderConversationsCount += - await folderConversations.getFolderEntitiesCount( - folderConversation.folders.name, - ); - const actualConversations = await conversations.getTodayConversations(); - expect - .soft( - actualFolderConversationsCount + actualConversations.length, - ExpectedMessages.conversationsCountIsValid, - ) - .toBe( - nestedConversations.length + nestedSharedConversations.length + 3, + await dialTest.step( + 'Uncheck "Shared by me" option and verify all conversations and folders are shown', + async () => { + await chatFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, ); - const actualFoldersCount = await folderConversations.getFoldersCount(); - expect - .soft(actualFoldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(nestedSharedConversations.length + 2); - }); - }); + let actualFolderConversationsCount = + await folderConversations.getFolderEntitiesCount( + nestedFolders[0].name, + ); + actualFolderConversationsCount += + await folderConversations.getFolderEntitiesCount( + folderConversation.folders.name, + ); + const actualConversations = await conversations.getTodayConversations(); + expect + .soft( + actualFolderConversationsCount + actualConversations.length, + ExpectedMessages.conversationsCountIsValid, + ) + .toBe( + nestedConversations.length + nestedSharedConversations.length + 3, + ); + + const actualFoldersCount = await folderConversations.getFoldersCount(); + expect + .soft(actualFoldersCount, ExpectedMessages.foldersCountIsValid) + .toBe(nestedSharedConversations.length + 2); + }, + ); + }, +); - test('Filter "Shared by me" stays checked if to search chats', async ({ +dialTest.skip( + 'Filter "Shared by me" stays checked if to search chats', + async ({ dialHomePage, conversations, conversationData, - localStorageManager, + dataInjector, chatFilter, chatFilterDropdownMenu, chatBarSearch, @@ -146,153 +169,184 @@ test.describe('Side panel filter tests', () => { const testConversations: Conversation[] = []; const searchTerm = 'test'; - await test.step('Prepare 3 conversations with common name and share two of them', async () => { - for (let i = 1; i <= 3; i++) { - const conversation = conversationData.prepareDefaultConversation( - ModelIds.GPT_3_5_TURBO, - `${searchTerm}${i}`, - ); - if (i !== 3) { - conversation.isShared = true; + await dialTest.step( + 'Prepare 3 conversations with common name and share two of them', + async () => { + for (let i = 1; i <= 3; i++) { + const conversation = conversationData.prepareDefaultConversation( + ModelIds.GPT_3_5_TURBO, + `${searchTerm}${i}`, + ); + if (i !== 3) { + conversation.isShared = true; + } + testConversations.push(conversation); + conversationData.resetData(); } - testConversations.push(conversation); - conversationData.resetData(); - } - await localStorageManager.setConversationHistory(...testConversations); - }); + await dataInjector.createConversations(testConversations); + }, + ); - await test.step('Open chat panel filter, check "Shared by me" option, set search term and verify only matched shared conversations are shown', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await chatFilter.openFilterDropdownMenu(); - await chatFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); - await chatBarSearch.setSearchValue(searchTerm); + await dialTest.step( + 'Open chat panel filter, check "Shared by me" option, set search term and verify only matched shared conversations are shown', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await chatFilter.openFilterDropdownMenu(); + await chatFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, + ); + await chatBarSearch.setSearchValue(searchTerm); - const filteredConversations = await conversations.getTodayConversations(); - expect - .soft( - filteredConversations.length, - ExpectedMessages.conversationsCountIsValid, - ) - .toBe(2); - }); - }); + const filteredConversations = + await conversations.getTodayConversations(); + expect + .soft( + filteredConversations.length, + ExpectedMessages.conversationsCountIsValid, + ) + .toBe(2); + }, + ); + }, +); - test('Filter "Shared by me" shows only shared prompts', async ({ +dialTest.skip( + 'Filter "Shared by me" shows only shared prompts', + async ({ dialHomePage, prompts, folderPrompts, promptData, - localStorageManager, + dataInjector, promptFilter, promptFilterDropdownMenu, + promptBar, setTestIds, }) => { setTestIds('EPMRTC-1635'); let nestedFolders: FolderInterface[]; let nestedSharedPrompts: Prompt[]; let nestedPrompts: Prompt[]; - let emptyFolder: FolderInterface; let folderPrompt: FolderPrompt; let sharedSinglePrompt: Prompt; let singlePrompt: Prompt; - await test.step('Prepare nested folders and single shared and not shared prompts', async () => { - nestedFolders = promptData.prepareNestedFolder(3); - promptData.resetData(); - nestedSharedPrompts = - promptData.preparePromptsForNestedFolders(nestedFolders); - nestedSharedPrompts.map((p) => (p.isShared = true)); - promptData.resetData(); - nestedPrompts = promptData.preparePromptsForNestedFolders(nestedFolders); - promptData.resetData(); - emptyFolder = promptData.prepareFolder(); - promptData.resetData(); - folderPrompt = promptData.preparePromptsInFolder(1); - promptData.resetData(); - sharedSinglePrompt = promptData.prepareDefaultSharedPrompt(); - promptData.resetData(); - singlePrompt = promptData.prepareDefaultPrompt(); + await dialTest.step( + 'Prepare nested folders and single shared and not shared prompts', + async () => { + nestedFolders = promptData.prepareNestedFolder(3); + promptData.resetData(); + nestedSharedPrompts = + promptData.preparePromptsForNestedFolders(nestedFolders); + nestedSharedPrompts.map((p) => (p.isShared = true)); + promptData.resetData(); + nestedPrompts = + promptData.preparePromptsForNestedFolders(nestedFolders); + promptData.resetData(); + folderPrompt = promptData.preparePromptsInFolder(1); + promptData.resetData(); + sharedSinglePrompt = promptData.prepareDefaultSharedPrompt(); + promptData.resetData(); + singlePrompt = promptData.prepareDefaultPrompt(); - await localStorageManager.setFolders( - ...nestedFolders, - emptyFolder, - folderPrompt.folders, - ); - await localStorageManager.setPrompts( - ...nestedSharedPrompts, - ...nestedPrompts, - ...folderPrompt.prompts, - sharedSinglePrompt, - singlePrompt, - ); - }); + await dataInjector.createPrompts( + [ + ...nestedSharedPrompts, + ...nestedPrompts, + ...folderPrompt.prompts, + sharedSinglePrompt, + singlePrompt, + ], + ...nestedFolders, + folderPrompt.folders, + ); + }, + ); - await test.step('Open prompt panel filter, check "Shared by me" option and verify only shared prompts and parent folders are shown', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - for (const nestedFolder of nestedFolders) { - await folderPrompts.expandCollapseFolder(nestedFolder.name); - } - await folderPrompts.expandCollapseFolder(emptyFolder.name); - await folderPrompts.expandCollapseFolder(folderPrompt.folders.name); - await promptFilter.openFilterDropdownMenu(); - await promptFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); + await dialTest.step( + 'Open prompt panel filter, check "Shared by me" option and verify only shared prompts and parent folders are shown', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await promptBar.createNewFolder(); + for (const nestedFolder of nestedFolders) { + await folderPrompts.expandCollapseFolder(nestedFolder.name); + } + await folderPrompts.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + await folderPrompts.expandCollapseFolder(folderPrompt.folders.name); + await promptFilter.openFilterDropdownMenu(); + await promptFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, + ); - const actualFilteredNestedFolderPromptsCount = - await folderPrompts.getFolderEntitiesCount(nestedFolders[0].name); - const actualFilteredSingleFolderPromptsCount = - await folderPrompts.getFolderEntitiesCount(folderPrompt.folders.name); - const actualFilteredPromptsCount = await prompts.getPromptsCount(); - expect - .soft( - actualFilteredNestedFolderPromptsCount + - actualFilteredSingleFolderPromptsCount + - actualFilteredPromptsCount, - ExpectedMessages.promptsCountIsValid, - ) - .toBe(nestedSharedPrompts.length + 1); + const actualFilteredNestedFolderPromptsCount = + await folderPrompts.getFolderEntitiesCount(nestedFolders[0].name); + const actualFilteredSingleFolderPromptsCount = + await folderPrompts.getFolderEntitiesCount(folderPrompt.folders.name); + const actualFilteredPromptsCount = await prompts.getPromptsCount(); + expect + .soft( + actualFilteredNestedFolderPromptsCount + + actualFilteredSingleFolderPromptsCount + + actualFilteredPromptsCount, + ExpectedMessages.promptsCountIsValid, + ) + .toBe(nestedSharedPrompts.length + 1); - const actualFilteredFoldersCount = await folderPrompts.getFoldersCount(); - expect - .soft(actualFilteredFoldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(nestedSharedPrompts.length); - }); + const actualFilteredFoldersCount = + await folderPrompts.getFoldersCount(); + expect + .soft( + actualFilteredFoldersCount, + ExpectedMessages.foldersCountIsValid, + ) + .toBe(nestedSharedPrompts.length); + }, + ); - await test.step('Uncheck "Shared by me" option and verify all prompts and folders are shown', async () => { - await promptFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); - const actualFilteredNestedFolderPromptsCount = - await folderPrompts.getFolderEntitiesCount(nestedFolders[0].name); - const actualFilteredSingleFolderPromptsCount = - await folderPrompts.getFolderEntitiesCount(folderPrompt.folders.name); - const actualPromptsCount = await prompts.getPromptsCount(); - expect - .soft( - actualFilteredNestedFolderPromptsCount + - actualFilteredSingleFolderPromptsCount + - actualPromptsCount, - ExpectedMessages.promptsCountIsValid, - ) - .toBe(nestedPrompts.length + nestedSharedPrompts.length + 3); + await dialTest.step( + 'Uncheck "Shared by me" option and verify all prompts and folders are shown', + async () => { + await promptFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, + ); + const actualFilteredNestedFolderPromptsCount = + await folderPrompts.getFolderEntitiesCount(nestedFolders[0].name); + const actualFilteredSingleFolderPromptsCount = + await folderPrompts.getFolderEntitiesCount(folderPrompt.folders.name); + const actualPromptsCount = await prompts.getPromptsCount(); + expect + .soft( + actualFilteredNestedFolderPromptsCount + + actualFilteredSingleFolderPromptsCount + + actualPromptsCount, + ExpectedMessages.promptsCountIsValid, + ) + .toBe(nestedPrompts.length + nestedSharedPrompts.length + 3); - const actualFoldersCount = await folderPrompts.getFoldersCount(); - expect - .soft(actualFoldersCount, ExpectedMessages.foldersCountIsValid) - .toBe(nestedSharedPrompts.length + 2); - }); - }); + const actualFoldersCount = await folderPrompts.getFoldersCount(); + expect + .soft(actualFoldersCount, ExpectedMessages.foldersCountIsValid) + .toBe(nestedSharedPrompts.length + 2); + }, + ); + }, +); - test('Filter "Shared by me" stays checked if to search prompts', async ({ +dialTest.skip( + 'Filter "Shared by me" stays checked if to search prompts', + async ({ dialHomePage, prompts, promptData, - localStorageManager, + dataInjector, promptFilter, promptFilterDropdownMenu, promptBarSearch, @@ -302,31 +356,39 @@ test.describe('Side panel filter tests', () => { const testPrompts: Prompt[] = []; const searchTerm = 'test'; - await test.step('Prepare 3 prompts with common name and share two of them', async () => { - for (let i = 1; i <= 3; i++) { - const prompt = promptData.prepareDefaultPrompt(`${searchTerm}${i}`); - if (i !== 3) { - prompt.isShared = true; + await dialTest.step( + 'Prepare 3 prompts with common name and share two of them', + async () => { + for (let i = 1; i <= 3; i++) { + const prompt = promptData.prepareDefaultPrompt(`${searchTerm}${i}`); + if (i !== 3) { + prompt.isShared = true; + } + testPrompts.push(prompt); + promptData.resetData(); } - testPrompts.push(prompt); - promptData.resetData(); - } - await localStorageManager.setPrompts(...testPrompts); - }); + await dataInjector.createPrompts(testPrompts); + }, + ); - await test.step('Open prompt panel filter, check "Shared by me" option, set search term and verify only matched shared prompts are shown', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await promptFilter.openFilterDropdownMenu(); - await promptFilterDropdownMenu.selectMenuOption( - FilterMenuOptions.sharedByMe, - ); - await promptBarSearch.setSearchValue(searchTerm); + await dialTest.step( + 'Open prompt panel filter, check "Shared by me" option, set search term and verify only matched shared prompts are shown', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await promptFilter.openFilterDropdownMenu(); + await promptFilterDropdownMenu.selectMenuOption( + FilterMenuOptions.sharedByMe, + ); + await promptBarSearch.setSearchValue(searchTerm); - const filteredPromptsCount = await prompts.getPromptsCount(); - expect - .soft(filteredPromptsCount, ExpectedMessages.promptsCountIsValid) - .toBe(2); - }); - }); -}); + const filteredPromptsCount = await prompts.getPromptsCount(); + expect + .soft(filteredPromptsCount, ExpectedMessages.promptsCountIsValid) + .toBe(2); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index ac2726b6e7..470e7fa093 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -1,9 +1,10 @@ import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; import { Prompt } from '@/chat/types/prompt'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { + ExpectedConstants, ExpectedMessages, FolderConversation, FolderPrompt, @@ -13,19 +14,17 @@ import { ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; let gpt35Model: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { gpt35Model = ModelsUtil.getDefaultModel()!; }); -test.describe('Side panel drag and drop tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Chat is moved from the folder via drag&drop', async ({ +dialTest( + 'Chat is moved from the folder via drag&drop', + async ({ dialHomePage, conversationData, folderConversations, - localStorageManager, + dataInjector, conversations, chatBar, page, @@ -34,12 +33,9 @@ test.describe('Side panel drag and drop tests', () => { setTestIds('EPMRTC-861'); const conversationInFolder = conversationData.prepareDefaultConversationInFolder(); - await localStorageManager.setFolders(conversationInFolder.folders); - await localStorageManager.setConversationHistory( - conversationInFolder.conversations[0], - ); - await localStorageManager.setSelectedConversation( - conversationInFolder.conversations[0], + await dataInjector.createConversations( + conversationInFolder.conversations, + conversationInFolder.folders, ); await dialHomePage.openHomePage({ iconsToBeLoaded: [gpt35Model.iconUrl], @@ -47,6 +43,7 @@ test.describe('Side panel drag and drop tests', () => { await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, + { isHttpMethodTriggered: true }, ); await chatBar.drugConversationFromFolder( conversationInFolder.folders.name, @@ -82,67 +79,90 @@ test.describe('Side panel drag and drop tests', () => { expect .soft(folderNameColor[0], ExpectedMessages.folderNameColorIsValid) .toBe(Colors.textPrimary); - }); + }, +); - test( - 'Chat is moved using drag&drop to collapsed folder.\n' + - 'Chat is moved using drag&drop to collapsed folder', - async ({ - dialHomePage, - conversationData, - conversations, - folderConversations, - localStorageManager, - chatBar, - setTestIds, - page, - }) => { - setTestIds('EPMRTC-1599', 'EPMRTC-591'); - let nestedFolders: FolderInterface[]; - let conversationToDrop: Conversation; - let conversation: Conversation; +dialTest( + 'Chat is moved using drag&drop to collapsed folder.\n' + + 'Chat is moved using drag&drop to collapsed folder', + async ({ + dialHomePage, + conversationData, + conversations, + folderConversations, + localStorageManager, + dataInjector, + chatBar, + setTestIds, + page, + }) => { + setTestIds('EPMRTC-1599', 'EPMRTC-591'); + let conversationToDrop: Conversation; + let conversation: Conversation; - await test.step('Prepare nested folders and single conversations outside folder', async () => { - nestedFolders = conversationData.prepareNestedFolder(3); + await dialTest.step( + 'Prepare nested folders and single conversations outside folder', + async () => { conversationData.resetData(); conversationToDrop = conversationData.prepareDefaultConversation(); conversationData.resetData(); conversation = conversationData.prepareDefaultConversation(); - await localStorageManager.setFolders(...nestedFolders); - await localStorageManager.setConversationHistory( + await dataInjector.createConversations([ conversationToDrop, conversation, - ); + ]); await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); - await test.step('Open app, drag conversation to collapsed folder and verify folders hierarchy is expanded, background is highlighted', async () => { + await dialTest.step( + 'Open app, drag conversation to collapsed folder and verify folders hierarchy is expanded, background is highlighted', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); - for (const nestedFolder of [ - nestedFolders[0], - nestedFolders[1], - nestedFolders[2], - ]) { - await folderConversations.expandCollapseFolder(nestedFolder.name); + for (let i = 1; i <= 3; i++) { + await chatBar.createNewFolder(); + } + for (let i = 3; i >= 2; i--) { + await chatBar.dragAndDropEntityToFolder( + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i), + ), + folderConversations.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(i - 1), + ), + ); } + await folderConversations.expandCollapseFolder( + ExpectedConstants.newFolderWithIndexTitle(2), + { isHttpMethodTriggered: true }, + ); + await chatBar.drugConversationToFolder( - nestedFolders[0].name, + ExpectedConstants.newFolderWithIndexTitle(1), conversationToDrop.name, ); await folderConversations.waitForFolderGroupIsHighlighted( - nestedFolders[0].name, + ExpectedConstants.newFolderWithIndexTitle(1), ); - for (const folder of nestedFolders) { - await folderConversations.getFolderByName(folder.name).waitFor(); + for (let i = 1; i <= 3; i++) { + await folderConversations + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(i)) + .waitFor(); } await page.mouse.up(); - }); + }, + ); - await test.step('Verify conversation is moving to root folder, another conversation remained selected', async () => { + await dialTest.step( + 'Verify conversation is moving to root folder, another conversation remained selected', + async () => { await folderConversations - .getFolderEntity(nestedFolders[0].name, conversationToDrop.name) + .getFolderEntity( + ExpectedConstants.newFolderWithIndexTitle(1), + conversationToDrop.name, + ) .waitFor(); const conversationBackgroundColor = await conversations.getConversationBackgroundColor(conversation.name); @@ -152,14 +172,18 @@ test.describe('Side panel drag and drop tests', () => { ExpectedMessages.conversationIsSelected, ) .toBe(Colors.backgroundAccentSecondary); - }); - }, - ); + }, + ); + }, +); - test('Chat is moved using drag&drop to expanded folder', async ({ +dialTest( + 'Chat is moved using drag&drop to expanded folder', + async ({ dialHomePage, conversationData, folderConversations, + dataInjector, localStorageManager, chatBar, setTestIds, @@ -168,61 +192,72 @@ test.describe('Side panel drag and drop tests', () => { let folderConversation: FolderConversation; let conversationToDrop: Conversation; - await test.step('Prepare folder with 2 conversation inside and 2 single conversations outside folder', async () => { - folderConversation = conversationData.prepareFolderWithConversations(2); - conversationData.resetData(); - conversationToDrop = conversationData.prepareDefaultConversation(); - - await localStorageManager.setFolders(folderConversation.folders); - await localStorageManager.setConversationHistory( - ...folderConversation.conversations, - conversationToDrop, - ); - await localStorageManager.setSelectedConversation(conversationToDrop); - }); + await dialTest.step( + 'Prepare folder with 2 conversation inside and 2 single conversations outside folder', + async () => { + folderConversation = conversationData.prepareFolderWithConversations(2); + conversationData.resetData(); + conversationToDrop = conversationData.prepareDefaultConversation(); - await test.step('Open app, drag 1st conversation to expanded folder conversation and verify conversation stays in the folder, folder remains expanded, folder name is highlighted', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await folderConversations.expandCollapseFolder( - folderConversation.folders.name, - ); - await chatBar.drugAndDropConversationToFolderConversation( - folderConversation.folders.name, - folderConversation.conversations[1].name, - conversationToDrop.name, - ); + await dataInjector.createConversations( + [...folderConversation.conversations, conversationToDrop], + folderConversation.folders, + ); + await localStorageManager.setSelectedConversation(conversationToDrop); + }, + ); - const folderConversationsCount = - await folderConversations.getFolderEntitiesCount( + await dialTest.step( + 'Open app, drag 1st conversation to expanded folder conversation and verify conversation stays in the folder, folder remains expanded, folder name is highlighted', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await folderConversations.expandCollapseFolder( + folderConversation.folders.name, + { isHttpMethodTriggered: true }, + ); + await chatBar.drugAndDropConversationToFolderConversation( folderConversation.folders.name, + folderConversation.conversations[1].name, + conversationToDrop.name, ); - expect - .soft(folderConversationsCount, ExpectedMessages.folderIsHighlighted) - .toBe(folderConversation.conversations.length + 1); - const folderNameColor = await folderConversations.getFolderNameColor( - folderConversation.folders.name, - ); - expect - .soft(folderNameColor[0], ExpectedMessages.folderNameColorIsValid) - .toBe(Colors.textAccentSecondary); - }); - }); + const folderConversationsCount = + await folderConversations.getFolderEntitiesCount( + folderConversation.folders.name, + ); + expect + .soft(folderConversationsCount, ExpectedMessages.folderIsHighlighted) + .toBe(folderConversation.conversations.length + 1); - test('Prompt is moved out of the folder via drag&drop', async ({ + const folderNameColor = await folderConversations.getFolderNameColor( + folderConversation.folders.name, + ); + expect + .soft(folderNameColor[0], ExpectedMessages.folderNameColorIsValid) + .toBe(Colors.textAccentSecondary); + }, + ); + }, +); + +dialTest( + 'Prompt is moved out of the folder via drag&drop', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, prompts, promptBar, setTestIds, }) => { setTestIds('EPMRTC-961'); const promptInFolder = promptData.prepareDefaultPromptInFolder(); - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(promptInFolder.prompts[0]); + await dataInjector.createPrompts( + promptInFolder.prompts, + promptInFolder.folders, + ); await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); @@ -245,48 +280,87 @@ test.describe('Side panel drag and drop tests', () => { .getPromptByName(promptInFolder.prompts[0].name) .isVisible(); expect.soft(isPromptVisible, ExpectedMessages.promptIsVisible).toBeTruthy(); - }); + }, +); - test('Prompt is moved using drag&drop to collapsed folder', async ({ +dialTest( + 'Prompt is moved using drag&drop to collapsed folder', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, promptBar, page, setTestIds, }) => { setTestIds('EPMRTC-959'); - let folders: FolderInterface[]; let prompt: Prompt; - await test.step('Prepare nested folders and prompt outside folder', async () => { - folders = promptData.prepareNestedFolder(1); - promptData.resetData(); - prompt = promptData.prepareDefaultPrompt(); + await dialTest.step( + 'Prepare nested folders and prompt outside folder', + async () => { + prompt = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt]); + }, + ); - await localStorageManager.setFolders(...folders); - await localStorageManager.setPrompts(prompt); - }); + await dialTest.step( + 'Drag and drop prompt to root folder name and verify folder is highlighted, prompt stays inside folder, folder is expanded', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + for (let i = 1; i <= 2; i++) { + await promptBar.createNewFolder(); + } + await promptBar.dragAndDropEntityToFolder( + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(2), + ), + folderPrompts.getFolderByName( + ExpectedConstants.newFolderWithIndexTitle(1), + ), + ); - await test.step('Drag and drop prompt to root folder name and verify folder is highlighted, prompt stays inside folder, folder is expanded', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await promptBar.drugPromptToFolder(folders[0].name, prompt.name); - await folderPrompts.getFolderByName(folders[1].name).waitFor(); - await folderPrompts.waitForFolderGroupIsHighlighted(folders[0].name); - await page.mouse.up(); - await folderPrompts - .getFolderEntity(folders[0].name, prompt.name) - .waitFor(); - }); - }); + await promptBar.drugPromptToFolder( + ExpectedConstants.newFolderWithIndexTitle(1), + prompt.name, + ); + await folderPrompts + .getFolderByName(ExpectedConstants.newFolderWithIndexTitle(2)) + .waitFor(); + await folderPrompts.waitForFolderGroupIsHighlighted( + ExpectedConstants.newFolderWithIndexTitle(1), + ); + if (isApiStorageType) { + const respPromise = page.waitForResponse((resp) => { + return resp.request().method() === 'PUT'; + }); + await page.mouse.up(); + return respPromise; + } else { + await page.mouse.up(); + } + await folderPrompts + .getFolderEntity( + ExpectedConstants.newFolderWithIndexTitle(1), + prompt.name, + ) + .waitFor(); + }, + ); + }, +); - test('Prompt is moved using drag&drop to expanded folder', async ({ +dialTest( + 'Prompt is moved using drag&drop to expanded folder', + async ({ dialHomePage, promptData, folderPrompts, - localStorageManager, + dataInjector, promptBar, setTestIds, }) => { @@ -294,27 +368,36 @@ test.describe('Side panel drag and drop tests', () => { let promptInFolder: FolderPrompt; let prompt: Prompt; - await test.step('Prepare folder with prompt and prompt outside folder', async () => { - promptInFolder = promptData.preparePromptsInFolder(1); - promptData.resetData(); - prompt = promptData.prepareDefaultPrompt(); - - await localStorageManager.setFolders(promptInFolder.folders); - await localStorageManager.setPrompts(...promptInFolder.prompts, prompt); - }); + await dialTest.step( + 'Prepare folder with prompt and prompt outside folder', + async () => { + promptInFolder = promptData.preparePromptsInFolder(1); + promptData.resetData(); + prompt = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts( + [...promptInFolder.prompts, prompt], + promptInFolder.folders, + ); + }, + ); - await test.step('Drag and drop prompt to prompt inside folder and verify prompt stays inside folder, folder remains expanded', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); - await promptBar.drugAndDropPromptToFolderPrompt( - promptInFolder.folders.name, - promptInFolder.prompts[0].name, - prompt.name, - ); - await folderPrompts - .getFolderEntity(promptInFolder.folders.name, prompt.name) - .waitFor(); - }); - }); -}); + await dialTest.step( + 'Drag and drop prompt to prompt inside folder and verify prompt stays inside folder, folder remains expanded', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); + await promptBar.drugAndDropPromptToFolderPrompt( + promptInFolder.folders.name, + promptInFolder.prompts[0].name, + prompt.name, + ); + await folderPrompts + .getFolderEntity(promptInFolder.folders.name, prompt.name) + .waitFor(); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/sidePanels.test.ts b/apps/chat-e2e/src/tests/sidePanels.test.ts index 69029c0f05..2e6d87f8df 100644 --- a/apps/chat-e2e/src/tests/sidePanels.test.ts +++ b/apps/chat-e2e/src/tests/sidePanels.test.ts @@ -1,40 +1,38 @@ -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages } from '@/src/testData'; import { Colors, Styles } from '@/src/ui/domData'; import { expect } from '@playwright/test'; -test.describe('Side panels tests', () => { - test.use({ - storageState: stateFilePath, - }); - test( - 'Hide panel with chats.\n' + - 'Hide panel with prompts.\n' + - "Browser refresh doesn't open hidden panels", - async ({ dialHomePage, setTestIds, chatBar, header, promptBar }) => { - setTestIds('EPMRTC-352', 'EPMRTC-353', 'EPMRTC-354'); - let isChatPanelVisible; - let isPromptsPanelVisible; - - await test.step('Hide chat panel', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - await header.chatPanelToggle.click(); - isChatPanelVisible = await chatBar.isVisible(); - expect - .soft(isChatPanelVisible, ExpectedMessages.sideBarPanelIsHidden) - .toBeFalsy(); - }); +dialTest( + 'Hide panel with chats.\n' + + 'Hide panel with prompts.\n' + + "Browser refresh doesn't open hidden panels", + async ({ dialHomePage, setTestIds, chatBar, header, promptBar }) => { + setTestIds('EPMRTC-352', 'EPMRTC-353', 'EPMRTC-354'); + let isChatPanelVisible; + let isPromptsPanelVisible; - await test.step('Hide prompts panel', async () => { - await header.promptsPanelToggle.click(); - isPromptsPanelVisible = await promptBar.isVisible(); - expect - .soft(isPromptsPanelVisible, ExpectedMessages.sideBarPanelIsHidden) - .toBeFalsy(); - }); + await dialTest.step('Hide chat panel', async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await header.chatPanelToggle.click(); + isChatPanelVisible = await chatBar.isVisible(); + expect + .soft(isChatPanelVisible, ExpectedMessages.sideBarPanelIsHidden) + .toBeFalsy(); + }); + + await dialTest.step('Hide prompts panel', async () => { + await header.promptsPanelToggle.click(); + isPromptsPanelVisible = await promptBar.isVisible(); + expect + .soft(isPromptsPanelVisible, ExpectedMessages.sideBarPanelIsHidden) + .toBeFalsy(); + }); - await test.step('Refresh page and verify both panels are hidden', async () => { + await dialTest.step( + 'Refresh page and verify both panels are hidden', + async () => { await dialHomePage.reloadPage(); isChatPanelVisible = await chatBar.isVisible(); isPromptsPanelVisible = await promptBar.isVisible(); @@ -46,30 +44,33 @@ test.describe('Side panels tests', () => { .soft(isPanelVisible, ExpectedMessages.sideBarPanelIsHidden) .toBeFalsy(); } - }); - }, - ); - - test( - 'Resize panels max and min size.\n' + - 'Resized panels are stored if to close/open or refresh.\n' + - 'Resize panel with chats max and min size.\n' + - 'Resize panel with prompts max and min size', - async ({ - dialHomePage, - setTestIds, - appContainer, - chatBar, - promptBar, - header, - tooltip, - }) => { - setTestIds('EPMRTC-1642', 'EPMRTC-1650', 'EPMRTC-1641', 'EPMRTC-1647'); - let appBounding; - let maxChatBarBounding; - let maxPromptBarBounding; - - await test.step('Open app, hover over resize chat panel icon and verify it is highlighted', async () => { + }, + ); + }, +); + +dialTest( + 'Resize panels max and min size.\n' + + 'Resized panels are stored if to close/open or refresh.\n' + + 'Resize panel with chats max and min size.\n' + + 'Resize panel with prompts max and min size', + async ({ + dialHomePage, + setTestIds, + appContainer, + chatBar, + promptBar, + header, + tooltip, + }) => { + setTestIds('EPMRTC-1642', 'EPMRTC-1650', 'EPMRTC-1641', 'EPMRTC-1647'); + let appBounding; + let maxChatBarBounding; + let maxPromptBarBounding; + + await dialTest.step( + 'Open app, hover over resize chat panel icon and verify it is highlighted', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); appBounding = await appContainer.getElementBoundingBox(); @@ -81,9 +82,12 @@ test.describe('Side panels tests', () => { expect .soft(iconColor[0], ExpectedMessages.iconColorIsValid) .toBe(Colors.textAccentSecondary); - }); + }, + ); - await test.step('Resize chat panel to max size and verify max width', async () => { + await dialTest.step( + 'Resize chat panel to max size and verify max width', + async () => { await chatBar.resizePanelWidth(appBounding!.width); maxChatBarBounding = await chatBar.getElementBoundingBox(); expect @@ -95,9 +99,12 @@ test.describe('Side panels tests', () => { appBounding!.width * ExpectedConstants.maxSidePanelWidthPercentage, 0, ); - }); + }, + ); - await test.step('Verify Attachment icon is visible at the panel bottom menu', async () => { + await dialTest.step( + 'Verify Attachment icon is visible at the panel bottom menu', + async () => { await chatBar.attachments.waitForState(); const isDotsMenuVisible = await chatBar.bottomDotsMenuIcon.isVisible(); expect @@ -116,9 +123,12 @@ test.describe('Side panels tests', () => { expect .soft(iconColor[0], ExpectedMessages.iconColorIsValid) .toBe(Colors.textAccentSecondary); - }); + }, + ); - await test.step('Hover over resize prompt panel icon and verify it is highlighted', async () => { + await dialTest.step( + 'Hover over resize prompt panel icon and verify it is highlighted', + async () => { await promptBar.resizeIcon.hoverOver({ force: true }); const iconColor = await promptBar.resizeIcon.getComputedStyleProperty( Styles.color, @@ -126,9 +136,12 @@ test.describe('Side panels tests', () => { expect .soft(iconColor[0], ExpectedMessages.iconColorIsValid) .toBe(Colors.textSecondary); - }); + }, + ); - await test.step('Resize prompt panel to max size and verify max width', async () => { + await dialTest.step( + 'Resize prompt panel to max size and verify max width', + async () => { await promptBar.resizePanelWidth(appBounding!.x); maxPromptBarBounding = await promptBar.getElementBoundingBox(); expect @@ -140,9 +153,12 @@ test.describe('Side panels tests', () => { appBounding!.width * ExpectedConstants.maxSidePanelWidthPercentage, 0, ); - }); + }, + ); - await test.step('Hide both panels, open again and verify panels size is stored', async () => { + await dialTest.step( + 'Hide both panels, open again and verify panels size is stored', + async () => { for (let i = 1; i <= 2; i++) { await header.chatPanelToggle.click(); await header.promptsPanelToggle.click(); @@ -163,9 +179,12 @@ test.describe('Side panels tests', () => { ExpectedMessages.sideBarPanelWidthIsValid, ) .toBeCloseTo(maxPromptBarBounding!.width, 0); - }); + }, + ); - await test.step('Refresh page and verify panels size is stored', async () => { + await dialTest.step( + 'Refresh page and verify panels size is stored', + async () => { await dialHomePage.reloadPage(); const openedChatBarPanelBounding = await chatBar.getElementBoundingBox(); @@ -183,9 +202,12 @@ test.describe('Side panels tests', () => { ExpectedMessages.sideBarPanelWidthIsValid, ) .toBeCloseTo(maxPromptBarBounding!.width, 0); - }); + }, + ); - await test.step('Resize chat panel to min size and verify min width', async () => { + await dialTest.step( + 'Resize chat panel to min size and verify min width', + async () => { await chatBar.resizePanelWidth(appBounding!.x); const chatBarBounding = await chatBar.getElementBoundingBox(); expect @@ -194,9 +216,12 @@ test.describe('Side panels tests', () => { ExpectedMessages.sideBarPanelWidthIsValid, ) .toBeCloseTo(ExpectedConstants.minSidePanelWidthPx, 0); - }); + }, + ); - await test.step('Verify dots menu is visible at the panel bottom menu', async () => { + await dialTest.step( + 'Verify dots menu is visible at the panel bottom menu', + async () => { await chatBar.bottomDotsMenuIcon.waitForState(); const isAttachmentsIconVisible = await chatBar.attachments.isVisible(); expect @@ -211,9 +236,12 @@ test.describe('Side panels tests', () => { expect .soft(dotsMenuIconColor[0], ExpectedMessages.iconColorIsValid) .toBe(Colors.controlsBackgroundDisable); - }); + }, + ); - await test.step('Resize prompt panel to min size and verify min width', async () => { + await dialTest.step( + 'Resize prompt panel to min size and verify min width', + async () => { await promptBar.resizePanelWidth(appBounding!.width); const promptBarBounding = await promptBar.getElementBoundingBox(); expect @@ -222,7 +250,7 @@ test.describe('Side panels tests', () => { ExpectedMessages.sideBarPanelWidthIsValid, ) .toBeCloseTo(ExpectedConstants.minSidePanelWidthPx, 0); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/tests/workWithModels.test.ts b/apps/chat-e2e/src/tests/workWithModels.test.ts index 3e8aff4c68..05ed15eaa1 100644 --- a/apps/chat-e2e/src/tests/workWithModels.test.ts +++ b/apps/chat-e2e/src/tests/workWithModels.test.ts @@ -1,6 +1,6 @@ import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import test, { stateFilePath } from '@/src/core/fixtures'; +import dialTest from '@/src/core/dialFixtures'; import { API, ExpectedConstants, @@ -21,20 +21,19 @@ const sysPrompt = `Type: "${expectedResponse}" if user types ${requestTerm}`; let gpt35Model: OpenAIEntityModel; let gpt4Model: OpenAIEntityModel; -test.beforeAll(async () => { +dialTest.beforeAll(async () => { gpt35Model = ModelsUtil.getModel(ModelIds.GPT_3_5_TURBO)!; gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -test.describe('Work with models tests', () => { - test.use({ - storageState: stateFilePath, - }); - test('Regenerate response when answer was received', async ({ +dialTest( + 'Regenerate response when answer was received', + async ({ dialHomePage, conversationData, chat, localStorageManager, + dataInjector, setTestIds, chatMessages, }) => { @@ -45,64 +44,74 @@ test.describe('Work with models tests', () => { 'second request', 'write down 100 adjectives', ]; - await test.step('Prepare model conversation', async () => { + await dialTest.step('Prepare model conversation', async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( gpt35Model, userRequests, ); - await localStorageManager.setConversationHistory(conversation); + await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); }); - await test.step('Regenerate response and verify only last response is regenerating', async () => { - await dialHomePage.openHomePage(); - await dialHomePage.waitForPageLoaded(); - const receivedPartialContent = await chatMessages.getGeneratedChatContent( - conversation.messages.length, - ); - await chat.regenerateResponse(false); - const preservedPartialContent = - await chatMessages.getGeneratedChatContent( - conversation.messages.length, - ); - expect - .soft( - preservedPartialContent.includes(receivedPartialContent), - ExpectedMessages.onlyLastResponseIsRegenerating, - ) - .toBeTruthy(); + await dialTest.step( + 'Regenerate response and verify only last response is regenerating', + async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + const receivedPartialContent = + await chatMessages.getGeneratedChatContent( + conversation.messages.length, + ); + await chat.regenerateResponse(false); + const preservedPartialContent = + await chatMessages.getGeneratedChatContent( + conversation.messages.length, + ); + expect + .soft( + preservedPartialContent.includes(receivedPartialContent), + ExpectedMessages.onlyLastResponseIsRegenerating, + ) + .toBeTruthy(); + }, + ); + }, +); + +dialTest( + 'Regenerate response when answer was not received.\n' + + 'Model: Send action is unavailable if there is an error instead of response', + async ({ + dialHomePage, + chat, + setTestIds, + chatMessages, + context, + sendMessage, + tooltip, + localStorageManager, + page, + }) => { + setTestIds('EPMRTC-477', 'EPMRTC-1463'); + await dialTest.step('Set random application theme', async () => { + const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); + await localStorageManager.setSettings(theme); }); - }); - - test( - 'Regenerate response when answer was not received.\n' + - 'Model: Send action is unavailable if there is an error instead of response', - async ({ - dialHomePage, - chat, - setTestIds, - chatMessages, - context, - sendMessage, - tooltip, - localStorageManager, - page, - }) => { - setTestIds('EPMRTC-477', 'EPMRTC-1463'); - await test.step('Set random application theme', async () => { - const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); - await localStorageManager.setSettings(theme); - }); - - await test.step('Send a request in chat and emulate error until response received', async () => { + + await dialTest.step( + 'Send a request in chat and emulate error until response received', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, }); await context.setOffline(true); await chat.sendRequestWithButton('Type a fairytale', false); - }); - await test.step('Verify error is displayed as a response, regenerate button is available', async () => { + }, + ); + await dialTest.step( + 'Verify error is displayed as a response, regenerate button is available', + async () => { const generatedContent = await chatMessages.getLastMessageContent(); expect .soft(generatedContent, ExpectedMessages.errorReceivedOnReplay) @@ -115,9 +124,12 @@ test.describe('Work with models tests', () => { ExpectedMessages.regenerateIsAvailable, ) .toBeTruthy(); - }); + }, + ); - await test.step('Hover over Send button and verify it is disabled and tooltip is shown', async () => { + await dialTest.step( + 'Hover over Send button and verify it is disabled and tooltip is shown', + async () => { await context.setOffline(false); for (let i = 1; i <= 2; i++) { if (i === 2) { @@ -162,9 +174,12 @@ test.describe('Work with models tests', () => { .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.regenerateResponseTooltip); } - }); + }, + ); - await test.step('Type any message, hit Enter key and verify Send button is disabled and tooltip is shown', async () => { + await dialTest.step( + 'Type any message, hit Enter key and verify Send button is disabled and tooltip is shown', + async () => { const isSendMessageBtnEnabled = await sendMessage.sendMessageButton.isElementEnabled(); expect @@ -187,44 +202,51 @@ test.describe('Work with models tests', () => { expect .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.regenerateResponseTooltip); - }); + }, + ); - await test.step('Click Regenerate response and validate answer received', async () => { + await dialTest.step( + 'Click Regenerate response and validate answer received', + async () => { await chat.regenerateResponse(false); await chatMessages.waitForPartialMessageReceived(2); const generatedContent = await chatMessages.getLastMessageContent(); expect .soft(generatedContent, ExpectedMessages.messageContentIsValid) .not.toContain(ExpectedConstants.answerError); - }); - }, - ); - - test( - 'Edit the message in the middle. Cancel.\n' + - 'Edit the message in the middle. Save & Submit.\n' + - 'Edited message can not be empty', - async ({ - dialHomePage, - conversationData, - localStorageManager, - setTestIds, - chatMessages, - }) => { - setTestIds('EPMRTC-485', 'EPMRTC-486', 'EPMRTC-487'); - const editData = 'updated message'; - let conversation: Conversation; - const userRequests = ['1+2=', '2+3=', '3+4=']; - await test.step('Prepare conversation with 3 requests', async () => { - conversation = conversationData.prepareModelConversationBasedOnRequests( - gpt35Model, - userRequests, - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); + }, +); + +dialTest( + 'Edit the message in the middle. Cancel.\n' + + 'Edit the message in the middle. Save & Submit.\n' + + 'Edited message can not be empty', + async ({ + dialHomePage, + conversationData, + localStorageManager, + dataInjector, + setTestIds, + chatMessages, + }) => { + setTestIds('EPMRTC-485', 'EPMRTC-486', 'EPMRTC-487'); + const editData = 'updated message'; + let conversation: Conversation; + const userRequests = ['1+2=', '2+3=', '3+4=']; + await dialTest.step('Prepare conversation with 3 requests', async () => { + conversation = conversationData.prepareModelConversationBasedOnRequests( + gpt35Model, + userRequests, + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }); - await test.step('Edit 2nd request, cancel edit and verify nothing changed', async () => { + await dialTest.step( + 'Edit 2nd request, cancel edit and verify nothing changed', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await chatMessages.openEditMessageMode(userRequests[1]); @@ -242,9 +264,12 @@ test.describe('Work with models tests', () => { expect .soft(isResponseLoading, ExpectedMessages.responseIsNotLoading) .toBeFalsy(); - }); + }, + ); - await test.step('Edit 2nd request, clear field and verify Save button is disabled', async () => { + await dialTest.step( + 'Edit 2nd request, clear field and verify Save button is disabled', + async () => { await chatMessages.openEditMessageMode(userRequests[1]); await chatMessages.fillEditData(userRequests[1], ''); @@ -253,9 +278,12 @@ test.describe('Work with models tests', () => { .soft(isSaveButtonDisabled, ExpectedMessages.saveIsDisabled) .toBeFalsy(); await chatMessages.cancel.click(); - }); + }, + ); - await test.step('Edit 2nd request, save changes and verify response is received, last request is removed', async () => { + await dialTest.step( + 'Edit 2nd request, save changes and verify response is received, last request is removed', + async () => { await chatMessages.openEditMessageMode(userRequests[1]); await chatMessages.editMessage(userRequests[1], editData); @@ -276,33 +304,37 @@ test.describe('Work with models tests', () => { expect .soft(lastMessage, ExpectedMessages.messageContentIsValid) .not.toBe(conversation.messages[3].content); - }); - }, - ); - - test( - 'Delete the message in the middle. Cancel.\n' + - 'Delete the message in the middle. Remove', - async ({ - dialHomePage, - conversationData, - localStorageManager, - setTestIds, - chatMessages, - confirmationDialog, - }) => { - setTestIds('EPMRTC-488', 'EPMRTC-489'); - await test.step('Prepare conversation with 3 requests', async () => { - const conversation = - conversationData.prepareModelConversationBasedOnRequests( - gpt35Model, - userRequests, - ); - await localStorageManager.setConversationHistory(conversation); - await localStorageManager.setSelectedConversation(conversation); - }); + }, + ); + }, +); + +dialTest( + 'Delete the message in the middle. Cancel.\n' + + 'Delete the message in the middle. Remove', + async ({ + dialHomePage, + conversationData, + localStorageManager, + dataInjector, + setTestIds, + chatMessages, + confirmationDialog, + }) => { + setTestIds('EPMRTC-488', 'EPMRTC-489'); + await dialTest.step('Prepare conversation with 3 requests', async () => { + const conversation = + conversationData.prepareModelConversationBasedOnRequests( + gpt35Model, + userRequests, + ); + await dataInjector.createConversations([conversation]); + await localStorageManager.setSelectedConversation(conversation); + }); - await test.step('Try to delete 2nd request but cancel deleting', async () => { + await dialTest.step( + 'Try to delete 2nd request but cancel deleting', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await chatMessages.openDeleteMessageDialog(userRequests[1]); @@ -312,9 +344,12 @@ test.describe('Work with models tests', () => { expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(userRequests.length * 2); - }); + }, + ); - await test.step('Delete 2nd request and verify request is deleted, other requests remain', async () => { + await dialTest.step( + 'Delete 2nd request and verify request is deleted, other requests remain', + async () => { await chatMessages.openDeleteMessageDialog(userRequests[1]); await confirmationDialog.confirm(); @@ -330,11 +365,14 @@ test.describe('Work with models tests', () => { expect .soft(isMessageVisible, ExpectedMessages.messageIsDeleted) .toBeFalsy(); - }); - }, - ); - - test('System prompt is applied in Model', async ({ + }, + ); + }, +); + +dialTest( + 'System prompt is applied in Model', + async ({ dialHomePage, chat, setTestIds, @@ -343,46 +381,59 @@ test.describe('Work with models tests', () => { entitySettings, }) => { setTestIds('EPMRTC-1085'); - await test.step('Set system prompt for model and send request', async () => { - await dialHomePage.openHomePage({ iconsToBeLoaded: [gpt4Model.iconUrl] }); - await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true }); - await talkToSelector.selectModel(gpt4Model.name); - await entitySettings.setSystemPrompt(sysPrompt); - await chat.sendRequestWithButton(requestTerm); - }); + await dialTest.step( + 'Set system prompt for model and send request', + async () => { + await dialHomePage.openHomePage({ + iconsToBeLoaded: [gpt4Model.iconUrl], + }); + await dialHomePage.waitForPageLoaded({ + isNewConversationVisible: true, + }); + await talkToSelector.selectModel(gpt4Model.name); + await entitySettings.setSystemPrompt(sysPrompt); + await chat.sendRequestWithButton(requestTerm); + }, + ); + + await dialTest.step( + 'Verify response correspond system prompt', + async () => { + const response = await chatMessages.getLastMessageContent(); + expect + .soft(response, ExpectedMessages.regenerateIsAvailable) + .toBe(expectedResponse); + }, + ); + }, +); + +dialTest( + 'Stop generating for models like GPT (1 symbol = 1 token).\n' + + 'Model: Send action is unavailable if there is empty response.\n' + + 'Edit the message after the response was stopped', + async ({ + dialHomePage, + chat, + setTestIds, + chatMessages, + sendMessage, + page, + tooltip, + localStorageManager, + iconApiHelper, + }) => { + setTestIds('EPMRTC-478', 'EPMRTC-1480', 'EPMRTC-1309'); + const expectedModelIcon = await iconApiHelper.getEntityIcon(gpt35Model); - await test.step('Verify response correspond system prompt', async () => { - const response = await chatMessages.getLastMessageContent(); - expect - .soft(response, ExpectedMessages.regenerateIsAvailable) - .toBe(expectedResponse); + await dialTest.step('Set random application theme', async () => { + const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); + await localStorageManager.setSettings(theme); }); - }); - - test( - 'Stop generating for models like GPT (1 symbol = 1 token).\n' + - 'Model: Send action is unavailable if there is empty response.\n' + - 'Edit the message after the response was stopped', - async ({ - dialHomePage, - chat, - setTestIds, - chatMessages, - sendMessage, - page, - tooltip, - localStorageManager, - iconApiHelper, - }) => { - setTestIds('EPMRTC-478', 'EPMRTC-1480', 'EPMRTC-1309'); - const expectedModelIcon = await iconApiHelper.getEntityIcon(gpt35Model); - - await test.step('Set random application theme', async () => { - const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); - await localStorageManager.setSettings(theme); - }); - - await test.step('Send request and stop generation immediately', async () => { + + await dialTest.step( + 'Send request and stop generation immediately', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -390,9 +441,12 @@ test.describe('Work with models tests', () => { await dialHomePage.throttleAPIResponse(API.chatHost); await chat.sendRequestWithButton(request, false); await chat.stopGenerating.click(); - }); + }, + ); - await test.step('Verify no content received and model icon is visible', async () => { + await dialTest.step( + 'Verify no content received and model icon is visible', + async () => { await dialHomePage.unRouteResponse(API.chatHost); const receivedContent = await chatMessages.getLastMessageContent(); expect @@ -412,9 +466,12 @@ test.describe('Work with models tests', () => { ExpectedMessages.regenerateIsAvailable, ) .toBeTruthy(); - }); + }, + ); - await test.step('Hover over Send button and verify it is disabled and tooltip is shown', async () => { + await dialTest.step( + 'Hover over Send button and verify it is disabled and tooltip is shown', + async () => { for (let i = 1; i <= 2; i++) { if (i === 2) { const messagesCountBefore = @@ -456,15 +513,21 @@ test.describe('Work with models tests', () => { .soft(tooltipContent, ExpectedMessages.tooltipContentIsValid) .toBe(ExpectedConstants.regenerateResponseTooltip); } - }); + }, + ); - await test.step('Send request and stop generation when partial content received', async () => { + await dialTest.step( + 'Send request and stop generation when partial content received', + async () => { await chat.regenerateResponse(false); await chatMessages.waitForPartialMessageReceived(2); await chat.stopGenerating.click(); - }); + }, + ); - await test.step('Verify partial content is preserved and model icon is visible', async () => { + await dialTest.step( + 'Verify partial content is preserved and model icon is visible', + async () => { const generatedContent = await chatMessages.getLastMessageContent(); expect .soft(generatedContent, ExpectedMessages.messageContentIsValid) @@ -482,9 +545,12 @@ test.describe('Work with models tests', () => { ExpectedMessages.regenerateIsAvailable, ) .toBeTruthy(); - }); + }, + ); - await test.step('Edit request, click "Save & Submit" and verify response is regenerated', async () => { + await dialTest.step( + 'Edit request, click "Save & Submit" and verify response is regenerated', + async () => { const updatedRequest = '1+2='; await chatMessages.openEditMessageMode(request); await chatMessages.editMessage(request, updatedRequest); @@ -493,23 +559,26 @@ test.describe('Work with models tests', () => { expect .soft(messagesCount, ExpectedMessages.messageCountIsCorrect) .toBe(2); - }); - }, - ); - - test( - 'Send button in new message is available for Model if previous response is partly received when Stop generating was used.\n' + - 'Compare mode button is not available while response is being generated', - async ({ - dialHomePage, - chat, - setTestIds, - chatMessages, - sendMessage, - chatBar, - }) => { - setTestIds('EPMRTC-1533', 'EPMRTC-538'); - await test.step('Send request, verify Compare button is disabled while generating the response and stop generation immediately', async () => { + }, + ); + }, +); + +dialTest( + 'Send button in new message is available for Model if previous response is partly received when Stop generating was used.\n' + + 'Compare mode button is not available while response is being generated', + async ({ + dialHomePage, + chat, + setTestIds, + chatMessages, + sendMessage, + chatBar, + }) => { + setTestIds('EPMRTC-1533', 'EPMRTC-538'); + await dialTest.step( + 'Send request, verify Compare button is disabled while generating the response and stop generation immediately', + async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded({ isNewConversationVisible: true, @@ -529,9 +598,12 @@ test.describe('Work with models tests', () => { await chatMessages.waitForPartialMessageReceived(2); await chat.stopGenerating.click(); await chat.stopGenerating.waitForState({ state: 'hidden' }); - }); + }, + ); - await test.step('Type a new message and verify Send button is enabled', async () => { + await dialTest.step( + 'Type a new message and verify Send button is enabled', + async () => { await sendMessage.messageInput.fillInInput( GeneratorUtil.randomString(10), ); @@ -540,7 +612,7 @@ test.describe('Work with models tests', () => { expect .soft(isSendButtonEnabled, ExpectedMessages.sendMessageButtonEnabled) .toBeTruthy(); - }); - }, - ); -}); + }, + ); + }, +); diff --git a/apps/chat-e2e/src/ui/domData/attributes.ts b/apps/chat-e2e/src/ui/domData/attributes.ts index c06c0aa09b..551811d9cb 100644 --- a/apps/chat-e2e/src/ui/domData/attributes.ts +++ b/apps/chat-e2e/src/ui/domData/attributes.ts @@ -10,4 +10,5 @@ export enum Attributes { ariaLabel = 'aria-label', visible = 'visible', invisible = 'invisible', + rotated = 'rotate-90', } diff --git a/apps/chat-e2e/src/ui/pages/auth0Page.ts b/apps/chat-e2e/src/ui/pages/auth0Page.ts index 185e6467c9..4b4a5c6ff4 100644 --- a/apps/chat-e2e/src/ui/pages/auth0Page.ts +++ b/apps/chat-e2e/src/ui/pages/auth0Page.ts @@ -20,7 +20,7 @@ export class Auth0Page extends BasePage { await this.page.waitForLoadState('domcontentloaded'); const auth0Form = this.getAuth0(); await auth0Form.setCredentials(username, process.env.E2E_PASSWORD!); - return this.waitFoApiResponsesReceived( + return this.waitForApiResponsesReceived( () => auth0Form.loginButton.click(), options, ); diff --git a/apps/chat-e2e/src/ui/pages/basePage.ts b/apps/chat-e2e/src/ui/pages/basePage.ts index d3f0b0ebf1..09fa1e73c4 100644 --- a/apps/chat-e2e/src/ui/pages/basePage.ts +++ b/apps/chat-e2e/src/ui/pages/basePage.ts @@ -28,13 +28,13 @@ export class BasePage { iconsToBeLoaded?: (string | undefined)[]; setEntitiesEnvVars?: boolean; }) { - await this.waitFoApiResponsesReceived( + await this.waitForApiResponsesReceived( () => this.navigateToBaseUrl(), options, ); } - async waitFoApiResponsesReceived( + async waitForApiResponsesReceived( method: () => Promise, options?: { iconsToBeLoaded?: (string | undefined)[]; @@ -92,9 +92,7 @@ export class BasePage { } async reloadPage() { - await this.page.reload(); - await this.page.waitForLoadState(); - await this.page.waitForLoadState('domcontentloaded'); + await this.page.reload({ waitUntil: 'domcontentloaded' }); } async bringPageToFront() { diff --git a/apps/chat-e2e/src/ui/pages/dialHomePage.ts b/apps/chat-e2e/src/ui/pages/dialHomePage.ts index 6b3ba82116..dc6c6c849e 100644 --- a/apps/chat-e2e/src/ui/pages/dialHomePage.ts +++ b/apps/chat-e2e/src/ui/pages/dialHomePage.ts @@ -18,8 +18,12 @@ export class DialHomePage extends BasePage { }) { const appContainer = this.getAppContainer(); const chatBar = appContainer.getChatBar(); + const promptBar = appContainer.getPromptBar(); await chatBar.waitForState({ state: 'attached' }); - await appContainer.getPromptBar().waitForState({ state: 'attached' }); + await promptBar.waitForState({ state: 'attached' }); + await chatBar.getChatLoader().waitForState({ state: 'hidden' }); + await promptBar.getChatLoader().waitForState({ state: 'hidden' }); + await appContainer.getChatLoader().waitForState({ state: 'hidden' }); const chat = appContainer.getChat(); await chat.waitForState({ state: 'attached' }); await chat.waitForChatLoaded(); @@ -39,4 +43,17 @@ export class DialHomePage extends BasePage { .waitForState({ state: 'attached' }); } } + + async reloadPage() { + await super.reloadPage(); + const appContainer = this.getAppContainer(); + await appContainer + .getChatBar() + .getChatLoader() + .waitForState({ state: 'hidden' }); + await appContainer + .getPromptBar() + .getChatLoader() + .waitForState({ state: 'hidden' }); + } } diff --git a/apps/chat-e2e/src/ui/selectors/chatSelectors.ts b/apps/chat-e2e/src/ui/selectors/chatSelectors.ts index 76dbef551f..8077fd645e 100644 --- a/apps/chat-e2e/src/ui/selectors/chatSelectors.ts +++ b/apps/chat-e2e/src/ui/selectors/chatSelectors.ts @@ -36,6 +36,7 @@ export const ChatSelectors = { listbox: '[role="listbox"]', listOptions: '[role="option"]', combobox: '[role="combobox"]', + showAllCheckbox: '[name="showAllCheckbox"]', promptList: '[data-qa="prompt-list"]', promptOption: '[data-qa="prompt-option"]', moreInfo: '[data-qa="more-info"]', @@ -76,4 +77,5 @@ export const ChatSelectors = { replayOldVersion: '[data-qa="replay-old-version"]', sendMessage: '[data-qa="send"]', rate: (rate: Rate) => `[data-qa="${rate}"]`, + chatLoader: '[data-qa="chat-loader"]', }; diff --git a/apps/chat-e2e/src/ui/webElements/appContainer.ts b/apps/chat-e2e/src/ui/webElements/appContainer.ts index 4fdc1ddfa2..ae8d545c7e 100644 --- a/apps/chat-e2e/src/ui/webElements/appContainer.ts +++ b/apps/chat-e2e/src/ui/webElements/appContainer.ts @@ -3,6 +3,7 @@ import { Banner } from '@/src/ui/webElements/banner'; import { BaseElement } from '@/src/ui/webElements/baseElement'; import { Chat } from '@/src/ui/webElements/chat'; import { ChatBar } from '@/src/ui/webElements/chatBar'; +import { ChatLoader } from '@/src/ui/webElements/chatLoader'; import { ConversationSettings } from '@/src/ui/webElements/conversationSettings'; import { Header } from '@/src/ui/webElements/header'; import { PromptBar } from '@/src/ui/webElements/promptBar'; @@ -19,6 +20,7 @@ export class AppContainer extends BaseElement { private chatBar!: ChatBar; private promptBar!: PromptBar; private conversationSettings!: ConversationSettings; + private chatLoader!: ChatLoader; getHeader(): Header { if (!this.header) { @@ -61,4 +63,11 @@ export class AppContainer extends BaseElement { } return this.conversationSettings; } + + getChatLoader(): ChatLoader { + if (!this.chatLoader) { + this.chatLoader = new ChatLoader(this.page, this.rootLocator); + } + return this.chatLoader; + } } diff --git a/apps/chat-e2e/src/ui/webElements/chat.ts b/apps/chat-e2e/src/ui/webElements/chat.ts index e460bb84cc..ca51cb95a9 100644 --- a/apps/chat-e2e/src/ui/webElements/chat.ts +++ b/apps/chat-e2e/src/ui/webElements/chat.ts @@ -170,8 +170,10 @@ export class Chat extends BaseElement { public waitForRequestSent(userRequest: string | undefined) { return userRequest - ? this.page.waitForRequest((request) => - request.postData()!.includes(userRequest), + ? this.page.waitForRequest( + (request) => + request.url().includes(API.chatHost) && + request.postData()!.includes(userRequest), ) : this.page.waitForRequest(API.chatHost); } diff --git a/apps/chat-e2e/src/ui/webElements/chatBar.ts b/apps/chat-e2e/src/ui/webElements/chatBar.ts index ee936eecf9..b01c9c0e4b 100644 --- a/apps/chat-e2e/src/ui/webElements/chatBar.ts +++ b/apps/chat-e2e/src/ui/webElements/chatBar.ts @@ -1,6 +1,7 @@ import { ChatBarSelectors, SideBarSelectors } from '../selectors'; import { Conversations } from './conversations'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { API } from '@/src/testData'; import { FolderConversations } from '@/src/ui/webElements/folderConversations'; import { SideBar } from '@/src/ui/webElements/sideBar'; @@ -40,9 +41,18 @@ export class ChatBar extends SideBar { public async createNewConversation() { const modelsResponsePromise = this.page.waitForResponse(API.modelsHost); const addonsResponsePromise = this.page.waitForResponse(API.addonsHost); + let putResponsePromise; + if (isApiStorageType) { + putResponsePromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'PUT', + ); + } await this.newEntityButton.click(); await modelsResponsePromise; await addonsResponsePromise; + if (isApiStorageType) { + await putResponsePromise; + } } public async openCompareMode() { diff --git a/apps/chat-e2e/src/ui/webElements/chatLoader.ts b/apps/chat-e2e/src/ui/webElements/chatLoader.ts new file mode 100644 index 0000000000..0f3e8f0df5 --- /dev/null +++ b/apps/chat-e2e/src/ui/webElements/chatLoader.ts @@ -0,0 +1,9 @@ +import { ChatSelectors } from '@/src/ui/selectors'; +import { BaseElement } from '@/src/ui/webElements/baseElement'; +import { Locator, Page } from '@playwright/test'; + +export class ChatLoader extends BaseElement { + constructor(page: Page, parentLocator: Locator) { + super(page, ChatSelectors.chatLoader, parentLocator); + } +} diff --git a/apps/chat-e2e/src/ui/webElements/chatMessages.ts b/apps/chat-e2e/src/ui/webElements/chatMessages.ts index d5b60eca51..2f9eeb9822 100644 --- a/apps/chat-e2e/src/ui/webElements/chatMessages.ts +++ b/apps/chat-e2e/src/ui/webElements/chatMessages.ts @@ -85,7 +85,7 @@ export class ChatMessages extends BaseElement { public async getMessageIconSize(index?: number) { const messagesCount = await this.chatMessages.getElementsCount(); - const icon = await this.chatMessages + const icon = this.chatMessages .getNthElement(index ?? messagesCount) .locator(Tags.svg) .first(); @@ -187,7 +187,11 @@ export class ChatMessages extends BaseElement { ); await thumb.hover({ force: true }); await thumb.waitFor(); + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'POST', + ); await thumb.click(); + return respPromise; } public async isComparedRowMessageRated( @@ -246,7 +250,7 @@ export class ChatMessages extends BaseElement { rowIndex, ); await messageToCopy.hover(); - const copyIcon = await messageToCopy.locator(selector); + const copyIcon = messageToCopy.locator(selector); await copyIcon.waitFor(); await copyIcon.click(); } diff --git a/apps/chat-e2e/src/ui/webElements/confirmationDialog.ts b/apps/chat-e2e/src/ui/webElements/confirmationDialog.ts index e7074fc751..938eae8c0a 100644 --- a/apps/chat-e2e/src/ui/webElements/confirmationDialog.ts +++ b/apps/chat-e2e/src/ui/webElements/confirmationDialog.ts @@ -1,3 +1,4 @@ +import { isApiStorageType } from '@/src/hooks/global-setup'; import { Dialog } from '@/src/ui/selectors/dialogSelectors'; import { BaseElement } from '@/src/ui/webElements/baseElement'; import { Page } from '@playwright/test'; @@ -18,7 +19,16 @@ export class ConfirmationDialog extends BaseElement { await this.cancelButton.click(); } - public async confirm() { + public async confirm({ + triggeredHttpMethod = undefined, + }: { triggeredHttpMethod?: 'PUT' | 'DELETE' | 'POST' } = {}) { + if (isApiStorageType && triggeredHttpMethod) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === triggeredHttpMethod, + ); + await this.confirmButton.click(); + return respPromise; + } await this.confirmButton.click(); } diff --git a/apps/chat-e2e/src/ui/webElements/conversationToCompare.ts b/apps/chat-e2e/src/ui/webElements/conversationToCompare.ts index f48012c256..36adfb3efc 100644 --- a/apps/chat-e2e/src/ui/webElements/conversationToCompare.ts +++ b/apps/chat-e2e/src/ui/webElements/conversationToCompare.ts @@ -10,6 +10,9 @@ export class ConversationToCompare extends BaseElement { } private conversationSelector!: ModelSelector; + public showAllConversationsCheckbox = this.getChildElementBySelector( + ChatSelectors.showAllCheckbox, + ); getConversationSelector(): ModelSelector { if (!this.conversationSelector) { @@ -20,4 +23,10 @@ export class ConversationToCompare extends BaseElement { } return this.conversationSelector; } + + public async checkShowAllConversations() { + if (await this.showAllConversationsCheckbox.isVisible()) { + await this.showAllConversationsCheckbox.click(); + } + } } diff --git a/apps/chat-e2e/src/ui/webElements/conversations.ts b/apps/chat-e2e/src/ui/webElements/conversations.ts index 13368b9af2..1d534f934d 100644 --- a/apps/chat-e2e/src/ui/webElements/conversations.ts +++ b/apps/chat-e2e/src/ui/webElements/conversations.ts @@ -1,5 +1,6 @@ import { ChatBarSelectors, SideBarSelectors } from '../selectors'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { Chronology } from '@/src/testData'; import { keys } from '@/src/ui/keyboard'; import { IconSelectors } from '@/src/ui/selectors/iconSelectors'; @@ -114,7 +115,15 @@ export class Conversations extends SideBarEntities { public async editConversationNameWithEnter(name: string, newName: string) { await this.openEditConversationNameMode(name, newName); - await this.page.keyboard.press(keys.enter); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await this.page.keyboard.press(keys.enter); + await respPromise; + } else { + await this.page.keyboard.press(keys.enter); + } await this.getConversationByName(name).waitFor({ state: 'hidden' }); } @@ -127,7 +136,7 @@ export class Conversations extends SideBarEntities { } public async isConversationHasPlaybackIcon(name: string, index?: number) { - const playBackIcon = await this.getConversationByName(name, index).locator( + const playBackIcon = this.getConversationByName(name, index).locator( IconSelectors.playbackIcon, ); return playBackIcon.isVisible(); diff --git a/apps/chat-e2e/src/ui/webElements/folderConversations.ts b/apps/chat-e2e/src/ui/webElements/folderConversations.ts index 4e6a0a49cb..9ad068f072 100644 --- a/apps/chat-e2e/src/ui/webElements/folderConversations.ts +++ b/apps/chat-e2e/src/ui/webElements/folderConversations.ts @@ -1,5 +1,6 @@ import { ChatBarSelectors, SideBarSelectors } from '../selectors'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { Folders } from '@/src/ui/webElements/folders'; import { Input } from '@/src/ui/webElements/input'; import { Page } from '@playwright/test'; @@ -22,4 +23,16 @@ export class FolderConversations extends Folders { } return this.folderConversationInput; } + + public async deleteConversation(name: string) { + const folderConversation = this.getFolderConversationInput(name); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await folderConversation.clickTickButton(); + return respPromise; + } + await folderConversation.clickTickButton(); + } } diff --git a/apps/chat-e2e/src/ui/webElements/folders.ts b/apps/chat-e2e/src/ui/webElements/folders.ts index a263a62698..f062a2366b 100644 --- a/apps/chat-e2e/src/ui/webElements/folders.ts +++ b/apps/chat-e2e/src/ui/webElements/folders.ts @@ -1,7 +1,8 @@ import { SideBarSelectors } from '../selectors'; import { BaseElement } from './baseElement'; -import { ExpectedConstants } from '@/src/testData'; +import { isApiStorageType } from '@/src/hooks/global-setup'; +import { API, ExpectedConstants } from '@/src/testData'; import { Attributes, Styles, Tags } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; import { DropdownMenu } from '@/src/ui/webElements/dropdownMenu'; @@ -53,10 +54,11 @@ export class Folders extends BaseElement { ); } - public getFolderCaret(name: string, index?: number) { + public async isFolderCaretExpanded(name: string, index?: number) { return this.getFolderByName(name, index) - .locator(Tags.span) - .getAttribute(Attributes.class); + .locator(`${Tags.span}[class='${Attributes.visible}']`) + .locator(`.${Attributes.rotated}`) + .isVisible(); } public foldersGroup = (parentFolderName: string) => { @@ -95,6 +97,16 @@ export class Folders extends BaseElement { public async editFolderNameWithTick(name: string, newName: string) { const folderInput = await this.editFolderName(name, newName); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse((resp) => { + return ( + resp.url().includes(API.conversationsListingHost()) || + resp.url().includes(API.promptsListingHost()) + ); + }); + await folderInput.clickTickButton(); + return respPromise; + } await folderInput.clickTickButton(); } @@ -104,8 +116,20 @@ export class Folders extends BaseElement { return folderInput; } - public async expandCollapseFolder(name: string, index?: number) { - await this.getFolderByName(name, index).click(); + public async expandCollapseFolder( + name: string, + { isHttpMethodTriggered = false }: { isHttpMethodTriggered?: boolean } = {}, + ) { + const folder = this.getFolderByName(name); + await folder.waitFor(); + if (isApiStorageType && isHttpMethodTriggered) { + const respPromise = this.page.waitForResponse((resp) => + resp.url().includes(API.conversationsListingHost()), + ); + await folder.click(); + return respPromise; + } + await folder.click(); } public async getFolderNameColor(name: string, index?: number) { diff --git a/apps/chat-e2e/src/ui/webElements/index.ts b/apps/chat-e2e/src/ui/webElements/index.ts index 9bfc096f10..1800f83757 100644 --- a/apps/chat-e2e/src/ui/webElements/index.ts +++ b/apps/chat-e2e/src/ui/webElements/index.ts @@ -39,3 +39,4 @@ export * from './menu'; export * from './search'; export * from './accountSettings'; export * from './banner'; +export * from './chatLoader'; diff --git a/apps/chat-e2e/src/ui/webElements/promptList.ts b/apps/chat-e2e/src/ui/webElements/promptList.ts index 6524b4b019..f3d3fc68e7 100644 --- a/apps/chat-e2e/src/ui/webElements/promptList.ts +++ b/apps/chat-e2e/src/ui/webElements/promptList.ts @@ -34,5 +34,6 @@ export class PromptList extends BaseElement { optionIndex++; } await this.getPromptByName(name).click(); + await this.waitForState({ state: 'hidden' }); } } diff --git a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts index 80a61e6781..5b30c9a186 100644 --- a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts +++ b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts @@ -39,7 +39,11 @@ export class PromptModalDialog extends BaseElement { value: string, ) { await this.fillPromptDetails(name, description, value); + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'PUT', + ); await this.saveButton.click(); + await respPromise; } public async updatePromptDetailsWithEnter( @@ -48,7 +52,11 @@ export class PromptModalDialog extends BaseElement { value: string, ) { await this.fillPromptDetails(name, description, value); + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'PUT', + ); await this.page.keyboard.press(keys.enter); + await respPromise; } public async getName() { diff --git a/apps/chat-e2e/src/ui/webElements/sideBar.ts b/apps/chat-e2e/src/ui/webElements/sideBar.ts index b96f687a28..5448772d7e 100644 --- a/apps/chat-e2e/src/ui/webElements/sideBar.ts +++ b/apps/chat-e2e/src/ui/webElements/sideBar.ts @@ -1,8 +1,10 @@ import { ChatSelectors, SideBarSelectors } from '../selectors'; import { BaseElement } from './baseElement'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { ExpectedConstants } from '@/src/testData'; import { Styles } from '@/src/ui/domData'; +import { ChatLoader } from '@/src/ui/webElements/chatLoader'; import { Search } from '@/src/ui/webElements/search'; import { Locator, Page } from '@playwright/test'; @@ -12,6 +14,7 @@ export class SideBar extends BaseElement { } private search!: Search; + private chatLoader!: ChatLoader; getSearch(): Search { if (!this.search) { @@ -20,6 +23,13 @@ export class SideBar extends BaseElement { return this.search; } + getChatLoader(): ChatLoader { + if (!this.chatLoader) { + this.chatLoader = new ChatLoader(this.page, this.rootLocator); + } + return this.chatLoader; + } + public newEntityButton = this.getChildElementBySelector( SideBarSelectors.newEntity, ); @@ -120,6 +130,16 @@ export class SideBar extends BaseElement { public async dragAndDropEntityFromFolder(entityLocator: Locator) { await this.dragEntityFromFolder(entityLocator); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse((resp) => { + return ( + resp.request().method() === 'PUT' || + resp.request().method() === 'POST' + ); + }); + await this.page.mouse.up(); + return respPromise; + } await this.page.mouse.up(); } diff --git a/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts b/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts index efd5f509ea..952aa32d23 100644 --- a/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts +++ b/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts @@ -1,9 +1,9 @@ import { SideBarSelectors } from '../selectors'; import { BaseElement } from './baseElement'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { ExpectedConstants } from '@/src/testData'; import { Styles, Tags } from '@/src/ui/domData'; -import { keys } from '@/src/ui/keyboard'; import { DropdownMenu } from '@/src/ui/webElements/dropdownMenu'; import { Input } from '@/src/ui/webElements/input'; import { Page } from '@playwright/test'; @@ -97,19 +97,16 @@ export class SideBarEntities extends BaseElement { newName: string, ) { const input = await this.openEditEntityNameMode(selector, name, newName); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await input.clickTickButton(); + return respPromise; + } await input.clickTickButton(); } - protected async editEntityNameWithEnter( - selector: string, - name: string, - newName: string, - ) { - await this.openEditEntityNameMode(selector, name, newName); - await this.page.keyboard.press(keys.enter); - await this.getEntityByName(selector, name).waitFor({ state: 'hidden' }); - } - protected async openEditEntityNameMode( selector: string, name: string, @@ -143,4 +140,15 @@ export class SideBarEntities extends BaseElement { ); return backgroundColor[0]; } + + public async selectMoveToMenuOption(name: string) { + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await this.getDropdownMenu().selectMenuOption(name); + return respPromise; + } + await this.getDropdownMenu().selectMenuOption(name); + } } diff --git a/apps/chat-e2e/src/utils/conversationUtil.ts b/apps/chat-e2e/src/utils/conversationUtil.ts new file mode 100644 index 0000000000..b60fb0d6cf --- /dev/null +++ b/apps/chat-e2e/src/utils/conversationUtil.ts @@ -0,0 +1,13 @@ +import { Conversation } from '@/chat/types/chat'; + +export class ConversationUtil { + static conversationIdSeparator = '__'; + + public static getApiConversationId(conversation: Conversation) { + const conversationId = `${ConversationUtil.conversationIdSeparator}${conversation.name}`; + if (conversation.replay.isReplay) { + return `replay${conversationId}`; + } + return `${conversation.model.id}${conversationId}`; + } +} diff --git a/apps/chat-e2e/src/utils/index.ts b/apps/chat-e2e/src/utils/index.ts index 59e9aaecc1..c13dfd970e 100644 --- a/apps/chat-e2e/src/utils/index.ts +++ b/apps/chat-e2e/src/utils/index.ts @@ -3,3 +3,4 @@ export * from './dateUtil'; export * from './fileUtil'; export * from './modelsUtil'; export * from './bucketUtil'; +export * from './conversationUtil'; From f8e7f975046fab8cae6214f93e1843a0c2ef3db3 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 14:25:01 +0100 Subject: [PATCH 02/19] feat/update-e2e-with-stateful-api: fixed file api endpoint --- apps/chat-e2e/src/testData/api/fileApiHelper.ts | 4 ++-- apps/chat-e2e/src/testData/expectedConstants.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/chat-e2e/src/testData/api/fileApiHelper.ts b/apps/chat-e2e/src/testData/api/fileApiHelper.ts index ec13285879..95e831557f 100644 --- a/apps/chat-e2e/src/testData/api/fileApiHelper.ts +++ b/apps/chat-e2e/src/testData/api/fileApiHelper.ts @@ -9,7 +9,7 @@ export class FileApiHelper extends BaseApiHelper { public async putFile(filename: string) { const filePath = path.join(Attachment.attachmentPath, filename); const bufferedFile = fs.readFileSync(filePath); - const url = `${API.uploadedFileHost()}/${BucketUtil.getBucket()}/${filename}`; + const url = `${API.fileHost}/${BucketUtil.getBucket()}/${filename}`; const response = await this.request.put(url, { headers: { Accept: '*/*', @@ -29,7 +29,7 @@ export class FileApiHelper extends BaseApiHelper { } public async deleteUploadedFile(filename: string) { - const url = `${API.uploadedFileHost()}/${BucketUtil.getBucket()}/${filename}`; + const url = `${API.fileHost}/${BucketUtil.getBucket()}/${filename}`; await this.request.delete(url); } diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts index e2c96723e2..8e0ae36cf6 100644 --- a/apps/chat-e2e/src/testData/expectedConstants.ts +++ b/apps/chat-e2e/src/testData/expectedConstants.ts @@ -109,8 +109,7 @@ export const API = { promptsHost: '/api/prompts', conversationsListingHost: () => `${API.conversationsHost}/listing`, promptsListingHost: () => `${API.promptsHost}/listing`, - fileHost: '/api/files/file', - uploadedFileHost: () => `${API.fileHost}/files`, + fileHost: '/api/files', }; export const Import = { From d35180c975fdab28600ac4da388b835172b9a56c Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 15:05:02 +0100 Subject: [PATCH 03/19] feat/update-e2e-with-stateful-api: fixed flaky tests --- apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts | 2 -- apps/chat-e2e/src/tests/promptExportImport.test.ts | 2 +- apps/chat-e2e/src/ui/webElements/chatBar.ts | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts index eca8faf949..f0a86cf842 100644 --- a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts @@ -61,7 +61,6 @@ dialTest( } await folderConversations.expandCollapseFolder( ExpectedConstants.newFolderWithIndexTitle(2), - { isHttpMethodTriggered: true }, ); await folderConversations.openFolderDropdownMenu( @@ -297,7 +296,6 @@ dialTest( } await folderConversations.expandCollapseFolder( ExpectedConstants.newFolderWithIndexTitle(2), - { isHttpMethodTriggered: true }, ); await folderConversations.openFolderDropdownMenu( diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index 320f2d6454..1eff781e3a 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -23,7 +23,7 @@ const newDescr = 'test description'; const newValue = 'what is {{A}}'; const levelsCount = 3; -dialTest( +dialTest.skip( 'Export and import prompt structure with all prompts.\n' + 'Continue working with imported file. Add imported prompt to a message', async ({ diff --git a/apps/chat-e2e/src/ui/webElements/chatBar.ts b/apps/chat-e2e/src/ui/webElements/chatBar.ts index b01c9c0e4b..75c5b5f5b8 100644 --- a/apps/chat-e2e/src/ui/webElements/chatBar.ts +++ b/apps/chat-e2e/src/ui/webElements/chatBar.ts @@ -44,7 +44,7 @@ export class ChatBar extends SideBar { let putResponsePromise; if (isApiStorageType) { putResponsePromise = this.page.waitForResponse( - (resp) => resp.request().method() === 'PUT', + (resp) => resp.request().method() === 'POST', ); } await this.newEntityButton.click(); From 19b609291118ef6c8fc83dda56e1dad4689ce770 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 16:00:19 +0100 Subject: [PATCH 04/19] feat/update-e2e-with-stateful-api: fixed flaky test --- apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index 470e7fa093..196cfa77d1 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -136,7 +136,6 @@ dialTest( } await folderConversations.expandCollapseFolder( ExpectedConstants.newFolderWithIndexTitle(2), - { isHttpMethodTriggered: true }, ); await chatBar.drugConversationToFolder( From c40ba5b8f9bc96c60c9071a63c125309eea7f9d1 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 18:24:55 +0100 Subject: [PATCH 05/19] feat/update-e2e-with-stateful-api: enabled part of chat export tests --- .../conversationHistory/importConversation.ts | 49 +++++++++++++++---- .../src/tests/chatExportImport.test.ts | 15 +++--- apps/chat-e2e/src/tests/folderPrompts.test.ts | 2 + .../src/tests/promptExportImport.test.ts | 4 +- apps/chat-e2e/src/tests/replay.test.ts | 2 +- .../tests/sidePanelEntityDragAndDrop.test.ts | 10 +++- .../chat-e2e/src/tests/workWithModels.test.ts | 2 + 7 files changed, 63 insertions(+), 21 deletions(-) diff --git a/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts b/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts index a650b3b056..cb18e266af 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts @@ -1,7 +1,8 @@ import { Conversation } from '@/chat/types/chat'; -import { LatestExportFormat } from '@/chat/types/importExport'; +import { isApiStorageType } from '@/src/hooks/global-setup'; import { FolderConversation } from '@/src/testData'; import { UploadDownloadData } from '@/src/ui/pages'; +import { ConversationUtil } from '@/src/utils'; import { FileUtil } from '@/src/utils/fileUtil'; export class ImportConversation { @@ -9,18 +10,46 @@ export class ImportConversation { importedConversation: Conversation, importedFolder?: FolderConversation, ): UploadDownloadData { - importedConversation.folderId = importedFolder - ? importedFolder.folders.id - : undefined; - const folderConversationToImport: LatestExportFormat = { - folders: importedFolder ? [importedFolder.folders] : [], - history: [importedConversation], - prompts: [], - version: 4, - }; + ImportConversation.setImportedItemAttributes( + importedConversation, + importedFolder, + ); + const folderConversationToImport = isApiStorageType + ? { + folders: importedFolder ? [importedFolder.folders] : [], + history: [importedConversation], + prompts: [], + version: 5, + } + : { + folders: importedFolder ? [importedFolder.folders] : [], + history: [importedConversation], + prompts: [], + version: 4, + }; return { path: FileUtil.writeDataToFile(folderConversationToImport), isDownloadedData: false, }; } + + private static setImportedItemAttributes( + importedConversation: Conversation, + importedFolder?: FolderConversation, + ) { + if (isApiStorageType) { + if (importedFolder) { + importedFolder.folders.id = importedFolder.folders.name; + importedConversation.folderId = importedFolder.folders.id; + importedConversation.id = `${importedConversation.folderId}/${ConversationUtil.getApiConversationId(importedConversation)}`; + } else { + importedConversation.id = + ConversationUtil.getApiConversationId(importedConversation); + } + } else { + importedConversation.folderId = importedFolder + ? importedFolder.folders.id + : undefined; + } + } } diff --git a/apps/chat-e2e/src/tests/chatExportImport.test.ts b/apps/chat-e2e/src/tests/chatExportImport.test.ts index 940c57517d..258052c96a 100644 --- a/apps/chat-e2e/src/tests/chatExportImport.test.ts +++ b/apps/chat-e2e/src/tests/chatExportImport.test.ts @@ -33,7 +33,7 @@ dialTest.beforeAll(async () => { gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -dialTest.skip( +dialTest( 'Export and import one chat in a folder.\n' + `Export and import one chat in a folder when folder doesn't exist`, async ({ @@ -151,7 +151,8 @@ dialTest.skip( }, ); -dialTest.skip( +//TODO: empty folder export +dialTest( 'Export and import chat structure with all conversations', async ({ dialHomePage, @@ -231,7 +232,7 @@ dialTest.skip( }, ); -dialTest.skip( +dialTest( 'Existed chats stay after import', async ({ dialHomePage, @@ -383,7 +384,7 @@ dialTest.skip( }, ); -dialTest.skip( +dialTest( 'Continue working with imported file. Regenerate response.\n' + 'Continue working with imported file. Send a message.\n' + 'Continue working with imported file. Edit a message', @@ -397,7 +398,7 @@ dialTest.skip( }) => { setTestIds('EPMRTC-923', 'EPMRTC-924', 'EPMRTC-925'); let importedRootConversation: Conversation; - const requests = ['1+2=', '2+3=', '3+4=']; + const requests = ['1+2', '2+3', '3+4']; await dialTest.step( 'Prepare conversation with several messages to import', @@ -435,7 +436,7 @@ dialTest.skip( await dialTest.step( 'Send new request in chat and verify response is received', async () => { - const newRequest = '4+5='; + const newRequest = '4+5'; await chat.sendRequestWithButton(newRequest); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -448,7 +449,7 @@ dialTest.skip( await dialTest.step( 'Edit 1st request in chat and verify 1st response is regenerated', async () => { - const updatedMessage = '6+7='; + const updatedMessage = '6+7'; await chatMessages.openEditMessageMode(1); await chatMessages.editMessage(requests[0], updatedMessage); const messagesCount = diff --git a/apps/chat-e2e/src/tests/folderPrompts.test.ts b/apps/chat-e2e/src/tests/folderPrompts.test.ts index b0265050cf..e53b283322 100644 --- a/apps/chat-e2e/src/tests/folderPrompts.test.ts +++ b/apps/chat-e2e/src/tests/folderPrompts.test.ts @@ -427,8 +427,10 @@ dialTest( confirmationDialog, promptData, setTestIds, + setIssueIds, }) => { setTestIds('EPMRTC-1384'); + setIssueIds('671'); const levelsCount = 3; const levelToDelete = 2; let nestedFolders: FolderInterface[]; diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index 1eff781e3a..e3def5d070 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -355,7 +355,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Existed prompts stay after import', async ({ dialHomePage, @@ -478,7 +478,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Import file from 1.4 version to prompts and continue working with it', async ({ dialHomePage, diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index 4c7b312584..4774d1bb01 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -978,7 +978,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( `"Replay as is" in chat from 1.4 milestone.\n` + `"Replay as is" in chat from 1.9 milestone`, async ({ diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index 196cfa77d1..b21752dcb0 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -53,7 +53,15 @@ dialTest( expect .soft(draggableAreaColor, ExpectedMessages.draggableAreaColorIsValid) .toBe(Colors.backgroundAccentSecondary); - await page.mouse.up(); + if (isApiStorageType) { + const respPromise = page.waitForResponse((resp) => { + return resp.request().method() === 'POST'; + }); + await page.mouse.up(); + return respPromise; + } else { + await page.mouse.up(); + } expect .soft( diff --git a/apps/chat-e2e/src/tests/workWithModels.test.ts b/apps/chat-e2e/src/tests/workWithModels.test.ts index 05ed15eaa1..4e28b4123d 100644 --- a/apps/chat-e2e/src/tests/workWithModels.test.ts +++ b/apps/chat-e2e/src/tests/workWithModels.test.ts @@ -91,8 +91,10 @@ dialTest( tooltip, localStorageManager, page, + setIssueIds, }) => { setTestIds('EPMRTC-477', 'EPMRTC-1463'); + setIssueIds('689'); await dialTest.step('Set random application theme', async () => { const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); await localStorageManager.setSettings(theme); From a5db64db903e50bde1dcdc29ec446ba1fb4ac283 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Tue, 13 Feb 2024 18:34:53 +0100 Subject: [PATCH 06/19] feat/update-e2e-with-stateful-api: fixed return --- apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index b21752dcb0..ed7d47ae23 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -58,7 +58,7 @@ dialTest( return resp.request().method() === 'POST'; }); await page.mouse.up(); - return respPromise; + await respPromise; } else { await page.mouse.up(); } From acd6ad92fcbe775a93d4a8857bc1d162f71a4f39 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 10:53:10 +0100 Subject: [PATCH 07/19] feat/update-e2e-with-stateful-api: adjusted items path to latest changes --- apps/chat-e2e/src/core/baseFixtures.ts | 2 + apps/chat-e2e/src/core/localStorageManager.ts | 20 +++--- .../src/testData/api/chatApiHelper.ts | 5 +- .../src/testData/api/itemApiHelper.ts | 35 +++++------ .../conversationBuilder.ts | 21 +++---- .../conversationHistory/conversationData.ts | 30 ++++----- .../conversationHistory/folderBuilder.ts | 8 ++- .../conversationHistory/importConversation.ts | 53 +++++++++------- .../conversationHistory/importPrompt.ts | 5 +- .../src/testData/injector/apiInjector.ts | 20 +++--- .../injector/browserStorageInjector.ts | 16 +++-- .../injector/dataInjectorInterface.ts | 22 +++---- .../src/testData/prompts/promptBuilder.ts | 8 ++- .../src/testData/prompts/promptData.ts | 19 +++--- .../src/tests/announcementBanner.test.ts | 9 ++- .../tests/chatApi/arithmeticRequest.test.ts | 2 + .../src/tests/chatApi/attachment.test.ts | 2 + .../src/tests/chatApi/imageGeneration.test.ts | 2 + .../src/tests/chatBarConversation.test.ts | 12 ++-- .../tests/chatBarFolderConversation.test.ts | 8 +-- .../src/tests/chatExportImport.test.ts | 39 ++++++------ apps/chat-e2e/src/tests/chatHeader.test.ts | 7 +-- .../src/tests/chatHeaderSettings.test.ts | 5 +- apps/chat-e2e/src/tests/compareMode.test.ts | 62 +++++++++---------- apps/chat-e2e/src/tests/folderPrompts.test.ts | 10 ++- apps/chat-e2e/src/tests/listing.test.ts | 4 +- apps/chat-e2e/src/tests/playBack.test.ts | 16 ++--- .../src/tests/promptExportImport.test.ts | 44 ++++++------- apps/chat-e2e/src/tests/prompts.test.ts | 12 ++-- apps/chat-e2e/src/tests/replay.test.ts | 49 ++++++++------- .../src/tests/sharedChatIcons.test.ts | 10 +-- .../src/tests/sharedPromptIcons.test.ts | 7 +-- .../chat-e2e/src/tests/sideBarFilters.test.ts | 30 ++++----- .../tests/sidePanelEntityDragAndDrop.test.ts | 14 ++--- .../chat-e2e/src/tests/workWithModels.test.ts | 6 +- apps/chat-e2e/src/utils/conversationUtil.ts | 13 ---- apps/chat-e2e/src/utils/index.ts | 2 +- apps/chat-e2e/src/utils/itemUtil.ts | 49 +++++++++++++++ 38 files changed, 358 insertions(+), 320 deletions(-) delete mode 100644 apps/chat-e2e/src/utils/conversationUtil.ts create mode 100644 apps/chat-e2e/src/utils/itemUtil.ts diff --git a/apps/chat-e2e/src/core/baseFixtures.ts b/apps/chat-e2e/src/core/baseFixtures.ts index 0ac747bddf..b6a53877e5 100644 --- a/apps/chat-e2e/src/core/baseFixtures.ts +++ b/apps/chat-e2e/src/core/baseFixtures.ts @@ -3,6 +3,8 @@ import { LoginPage } from '@/src/ui/pages'; import { Auth0Page } from '@/src/ui/pages/auth0Page'; import { test as base } from '@playwright/test'; +export const skipReason = 'Execute test on CI env only'; + const test = base.extend<{ loginPage: LoginPage; auth0Page: Auth0Page; diff --git a/apps/chat-e2e/src/core/localStorageManager.ts b/apps/chat-e2e/src/core/localStorageManager.ts index 193ff22e71..1cfc26c52b 100644 --- a/apps/chat-e2e/src/core/localStorageManager.ts +++ b/apps/chat-e2e/src/core/localStorageManager.ts @@ -1,7 +1,5 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; import { Settings } from '@/chat/types/settings'; +import { TestConversation, TestFolder, TestPrompt } from '@/src/testData'; import { Page } from '@playwright/test'; export class LocalStorageManager { @@ -31,50 +29,50 @@ export class LocalStorageManager { window.localStorage.setItem('settings', settings); }; - async setConversationHistory(...conversation: Conversation[]) { + async setConversationHistory(...conversation: TestConversation[]) { await this.page.addInitScript( this.setConversationHistoryKey(), JSON.stringify(conversation), ); } - async updateConversationHistory(...conversation: Conversation[]) { + async updateConversationHistory(...conversation: TestConversation[]) { await this.page.evaluate( this.setConversationHistoryKey(), JSON.stringify(conversation), ); } - async setSelectedConversation(...conversation: Conversation[]) { + async setSelectedConversation(...conversation: TestConversation[]) { await this.page.addInitScript( this.setSelectedConversationKey(), JSON.stringify(conversation.map((c) => c.id)), ); } - async updateSelectedConversation(...conversation: Conversation[]) { + async updateSelectedConversation(...conversation: TestConversation[]) { await this.page.evaluate( this.setSelectedConversationKey(), JSON.stringify(conversation.map((c) => c.id)), ); } - async setFolders(...folders: FolderInterface[]) { + async setFolders(...folders: TestFolder[]) { await this.page.addInitScript( this.setFoldersKey(), JSON.stringify(folders), ); } - async updateFolders(...folders: FolderInterface[]) { + async updateFolders(...folders: TestFolder[]) { await this.page.evaluate(this.setFoldersKey(), JSON.stringify(folders)); } - async setPrompts(...prompt: Prompt[]) { + async setPrompts(...prompt: TestPrompt[]) { await this.page.addInitScript(this.setPromptsKey(), JSON.stringify(prompt)); } - async updatePrompts(...prompt: Prompt[]) { + async updatePrompts(...prompt: TestPrompt[]) { await this.page.evaluate(this.setPromptsKey(), JSON.stringify(prompt)); } diff --git a/apps/chat-e2e/src/testData/api/chatApiHelper.ts b/apps/chat-e2e/src/testData/api/chatApiHelper.ts index 5693f657c4..0610116de3 100644 --- a/apps/chat-e2e/src/testData/api/chatApiHelper.ts +++ b/apps/chat-e2e/src/testData/api/chatApiHelper.ts @@ -1,9 +1,8 @@ -import { Conversation } from '@/chat/types/chat'; -import { API } from '@/src/testData'; +import { API, TestConversation } from '@/src/testData'; import { BaseApiHelper } from '@/src/testData/api/baseApiHelper'; export class ChatApiHelper extends BaseApiHelper { - public async postRequest(conversation: Conversation) { + public async postRequest(conversation: TestConversation) { const requestData = { ...conversation, messages: [conversation.messages[0]], diff --git a/apps/chat-e2e/src/testData/api/itemApiHelper.ts b/apps/chat-e2e/src/testData/api/itemApiHelper.ts index 4ed4dbb3bb..94b6c8b168 100644 --- a/apps/chat-e2e/src/testData/api/itemApiHelper.ts +++ b/apps/chat-e2e/src/testData/api/itemApiHelper.ts @@ -1,10 +1,7 @@ -import { Conversation } from '@/chat/types/chat'; import { BackendDataEntity, BackendDataNodeType } from '@/chat/types/common'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; -import { API } from '@/src/testData'; +import { API, TestConversation, TestFolder, TestPrompt } from '@/src/testData'; import { BaseApiHelper } from '@/src/testData/api/baseApiHelper'; -import { BucketUtil, ConversationUtil } from '@/src/utils'; +import { BucketUtil, ItemUtil } from '@/src/utils'; import { expect } from '@playwright/test'; export class ItemApiHelper extends BaseApiHelper { @@ -42,29 +39,28 @@ export class ItemApiHelper extends BaseApiHelper { } public async createConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ) { for (const conversation of conversations) { const path = await this.getItemPath(conversation, ...folders); - conversation.id = - path.length === 0 - ? ConversationUtil.getApiConversationId(conversation) - : `${path}/${ConversationUtil.getApiConversationId(conversation)}`; - await this.createItem(API.conversationsHost, conversation); + conversation.folderId = ItemUtil.getApiConversationFolderId(path); + conversation.id = ItemUtil.getApiConversationId(conversation, path); + await this.createItem(conversation); } } - public async createPrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + public async createPrompts(prompts: TestPrompt[], ...folders: TestFolder[]) { for (const prompt of prompts) { const path = await this.getItemPath(prompt, ...folders); - prompt.id = path.length === 0 ? prompt.name : `${path}/${prompt.name}`; - await this.createItem(API.promptsHost, prompt); + prompt.folderId = ItemUtil.getApiPromptFolderId(path); + prompt.id = ItemUtil.getApiPromptId(prompt, path); + await this.createItem(prompt); } } - private async createItem(host: string, item: Prompt | Conversation) { - const url = `${host}/${BucketUtil.getBucket()}/${item.id}`; + private async createItem(item: TestPrompt | TestConversation) { + const url = `api/${item.id}`; const response = await this.request.put(url, { data: item, }); @@ -75,8 +71,8 @@ export class ItemApiHelper extends BaseApiHelper { } private async getItemPath( - item: Prompt | Conversation, - ...folders: FolderInterface[] + item: TestPrompt | TestConversation, + ...folders: TestFolder[] ) { let path = ''; const itemFolderId = item.folderId; @@ -87,7 +83,6 @@ export class ItemApiHelper extends BaseApiHelper { itemFolder = folders.find((f) => f.id === itemFolder?.folderId); path = `${itemFolder?.name}/${path}`; } - item.folderId = path; } return path; } diff --git a/apps/chat-e2e/src/testData/conversationHistory/conversationBuilder.ts b/apps/chat-e2e/src/testData/conversationHistory/conversationBuilder.ts index 9e909c781e..7a540331f5 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/conversationBuilder.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/conversationBuilder.ts @@ -10,21 +10,19 @@ import { Message, Replay, } from '@/chat/types/chat'; -import { constructPath } from '@/chat/utils/app/file'; -import { getRootId } from '@/chat/utils/app/id'; -import { ApiKeys } from '@/chat/utils/server/api'; import { ModelsUtil } from '@/src/utils'; import { v4 as uuidv4 } from 'uuid'; +export interface TestConversation extends Omit { + folderId?: string | undefined; +} + export class ConversationBuilder { - private conversation: Conversation; + private conversation: TestConversation; constructor() { this.conversation = { - id: constructPath( - getRootId({ apiKey: ApiKeys.Conversations }), - DEFAULT_CONVERSATION_NAME, - ), + id: uuidv4(), name: DEFAULT_CONVERSATION_NAME, messages: [], model: { id: ModelsUtil.getDefaultModel()!.id }, @@ -34,7 +32,6 @@ export class ConversationBuilder { selectedAddons: ModelsUtil.getDefaultModel()!.selectedAddons ?? [], lastActivityDate: Date.now(), isMessageStreaming: false, - folderId: getRootId({ apiKey: ApiKeys.Conversations }), }; } @@ -42,7 +39,7 @@ export class ConversationBuilder { return this.conversation; } - setConversation(conversation: Conversation): Conversation { + setConversation(conversation: TestConversation): TestConversation { this.conversation = conversation; return conversation; } @@ -77,7 +74,7 @@ export class ConversationBuilder { return this; } - withFolderId(folderId: string): ConversationBuilder { + withFolderId(folderId: undefined | string): ConversationBuilder { this.conversation.folderId = folderId; return this; } @@ -97,7 +94,7 @@ export class ConversationBuilder { return this; } - build(): Conversation { + build(): TestConversation { return this.conversation; } } diff --git a/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts b/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts index d4feefe14c..5ebd6810c1 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/conversationData.ts @@ -1,11 +1,13 @@ -import { Conversation, Message, Role, Stage } from '@/chat/types/chat'; -import { FolderInterface, FolderType } from '@/chat/types/folder'; +import { Message, Role, Stage } from '@/chat/types/chat'; +import { FolderType } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; import { ConversationBuilder, ExpectedConstants, MenuOptions, ModelIds, + TestConversation, + TestFolder, } from '@/src/testData'; import { FileApiHelper } from '@/src/testData/api'; import { FolderData } from '@/src/testData/folders/folderData'; @@ -14,8 +16,8 @@ import { GeneratorUtil } from '@/src/utils/generatorUtil'; import { v4 as uuidv4 } from 'uuid'; export interface FolderConversation { - conversations: Conversation[]; - folders: FolderInterface; + conversations: TestConversation[]; + folders: TestFolder; } export class ConversationData extends FolderData { @@ -131,13 +133,13 @@ export class ConversationData extends FolderData { return defaultConversation; } - public prepareDefaultReplayConversation(conversation: Conversation) { + public prepareDefaultReplayConversation(conversation: TestConversation) { const userMessages = conversation.messages.filter((m) => m.role === 'user'); return this.fillReplayData(conversation, userMessages!); } public preparePartiallyReplayedStagedConversation( - conversation: Conversation, + conversation: TestConversation, ) { const userMessages = conversation.messages.filter((m) => m.role === 'user'); const assistantMessage = conversation.messages.filter( @@ -158,7 +160,7 @@ export class ConversationData extends FolderData { return replayConversation; } - public preparePartiallyReplayedConversation(conversation: Conversation) { + public preparePartiallyReplayedConversation(conversation: TestConversation) { const defaultReplayConversation = this.prepareDefaultReplayConversation(conversation); const assistantMessages = conversation.messages.find( @@ -226,10 +228,8 @@ export class ConversationData extends FolderData { return super.prepareNestedFolder(nestedLevel, FolderType.Chat); } - public prepareConversationsForNestedFolders( - nestedFolders: FolderInterface[], - ) { - const nestedConversations: Conversation[] = []; + public prepareConversationsForNestedFolders(nestedFolders: TestFolder[]) { + const nestedConversations: TestConversation[] = []; for (const item of nestedFolders) { const nestedConversation = this.prepareDefaultConversation(); nestedConversations.push(nestedConversation); @@ -243,7 +243,7 @@ export class ConversationData extends FolderData { conversationsCount: number, ): FolderConversation { const folder = this.prepareFolder(); - const conversations: Conversation[] = []; + const conversations: TestConversation[] = []; for (let i = 1; i <= conversationsCount; i++) { const conversation = this.prepareDefaultConversation(); conversation.folderId = folder.id; @@ -294,7 +294,7 @@ export class ConversationData extends FolderData { } public prepareDefaultPlaybackConversation( - conversation: Conversation, + conversation: TestConversation, playbackIndex?: number, ) { const messages = conversation.messages; @@ -348,9 +348,9 @@ export class ConversationData extends FolderData { } private fillReplayData( - conversation: Conversation, + conversation: TestConversation, userMessages: Message[], - ): Conversation { + ): TestConversation { const replayConversation = JSON.parse(JSON.stringify(conversation)); replayConversation.id = uuidv4(); replayConversation.name = `${ExpectedConstants.replayConversation}${conversation.name}`; diff --git a/apps/chat-e2e/src/testData/conversationHistory/folderBuilder.ts b/apps/chat-e2e/src/testData/conversationHistory/folderBuilder.ts index f4178b1093..c0ee72e0f2 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/folderBuilder.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/folderBuilder.ts @@ -2,8 +2,12 @@ import { FolderInterface, FolderType } from '@/chat/types/folder'; import { ExpectedConstants } from '@/src/testData'; import { v4 as uuidv4 } from 'uuid'; +export interface TestFolder extends Omit { + folderId?: string | undefined; +} + export class FolderBuilder { - private folder: FolderInterface; + private folder: TestFolder; constructor() { this.folder = { @@ -37,7 +41,7 @@ export class FolderBuilder { return this; } - build(): FolderInterface { + build(): TestFolder { return this.folder; } } diff --git a/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts b/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts index cb18e266af..b0e024de99 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/importConversation.ts @@ -1,32 +1,38 @@ -import { Conversation } from '@/chat/types/chat'; import { isApiStorageType } from '@/src/hooks/global-setup'; -import { FolderConversation } from '@/src/testData'; +import { + FolderConversation, + TestConversation, + TestFolder, + TestPrompt, +} from '@/src/testData'; import { UploadDownloadData } from '@/src/ui/pages'; -import { ConversationUtil } from '@/src/utils'; +import { ItemUtil } from '@/src/utils'; import { FileUtil } from '@/src/utils/fileUtil'; +export interface TestImportFormat { + history: TestConversation[]; + folders: TestFolder[]; + prompts: TestPrompt[]; + version?: number; +} + export class ImportConversation { public static prepareConversationFile( - importedConversation: Conversation, + importedConversation: TestConversation, importedFolder?: FolderConversation, ): UploadDownloadData { ImportConversation.setImportedItemAttributes( importedConversation, importedFolder, ); - const folderConversationToImport = isApiStorageType - ? { - folders: importedFolder ? [importedFolder.folders] : [], - history: [importedConversation], - prompts: [], - version: 5, - } - : { - folders: importedFolder ? [importedFolder.folders] : [], - history: [importedConversation], - prompts: [], - version: 4, - }; + const folderConversationToImport: TestImportFormat = { + folders: importedFolder ? [importedFolder.folders] : [], + history: [importedConversation], + prompts: [], + }; + isApiStorageType + ? (folderConversationToImport.version = 5) + : (folderConversationToImport.version = 4); return { path: FileUtil.writeDataToFile(folderConversationToImport), isDownloadedData: false, @@ -34,17 +40,22 @@ export class ImportConversation { } private static setImportedItemAttributes( - importedConversation: Conversation, + importedConversation: TestConversation, importedFolder?: FolderConversation, ) { if (isApiStorageType) { if (importedFolder) { - importedFolder.folders.id = importedFolder.folders.name; + importedFolder.folders.id = ItemUtil.getApiConversationFolderId( + importedFolder.folders.name, + ); importedConversation.folderId = importedFolder.folders.id; - importedConversation.id = `${importedConversation.folderId}/${ConversationUtil.getApiConversationId(importedConversation)}`; + importedConversation.id = ItemUtil.getApiConversationId( + importedConversation, + importedFolder.folders.name, + ); } else { importedConversation.id = - ConversationUtil.getApiConversationId(importedConversation); + ItemUtil.getApiConversationId(importedConversation); } } else { importedConversation.folderId = importedFolder diff --git a/apps/chat-e2e/src/testData/conversationHistory/importPrompt.ts b/apps/chat-e2e/src/testData/conversationHistory/importPrompt.ts index 027b032326..a2a1d3d307 100644 --- a/apps/chat-e2e/src/testData/conversationHistory/importPrompt.ts +++ b/apps/chat-e2e/src/testData/conversationHistory/importPrompt.ts @@ -1,12 +1,11 @@ -import { Prompt } from '@/chat/types/prompt'; import { ImportPromtsResponse } from '@/chat/utils/app/import-export'; -import { FolderPrompt } from '@/src/testData'; +import { FolderPrompt, TestPrompt } from '@/src/testData'; import { UploadDownloadData } from '@/src/ui/pages'; import { FileUtil } from '@/src/utils/fileUtil'; export class ImportPrompt { public static preparePromptFile( - importedPrompt: Prompt, + importedPrompt: TestPrompt, importedFolder?: FolderPrompt, ): UploadDownloadData { importedPrompt.folderId = importedFolder diff --git a/apps/chat-e2e/src/testData/injector/apiInjector.ts b/apps/chat-e2e/src/testData/injector/apiInjector.ts index cc255c4044..cab6b9dc05 100644 --- a/apps/chat-e2e/src/testData/injector/apiInjector.ts +++ b/apps/chat-e2e/src/testData/injector/apiInjector.ts @@ -1,6 +1,4 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; +import { TestConversation, TestFolder, TestPrompt } from '@/src/testData'; import { ItemApiHelper } from '@/src/testData/api'; import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface'; @@ -12,29 +10,29 @@ export class ApiInjector implements DataInjectorInterface { } async createPrompts( - prompts: Prompt[], - ...folders: FolderInterface[] + prompts: TestPrompt[], + ...folders: TestFolder[] ): Promise { await this.itemApiHelper.createPrompts(prompts, ...folders); } async updateConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ): Promise { await this.itemApiHelper.createConversations(conversations, ...folders); } async updatePrompts( - prompts: Prompt[], - ...folders: FolderInterface[] + prompts: TestPrompt[], + ...folders: TestFolder[] ): Promise { await this.itemApiHelper.createPrompts(prompts, ...folders); } async createConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ) { await this.itemApiHelper.createConversations(conversations, ...folders); } diff --git a/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts b/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts index 2009c5efc4..180e2068a1 100644 --- a/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts +++ b/apps/chat-e2e/src/testData/injector/browserStorageInjector.ts @@ -1,7 +1,5 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; import { LocalStorageManager } from '@/src/core/localStorageManager'; +import { TestConversation, TestFolder, TestPrompt } from '@/src/testData'; import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface'; export class BrowserStorageInjector implements DataInjectorInterface { @@ -12,27 +10,27 @@ export class BrowserStorageInjector implements DataInjectorInterface { } async createConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ): Promise { await this.localStorageManager.setFolders(...folders); await this.localStorageManager.setConversationHistory(...conversations); } async updateConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ) { await this.localStorageManager.updateConversationHistory(...conversations); await this.localStorageManager.updateFolders(...folders); } - async createPrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + async createPrompts(prompts: TestPrompt[], ...folders: TestFolder[]) { await this.localStorageManager.setFolders(...folders); await this.localStorageManager.setPrompts(...prompts); } - async updatePrompts(prompts: Prompt[], ...folders: FolderInterface[]) { + async updatePrompts(prompts: TestPrompt[], ...folders: TestFolder[]) { await this.localStorageManager.updatePrompts(...prompts); await this.localStorageManager.updateFolders(...folders); } diff --git a/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts b/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts index be419ed46a..f86e605c7d 100644 --- a/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts +++ b/apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts @@ -1,23 +1,15 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; +import { TestConversation, TestFolder, TestPrompt } from '@/src/testData'; export interface DataInjectorInterface { createConversations( - conversations: Conversation[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ): Promise; updateConversations( - conversations: Conversation[], - ...folders: FolderInterface[] - ): Promise; - createPrompts( - prompts: Prompt[], - ...folders: FolderInterface[] - ): Promise; - updatePrompts( - prompts: Prompt[], - ...folders: FolderInterface[] + conversations: TestConversation[], + ...folders: TestFolder[] ): Promise; + createPrompts(prompts: TestPrompt[], ...folders: TestFolder[]): Promise; + updatePrompts(prompts: TestPrompt[], ...folders: TestFolder[]): Promise; deleteAllData(): Promise; } diff --git a/apps/chat-e2e/src/testData/prompts/promptBuilder.ts b/apps/chat-e2e/src/testData/prompts/promptBuilder.ts index 8f0b09ba85..c6c0a4b3f4 100644 --- a/apps/chat-e2e/src/testData/prompts/promptBuilder.ts +++ b/apps/chat-e2e/src/testData/prompts/promptBuilder.ts @@ -2,8 +2,12 @@ import { Prompt } from '@/chat/types/prompt'; import { ExpectedConstants } from '@/src/testData'; import { v4 as uuidv4 } from 'uuid'; +export interface TestPrompt extends Omit { + folderId?: string | undefined; +} + export class PromptBuilder { - private prompt: Prompt; + private prompt: TestPrompt; constructor() { this.prompt = { @@ -43,7 +47,7 @@ export class PromptBuilder { return this; } - build(): Prompt { + build(): TestPrompt { return this.prompt; } } diff --git a/apps/chat-e2e/src/testData/prompts/promptData.ts b/apps/chat-e2e/src/testData/prompts/promptData.ts index 411541751e..268270a911 100644 --- a/apps/chat-e2e/src/testData/prompts/promptData.ts +++ b/apps/chat-e2e/src/testData/prompts/promptData.ts @@ -1,12 +1,15 @@ -import { FolderInterface, FolderType } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; +import { FolderType } from '@/chat/types/folder'; +import { TestFolder } from '@/src/testData'; import { FolderData } from '@/src/testData/folders/folderData'; -import { PromptBuilder } from '@/src/testData/prompts/promptBuilder'; +import { + PromptBuilder, + TestPrompt, +} from '@/src/testData/prompts/promptBuilder'; import { GeneratorUtil } from '@/src/utils/generatorUtil'; export interface FolderPrompt { - prompts: Prompt[]; - folders: FolderInterface; + prompts: TestPrompt[]; + folders: TestFolder; } export class PromptData extends FolderData { @@ -57,7 +60,7 @@ export class PromptData extends FolderData { public preparePromptsInFolder(promptsCount: number): FolderPrompt { const folder = this.prepareFolder(); - const prompts: Prompt[] = []; + const prompts: TestPrompt[] = []; for (let i = 1; i <= promptsCount; i++) { const prompt = this.prepareDefaultPrompt(); prompt.folderId = folder.id; @@ -75,8 +78,8 @@ export class PromptData extends FolderData { .build(); } - public preparePromptsForNestedFolders(nestedFolders: FolderInterface[]) { - const nestedPrompts: Prompt[] = []; + public preparePromptsForNestedFolders(nestedFolders: TestFolder[]) { + const nestedPrompts: TestPrompt[] = []; for (const item of nestedFolders) { const nestedPrompt = this.prepareDefaultPrompt(); nestedPrompts.push(nestedPrompt); diff --git a/apps/chat-e2e/src/tests/announcementBanner.test.ts b/apps/chat-e2e/src/tests/announcementBanner.test.ts index bba1fe1707..cfce7d1abf 100644 --- a/apps/chat-e2e/src/tests/announcementBanner.test.ts +++ b/apps/chat-e2e/src/tests/announcementBanner.test.ts @@ -1,6 +1,9 @@ -import { Conversation } from '@/chat/types/chat'; import dialTest from '@/src/core/dialFixtures'; -import { AccountMenuOptions, ExpectedMessages } from '@/src/testData'; +import { + AccountMenuOptions, + ExpectedMessages, + TestConversation, +} from '@/src/testData'; import { expect } from '@playwright/test'; dialTest( @@ -24,7 +27,7 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-1576', 'EPMRTC-1580', 'EPMRTC-1577'); - let conversation: Conversation; + let conversation: TestConversation; let chatBarBounding; let promptBarBounding; diff --git a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts index ca6a48ebde..6babff64e1 100644 --- a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts @@ -1,3 +1,4 @@ +import test, { skipReason } from '@/src/core/baseFixtures'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, ModelIds } from '@/src/testData'; import { expect } from '@playwright/test'; @@ -38,6 +39,7 @@ for (const modelToUse of modelsForArithmeticRequest) { dialTest( `Generate arithmetic response for model: ${modelToUse.modelId}`, async ({ conversationData, chatApiHelper }) => { + test.skip(process.env.E2E_HOST === undefined, skipReason); const conversation = conversationData.prepareModelConversation( 0, modelToUse.isSysPromptAllowed diff --git a/apps/chat-e2e/src/tests/chatApi/attachment.test.ts b/apps/chat-e2e/src/tests/chatApi/attachment.test.ts index b1d28fda75..fe584ebb4c 100644 --- a/apps/chat-e2e/src/tests/chatApi/attachment.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/attachment.test.ts @@ -1,3 +1,4 @@ +import test, { skipReason } from '@/src/core/baseFixtures'; import dialTest from '@/src/core/dialFixtures'; import { Attachment, @@ -24,6 +25,7 @@ for (const modelToUse of modelsForRequestWithAttachment) { dialTest( `Generate response on request with attachment for model: ${modelToUse.modelId}`, async ({ conversationData, chatApiHelper }) => { + test.skip(process.env.E2E_HOST === undefined, skipReason); const conversation = conversationData.prepareConversationWithAttachment( imageUrl, modelToUse.modelId, diff --git a/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts b/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts index 365210218c..2de30c62ad 100644 --- a/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/imageGeneration.test.ts @@ -1,3 +1,4 @@ +import test, { skipReason } from '@/src/core/baseFixtures'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, ModelIds } from '@/src/testData'; import { expect } from '@playwright/test'; @@ -14,6 +15,7 @@ for (const modelToUse of modelsForImageGeneration) { dialTest( `Generate image for model: ${modelToUse}`, async ({ conversationData, chatApiHelper }) => { + test.skip(process.env.E2E_HOST === undefined, skipReason); const conversation = conversationData.prepareModelConversationBasedOnRequests(modelToUse, [ 'draw smiling emoticon', diff --git a/apps/chat-e2e/src/tests/chatBarConversation.test.ts b/apps/chat-e2e/src/tests/chatBarConversation.test.ts index db85315b0c..0d499e0567 100644 --- a/apps/chat-e2e/src/tests/chatBarConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarConversation.test.ts @@ -1,5 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { isApiStorageType } from '@/src/hooks/global-setup'; @@ -9,6 +7,8 @@ import { ExpectedMessages, MenuOptions, ModelIds, + TestConversation, + TestFolder, } from '@/src/testData'; import { Colors, Overflow, Styles } from '@/src/ui/domData'; import { GeneratorUtil } from '@/src/utils'; @@ -69,7 +69,7 @@ dialTest( }) => { setTestIds('EPMRTC-588', 'EPMRTC-816', 'EPMRTC-1494'); const newName = 'new name to cancel'; - let conversation: Conversation; + let conversation: TestConversation; const conversationName = GeneratorUtil.randomString(70); await dialTest.step('Prepare conversation with long name', async () => { @@ -589,7 +589,7 @@ dialTest( }) => { setTestIds('EPMRTC-863', 'EPMRTC-942'); const folderName = GeneratorUtil.randomString(70); - let conversation: Conversation; + let conversation: TestConversation; await dialTest.step( 'Prepare conversation and folder with long name to move conversation in', @@ -1033,8 +1033,8 @@ dialTest( }) => { setTestIds('EPMRTC-1201'); - let firstFolder: FolderInterface; - let secondFolder: FolderInterface; + let firstFolder: TestFolder; + let secondFolder: TestFolder; await dialTest.step( 'Prepare conversations in folders with different content', diff --git a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts index f0a86cf842..d35906c16f 100644 --- a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts @@ -1,11 +1,11 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, FolderConversation, MenuOptions, + TestConversation, + TestFolder, } from '@/src/testData'; import { Overflow, Styles } from '@/src/ui/domData'; import { GeneratorUtil } from '@/src/utils'; @@ -393,8 +393,8 @@ dialTest( setTestIds('EPMRTC-1372'); const levelsCount = 3; const levelToDelete = 2; - let nestedFolders: FolderInterface[]; - let nestedConversations: Conversation[] = []; + let nestedFolders: TestFolder[]; + let nestedConversations: TestConversation[] = []; await dialTest.step( 'Prepare nested folders with conversations inside each one', diff --git a/apps/chat-e2e/src/tests/chatExportImport.test.ts b/apps/chat-e2e/src/tests/chatExportImport.test.ts index 258052c96a..137bdc71f8 100644 --- a/apps/chat-e2e/src/tests/chatExportImport.test.ts +++ b/apps/chat-e2e/src/tests/chatExportImport.test.ts @@ -1,5 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { @@ -9,6 +7,8 @@ import { Import, MenuOptions, ModelIds, + TestConversation, + TestFolder, } from '@/src/testData'; import { ImportConversation } from '@/src/testData/conversationHistory/importConversation'; import { UploadDownloadData } from '@/src/ui/pages'; @@ -33,7 +33,7 @@ dialTest.beforeAll(async () => { gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -dialTest( +dialTest.skip( 'Export and import one chat in a folder.\n' + `Export and import one chat in a folder when folder doesn't exist`, async ({ @@ -151,8 +151,7 @@ dialTest( }, ); -//TODO: empty folder export -dialTest( +dialTest.skip( 'Export and import chat structure with all conversations', async ({ dialHomePage, @@ -165,9 +164,9 @@ dialTest( confirmationDialog, }) => { setTestIds('EPMRTC-907'); - let nestedFolders: FolderInterface[]; - let conversationOutsideFolder: Conversation; - let nestedConversations: Conversation[] = []; + let nestedFolders: TestFolder[]; + let conversationOutsideFolder: TestConversation; + let nestedConversations: TestConversation[] = []; let exportedData: UploadDownloadData; await dialTest.step( @@ -232,7 +231,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Existed chats stay after import', async ({ dialHomePage, @@ -246,9 +245,9 @@ dialTest( }) => { setTestIds('EPMRTC-913'); let conversationsInFolder: FolderConversation; - let conversationOutsideFolder: Conversation; - let importedFolderConversation: Conversation; - let importedRootConversation: Conversation; + let conversationOutsideFolder: TestConversation; + let importedFolderConversation: TestConversation; + let importedRootConversation: TestConversation; let importedNewFolderConversation: FolderConversation; await dialTest.step( @@ -384,7 +383,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Continue working with imported file. Regenerate response.\n' + 'Continue working with imported file. Send a message.\n' + 'Continue working with imported file. Edit a message', @@ -397,7 +396,7 @@ dialTest( chatBar, }) => { setTestIds('EPMRTC-923', 'EPMRTC-924', 'EPMRTC-925'); - let importedRootConversation: Conversation; + let importedRootConversation: TestConversation; const requests = ['1+2', '2+3', '3+4']; await dialTest.step( @@ -608,8 +607,8 @@ dialTest.skip( folderDropdownMenu, }) => { setTestIds('EPMRTC-1359', 'EPMRTC-1368', 'EPMRTC-1369'); - let nestedFolders: FolderInterface[]; - let nestedConversations: Conversation[] = []; + let nestedFolders: TestFolder[]; + let nestedConversations: TestConversation[] = []; let exportedData: UploadDownloadData; await dialTest.step( 'Prepare 3 level nested folders with conversations in each folder', @@ -751,8 +750,8 @@ dialTest.skip( conversationDropdownMenu, }) => { setTestIds('EPMRTC-1374'); - let nestedFolders: FolderInterface[]; - let nestedConversations: Conversation[] = []; + let nestedFolders: TestFolder[]; + let nestedConversations: TestConversation[] = []; const updatedConversationNames: string[] = []; await dialTest.step( @@ -882,8 +881,8 @@ dialTest.skip( conversationDropdownMenu, }) => { setTestIds('EPMRTC-1387'); - let nestedFolders: FolderInterface[]; - let thirdLevelFolderConversation: Conversation; + let nestedFolders: TestFolder[]; + let thirdLevelFolderConversation: TestConversation; let exportedData: UploadDownloadData; await dialTest.step( diff --git a/apps/chat-e2e/src/tests/chatHeader.test.ts b/apps/chat-e2e/src/tests/chatHeader.test.ts index 1bae3b381d..ce5326ca75 100644 --- a/apps/chat-e2e/src/tests/chatHeader.test.ts +++ b/apps/chat-e2e/src/tests/chatHeader.test.ts @@ -1,7 +1,6 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; -import { ExpectedMessages } from '@/src/testData'; +import { ExpectedMessages, TestConversation } from '@/src/testData'; import { ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; @@ -31,7 +30,7 @@ dialTest( iconApiHelper, }) => { setTestIds('EPMRTC-1115', 'EPMRTC-473'); - let conversation: Conversation; + let conversation: TestConversation; const temp = 0; const request = 'This is a test request'; const expectedModelIcon = await iconApiHelper.getEntityIcon(defaultModel); @@ -178,7 +177,7 @@ dialTest( confirmationDialog, }) => { setTestIds('EPMRTC-490', 'EPMRTC-491'); - let conversation: Conversation; + let conversation: TestConversation; await dialTest.step('Prepare conversation with history', async () => { conversation = await conversationData.prepareModelConversationBasedOnRequests( diff --git a/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts b/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts index 9e3e174763..d413b14c13 100644 --- a/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts +++ b/apps/chat-e2e/src/tests/chatHeaderSettings.test.ts @@ -1,7 +1,6 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; -import { ExpectedMessages } from '@/src/testData'; +import { ExpectedMessages, TestConversation } from '@/src/testData'; import { GeneratorUtil, ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; @@ -26,7 +25,7 @@ dialTest( dataInjector, }) => { setTestIds('EPMRTC-449'); - let conversation: Conversation; + let conversation: TestConversation; const allModels = ModelsUtil.getModels(); const randomModel = GeneratorUtil.randomArrayElement( allModels.filter((m) => m.id !== defaultModel.id), diff --git a/apps/chat-e2e/src/tests/compareMode.test.ts b/apps/chat-e2e/src/tests/compareMode.test.ts index 167faf538a..76e2b1ae06 100644 --- a/apps/chat-e2e/src/tests/compareMode.test.ts +++ b/apps/chat-e2e/src/tests/compareMode.test.ts @@ -1,4 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { isApiStorageType } from '@/src/hooks/global-setup'; @@ -11,6 +10,7 @@ import { ModelIds, Rate, Side, + TestConversation, } from '@/src/testData'; import { Overflow, Styles } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; @@ -74,10 +74,10 @@ dialTest( iconApiHelper, }) => { setTestIds('EPMRTC-546', 'EPMRTC-383'); - let firstModelConversation: Conversation; - let secondModelConversation: Conversation; + let firstModelConversation: TestConversation; + let secondModelConversation: TestConversation; let modelConversationInFolder: FolderConversation; - let thirdModelConversation: Conversation; + let thirdModelConversation: TestConversation; const conversationName = GeneratorUtil.randomString(7); await dialTest.step('Prepare three conversations to compare', async () => { @@ -195,10 +195,10 @@ dialTest( compare, }) => { setTestIds('EPMRTC-1133', 'EPMRTC-541'); - let modelConversation: Conversation; - let replayConversation: Conversation; - let firstEmptyConversation: Conversation; - let secondEmptyConversation: Conversation; + let modelConversation: TestConversation; + let replayConversation: TestConversation; + let firstEmptyConversation: TestConversation; + let secondEmptyConversation: TestConversation; const conversationName = GeneratorUtil.randomString(7); await dialTest.step( @@ -285,8 +285,8 @@ dialTest( leftChatHeader, }) => { setTestIds('EPMRTC-544', 'EPMRTC-545'); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; await dialTest.step( 'Prepare two conversations in compare mode', @@ -353,11 +353,11 @@ dialTest( const firstRequest = 'What is EPAM official name?'; const secondRequest = 'What is DIAL?'; const thirdRequest = 'Who is EPAM founder?'; - let firstConversation: Conversation; - let secondConversation: Conversation; - let thirdConversation: Conversation; - let forthConversation: Conversation; - let fifthConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; + let thirdConversation: TestConversation; + let forthConversation: TestConversation; + let fifthConversation: TestConversation; await dialTest.step( 'Prepare five conversations with requests combination', @@ -454,8 +454,8 @@ dialTest( }) => { setTestIds('EPMRTC-552', 'EPMRTC-558'); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; const firstPrompt = 'repeat the same text'; const firstTemp = 1; @@ -588,8 +588,8 @@ dialTest( }) => { setTestIds('EPMRTC-553', 'EPMRTC-555'); const request = ['beautiful']; - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; await dialTest.step('Prepare two conversations for comparing', async () => { firstConversation = @@ -705,8 +705,8 @@ dialTest( }) => { dialTest.slow(); setTestIds('EPMRTC-1021'); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; const models = ModelsUtil.getModels(); const initRandomModel = GeneratorUtil.randomArrayElement(models); const modelsForUpdate = models.filter((m) => m !== initRandomModel); @@ -879,8 +879,8 @@ dialTest( }) => { dialTest.slow(); setTestIds('EPMRTC-556', 'EPMRTC-1134'); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; const sides = Object.values(Side); await dialTest.step('Prepare two conversations for comparing', async () => { @@ -971,10 +971,10 @@ dialTest( const underscoreSearchTerm = '_'; const noResultSearchTerm = 'epaQ'; - let firstConversation: Conversation; - let secondConversation: Conversation; - let thirdConversation: Conversation; - let fourthConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; + let thirdConversation: TestConversation; + let fourthConversation: TestConversation; const matchedConversations: string[] = []; await dialTest.step( @@ -1177,8 +1177,8 @@ dialTest( leftChatHeader, }) => { setTestIds('EPMRTC-542', 'EPMRTC-543', 'EPMRTC-548', 'EPMRTC-828'); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; await dialTest.step( 'Prepare two conversations for compare mode', @@ -1404,8 +1404,8 @@ dialTest( 'EPMRTC-563', 'EPMRTC-564', ); - let firstConversation: Conversation; - let secondConversation: Conversation; + let firstConversation: TestConversation; + let secondConversation: TestConversation; const firstConversationRequests = ['1+2', '2+3', '3+4']; const secondConversationRequests = ['1+2', '4+5', '5+6']; let updatedRequestContent: string; diff --git a/apps/chat-e2e/src/tests/folderPrompts.test.ts b/apps/chat-e2e/src/tests/folderPrompts.test.ts index e53b283322..d24be023ad 100644 --- a/apps/chat-e2e/src/tests/folderPrompts.test.ts +++ b/apps/chat-e2e/src/tests/folderPrompts.test.ts @@ -1,5 +1,3 @@ -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; import { isApiStorageType } from '@/src/hooks/global-setup'; import { @@ -7,6 +5,8 @@ import { ExpectedMessages, FolderPrompt, MenuOptions, + TestFolder, + TestPrompt, } from '@/src/testData'; import { GeneratorUtil } from '@/src/utils'; import { expect } from '@playwright/test'; @@ -427,14 +427,12 @@ dialTest( confirmationDialog, promptData, setTestIds, - setIssueIds, }) => { setTestIds('EPMRTC-1384'); - setIssueIds('671'); const levelsCount = 3; const levelToDelete = 2; - let nestedFolders: FolderInterface[]; - const nestedPrompts: Prompt[] = []; + let nestedFolders: TestFolder[]; + const nestedPrompts: TestPrompt[] = []; await dialTest.step( 'Prepare nested folders with prompts inside each one', diff --git a/apps/chat-e2e/src/tests/listing.test.ts b/apps/chat-e2e/src/tests/listing.test.ts index e82a79c7eb..d01f0078ba 100644 --- a/apps/chat-e2e/src/tests/listing.test.ts +++ b/apps/chat-e2e/src/tests/listing.test.ts @@ -1,10 +1,8 @@ -import test from '@/src/core/baseFixtures'; +import test, { skipReason } from '@/src/core/baseFixtures'; import { AddonIds, ExpectedMessages, ModelIds } from '@/src/testData'; import { ModelsUtil } from '@/src/utils'; import { expect } from '@playwright/test'; -const skipReason = 'Execute test on CI env only'; - test('Models API listing', async () => { test.skip(process.env.E2E_HOST === undefined, skipReason); const models = ModelsUtil.getModels(); diff --git a/apps/chat-e2e/src/tests/playBack.test.ts b/apps/chat-e2e/src/tests/playBack.test.ts index b6fc863a69..2d75e82a38 100644 --- a/apps/chat-e2e/src/tests/playBack.test.ts +++ b/apps/chat-e2e/src/tests/playBack.test.ts @@ -1,4 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { @@ -6,6 +5,7 @@ import { ExpectedMessages, MenuOptions, ModelIds, + TestConversation, Theme, } from '@/src/testData'; import { keys } from '@/src/ui/keyboard'; @@ -40,7 +40,7 @@ dialTest.skip( iconApiHelper, }) => { setTestIds('EPMRTC-1417', 'EPMRTC-1418', 'EPMRTC-1422'); - let conversation: Conversation; + let conversation: TestConversation; const conversationModels = [defaultModel, gpt4Model]; let playbackConversationName: string; @@ -443,8 +443,8 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1420', 'EPMRTC-1421'); - let conversation: Conversation; - let playbackConversation: Conversation; + let conversation: TestConversation; + let playbackConversation: TestConversation; const playNextKeys = [ keys.space, keys.enter, @@ -702,8 +702,8 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1425'); - let conversation: Conversation; - let playbackConversation: Conversation; + let conversation: TestConversation; + let playbackConversation: TestConversation; await dialTest.step( 'Prepare playback conversation based on 2 requests and played back till the last message', @@ -774,8 +774,8 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1427', 'EPMRTC-1470', 'EPMRTC-1473', 'EPMRTC-1428'); - let conversation: Conversation; - let playbackConversation: Conversation; + let conversation: TestConversation; + let playbackConversation: TestConversation; await dialTest.step( 'Prepare playback conversation based on several long requests', diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index e3def5d070..61ffeb873e 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -1,11 +1,11 @@ -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedMessages, FolderPrompt, Import, MenuOptions, + TestFolder, + TestPrompt, } from '@/src/testData'; import { ImportPrompt } from '@/src/testData/conversationHistory/importPrompt'; import { UploadDownloadData } from '@/src/ui/pages'; @@ -39,10 +39,10 @@ dialTest.skip( }) => { setTestIds('EPMRTC-883', 'EPMRTC-895'); let promptsInsideFolder: FolderPrompt; - let emptyFolder: FolderInterface; - let promptOutsideFolder: Prompt; - let nestedFolders: FolderInterface[]; - let nestedPrompts: Prompt[]; + let emptyFolder: TestFolder; + let promptOutsideFolder: TestPrompt; + let nestedFolders: TestFolder[]; + let nestedPrompts: TestPrompt[]; let exportedData: UploadDownloadData; const promptContent = 'test'; @@ -153,7 +153,7 @@ dialTest.skip( }, ); -dialTest( +dialTest.skip( 'Export and import one prompt in a folder.\n' + `Export and import one prompt in a folder when folder doesn't exist.\n` + 'Continue working with imported file. Edit imported prompt', @@ -171,7 +171,7 @@ dialTest( }) => { setTestIds('EPMRTC-884', 'EPMRTC-885', 'EPMRTC-896'); let promptInsideFolder: FolderPrompt; - let promptOutsideFolder: Prompt; + let promptOutsideFolder: TestPrompt; let exportedData: UploadDownloadData; await dialTest.step( @@ -288,7 +288,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Export and import one prompt in hierarchy tree', async ({ dialHomePage, @@ -301,7 +301,7 @@ dialTest( }) => { setTestIds('EPMRTC-886'); let promptInsideFolder: FolderPrompt; - let promptOutsideFolder: Prompt; + let promptOutsideFolder: TestPrompt; let exportedData: UploadDownloadData; const promptContent = 'test prompt'; @@ -368,9 +368,9 @@ dialTest.skip( }) => { setTestIds('EPMRTC-889'); let promptsInsideFolder: FolderPrompt; - let promptOutsideFolder: Prompt; - let importedFolderPrompt: Prompt; - let importedRootPrompt: Prompt; + let promptOutsideFolder: TestPrompt; + let importedFolderPrompt: TestPrompt; + let importedRootPrompt: TestPrompt; let importedNewFolderPrompt: FolderPrompt; await dialTest.step( @@ -554,7 +554,7 @@ dialTest.skip( }, ); -dialTest( +dialTest.skip( `Export and import single prompt in nested folders when folders structure doesn't exist.\n` + `Export and import single prompt in nested folders when it's folder doesn't exist.\n` + `Export and import single prompt in nested folders when parent folder doesn't exist`, @@ -570,8 +570,8 @@ dialTest( folderDropdownMenu, }) => { setTestIds('EPMRTC-1375', 'EPMRTC-1376', 'EPMRTC-1377'); - let nestedFolders: FolderInterface[]; - let nestedPrompts: Prompt[]; + let nestedFolders: TestFolder[]; + let nestedPrompts: TestPrompt[]; let exportedData: UploadDownloadData; await dialTest.step( @@ -693,7 +693,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Import a prompt in nested folder', async ({ dialHomePage, @@ -705,8 +705,8 @@ dialTest( promptDropdownMenu, }) => { setTestIds('EPMRTC-1378'); - let nestedFolders: FolderInterface[]; - let nestedPrompts: Prompt[]; + let nestedFolders: TestFolder[]; + let nestedPrompts: TestPrompt[]; const updatedPromptNames: string[] = []; await dialTest.step( @@ -808,7 +808,7 @@ dialTest( }, ); -dialTest( +dialTest.skip( 'Import a prompt from nested folder which was moved to another place', async ({ dialHomePage, @@ -820,8 +820,8 @@ dialTest( promptDropdownMenu, }) => { setTestIds('EPMRTC-1388'); - let nestedFolders: FolderInterface[]; - let thirdLevelFolderPrompt: Prompt; + let nestedFolders: TestFolder[]; + let thirdLevelFolderPrompt: TestPrompt; let exportedData: UploadDownloadData; await dialTest.step( diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts index 9d4ae641dc..4404af2e3d 100644 --- a/apps/chat-e2e/src/tests/prompts.test.ts +++ b/apps/chat-e2e/src/tests/prompts.test.ts @@ -1,10 +1,10 @@ -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; import { isApiStorageType } from '@/src/hooks/global-setup'; import { ExpectedConstants, ExpectedMessages, MenuOptions, + TestPrompt, } from '@/src/testData'; import { Colors, Cursors } from '@/src/ui/domData'; import { expect } from '@playwright/test'; @@ -663,11 +663,11 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-1173'); - let firstPrompt: Prompt; - let secondPrompt: Prompt; - let thirdPrompt: Prompt; - let fourthPrompt: Prompt; - let fifthPrompt: Prompt; + let firstPrompt: TestPrompt; + let secondPrompt: TestPrompt; + let thirdPrompt: TestPrompt; + let fourthPrompt: TestPrompt; + let fifthPrompt: TestPrompt; const promptContent = 'Prompt search test'; const notMatchingSearchTerm = 'abc'; const searchTerm = 'test'; diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index 4774d1bb01..0ba2d79fbd 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -1,5 +1,4 @@ -import { ChatBody, Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; +import { ChatBody } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { @@ -8,6 +7,8 @@ import { Import, MenuOptions, ModelIds, + TestConversation, + TestFolder, } from '@/src/testData'; import { Colors, Styles } from '@/src/ui/domData'; import { GeneratorUtil, ModelsUtil } from '@/src/utils'; @@ -44,10 +45,10 @@ dialTest( addons, }) => { setTestIds('EPMRTC-501', 'EPMRTC-1264'); - let replayConversation: Conversation; + let replayConversation: TestConversation; const replayTemp = 0; const replayPrompt = 'replay prompt'; - let firstConversation: Conversation; + let firstConversation: TestConversation; await dialTest.step( 'Prepare two conversation with different settings', @@ -174,8 +175,8 @@ dialTest( conversationDropdownMenu, }) => { setTestIds('EPMRTC-503'); - let nestedFolders: FolderInterface[]; - let nestedConversations: Conversation[] = []; + let nestedFolders: TestFolder[]; + let nestedConversations: TestConversation[] = []; const nestedLevels = 3; await dialTest.step( @@ -349,8 +350,8 @@ dialTest( chatMessages, }) => { setTestIds('EPMRTC-512'); - let conversation: Conversation; - let replayConversation: Conversation; + let conversation: TestConversation; + let replayConversation: TestConversation; const userRequest = 'write down 100 adjectives'; await dialTest.step('Prepare model conversation to replay', async () => { @@ -420,8 +421,8 @@ dialTest( conversations, }) => { setTestIds('EPMRTC-514', 'EPMRTC-1165'); - let conversation: Conversation; - let replayConversation: Conversation; + let conversation: TestConversation; + let replayConversation: TestConversation; await dialTest.step('Prepare conversation to replay', async () => { conversation = conversationData.prepareDefaultConversation(gpt35Model); replayConversation = @@ -497,8 +498,8 @@ dialTest( setTestIds('EPMRTC-1323', 'EPMRTC-1324'); const replayTemp = 0.8; const replayPrompt = 'reply the same text'; - let conversation: Conversation; - let replayConversation: Conversation; + let conversation: TestConversation; + let replayConversation: TestConversation; const expectedModelIcon = await iconApiHelper.getEntityIcon(gpt35Model); await dialTest.step('Prepare conversation to replay', async () => { @@ -596,8 +597,8 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-1322', 'EPMRTC-388'); - let replayConversation: Conversation; - let conversation: Conversation; + let replayConversation: TestConversation; + let conversation: TestConversation; const firstModel = gpt35Model; const secondModel = gpt4Model; const conversationModels = [gpt35Model, gpt4Model]; @@ -674,7 +675,7 @@ dialTest( }) => { setTestIds('EPMRTC-1535'); const message = GeneratorUtil.randomString(10); - let replayConversation: Conversation; + let replayConversation: TestConversation; await dialTest.step('Prepare conversation to replay', async () => { const requests: string[] = []; @@ -781,8 +782,8 @@ dialTest( conversations, }) => { setTestIds('EPMRTC-505', 'EPMRTC-506', 'EPMRTC-515', 'EPMRTC-516'); - let conversation: Conversation; - let replayConversation: Conversation; + let conversation: TestConversation; + let replayConversation: TestConversation; await dialTest.step( 'Prepare conversation to replay with updated name', @@ -872,8 +873,8 @@ dialTest( conversations, }) => { setTestIds('EPMRTC-1312'); - let errorConversation: Conversation; - let replayConversation: Conversation; + let errorConversation: TestConversation; + let replayConversation: TestConversation; await dialTest.step( 'Prepare errorConversation with error response and replay errorConversation', @@ -919,8 +920,8 @@ dialTest( conversations, }) => { setTestIds('EPMRTC-1328'); - let notAllowedModelConversation: Conversation; - let replayConversation: Conversation; + let notAllowedModelConversation: TestConversation; + let replayConversation: TestConversation; await dialTest.step( 'Prepare conversation with not allowed model and replay for it', @@ -1093,7 +1094,7 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-500'); - let conversation: Conversation; + let conversation: TestConversation; await dialTest.step('Prepare empty conversation', async () => { conversation = conversationData.prepareEmptyConversation(); @@ -1131,8 +1132,8 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-1542'); - let conversation: Conversation; - let replayConversation: Conversation; + let conversation: TestConversation; + let replayConversation: TestConversation; await dialTest.step('Prepare partially replayed conversation', async () => { conversation = conversationData.prepareConversationWithDifferentModels([ diff --git a/apps/chat-e2e/src/tests/sharedChatIcons.test.ts b/apps/chat-e2e/src/tests/sharedChatIcons.test.ts index 43c9ffdc0f..6e48092d3a 100644 --- a/apps/chat-e2e/src/tests/sharedChatIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedChatIcons.test.ts @@ -1,10 +1,10 @@ -import { Conversation } from '@/chat/types/chat'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, ExpectedMessages, MenuOptions, ModelIds, + TestConversation, } from '@/src/testData'; import { Colors, Overflow, Styles } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; @@ -181,7 +181,7 @@ dialTest.skip( 'EPMRTC-1508', 'EPMRTC-1509', ); - let conversation: Conversation; + let conversation: TestConversation; const conversationName = GeneratorUtil.randomString(60); await dialTest.step('Prepare default conversation', async () => { @@ -331,7 +331,7 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1510'); - let conversation: Conversation; + let conversation: TestConversation; await dialTest.step('Prepare shared conversation', async () => { conversation = conversationData.prepareDefaultSharedConversation(); @@ -381,8 +381,8 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1600', 'EPMRTC-1511'); - let notSharedConversation: Conversation; - let sharedConversation: Conversation; + let notSharedConversation: TestConversation; + let sharedConversation: TestConversation; await dialTest.step( 'Prepare one shared and one not shared conversations', diff --git a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts index a8003ab5c3..8a8c6cc69e 100644 --- a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts @@ -1,6 +1,5 @@ -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; -import { ExpectedMessages, MenuOptions } from '@/src/testData'; +import { ExpectedMessages, MenuOptions, TestPrompt } from '@/src/testData'; import { Colors } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; import { GeneratorUtil } from '@/src/utils'; @@ -22,7 +21,7 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1517', 'EPMRTC-1520', 'EPMRTC-1521', 'EPMRTC-1523'); - let prompt: Prompt; + let prompt: TestPrompt; await dialTest.step('Prepare a new prompt', async () => { prompt = promptData.prepareDefaultPrompt(); await dataInjector.createPrompts([prompt]); @@ -123,7 +122,7 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1518', 'EPMRTC-1524'); - let prompt: Prompt; + let prompt: TestPrompt; await dialTest.step('Prepare a new prompt', async () => { prompt = promptData.prepareDefaultPrompt(); await dataInjector.createPrompts([prompt]); diff --git a/apps/chat-e2e/src/tests/sideBarFilters.test.ts b/apps/chat-e2e/src/tests/sideBarFilters.test.ts index ed0b00a3ec..f47bc55c06 100644 --- a/apps/chat-e2e/src/tests/sideBarFilters.test.ts +++ b/apps/chat-e2e/src/tests/sideBarFilters.test.ts @@ -1,6 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; -import { FolderInterface } from '@/chat/types/folder'; -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; import { ExpectedConstants, @@ -9,6 +6,9 @@ import { FolderConversation, FolderPrompt, ModelIds, + TestConversation, + TestFolder, + TestPrompt, } from '@/src/testData'; import { expect } from '@playwright/test'; @@ -27,12 +27,12 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1597'); - let nestedFolders: FolderInterface[]; - let nestedSharedConversations: Conversation[]; - let nestedConversations: Conversation[]; + let nestedFolders: TestFolder[]; + let nestedSharedConversations: TestConversation[]; + let nestedConversations: TestConversation[]; let folderConversation: FolderConversation; - let sharedSingleConversation: Conversation; - let singleConversation: Conversation; + let sharedSingleConversation: TestConversation; + let singleConversation: TestConversation; await dialTest.step( 'Prepare nested folders and single shared and not shared conversations', @@ -166,7 +166,7 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1631'); - const testConversations: Conversation[] = []; + const testConversations: TestConversation[] = []; const searchTerm = 'test'; await dialTest.step( @@ -227,12 +227,12 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1635'); - let nestedFolders: FolderInterface[]; - let nestedSharedPrompts: Prompt[]; - let nestedPrompts: Prompt[]; + let nestedFolders: TestFolder[]; + let nestedSharedPrompts: TestPrompt[]; + let nestedPrompts: TestPrompt[]; let folderPrompt: FolderPrompt; - let sharedSinglePrompt: Prompt; - let singlePrompt: Prompt; + let sharedSinglePrompt: TestPrompt; + let singlePrompt: TestPrompt; await dialTest.step( 'Prepare nested folders and single shared and not shared prompts', @@ -353,7 +353,7 @@ dialTest.skip( setTestIds, }) => { setTestIds('EPMRTC-1636'); - const testPrompts: Prompt[] = []; + const testPrompts: TestPrompt[] = []; const searchTerm = 'test'; await dialTest.step( diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index ed7d47ae23..7e04e6e8f4 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -1,6 +1,4 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; -import { Prompt } from '@/chat/types/prompt'; import dialTest from '@/src/core/dialFixtures'; import { isApiStorageType } from '@/src/hooks/global-setup'; import { @@ -8,6 +6,8 @@ import { ExpectedMessages, FolderConversation, FolderPrompt, + TestConversation, + TestPrompt, } from '@/src/testData'; import { Colors } from '@/src/ui/domData'; import { ModelsUtil } from '@/src/utils'; @@ -105,8 +105,8 @@ dialTest( page, }) => { setTestIds('EPMRTC-1599', 'EPMRTC-591'); - let conversationToDrop: Conversation; - let conversation: Conversation; + let conversationToDrop: TestConversation; + let conversation: TestConversation; await dialTest.step( 'Prepare nested folders and single conversations outside folder', @@ -197,7 +197,7 @@ dialTest( }) => { setTestIds('EPMRTC-941'); let folderConversation: FolderConversation; - let conversationToDrop: Conversation; + let conversationToDrop: TestConversation; await dialTest.step( 'Prepare folder with 2 conversation inside and 2 single conversations outside folder', @@ -302,7 +302,7 @@ dialTest( setTestIds, }) => { setTestIds('EPMRTC-959'); - let prompt: Prompt; + let prompt: TestPrompt; await dialTest.step( 'Prepare nested folders and prompt outside folder', @@ -373,7 +373,7 @@ dialTest( }) => { setTestIds('EPMRTC-960'); let promptInFolder: FolderPrompt; - let prompt: Prompt; + let prompt: TestPrompt; await dialTest.step( 'Prepare folder with prompt and prompt outside folder', diff --git a/apps/chat-e2e/src/tests/workWithModels.test.ts b/apps/chat-e2e/src/tests/workWithModels.test.ts index 4e28b4123d..14770ccf1f 100644 --- a/apps/chat-e2e/src/tests/workWithModels.test.ts +++ b/apps/chat-e2e/src/tests/workWithModels.test.ts @@ -1,4 +1,3 @@ -import { Conversation } from '@/chat/types/chat'; import { OpenAIEntityModel } from '@/chat/types/openai'; import dialTest from '@/src/core/dialFixtures'; import { @@ -6,6 +5,7 @@ import { ExpectedConstants, ExpectedMessages, ModelIds, + TestConversation, Theme, } from '@/src/testData'; import { Cursors, Styles } from '@/src/ui/domData'; @@ -38,7 +38,7 @@ dialTest( chatMessages, }) => { setTestIds('EPMRTC-476'); - let conversation: Conversation; + let conversation: TestConversation; const userRequests = [ 'first request', 'second request', @@ -235,7 +235,7 @@ dialTest( }) => { setTestIds('EPMRTC-485', 'EPMRTC-486', 'EPMRTC-487'); const editData = 'updated message'; - let conversation: Conversation; + let conversation: TestConversation; const userRequests = ['1+2=', '2+3=', '3+4=']; await dialTest.step('Prepare conversation with 3 requests', async () => { conversation = conversationData.prepareModelConversationBasedOnRequests( diff --git a/apps/chat-e2e/src/utils/conversationUtil.ts b/apps/chat-e2e/src/utils/conversationUtil.ts deleted file mode 100644 index b60fb0d6cf..0000000000 --- a/apps/chat-e2e/src/utils/conversationUtil.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Conversation } from '@/chat/types/chat'; - -export class ConversationUtil { - static conversationIdSeparator = '__'; - - public static getApiConversationId(conversation: Conversation) { - const conversationId = `${ConversationUtil.conversationIdSeparator}${conversation.name}`; - if (conversation.replay.isReplay) { - return `replay${conversationId}`; - } - return `${conversation.model.id}${conversationId}`; - } -} diff --git a/apps/chat-e2e/src/utils/index.ts b/apps/chat-e2e/src/utils/index.ts index c13dfd970e..1da8d24745 100644 --- a/apps/chat-e2e/src/utils/index.ts +++ b/apps/chat-e2e/src/utils/index.ts @@ -3,4 +3,4 @@ export * from './dateUtil'; export * from './fileUtil'; export * from './modelsUtil'; export * from './bucketUtil'; -export * from './conversationUtil'; +export * from './itemUtil'; diff --git a/apps/chat-e2e/src/utils/itemUtil.ts b/apps/chat-e2e/src/utils/itemUtil.ts new file mode 100644 index 0000000000..54144816e0 --- /dev/null +++ b/apps/chat-e2e/src/utils/itemUtil.ts @@ -0,0 +1,49 @@ +import { TestConversation, TestPrompt } from '@/src/testData'; +import { BucketUtil } from '@/src/utils/bucketUtil'; + +export class ItemUtil { + static conversationIdSeparator = '__'; + + public static getConversationBucketPath() { + return `conversations/${BucketUtil.getBucket()}`; + } + + public static getPromptBucketPath() { + return `prompts/${BucketUtil.getBucket()}`; + } + + public static getApiConversationId( + conversation: TestConversation, + path = '', + ) { + const bucketPath = ItemUtil.getConversationBucketPath(); + const conversationId = `${ItemUtil.conversationIdSeparator}${conversation.name}`; + if (conversation.replay.isReplay) { + return path.length === 0 + ? `${bucketPath}/replay${conversationId}` + : `${bucketPath}/${path}/replay${conversationId}`; + } + return path.length === 0 + ? `${bucketPath}/${conversation.model.id}${conversationId}` + : `${bucketPath}/${path}/${conversation.model.id}${conversationId}`; + } + + public static getApiPromptId(prompt: TestPrompt, path: string) { + const bucketPath = ItemUtil.getPromptBucketPath(); + return path.length === 0 + ? `${bucketPath}/${prompt.name}` + : `${bucketPath}/${path}/${prompt.name}`; + } + + public static getApiPromptFolderId(path: string) { + return path.length === 0 + ? ItemUtil.getPromptBucketPath() + : `${ItemUtil.getPromptBucketPath()}/${path}`; + } + + public static getApiConversationFolderId(path: string) { + return path.length === 0 + ? ItemUtil.getConversationBucketPath() + : `${ItemUtil.getConversationBucketPath()}/${path}`; + } +} From 74465cb168a83de3f869c58009d97340c50f9f48 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 12:15:28 +0100 Subject: [PATCH 08/19] feat/update-e2e-with-stateful-api: fixed prompt update method --- apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index 7e04e6e8f4..e84291cd07 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -343,7 +343,7 @@ dialTest( ); if (isApiStorageType) { const respPromise = page.waitForResponse((resp) => { - return resp.request().method() === 'PUT'; + return resp.request().method() === 'POST'; }); await page.mouse.up(); return respPromise; From 28912f45f72d392cc5d7b6858859c5df119d5fb3 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 16:51:03 +0100 Subject: [PATCH 09/19] feat/update-e2e-with-stateful-api: added uuid dev dependency, fixed test --- apps/chat-e2e/src/tests/compareMode.test.ts | 9 ++++++++- package-lock.json | 21 +++++++++++++++++++++ package.json | 4 +++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/apps/chat-e2e/src/tests/compareMode.test.ts b/apps/chat-e2e/src/tests/compareMode.test.ts index 76e2b1ae06..241f13548c 100644 --- a/apps/chat-e2e/src/tests/compareMode.test.ts +++ b/apps/chat-e2e/src/tests/compareMode.test.ts @@ -122,10 +122,17 @@ dialTest( await dialTest.step( 'Open compare mode from 1st chat dropdown menu and verify chats with valid icons available for comparison', async () => { - await dialHomePage.openHomePage(); + await dialHomePage.openHomePage({ + iconsToBeLoaded: [ + defaultModel.iconUrl, + gpt4Model.iconUrl, + bisonModel.iconUrl, + ], + }); await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu( thirdModelConversation.name, + 3, ); await conversationDropdownMenu.selectMenuOption(MenuOptions.compare); diff --git a/package-lock.json b/package-lock.json index 209f63fd49..718b888d12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,6 +84,7 @@ "@types/react": "18.2.33", "@types/react-dom": "18.2.14", "@types/react-syntax-highlighter": "^15.5.6", + "@types/uuid": "^9.0.1", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "@vitejs/plugin-react": "^4.2.1", @@ -112,6 +113,7 @@ "tailwindcss": "^3.3.5", "ts-node": "10.9.1", "typescript": "^5.2.2", + "uuid": "^9.0.0", "vite": "^5.0.0", "vitest": "^1.2.1" }, @@ -7182,6 +7184,12 @@ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", @@ -20674,6 +20682,19 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/uvu": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", diff --git a/package.json b/package.json index 3e667aa59b..9f21916dbc 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,7 @@ "@types/react": "18.2.33", "@types/react-dom": "18.2.14", "@types/react-syntax-highlighter": "^15.5.6", + "@types/uuid": "^9.0.1", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "@vitejs/plugin-react": "^4.2.1", @@ -134,7 +135,8 @@ "ts-node": "10.9.1", "typescript": "^5.2.2", "vite": "^5.0.0", - "vitest": "^1.2.1" + "vitest": "^1.2.1", + "uuid": "^9.0.0" }, "overrides": { "js-yaml": "4.1.0", From 1f6a82092d70a590fd653abba9e7521778321203 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 17:01:48 +0100 Subject: [PATCH 10/19] feat/update-e2e-with-stateful-api: prettier --- apps/chat-e2e/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/chat-e2e/README.md b/apps/chat-e2e/README.md index 3c305b384f..130fa97999 100644 --- a/apps/chat-e2e/README.md +++ b/apps/chat-e2e/README.md @@ -59,12 +59,12 @@ CI report includes screenshots for failed tests. The following variables should be placed inside `chat-e2e/.env.local` file in order to run tests locally -| Variable | Required | Description | Available Values | Default values | -|-----------------| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- --|----------------| -| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | -| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | -| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | -| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | -| `TMS_URL` | No | TMS URL | Any string | | -| `ISSUE_URL` | No | Issue URL | Any string | | -| `STORAGE_TYPE` | No | Storage type used for e2e tests data | api,browserStorage | api | +| Variable | Required | Description | Available Values | Default values | +| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | +| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | +| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | +| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | +| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | +| `TMS_URL` | No | TMS URL | Any string | | +| `ISSUE_URL` | No | Issue URL | Any string | | +| `STORAGE_TYPE` | No | Storage type used for e2e tests data | api,browserStorage | api | From 35368ab392fb448a9343c038b0aedb7e978d55a0 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 17:48:33 +0100 Subject: [PATCH 11/19] feat/update-e2e-with-stateful-api: added GPT_4_0125_PREVIEW model --- apps/chat-e2e/src/testData/expectedConstants.ts | 1 + apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts index 8e0ae36cf6..d2a45e6683 100644 --- a/apps/chat-e2e/src/testData/expectedConstants.ts +++ b/apps/chat-e2e/src/testData/expectedConstants.ts @@ -144,6 +144,7 @@ export enum ModelIds { GPT_4_0314 = 'gpt-4-0314', GPT_4_0613 = 'gpt-4-0613', GPT_4_1106_PREVIEW = 'gpt-4-1106-preview', + GPT_4_0125_PREVIEW = 'gpt-4-0125-preview', GPT_4_32K = 'gpt-4-32k', GPT_4_32K_0314 = 'gpt-4-32k-0314', GPT_4_32K_0613 = 'gpt-4-32k-0613', diff --git a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts index 6babff64e1..28cd651bff 100644 --- a/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts +++ b/apps/chat-e2e/src/tests/chatApi/arithmeticRequest.test.ts @@ -15,6 +15,7 @@ const modelsForArithmeticRequest: { { modelId: ModelIds.GPT_4_0613, isSysPromptAllowed: true }, { modelId: ModelIds.GPT_4, isSysPromptAllowed: true }, { modelId: ModelIds.GPT_4_1106_PREVIEW, isSysPromptAllowed: true }, + { modelId: ModelIds.GPT_4_0125_PREVIEW, isSysPromptAllowed: true }, { modelId: ModelIds.GPT_4_32K_0314, isSysPromptAllowed: true }, { modelId: ModelIds.GPT_4_32K_0613, isSysPromptAllowed: true }, { modelId: ModelIds.GPT_4_32K, isSysPromptAllowed: true }, From 54279eb01efa186aa778903cef4cb78205c97812 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 22:51:27 +0100 Subject: [PATCH 12/19] feat/update-e2e-with-stateful-api: updated paths, removed response wait on folder expand --- .../src/testData/api/itemApiHelper.ts | 18 ++++++++------- .../src/testData/expectedConstants.ts | 6 ++--- .../src/tests/chatBarConversation.test.ts | 12 ++++------ .../tests/chatBarFolderConversation.test.ts | 7 ++---- .../src/tests/chatExportImport.test.ts | 23 ++++--------------- apps/chat-e2e/src/tests/compareMode.test.ts | 1 - apps/chat-e2e/src/tests/prompts.test.ts | 3 --- apps/chat-e2e/src/tests/replay.test.ts | 5 +--- .../chat-e2e/src/tests/sideBarFilters.test.ts | 6 +---- .../tests/sidePanelEntityDragAndDrop.test.ts | 2 -- apps/chat-e2e/src/ui/webElements/folders.ts | 6 ++--- .../src/ui/webElements/promptModalDialog.ts | 2 +- 12 files changed, 29 insertions(+), 62 deletions(-) diff --git a/apps/chat-e2e/src/testData/api/itemApiHelper.ts b/apps/chat-e2e/src/testData/api/itemApiHelper.ts index 94b6c8b168..4ded7cf6b1 100644 --- a/apps/chat-e2e/src/testData/api/itemApiHelper.ts +++ b/apps/chat-e2e/src/testData/api/itemApiHelper.ts @@ -6,19 +6,21 @@ import { expect } from '@playwright/test'; export class ItemApiHelper extends BaseApiHelper { public async deleteAllData() { - const conversations = await this.listItems(API.conversationsListingHost()); - const prompts = await this.listItems(API.promptsListingHost()); + const conversations = await this.listItems(API.conversationsHost); + const prompts = await this.listItems(API.promptsHost); await this.deleteBackendItem(...conversations, ...prompts); } public async listItems(url: string) { - const response = await this.request.get(url, { - params: { - filter: BackendDataNodeType.ITEM, - bucket: BucketUtil.getBucket(), - recursive: true, + const response = await this.request.get( + `${url}/${BucketUtil.getBucket()}`, + { + params: { + filter: BackendDataNodeType.ITEM, + recursive: true, + }, }, - }); + ); const entities = (await response.json()) as BackendDataEntity[]; expect( response.status(), diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts index d2a45e6683..5df5dcf3bc 100644 --- a/apps/chat-e2e/src/testData/expectedConstants.ts +++ b/apps/chat-e2e/src/testData/expectedConstants.ts @@ -105,10 +105,8 @@ export const API = { sessionHost: '/api/auth/session', defaultIconHost: '/api/themes/image?name=default-model', bucketHost: '/api/bucket', - conversationsHost: '/api/conversations', - promptsHost: '/api/prompts', - conversationsListingHost: () => `${API.conversationsHost}/listing`, - promptsListingHost: () => `${API.promptsHost}/listing`, + conversationsHost: '/api/listing/conversations', + promptsHost: '/api/listing/prompts', fileHost: '/api/files', }; diff --git a/apps/chat-e2e/src/tests/chatBarConversation.test.ts b/apps/chat-e2e/src/tests/chatBarConversation.test.ts index 0d499e0567..338a2a40ad 100644 --- a/apps/chat-e2e/src/tests/chatBarConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarConversation.test.ts @@ -367,7 +367,6 @@ dialTest( await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await folderConversations.openFolderEntityDropdownMenu( conversationInFolder.folders.name, @@ -545,11 +544,12 @@ dialTest( await dialHomePage.waitForPageLoaded(); await conversations.openConversationDropdownMenu(conversation.name); await conversationDropdownMenu.selectMenuOption(MenuOptions.moveTo); - await conversationDropdownMenu.selectMenuOption(MenuOptions.newFolder); + await conversations.selectMoveToMenuOption( + ExpectedConstants.newFolderTitle, + ); await folderConversations.expandCollapseFolder( ExpectedConstants.newFolderWithIndexTitle(1), - { isHttpMethodTriggered: true }, ); const isFolderConversationVisible = await folderConversations.isFolderEntityVisible( @@ -634,9 +634,7 @@ dialTest( 'Select folder name from menu and conversation is moved into folder', async () => { await conversations.selectMoveToMenuOption(folderName); - await folderConversations.expandCollapseFolder(folderName, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(folderName); const isFolderConversationVisible = await folderConversations.isFolderEntityVisible( folderName, @@ -681,7 +679,6 @@ dialTest( await chatBar.createNewFolder(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await chatBar.deleteAllEntities(); await confirmationDialog.cancelDialog(); @@ -776,7 +773,6 @@ dialTest( await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await chatBar.deleteAllEntities(); diff --git a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts index d35906c16f..b4186e559b 100644 --- a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts @@ -253,8 +253,7 @@ dialTest( .toBeFalsy(); await folderConversations.expandCollapseFolder( - conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, + conversationInFolder.folders.name ); isFolderCaretExpanded = await folderConversations.isFolderCaretExpanded( conversationInFolder.folders.name, @@ -415,9 +414,7 @@ dialTest( await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } await folderConversations.openFolderDropdownMenu( nestedFolders[levelToDelete].name, diff --git a/apps/chat-e2e/src/tests/chatExportImport.test.ts b/apps/chat-e2e/src/tests/chatExportImport.test.ts index 137bdc71f8..c58be0f58d 100644 --- a/apps/chat-e2e/src/tests/chatExportImport.test.ts +++ b/apps/chat-e2e/src/tests/chatExportImport.test.ts @@ -85,7 +85,6 @@ dialTest.skip( if (!isFolderExpanded) { await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); } @@ -195,9 +194,7 @@ dialTest.skip( await chatBar.createNewFolder(); await chatBar.createNewConversation(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } exportedData = await dialHomePage.downloadData(() => chatBar.exportButton.click(), @@ -313,7 +310,6 @@ dialTest.skip( if (!isFolderExpanded) { await folderConversations.expandCollapseFolder( conversationsInFolder.folders.name, - { isHttpMethodTriggered: true }, ); } expect @@ -491,7 +487,6 @@ dialTest.skip( await folderConversations.expandCollapseFolder( Import.oldVersionAppFolderName, - { isHttpMethodTriggered: true }, ); expect .soft( @@ -633,9 +628,7 @@ dialTest.skip( await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } await folderConversations.openFolderEntityDropdownMenu( @@ -778,9 +771,7 @@ dialTest.skip( await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } for (let i = 0; i <= 2; i = i + 2) { @@ -907,9 +898,7 @@ dialTest.skip( await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } await folderConversations.openFolderEntityDropdownMenu( nestedFolders[levelsCount].name, @@ -940,9 +929,7 @@ dialTest.skip( 'Verify imported conversations is in 3rd level folder on the root level', async () => { for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } await folderConversations .getFolderEntity( diff --git a/apps/chat-e2e/src/tests/compareMode.test.ts b/apps/chat-e2e/src/tests/compareMode.test.ts index 241f13548c..0180ef5b2f 100644 --- a/apps/chat-e2e/src/tests/compareMode.test.ts +++ b/apps/chat-e2e/src/tests/compareMode.test.ts @@ -1333,7 +1333,6 @@ dialTest( await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( firstFolderConversation.folders.name, - { isHttpMethodTriggered: true }, ); await folderConversations.openFolderEntityDropdownMenu( firstFolderConversation.folders.name, diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts index 4404af2e3d..d8e80b2ecd 100644 --- a/apps/chat-e2e/src/tests/prompts.test.ts +++ b/apps/chat-e2e/src/tests/prompts.test.ts @@ -329,7 +329,6 @@ dialTest( await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await promptBar.deleteAllEntities(); await confirmationDialog.cancelDialog(); @@ -442,7 +441,6 @@ dialTest( await folderPrompts.expandCollapseFolder(promptInFolder.folders.name); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await conversations .getConversationByName(singleConversation.name) @@ -458,7 +456,6 @@ dialTest( .waitFor({ state: 'hidden' }); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); } else { await folderConversations diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index 0ba2d79fbd..56ea0fc740 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -200,9 +200,7 @@ dialTest( isNewConversationVisible: true, }); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } for (let i = 0; i < nestedLevels; i = i + 2) { await folderConversations.openFolderEntityDropdownMenu( @@ -1011,7 +1009,6 @@ dialTest.skip( ); await folderConversations.expandCollapseFolder( Import.oldVersionAppFolderName, - { isHttpMethodTriggered: true }, ); await folderConversations.selectFolderEntity( Import.oldVersionAppFolderName, diff --git a/apps/chat-e2e/src/tests/sideBarFilters.test.ts b/apps/chat-e2e/src/tests/sideBarFilters.test.ts index f47bc55c06..011d0bc4bc 100644 --- a/apps/chat-e2e/src/tests/sideBarFilters.test.ts +++ b/apps/chat-e2e/src/tests/sideBarFilters.test.ts @@ -77,17 +77,13 @@ dialTest.skip( await dialHomePage.waitForPageLoaded(); await chatBar.createNewFolder(); for (const nestedFolder of nestedFolders) { - await folderConversations.expandCollapseFolder(nestedFolder.name, { - isHttpMethodTriggered: true, - }); + await folderConversations.expandCollapseFolder(nestedFolder.name); } await folderConversations.expandCollapseFolder( ExpectedConstants.newFolderWithIndexTitle(1), - { isHttpMethodTriggered: true }, ); await folderConversations.expandCollapseFolder( folderConversation.folders.name, - { isHttpMethodTriggered: true }, ); await chatFilter.openFilterDropdownMenu(); await chatFilterDropdownMenu.selectMenuOption( diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index e84291cd07..2dd53f232c 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -43,7 +43,6 @@ dialTest( await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( conversationInFolder.folders.name, - { isHttpMethodTriggered: true }, ); await chatBar.drugConversationFromFolder( conversationInFolder.folders.name, @@ -221,7 +220,6 @@ dialTest( await dialHomePage.waitForPageLoaded(); await folderConversations.expandCollapseFolder( folderConversation.folders.name, - { isHttpMethodTriggered: true }, ); await chatBar.drugAndDropConversationToFolderConversation( folderConversation.folders.name, diff --git a/apps/chat-e2e/src/ui/webElements/folders.ts b/apps/chat-e2e/src/ui/webElements/folders.ts index f062a2366b..12422305b5 100644 --- a/apps/chat-e2e/src/ui/webElements/folders.ts +++ b/apps/chat-e2e/src/ui/webElements/folders.ts @@ -100,8 +100,8 @@ export class Folders extends BaseElement { if (isApiStorageType) { const respPromise = this.page.waitForResponse((resp) => { return ( - resp.url().includes(API.conversationsListingHost()) || - resp.url().includes(API.promptsListingHost()) + resp.url().includes(API.conversationsHost) || + resp.url().includes(API.promptsHost) ); }); await folderInput.clickTickButton(); @@ -124,7 +124,7 @@ export class Folders extends BaseElement { await folder.waitFor(); if (isApiStorageType && isHttpMethodTriggered) { const respPromise = this.page.waitForResponse((resp) => - resp.url().includes(API.conversationsListingHost()), + resp.url().includes(API.conversationsHost), ); await folder.click(); return respPromise; diff --git a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts index 5b30c9a186..f0712a82e1 100644 --- a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts +++ b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts @@ -40,7 +40,7 @@ export class PromptModalDialog extends BaseElement { ) { await this.fillPromptDetails(name, description, value); const respPromise = this.page.waitForResponse( - (resp) => resp.request().method() === 'PUT', + (resp) => resp.request().method() === 'POST', ); await this.saveButton.click(); await respPromise; From 1aa0ecc38f96a7993601e91e872ab972cdd83c46 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Wed, 14 Feb 2024 23:39:49 +0100 Subject: [PATCH 13/19] feat/update-e2e-with-stateful-api: prettier, fixed authentication failure behaviour --- .../src/tests/chatBarFolderConversation.test.ts | 2 +- apps/chat-e2e/src/tests/desktopAuth.ts | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts index b4186e559b..403144f746 100644 --- a/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarFolderConversation.test.ts @@ -253,7 +253,7 @@ dialTest( .toBeFalsy(); await folderConversations.expandCollapseFolder( - conversationInFolder.folders.name + conversationInFolder.folders.name, ); isFolderCaretExpanded = await folderConversations.isFolderCaretExpanded( conversationInFolder.folders.name, diff --git a/apps/chat-e2e/src/tests/desktopAuth.ts b/apps/chat-e2e/src/tests/desktopAuth.ts index 5b32ee5470..c4c79e65ef 100644 --- a/apps/chat-e2e/src/tests/desktopAuth.ts +++ b/apps/chat-e2e/src/tests/desktopAuth.ts @@ -8,8 +8,8 @@ const usernames = process.env .E2E_USERNAME!.split(',') .slice(0, +config.workers!); -for (const username of usernames) { - test(`Authenticate user: ${username}`, async ({ +for (let i = 0; i < usernames.length; i++) { + test(`Authenticate user: ${usernames[i]}`, async ({ page, loginPage, auth0Page, @@ -22,7 +22,7 @@ for (const username of usernames) { options = { setEntitiesEnvVars: true }; } const retrievedResponses = await auth0Page.loginToChatBot( - username, + usernames[i], options, ); if (options?.setEntitiesEnvVars) { @@ -31,9 +31,7 @@ for (const username of usernames) { process.env.RECENT_ADDONS = await localStorageManager.getRecentAddons(); process.env.RECENT_MODELS = await localStorageManager.getRecentModels(); } - process.env['BUCKET' + testInfo.parallelIndex] = retrievedResponses.get( - API.bucketHost, - ); + process.env['BUCKET' + i] = retrievedResponses.get(API.bucketHost); await page.context().storageState({ path: stateFilePath }); }); } From f2c6a2efab78ec2e381975a5562bd39a2ed41184 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 08:50:57 +0100 Subject: [PATCH 14/19] feat/update-e2e-with-stateful-api: fixed playwright project's test sets --- apps/chat-e2e/config/playwright.config.ts | 1 + apps/chat-e2e/src/tests/{ => listingApi}/listing.test.ts | 0 2 files changed, 1 insertion(+) rename apps/chat-e2e/src/tests/{ => listingApi}/listing.test.ts (100%) diff --git a/apps/chat-e2e/config/playwright.config.ts b/apps/chat-e2e/config/playwright.config.ts index 4088fa1a7a..142df7edaf 100644 --- a/apps/chat-e2e/config/playwright.config.ts +++ b/apps/chat-e2e/config/playwright.config.ts @@ -66,6 +66,7 @@ export default defineConfig({ }, { name: 'chromium', + testIgnore: /\/chatApi|listingApi\/.*\.test\.ts/, use: { ...devices['Desktop Chrome'], viewport: { width: 1536, height: 864 }, diff --git a/apps/chat-e2e/src/tests/listing.test.ts b/apps/chat-e2e/src/tests/listingApi/listing.test.ts similarity index 100% rename from apps/chat-e2e/src/tests/listing.test.ts rename to apps/chat-e2e/src/tests/listingApi/listing.test.ts From 6e1396a9f7274d29e93b2889a008b36fb385c575 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 10:11:53 +0100 Subject: [PATCH 15/19] feat/update-e2e-with-stateful-api: fixed flaky tests, added issue ids --- .../src/tests/chatBarConversation.test.ts | 4 +++ apps/chat-e2e/src/tests/compareMode.test.ts | 4 +-- .../src/tests/promptExportImport.test.ts | 8 +++-- apps/chat-e2e/src/tests/prompts.test.ts | 6 +++- .../src/tests/sharedPromptIcons.test.ts | 2 +- .../src/ui/webElements/conversations.ts | 20 ++++++++--- .../src/ui/webElements/promptModalDialog.ts | 34 +++++++++++++------ .../src/ui/webElements/sideBarEntities.ts | 30 ++++++++-------- 8 files changed, 69 insertions(+), 39 deletions(-) diff --git a/apps/chat-e2e/src/tests/chatBarConversation.test.ts b/apps/chat-e2e/src/tests/chatBarConversation.test.ts index 338a2a40ad..c8f33648fb 100644 --- a/apps/chat-e2e/src/tests/chatBarConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarConversation.test.ts @@ -534,8 +534,10 @@ dialTest( localStorageManager, folderConversations, setTestIds, + setIssueIds, }) => { setTestIds('EPMRTC-864'); + setIssueIds('726'); const conversation = conversationData.prepareDefaultConversation(); await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); @@ -586,8 +588,10 @@ dialTest( folderDropdownMenu, chatBar, setTestIds, + setIssueIds, }) => { setTestIds('EPMRTC-863', 'EPMRTC-942'); + setIssueIds('726'); const folderName = GeneratorUtil.randomString(70); let conversation: TestConversation; diff --git a/apps/chat-e2e/src/tests/compareMode.test.ts b/apps/chat-e2e/src/tests/compareMode.test.ts index 0180ef5b2f..d7e819e5e6 100644 --- a/apps/chat-e2e/src/tests/compareMode.test.ts +++ b/apps/chat-e2e/src/tests/compareMode.test.ts @@ -1538,9 +1538,7 @@ dialTest( async () => { await conversations.openConversationDropdownMenu(updatedRequestContent); await conversationDropdownMenu.selectMenuOption(MenuOptions.delete); - await conversations - .getConversationInput(updatedRequestContent) - .clickTickButton(); + await conversations.deleteConversationWithTick(updatedRequestContent); expect .soft( await conversations diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index 61ffeb873e..81cb05a402 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -263,7 +263,7 @@ dialTest.skip( async () => { await prompts.openPromptDropdownMenu(promptOutsideFolder.name); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - await promptModalDialog.updatePromptDetails( + await promptModalDialog.updatePromptDetailsWithButton( newName, newDescr, newValue, @@ -522,7 +522,11 @@ dialTest.skip( Import.v14AppFolderPromptName, ); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - await promptModalDialog.updatePromptDetails(newName, newDescr, newValue); + await promptModalDialog.updatePromptDetailsWithButton( + newName, + newDescr, + newValue, + ); await folderPrompts .getFolderEntity(Import.oldVersionAppFolderName, newName) .waitFor(); diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts index d8e80b2ecd..7bdc1ee7f9 100644 --- a/apps/chat-e2e/src/tests/prompts.test.ts +++ b/apps/chat-e2e/src/tests/prompts.test.ts @@ -137,7 +137,11 @@ dialTest( await dialHomePage.waitForPageLoaded(); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - await promptModalDialog.updatePromptDetails(newName, newDescr, newValue); + await promptModalDialog.updatePromptDetailsWithButton( + newName, + newDescr, + newValue, + ); const isPromptModalVisible = await promptModalDialog.isVisible(); await expect diff --git a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts index 8a8c6cc69e..0a7027285e 100644 --- a/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedPromptIcons.test.ts @@ -167,7 +167,7 @@ dialTest.skip( const newName = GeneratorUtil.randomString(10); await prompts.openPromptDropdownMenu(prompt.name); await promptDropdownMenu.selectMenuOption(MenuOptions.edit); - await promptModalDialog.updatePromptDetails( + await promptModalDialog.updatePromptDetailsWithButton( newName, GeneratorUtil.randomString(20), GeneratorUtil.randomString(20), diff --git a/apps/chat-e2e/src/ui/webElements/conversations.ts b/apps/chat-e2e/src/ui/webElements/conversations.ts index 1d534f934d..ce50cc0142 100644 --- a/apps/chat-e2e/src/ui/webElements/conversations.ts +++ b/apps/chat-e2e/src/ui/webElements/conversations.ts @@ -110,7 +110,15 @@ export class Conversations extends SideBarEntities { } public async editConversationNameWithTick(name: string, newName: string) { - await this.editEntityNameWithTick(this.entitySelector, name, newName); + const input = await this.openEditConversationNameMode(name, newName); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await input.clickTickButton(); + return respPromise; + } + await input.clickTickButton(); } public async editConversationNameWithEnter(name: string, newName: string) { @@ -120,11 +128,13 @@ export class Conversations extends SideBarEntities { (resp) => resp.request().method() === 'DELETE', ); await this.page.keyboard.press(keys.enter); - await respPromise; - } else { - await this.page.keyboard.press(keys.enter); + return respPromise; } - await this.getConversationByName(name).waitFor({ state: 'hidden' }); + await this.page.keyboard.press(keys.enter); + } + + public async deleteConversationWithTick(name: string) { + await this.deleteEntityWithTick(this.entitySelector, name); } public async openEditConversationNameMode(name: string, newName: string) { diff --git a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts index f0712a82e1..54bec18237 100644 --- a/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts +++ b/apps/chat-e2e/src/ui/webElements/promptModalDialog.ts @@ -1,3 +1,4 @@ +import { isApiStorageType } from '@/src/hooks/global-setup'; import { Attributes } from '@/src/ui/domData'; import { keys } from '@/src/ui/keyboard'; import { PromptModal } from '@/src/ui/selectors/dialogSelectors'; @@ -33,17 +34,14 @@ export class PromptModalDialog extends BaseElement { await this.prompt.typeInInput(value); } - public async updatePromptDetails( + public async updatePromptDetailsWithButton( name: string, description: string, value: string, ) { - await this.fillPromptDetails(name, description, value); - const respPromise = this.page.waitForResponse( - (resp) => resp.request().method() === 'POST', + await this.updatePromptDetails(name, description, value, () => + this.saveButton.click(), ); - await this.saveButton.click(); - await respPromise; } public async updatePromptDetailsWithEnter( @@ -51,12 +49,26 @@ export class PromptModalDialog extends BaseElement { description: string, value: string, ) { - await this.fillPromptDetails(name, description, value); - const respPromise = this.page.waitForResponse( - (resp) => resp.request().method() === 'PUT', + await this.updatePromptDetails(name, description, value, () => + this.page.keyboard.press(keys.enter), ); - await this.page.keyboard.press(keys.enter); - await respPromise; + } + + public async updatePromptDetails( + name: string, + description: string, + value: string, + method: () => Promise, + ) { + await this.fillPromptDetails(name, description, value); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'POST', + ); + await method(); + return respPromise; + } + await method(); } public async getName() { diff --git a/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts b/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts index 952aa32d23..063f566187 100644 --- a/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts +++ b/apps/chat-e2e/src/ui/webElements/sideBarEntities.ts @@ -91,22 +91,6 @@ export class SideBarEntities extends BaseElement { await this.getDropdownMenu().waitForState(); } - protected async editEntityNameWithTick( - selector: string, - name: string, - newName: string, - ) { - const input = await this.openEditEntityNameMode(selector, name, newName); - if (isApiStorageType) { - const respPromise = this.page.waitForResponse( - (resp) => resp.request().method() === 'DELETE', - ); - await input.clickTickButton(); - return respPromise; - } - await input.clickTickButton(); - } - protected async openEditEntityNameMode( selector: string, name: string, @@ -151,4 +135,18 @@ export class SideBarEntities extends BaseElement { } await this.getDropdownMenu().selectMenuOption(name); } + + public async deleteEntityWithTick(selector: string, name: string) { + const input = await this.getEntityInput(selector, name); + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'DELETE', + ); + await input.clickTickButton(); + await respPromise; + } else { + await input.clickTickButton(); + } + await this.getEntityByName(selector, name).waitFor({ state: 'hidden' }); + } } From 74130b01c90c41667f3fbd4991e981b8f3857360 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 12:08:30 +0100 Subject: [PATCH 16/19] feat/update-e2e-with-stateful-api: enabled fixed tests, fixed storage state issue when auth fails --- apps/chat-e2e/src/core/dialFixtures.ts | 9 ++++----- apps/chat-e2e/src/tests/chatBarConversation.test.ts | 4 ---- apps/chat-e2e/src/tests/desktopAuth.ts | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/chat-e2e/src/core/dialFixtures.ts b/apps/chat-e2e/src/core/dialFixtures.ts index c9a9f68270..4954dd8f80 100644 --- a/apps/chat-e2e/src/core/dialFixtures.ts +++ b/apps/chat-e2e/src/core/dialFixtures.ts @@ -58,11 +58,10 @@ import { Tooltip } from '@/src/ui/webElements/tooltip'; import { VariableModalDialog } from '@/src/ui/webElements/variableModalDialog'; import { allure } from 'allure-playwright'; import path from 'path'; +import * as process from 'process'; -export const stateFilePath = path.join( - __dirname, - `../../auth/desktopUser${process.env.TEST_PARALLEL_INDEX}.json`, -); +export const stateFilePath = (index: number) => + path.join(__dirname, `../../auth/desktopUser${index}.json`); interface ReportAttributes { setTestIds: (...testId: string[]) => void; @@ -164,7 +163,7 @@ const dialTest = test.extend< ], // eslint-disable-next-line no-empty-pattern storageState: async ({}, use) => { - await use(stateFilePath); + await use(stateFilePath(+process.env.TEST_PARALLEL_INDEX!)); }, dialHomePage: async ({ page }, use) => { const dialHomePage = new DialHomePage(page); diff --git a/apps/chat-e2e/src/tests/chatBarConversation.test.ts b/apps/chat-e2e/src/tests/chatBarConversation.test.ts index c8f33648fb..338a2a40ad 100644 --- a/apps/chat-e2e/src/tests/chatBarConversation.test.ts +++ b/apps/chat-e2e/src/tests/chatBarConversation.test.ts @@ -534,10 +534,8 @@ dialTest( localStorageManager, folderConversations, setTestIds, - setIssueIds, }) => { setTestIds('EPMRTC-864'); - setIssueIds('726'); const conversation = conversationData.prepareDefaultConversation(); await dataInjector.createConversations([conversation]); await localStorageManager.setSelectedConversation(conversation); @@ -588,10 +586,8 @@ dialTest( folderDropdownMenu, chatBar, setTestIds, - setIssueIds, }) => { setTestIds('EPMRTC-863', 'EPMRTC-942'); - setIssueIds('726'); const folderName = GeneratorUtil.randomString(70); let conversation: TestConversation; diff --git a/apps/chat-e2e/src/tests/desktopAuth.ts b/apps/chat-e2e/src/tests/desktopAuth.ts index c4c79e65ef..83d78da862 100644 --- a/apps/chat-e2e/src/tests/desktopAuth.ts +++ b/apps/chat-e2e/src/tests/desktopAuth.ts @@ -32,6 +32,6 @@ for (let i = 0; i < usernames.length; i++) { process.env.RECENT_MODELS = await localStorageManager.getRecentModels(); } process.env['BUCKET' + i] = retrievedResponses.get(API.bucketHost); - await page.context().storageState({ path: stateFilePath }); + await page.context().storageState({ path: stateFilePath(i) }); }); } From 7e76878e176bbad69046977d8d38da886049e815 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 16:17:13 +0100 Subject: [PATCH 17/19] feat/update-e2e-with-stateful-api: fixed review comment; enabled fixed test --- apps/chat-e2e/README.md | 17 ++++++++--------- apps/chat-e2e/config/local.playwright.config.ts | 3 ++- apps/chat-e2e/src/tests/prompts.test.ts | 2 ++ apps/chat-e2e/src/tests/workWithModels.test.ts | 2 -- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/chat-e2e/README.md b/apps/chat-e2e/README.md index 130fa97999..e08840bcf3 100644 --- a/apps/chat-e2e/README.md +++ b/apps/chat-e2e/README.md @@ -59,12 +59,11 @@ CI report includes screenshots for failed tests. The following variables should be placed inside `chat-e2e/.env.local` file in order to run tests locally -| Variable | Required | Description | Available Values | Default values | -| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------- | -| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | -| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | -| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | -| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | -| `TMS_URL` | No | TMS URL | Any string | | -| `ISSUE_URL` | No | Issue URL | Any string | | -| `STORAGE_TYPE` | No | Storage type used for e2e tests data | api,browserStorage | api | +| Variable | Required | Description | Available Values | Default values | +| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | -------------- | +| `E2E_HOST` | No | The host URL for end-to-end testing. | Any string | | +| `E2E_USERNAME` | No | Comma separated list of usernames for e2e authentification. The number of users should be more or equal number of workers set in playwright config | Any string | | +| `E2E_WORKERS` | No | Number of threads to run e2e tests | Any number | | +| `E2E_PASSWORD` | No | A password for e2e authentification | Any string | | +| `TMS_URL` | No | TMS URL | Any string | | +| `ISSUE_URL` | No | Issue URL | Any string | | diff --git a/apps/chat-e2e/config/local.playwright.config.ts b/apps/chat-e2e/config/local.playwright.config.ts index 8f1ccc187a..d3013ea941 100644 --- a/apps/chat-e2e/config/local.playwright.config.ts +++ b/apps/chat-e2e/config/local.playwright.config.ts @@ -4,12 +4,13 @@ import { ResultFolder } from '@/src/testData'; import { workspaceRoot } from '@nx/devkit'; import { ReporterDescription } from '@playwright/test'; import dotenv from 'dotenv'; +import path from 'path'; /** * Read environment variables from file. * https://github.com/motdotla/dotenv */ -dotenv.config({ path: './.env.development' }); +dotenv.config({ path: path.resolve(__dirname, '../../chat/.env.local') }); dotenv.config({ path: './.env.local' }); /** * Config used for a local run diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts index 7bdc1ee7f9..de3f4ade47 100644 --- a/apps/chat-e2e/src/tests/prompts.test.ts +++ b/apps/chat-e2e/src/tests/prompts.test.ts @@ -20,6 +20,7 @@ dialTest( promptBar, prompts, conversationSettings, + promptModalDialog, setTestIds, }) => { setTestIds('EPMRTC-945'); @@ -38,6 +39,7 @@ dialTest( .toBe(Colors.backgroundAccentTertiary); await promptBar.createNewPrompt(); + await promptModalDialog.saveButton.click(); expect .soft( await prompts diff --git a/apps/chat-e2e/src/tests/workWithModels.test.ts b/apps/chat-e2e/src/tests/workWithModels.test.ts index 14770ccf1f..01a2eeb609 100644 --- a/apps/chat-e2e/src/tests/workWithModels.test.ts +++ b/apps/chat-e2e/src/tests/workWithModels.test.ts @@ -91,10 +91,8 @@ dialTest( tooltip, localStorageManager, page, - setIssueIds, }) => { setTestIds('EPMRTC-477', 'EPMRTC-1463'); - setIssueIds('689'); await dialTest.step('Set random application theme', async () => { const theme = GeneratorUtil.randomArrayElement(Object.keys(Theme)); await localStorageManager.setSettings(theme); From 3b56b7976cd3358cd08c442bdc593748e3b564f5 Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 17:12:12 +0100 Subject: [PATCH 18/19] feat/update-e2e-with-stateful-api: fixed test --- apps/chat-e2e/src/tests/playBack.test.ts | 65 ++++--------------- apps/chat-e2e/src/tests/replay.test.ts | 3 +- .../src/ui/webElements/conversations.ts | 13 +++- 3 files changed, 26 insertions(+), 55 deletions(-) diff --git a/apps/chat-e2e/src/tests/playBack.test.ts b/apps/chat-e2e/src/tests/playBack.test.ts index 2d75e82a38..1c15607057 100644 --- a/apps/chat-e2e/src/tests/playBack.test.ts +++ b/apps/chat-e2e/src/tests/playBack.test.ts @@ -20,8 +20,7 @@ dialTest.beforeAll(async () => { gpt4Model = ModelsUtil.getModel(ModelIds.GPT_4)!; }); -// TODO: redo after new changes in playback -dialTest.skip( +dialTest( 'Playback: first screen.\n' + 'Playback: move to the next using next button.\n' + 'Playback: move to the previous using back button', @@ -37,9 +36,11 @@ dialTest.skip( chatMessages, chatHeader, setTestIds, + setIssueIds, iconApiHelper, }) => { setTestIds('EPMRTC-1417', 'EPMRTC-1418', 'EPMRTC-1422'); + setIssueIds('738'); let conversation: TestConversation; const conversationModels = [defaultModel, gpt4Model]; let playbackConversationName: string; @@ -209,14 +210,9 @@ dialTest.skip( await dialTest.step( 'Click on Next button again twice and verify chat header icon updated, history contains all messages and Next button disabled on bottom controls', async () => { - await chat.playNextChatMessage(); - const playBackMessage = - await playbackControl.playbackMessage.getElementContent(); - expect - .soft(playBackMessage, ExpectedMessages.playbackChatMessageIsValid) - .toBe(conversation.messages[2].content); - - await chat.playNextChatMessage(); + for (let i = 1; i <= 2; i++) { + await chat.playNextChatMessage(); + } const messagesCount = await chatMessages.chatMessages.getElementsCount(); expect @@ -288,7 +284,7 @@ dialTest.skip( isPlaybackNextBtnEnabled, ExpectedMessages.playbackNextButtonEnabled, ) - .toBeFalsy(); + .toBeTruthy(); const isPlaybackPreviousBtnEnabled = await playbackControl.playbackPreviousButton.isElementEnabled(); @@ -299,17 +295,6 @@ dialTest.skip( ) .toBeTruthy(); - const playbackMessage = - await playbackControl.playbackMessage.getElementContent(); - expect - .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) - .toBe(ExpectedConstants.emptyPlaybackMessage); - }, - ); - await dialTest.step( - 'Click on Back button and verify chat header icon updated, history contains first request/response, Next button is enabled on bottom controls', - async () => { - await chat.playPreviousChatMessage(); const messagesCount = await chatMessages.chatMessages.getElementsCount(); expect @@ -321,30 +306,13 @@ dialTest.skip( .soft(lastMessage, ExpectedMessages.messageContentIsValid) .toBe(conversation.messages[1].content); - await chatHeader.leavePlaybackMode.waitForState(); - const isPlaybackNextBtnEnabled = - await playbackControl.playbackNextButton.isElementEnabled(); - expect - .soft( - isPlaybackNextBtnEnabled, - ExpectedMessages.playbackNextButtonEnabled, - ) - .toBeTruthy(); - - const isPlaybackPreviousBtnEnabled = - await playbackControl.playbackPreviousButton.isElementEnabled(); - expect - .soft( - isPlaybackPreviousBtnEnabled, - ExpectedMessages.playbackPreviousButtonEnabled, - ) - .toBeTruthy(); - const playbackMessage = await playbackControl.playbackMessage.getElementContent(); expect .soft(playbackMessage, ExpectedMessages.playbackChatMessageIsValid) - .toBe(ExpectedConstants.emptyPlaybackMessage); + .toBe(conversation.messages[2].content); + + await chatHeader.leavePlaybackMode.waitForState(); const headerTitle = await chatHeader.chatTitle.getElementInnerContent(); expect @@ -370,15 +338,8 @@ dialTest.skip( ); await dialTest.step( - 'Click on Back button again twice and verify chat header icon updated, history is empty and Back button is disabled on bottom controls', + 'Click on Back button again and verify chat header icon updated, history is empty and Back button is disabled on bottom controls', async () => { - await chat.playPreviousChatMessage(); - let playBackMessage = - await playbackControl.playbackMessage.getElementContent(); - expect - .soft(playBackMessage, ExpectedMessages.playbackChatMessageIsValid) - .toBe(conversation.messages[2].content); - await chat.playPreviousChatMessage(); const messagesCount = await chatMessages.chatMessages.getElementsCount(); @@ -404,11 +365,11 @@ dialTest.skip( ) .toBeFalsy(); - playBackMessage = + const playBackMessage = await playbackControl.playbackMessage.getElementContent(); expect .soft(playBackMessage, ExpectedMessages.playbackChatMessageIsValid) - .toBe(ExpectedConstants.emptyPlaybackMessage); + .toBe(conversation.messages[0].content); await chatHeader.waitForState({ state: 'hidden' }); diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index 56ea0fc740..b8e25480d9 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -34,7 +34,6 @@ dialTest( conversationData, chat, dataInjector, - conversationDropdownMenu, conversations, setTestIds, recentEntities, @@ -91,7 +90,7 @@ dialTest( await conversations.openConversationDropdownMenu( replayConversation!.name, ); - await conversationDropdownMenu.selectMenuOption(MenuOptions.replay); + await conversations.selectReplayMenuOption(); }, ); diff --git a/apps/chat-e2e/src/ui/webElements/conversations.ts b/apps/chat-e2e/src/ui/webElements/conversations.ts index ce50cc0142..2a245861d2 100644 --- a/apps/chat-e2e/src/ui/webElements/conversations.ts +++ b/apps/chat-e2e/src/ui/webElements/conversations.ts @@ -1,7 +1,7 @@ import { ChatBarSelectors, SideBarSelectors } from '../selectors'; import { isApiStorageType } from '@/src/hooks/global-setup'; -import { Chronology } from '@/src/testData'; +import { Chronology, MenuOptions } from '@/src/testData'; import { keys } from '@/src/ui/keyboard'; import { IconSelectors } from '@/src/ui/selectors/iconSelectors'; import { Input } from '@/src/ui/webElements/input'; @@ -141,6 +141,17 @@ export class Conversations extends SideBarEntities { return this.openEditEntityNameMode(this.entitySelector, name, newName); } + public async selectReplayMenuOption() { + if (isApiStorageType) { + const respPromise = this.page.waitForResponse( + (resp) => resp.request().method() === 'POST', + ); + await this.getDropdownMenu().selectMenuOption(MenuOptions.replay); + return respPromise; + } + await this.getDropdownMenu().selectMenuOption(MenuOptions.replay); + } + public async getConversationIcon(name: string, index?: number) { return this.getEntityIcon(this.entitySelector, name, index); } From ee782266c6a9ead829782ca31977bb97cba9117d Mon Sep 17 00:00:00 2001 From: Irina_Kartun Date: Thu, 15 Feb 2024 17:41:37 +0100 Subject: [PATCH 19/19] feat/update-e2e-with-stateful-api: fixed test --- apps/chat-e2e/src/tests/replay.test.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/apps/chat-e2e/src/tests/replay.test.ts b/apps/chat-e2e/src/tests/replay.test.ts index b8e25480d9..eb015b4581 100644 --- a/apps/chat-e2e/src/tests/replay.test.ts +++ b/apps/chat-e2e/src/tests/replay.test.ts @@ -97,18 +97,13 @@ dialTest( await dialTest.step( 'Verify new Replay conversation is created and Replay button appears', async () => { - expect - .soft( - await conversations - .getConversationByName( - `${ExpectedConstants.replayConversation}${ - replayConversation!.name - }`, - ) - .isVisible(), - ExpectedMessages.replayConversationCreated, + await conversations + .getConversationByName( + `${ExpectedConstants.replayConversation}${ + replayConversation!.name + }`, ) - .toBeTruthy(); + .waitFor(); expect .soft( await chat.replay.getElementContent(),