Skip to content

Commit

Permalink
feat(chat-e2e): isolated view tests (#2937)
Browse files Browse the repository at this point in the history
  • Loading branch information
nartovm authored Jan 16, 2025
1 parent 471da54 commit 5d38692
Show file tree
Hide file tree
Showing 16 changed files with 476 additions and 63 deletions.
7 changes: 5 additions & 2 deletions apps/chat-e2e/src/assertions/baseAssertion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ export class BaseAssertion {
}

public async assertElementActionabilityState(
element: BaseElement,
element: BaseElement | Locator,
expectedState: ElementActionabilityState,
) {
const elementLocator = element.getElementLocator();
const elementLocator =
element instanceof BaseElement
? element.getElementLocator()
: (element as Locator);
expectedState == 'enabled'
? await expect
.soft(elementLocator, ExpectedMessages.elementIsEnabled)
Expand Down
18 changes: 11 additions & 7 deletions apps/chat-e2e/src/assertions/chatAssertion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ export class ChatAssertion extends BaseAssertion {

public async assertReplayButtonState(expectedState: ElementState) {
const replayButton = this.chat.replay.getElementLocator();
expectedState === 'visible'
? await expect
.soft(replayButton, ExpectedMessages.buttonIsVisible)
.toBeVisible()
: await expect
.soft(replayButton, ExpectedMessages.buttonIsNotVisible)
.toBeHidden();
await this.assertElementState(replayButton, expectedState);
}

public async assertAddAgentButtonState(expectedState: ElementState) {
const addModelButton = this.chat.addModelButton.getElementLocator();
await this.assertElementState(addModelButton, expectedState);
}

public async assertChangeAgentLinkState(expectedState: ElementState) {
const changeAgentButton = this.chat.changeAgentButton.getElementLocator();
await this.assertElementState(changeAgentButton, expectedState);
}

public async assertNotAllowedModelLabelContent() {
Expand Down
22 changes: 20 additions & 2 deletions apps/chat-e2e/src/assertions/sendMessageAssertion.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { ElementState, ExpectedMessages } from '@/src/testData';
import { BaseAssertion } from '@/src/assertions/baseAssertion';
import {
ElementActionabilityState,
ElementState,
ExpectedMessages,
} from '@/src/testData';
import { Styles } from '@/src/ui/domData';
import { SendMessage } from '@/src/ui/webElements';
import { expect } from '@playwright/test';

export class SendMessageAssertion {
export class SendMessageAssertion extends BaseAssertion {
readonly sendMessage: SendMessage;

constructor(sendMessage: SendMessage) {
super();
this.sendMessage = sendMessage;
}

Expand Down Expand Up @@ -56,4 +62,16 @@ export class SendMessageAssertion {
.soft(scrollDownButton, ExpectedMessages.scrollDownButtonIsNotVisible)
.toBeHidden();
}

public async assertInputFieldState(
expectedState: ElementState,
expectedActionability: ElementActionabilityState,
) {
const messageInput = this.sendMessage.messageInput.getElementLocator();
await this.assertElementState(messageInput, expectedState);
await this.assertElementActionabilityState(
messageInput,
expectedActionability,
);
}
}
17 changes: 17 additions & 0 deletions apps/chat-e2e/src/core/localStorageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,23 @@ export class LocalStorageManager {
);
}

async setRecentModelsIdsOnce(...models: DialAIEntityModel[]) {
const uniqueKey = `recentModelsSet_${Date.now()}`;
await this.page.addInitScript(
(data) => {
const { modelIds, key } = data;
if (!sessionStorage.getItem(key)) {
localStorage.setItem('recentModelsIds', modelIds);
sessionStorage.setItem(key, 'true');
}
},
{
modelIds: JSON.stringify(models.map((m) => m.id)),
key: uniqueKey,
},
);
}

async setRecentAddonsIds(...addons: DialAIEntityModel[]) {
await this.page.addInitScript(
this.setRecentAddonsIdsKey(),
Expand Down
37 changes: 33 additions & 4 deletions apps/chat-e2e/src/testData/api/fileApiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ export class FileApiHelper extends BaseApiHelper {
this.userBucket = userBucket;
}

public async putFile(filename: string, parentPath?: string) {
private async putFileGeneric(
buffer: Buffer,
filename: string,
parentPath?: string,
) {
const encodedFilename = encodeURIComponent(filename);
const encodedParentPath = parentPath
? ItemUtil.getEncodedItemId(parentPath)
: undefined;
const filePath = path.join(Attachment.attachmentPath, filename);
const bufferedFile = fs.readFileSync(filePath);

const baseUrl = `${API.fileHost}/${this.userBucket ?? BucketUtil.getBucket()}`;
const url = parentPath
? `${baseUrl}/${encodedParentPath}/${encodedFilename}`
: `${baseUrl}/${encodedFilename}`;

const response = await this.request.put(url, {
headers: {
Accept: '*/*',
Expand All @@ -36,10 +40,11 @@ export class FileApiHelper extends BaseApiHelper {
file: {
name: filename,
mimeType: FileApiHelper.getContentTypeForFile(filename)!,
buffer: bufferedFile,
buffer: buffer,
},
},
});

expect(
response.status(),
`File ${filename} was uploaded to path: ${parentPath}`,
Expand All @@ -49,6 +54,29 @@ export class FileApiHelper extends BaseApiHelper {
return decodeURIComponent(body.url);
}

public async putFile(filename: string, parentPath?: string) {
const filePath = path.join(Attachment.attachmentPath, filename);
const buffer = fs.readFileSync(filePath);
return this.putFileGeneric(buffer, filename, parentPath);
}

public async putStringAsFile(
filename: string,
content: string,
parentPath?: string,
) {
const buffer = Buffer.from(content, 'utf-8');
return this.putFileGeneric(buffer, filename, parentPath);
}

public async getFile(filePath: string) {
const baseUrl = `${API.fileHost}/${this.userBucket ?? BucketUtil.getBucket()}`;
const url = `${baseUrl}/${filePath}`;
const response = await this.request.get(url);
expect(response.status()).toBe(200);
return response;
}

public async deleteFromAllFiles(path: string) {
const url = `/api/${path}`;
const response = await this.request.delete(url);
Expand Down Expand Up @@ -122,6 +150,7 @@ export class FileApiHelper extends BaseApiHelper {
return 'application/octet-stream'; // Default to generic binary type
}
}

public static extractFilename(filePath: string) {
const lastSlashIndex = filePath.lastIndexOf('/');
return lastSlashIndex !== -1
Expand Down
10 changes: 9 additions & 1 deletion apps/chat-e2e/src/testData/expectedConstants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import config from '../../config/chat.playwright.config';

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

export const ExpectedConstants = {
settingsTooltip: (entityType: EntityType) =>
entityType === EntityType.Application
? 'Change conversation settings:\nThere are no conversation settings for this agent'
: 'Change conversation settings:\nTemperature:',
newConversationTitle: 'New conversation',
newConversationWithIndexTitle: (index: number) =>
`${ExpectedConstants.newConversationTitle} ${index}`,
Expand Down Expand Up @@ -292,7 +297,10 @@ export const API = {
shareConversationHost: '/api/share/create',
shareListing: '/api/share/listing',
discardShareWithMeItem: '/api/share/discard',
installedDeploymentsHost: 'clientdata/installed_deployments.json',
installedDeploymentsFolder: 'clientdata',
installedDeploymentsFile: 'installed_deployments.json',
installedDeploymentsHost: () =>
`${API.installedDeploymentsFolder}/${API.installedDeploymentsFile}`,
marketplaceHost: 'marketplace.json',
publicationRequestHost: '/api/publication/create',
publicationRequestCreate: '/api/publication/create',
Expand Down
Loading

0 comments on commit 5d38692

Please sign in to comment.