Skip to content

Commit

Permalink
feat(chat-e2e): overlay events tests (#3001)
Browse files Browse the repository at this point in the history
Co-authored-by: Maksim Nartov <[email protected]>
  • Loading branch information
irinakartun and nartovm authored Feb 5, 2025
1 parent 129737e commit bae8438
Show file tree
Hide file tree
Showing 19 changed files with 807 additions and 31 deletions.
5 changes: 3 additions & 2 deletions apps/chat-e2e/src/assertions/agentInfoAssertion.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DialAIEntityModel } from '@/chat/types/models';
import { BaseAssertion } from '@/src/assertions/base/baseAssertion';
import { ExpectedMessages } from '@/src/testData';
import { AgentInfo } from '@/src/ui/webElements';
Expand All @@ -18,10 +19,10 @@ export class AgentInfoAssertion extends BaseAssertion {
);
}

public async assertDescription(expectedDescription?: string) {
public async assertShortDescription(expectedModel: DialAIEntityModel) {
const description = await this.agentInfo.getAgentDescription();
expect
.soft(description, ExpectedMessages.agentDescriptionIsValid)
.toBe(expectedDescription ?? '');
.toBe(expectedModel.description?.split(/\s*\n\s*\n\s*/g)[0] ?? '');
}
}
77 changes: 77 additions & 0 deletions apps/chat-e2e/src/core/dialOverlayFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ import {
} from '@/src/assertions';
import { OverlayAssertion } from '@/src/assertions/overlay/overlayAssertion';
import test from '@/src/core/baseFixtures';
import { LocalStorageManager } from '@/src/core/localStorageManager';
import { isApiStorageType } from '@/src/hooks/global-setup';
import {
FileApiHelper,
IconApiHelper,
ItemApiHelper,
PublicationApiHelper,
ShareApiHelper,
} from '@/src/testData/api';
import { ApiInjector } from '@/src/testData/injector/apiInjector';
import { BrowserStorageInjector } from '@/src/testData/injector/browserStorageInjector';
import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface';
import { OverlayHomePage } from '@/src/ui/pages/overlay/overlayHomePage';
import { OverlayMarketplacePage } from '@/src/ui/pages/overlay/overlayMarketplacePage';
Expand All @@ -48,11 +52,15 @@ import {
import { ReportAnIssueModal } from '@/src/ui/webElements/footer/reportAnIssueModal';
import { RequestApiKeyModal } from '@/src/ui/webElements/footer/requestApiKeyModal';
import { Header } from '@/src/ui/webElements/header';
import { Actions } from '@/src/ui/webElements/overlay/actions';
import { Configuration } from '@/src/ui/webElements/overlay/configuration';
import { Dialog } from '@/src/ui/webElements/overlay/dialog';
import { ProfilePanel } from '@/src/ui/webElements/overlay/profilePanel';
import { PlaybackControl } from '@/src/ui/webElements/playbackControl';
import { SettingsModal } from '@/src/ui/webElements/settingsModal';
import { ShareModal } from '@/src/ui/webElements/shareModal';
import { BucketUtil } from '@/src/utils';
import { Page } from '@playwright/test';
import path from 'path';
import { APIRequestContext } from 'playwright-core';
import * as process from 'process';
Expand Down Expand Up @@ -106,8 +114,19 @@ const dialOverlayTest = test.extend<{
overlayAssertion: OverlayAssertion;
overlayConversationAssertion: ConversationAssertion;
overlayPromptAssertion: PromptAssertion;
overlayShareApiHelper: ShareApiHelper;
adminUserRequestContext: APIRequestContext;
adminPublicationApiHelper: PublicationApiHelper;
adminShareApiHelper: ShareApiHelper;
adminItemApiHelper: ItemApiHelper;
adminApiInjector: ApiInjector;
adminBrowserStorageInjector: BrowserStorageInjector;
adminPage: Page;
adminLocalStorageManager: LocalStorageManager;
adminDataInjector: DataInjectorInterface;
overlayActions: Actions;
overlayConfiguration: Configuration;
overlayDialog: Dialog;
}>({
// eslint-disable-next-line no-empty-pattern
storageState: async ({}, use) => {
Expand Down Expand Up @@ -354,6 +373,10 @@ const dialOverlayTest = test.extend<{
const promptAssertion = new PromptAssertion(overlayPrompts);
await use(promptAssertion);
},
overlayShareApiHelper: async ({ request }, use) => {
const overlayShareApiHelper = new ShareApiHelper(request);
await use(overlayShareApiHelper);
},
adminUserRequestContext: async ({ playwright }, use) => {
const adminUserRequestContext = await playwright.request.newContext({
storageState: overlayStateFilePath(+config.workers!),
Expand All @@ -367,6 +390,60 @@ const dialOverlayTest = test.extend<{
);
await use(adminPublicationApiHelper);
},
adminShareApiHelper: async ({ adminUserRequestContext }, use) => {
const adminShareApiHelper = new ShareApiHelper(adminUserRequestContext);
await use(adminShareApiHelper);
},
adminItemApiHelper: async ({ adminUserRequestContext }, use) => {
const adminItemApiHelper = new ItemApiHelper(
adminUserRequestContext,
BucketUtil.getAdminUserBucket(),
);
await use(adminItemApiHelper);
},
adminApiInjector: async ({ adminItemApiHelper }, use) => {
const adminApiInjector = new ApiInjector(adminItemApiHelper);
await use(adminApiInjector);
},
adminPage: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: overlayStateFilePath(+config.workers!),
});
const adminPage = await context.newPage();
await use(adminPage);
await context.close();
},
adminLocalStorageManager: async ({ adminPage }, use) => {
const adminLocalStorageManager = new LocalStorageManager(adminPage);
await use(adminLocalStorageManager);
},
adminBrowserStorageInjector: async ({ adminLocalStorageManager }, use) => {
const adminBrowserStorageInjector = new BrowserStorageInjector(
adminLocalStorageManager,
);
await use(adminBrowserStorageInjector);
},
adminDataInjector: async (
{ adminApiInjector, adminBrowserStorageInjector },
use,
) => {
const adminDataInjector = isApiStorageType
? adminApiInjector
: adminBrowserStorageInjector;
await use(adminDataInjector);
},
overlayActions: async ({ overlayHomePage }, use) => {
const overlayActions = overlayHomePage.getActions();
await use(overlayActions);
},
overlayConfiguration: async ({ overlayHomePage }, use) => {
const overlayConfiguration = overlayHomePage.getConfiguration();
await use(overlayConfiguration);
},
overlayDialog: async ({ page }, use) => {
const overlayDialog = new Dialog(page);
await use(overlayDialog);
},
});

export default dialOverlayTest;
30 changes: 17 additions & 13 deletions apps/chat-e2e/src/core/localStorageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,23 @@ export class LocalStorageManager {
}

async getSelectedConversationIds(originHost?: string) {
let selectedConversationIds;
const storage = await this.page.context().storageState();
let origin;
if (originHost) {
origin = storage.origins.find((o) => o.origin === originHost);
} else {
origin = storage.origins[0];
}
if (origin) {
selectedConversationIds = origin.localStorage.find(
(s) => s.name === 'selectedConversationIds',
)?.value;
}
const selectedConversationIds = await this.getKey(
'selectedConversationIds',
originHost,
);
return selectedConversationIds ? JSON.parse(selectedConversationIds) : '';
}

async getRecentModelsIds(originHost?: string) {
const recentModelsIds = await this.getKey('recentModelsIds', originHost);
return recentModelsIds ? JSON.parse(recentModelsIds) : '';
}

private async getKey(key: string, originHost?: string) {
const storage = await this.page.context().storageState();
const origin = originHost
? storage.origins.find((o) => o.origin === originHost)
: storage.origins[0];
return origin?.localStorage.find((s) => s.name === key)?.value;
}
}
16 changes: 13 additions & 3 deletions apps/chat-e2e/src/testData/api/itemApiHelper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Conversation } from '@/chat/types/chat';
import { BackendDataEntity, BackendDataNodeType } from '@/chat/types/common';
import { BackendChatEntity, BackendDataNodeType } from '@/chat/types/common';
import { Prompt } from '@/chat/types/prompt';
import { API } from '@/src/testData';
import { BaseApiHelper } from '@/src/testData/api/baseApiHelper';
Expand Down Expand Up @@ -39,10 +39,20 @@ export class ItemApiHelper extends BaseApiHelper {
statusCode,
`Received response code: ${statusCode} with body: ${await response.text()}`,
).toBe(200);
return (await response.json()) as BackendDataEntity[];
return (await response.json()) as BackendChatEntity[];
}

public async deleteBackendItem(...items: BackendDataEntity[]) {
public async getItem(id: string) {
const response = await this.request.get(this.getHost(`/api/${id}`));
const statusCode = response.status();
expect(
statusCode,
`Received response code: ${statusCode} with body: ${await response.text()}`,
).toBe(200);
return (await response.json()) as Conversation;
}

public async deleteBackendItem(...items: BackendChatEntity[]) {
for (const item of items) {
const path = `/api/${item.url}`;
const response = await this.request.delete(this.getHost(path));
Expand Down
31 changes: 31 additions & 0 deletions apps/chat-e2e/src/testData/api/publicationApiHelper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Conversation } from '@/chat/types/chat';
import {
Publication,
PublicationInfo,
PublicationRequestModel,
PublicationStatus,
PublicationsListModel,
PublishedList,
} from '@/chat/types/publication';
import { API, ExpectedConstants } from '@/src/testData';
import { BaseApiHelper } from '@/src/testData/api/baseApiHelper';
Expand Down Expand Up @@ -31,6 +33,23 @@ export class PublicationApiHelper extends BaseApiHelper {
return (await response.json()) as PublicationsListModel;
}

public async listPublishedConversations() {
const response = await this.request.get(
this.getHost(API.publishedConversations),
{
params: {
recursive: true,
},
},
);
const statusCode = response.status();
expect(
statusCode,
`Received response code: ${statusCode} with body: ${await response.text()}`,
).toBe(200);
return (await response.json()) as PublishedList;
}

public async getPublicationRequestDetails(publicationUrl: string) {
const response = await this.request.post(
this.getHost(API.publicationRequestDetails),
Expand All @@ -46,6 +65,18 @@ export class PublicationApiHelper extends BaseApiHelper {
return (await response.json()) as Publication;
}

public async getPublishedConversation(conversationUrl: string) {
const response = await this.request.get(
this.getHost(`/api/${conversationUrl}`),
);
const statusCode = response.status();
expect(
statusCode,
`Received response code: ${statusCode} with body: ${await response.text()}`,
).toBe(200);
return (await response.json()) as Conversation;
}

public async approveRequest(
publicationRequest: Publication | PublicationInfo,
) {
Expand Down
6 changes: 6 additions & 0 deletions apps/chat-e2e/src/testData/expectedConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ export const API = {
publicationRulesList: '/api/publication/rulesList',
multipleListingHost: () => `${API.listingHost}/multiple?recursive=true`,
pendingPublicationsListing: '/api/publication/listing',
publishedConversations: '/api/publication/conversations/public',
};

export const Import = {
Expand Down Expand Up @@ -433,3 +434,8 @@ export enum AttachFilesFolders {
appdata = 'appdata',
images = 'images',
}

export enum PseudoModel {
replay = 'replay',
playback = 'playback',
}
12 changes: 9 additions & 3 deletions apps/chat-e2e/src/tests/overlay/chatSettingsFeature.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ dialOverlayTest(

dialOverlayTest(
`[Overlay] When no any feature is enabled in the code.\n` +
'[Overlay] Display configure settings for empty chat - Feature.EmptyChatSettings. p1',
'[Overlay] Display configure settings for empty chat - Feature.EmptyChatSettings. p1.\n' +
`[Overlay] Send 'Hello' to Chat manually`,
async ({
overlayHomePage,
overlayChat,
Expand All @@ -212,7 +213,7 @@ dialOverlayTest(
overlaySendMessage,
setTestIds,
}) => {
setTestIds('EPMRTC-3780', 'EPMRTC-3765');
setTestIds('EPMRTC-3780', 'EPMRTC-3765', 'EPMRTC-4846');

await dialTest.step(
'Open sandbox and verify model information, send request field and "Change agent" link are available',
Expand Down Expand Up @@ -255,7 +256,12 @@ dialOverlayTest(
MockedChatApiResponseBodies.simpleTextBody,
{ isOverlay: true },
);
await overlayChat.sendRequestWithButton('test');
const requestContent = 'test';
const request = await overlayChat.sendRequestWithButton(requestContent);
overlayBaseAssertion.assertValue(
request.messages[0].content,
requestContent,
);
await overlayChatMessagesAssertion.assertMessageDeleteIconState(
1,
'visible',
Expand Down
Loading

0 comments on commit bae8438

Please sign in to comment.