diff --git a/apps/chat-e2e/src/assertions/baseAssertion.ts b/apps/chat-e2e/src/assertions/baseAssertion.ts index 64f56111ab..a8a0165adb 100644 --- a/apps/chat-e2e/src/assertions/baseAssertion.ts +++ b/apps/chat-e2e/src/assertions/baseAssertion.ts @@ -164,6 +164,50 @@ export class BaseAssertion { .toBe(expectedColor); } + public async assertStringTruncatedTo160( + originalString: string | null | undefined, + truncatedString: string | null | undefined, + ) { + const maxLength = 160; + + // Handle null or undefined input + if (originalString == null || truncatedString == null) { + expect + .soft(originalString, 'Original string should not be null or undefined') + .not.toBeNull(); + expect + .soft( + truncatedString, + 'Truncated string should not be null or undefined', + ) + .not.toBeNull(); + return; + } + + // Handle strings shorter than the maximum length + if (originalString.length <= maxLength) { + expect + .soft(truncatedString, 'String should not be truncated') + .toBe(originalString); + return; + } + + // Assert that the truncated string has the correct length + expect + .soft( + truncatedString.length, + 'Truncated string should have a length of 160', + ) + .toBe(maxLength); + // Assert that the truncated string is a substring of the original + expect + .soft( + truncatedString, + 'Truncated string should be a substring of the original', + ) + .toBe(originalString.substring(0, maxLength)); + } + public async assertElementsCount( element: BaseElement | Locator, expectedCount: number, @@ -172,7 +216,6 @@ export class BaseAssertion { element instanceof BaseElement ? await element.getElementsCount() : await element.count(); - expect .soft(elementsCount, ExpectedMessages.elementsCountIsValid) .toBe(expectedCount); diff --git a/apps/chat-e2e/src/assertions/promptPreviewModalAssertion.ts b/apps/chat-e2e/src/assertions/promptPreviewModalAssertion.ts new file mode 100644 index 0000000000..21bc9704c1 --- /dev/null +++ b/apps/chat-e2e/src/assertions/promptPreviewModalAssertion.ts @@ -0,0 +1,56 @@ +import { BaseAssertion } from '@/src/assertions/baseAssertion'; +import { ElementState, ExpectedMessages } from '@/src/testData'; +import { PromptPreviewModalWindow } from '@/src/ui/webElements/promptPreviewModalWindow'; + +export class PromptPreviewModalAssertion extends BaseAssertion { + readonly promptPreviewModal: PromptPreviewModalWindow; + + constructor(promptPreviewModal: PromptPreviewModalWindow) { + super(); + this.promptPreviewModal = promptPreviewModal; + } + + public async assertPromptPreviewModalState(expectedState: ElementState) { + await super.assertElementState(this.promptPreviewModal, expectedState); // Use base class method + } + + public async assertPromptPreviewModalTitle(expectedValue: string) { + await super.assertElementText( + this.promptPreviewModal.modalTitle, + expectedValue, + ExpectedMessages.modalDialogTitleIsValid, + ); // Use base class method + } + + public async assertPromptName(expectedValue: string) { + await super.assertElementText( + this.promptPreviewModal.promptName, + expectedValue, + ExpectedMessages.promptNameValid, + ); // Use base class method + } + + public async assertPromptDescription(expectedValue: string | undefined) { + if (expectedValue === '' || expectedValue === undefined) { + await super.assertElementState( + this.promptPreviewModal.promptDescription, + 'hidden', + ExpectedMessages.promptDescriptionValid, + ); + } else { + await super.assertElementText( + this.promptPreviewModal.promptDescription, + expectedValue, + ExpectedMessages.promptDescriptionValid, + ); + } + } + + public async assertPromptContent(expectedValue: string) { + await super.assertElementText( + this.promptPreviewModal.promptContent, + expectedValue, + ExpectedMessages.promptContentValid, + ); + } +} diff --git a/apps/chat-e2e/src/assertions/promptToApproveAssertion.ts b/apps/chat-e2e/src/assertions/promptToApproveAssertion.ts new file mode 100644 index 0000000000..6e977bbabc --- /dev/null +++ b/apps/chat-e2e/src/assertions/promptToApproveAssertion.ts @@ -0,0 +1,4 @@ +import { PublishEntityAssertion } from '@/src/assertions/publishEntityAssertion'; +import { PromptsToApproveTree } from '@/src/ui/webElements/entityTree'; + +export class PromptToApproveAssertion extends PublishEntityAssertion {} diff --git a/apps/chat-e2e/src/assertions/promptToPublishAssertion.ts b/apps/chat-e2e/src/assertions/promptToPublishAssertion.ts new file mode 100644 index 0000000000..6b082da522 --- /dev/null +++ b/apps/chat-e2e/src/assertions/promptToPublishAssertion.ts @@ -0,0 +1,4 @@ +import { PublishEntityAssertion } from '@/src/assertions/publishEntityAssertion'; +import { PromptsToPublishTree } from '@/src/ui/webElements/entityTree'; + +export class PromptToPublishAssertion extends PublishEntityAssertion {} diff --git a/apps/chat-e2e/src/assertions/publishedPromptPreviewModalAssertion.ts b/apps/chat-e2e/src/assertions/publishedPromptPreviewModalAssertion.ts new file mode 100644 index 0000000000..e8a3065500 --- /dev/null +++ b/apps/chat-e2e/src/assertions/publishedPromptPreviewModalAssertion.ts @@ -0,0 +1,13 @@ +import { PromptPreviewModalAssertion } from '@/src/assertions/promptPreviewModalAssertion'; +import { PublishedPromptPreviewModal } from '@/src/ui/webElements/publishedPromptPreviewModal'; + +export class PublishedPromptPreviewModalAssertion extends PromptPreviewModalAssertion { + readonly publishedPromptPreviewModal: PublishedPromptPreviewModal; + + constructor(publishedPromptPreviewModal: PublishedPromptPreviewModal) { + super(publishedPromptPreviewModal); + this.publishedPromptPreviewModal = publishedPromptPreviewModal; + } + + // Add assertions specific to PublishedPromptPreviewModal here +} diff --git a/apps/chat-e2e/src/assertions/sharedPromptPreviewModalAssertion.ts b/apps/chat-e2e/src/assertions/sharedPromptPreviewModalAssertion.ts index 56eda8e354..f9fd409075 100644 --- a/apps/chat-e2e/src/assertions/sharedPromptPreviewModalAssertion.ts +++ b/apps/chat-e2e/src/assertions/sharedPromptPreviewModalAssertion.ts @@ -1,74 +1,17 @@ -import { ElementState, ExpectedMessages } from '@/src/testData'; +import { PromptPreviewModalAssertion } from '@/src/assertions/promptPreviewModalAssertion'; +import { ExpectedMessages } from '@/src/testData'; import { Styles } from '@/src/ui/domData'; import { SharedPromptPreviewModal } from '@/src/ui/webElements'; import { expect } from '@playwright/test'; -export class SharedPromptPreviewModalAssertion { +export class SharedPromptPreviewModalAssertion extends PromptPreviewModalAssertion { readonly sharedPromptPreviewModal: SharedPromptPreviewModal; constructor(sharedPromptPreviewModal: SharedPromptPreviewModal) { + super(sharedPromptPreviewModal); this.sharedPromptPreviewModal = sharedPromptPreviewModal; } - public async assertSharedPromptPreviewModalState( - expectedState: ElementState, - ) { - const sharedPromptPreviewModal = - this.sharedPromptPreviewModal.getElementLocator(); - expectedState === 'visible' - ? await expect - .soft(sharedPromptPreviewModal, ExpectedMessages.modalWindowIsOpened) - .toBeVisible() - : await expect - .soft(sharedPromptPreviewModal, ExpectedMessages.modalWindowIsClosed) - .toBeHidden(); - } - - public async assertSharedPromptPreviewModalTitle(expectedValue: string) { - expect - .soft( - await this.sharedPromptPreviewModal.modalTitle.getElementInnerContent(), - ExpectedMessages.modalDialogTitleIsValid, - ) - .toBe(expectedValue); - } - - public async assertSharedPromptName(expectedValue: string) { - expect - .soft( - await this.sharedPromptPreviewModal.promptName.getElementInnerContent(), - ExpectedMessages.promptNameValid, - ) - .toBe(expectedValue); - } - - public async assertSharedPromptDescription( - expectedValue: string | undefined, - ) { - expectedValue === '' || expectedValue === undefined - ? await expect - .soft( - this.sharedPromptPreviewModal.promptDescription.getElementLocator(), - ExpectedMessages.promptDescriptionValid, - ) - .toBeHidden() - : expect - .soft( - await this.sharedPromptPreviewModal.promptDescription.getElementInnerContent(), - ExpectedMessages.promptDescriptionValid, - ) - .toBe(expectedValue); - } - - public async assertSharedPromptContent(expectedValue: string) { - expect - .soft( - await this.sharedPromptPreviewModal.promptContent.getElementInnerContent(), - ExpectedMessages.promptContentValid, - ) - .toBe(expectedValue); - } - public async assertExportButtonColors(expectedColor: string) { const buttonColor = await this.sharedPromptPreviewModal.promptExportButton.getComputedStyleProperty( @@ -76,6 +19,7 @@ export class SharedPromptPreviewModalAssertion { ); const buttonBordersColor = await this.sharedPromptPreviewModal.promptExportButton.getAllBorderColors(); + expect .soft(buttonColor[0], ExpectedMessages.elementColorIsValid) .toBe(expectedColor); @@ -95,6 +39,7 @@ export class SharedPromptPreviewModalAssertion { ); const buttonBordersColor = await this.sharedPromptPreviewModal.promptDeleteButton.getAllBorderColors(); + expect .soft(buttonColor[0], ExpectedMessages.elementColorIsValid) .toBe(expectedColor); diff --git a/apps/chat-e2e/src/core/dialAdminFixtures.ts b/apps/chat-e2e/src/core/dialAdminFixtures.ts index 31770cc37e..26ed75487e 100644 --- a/apps/chat-e2e/src/core/dialAdminFixtures.ts +++ b/apps/chat-e2e/src/core/dialAdminFixtures.ts @@ -20,6 +20,8 @@ import { } from '@/src/assertions'; import { ConversationToApproveAssertion } from '@/src/assertions/conversationToApproveAssertion'; import { FolderAssertion } from '@/src/assertions/folderAssertion'; +import { PromptToApproveAssertion } from '@/src/assertions/promptToApproveAssertion'; +import { PublishedPromptPreviewModalAssertion } from '@/src/assertions/publishedPromptPreviewModalAssertion'; import { PublishingApprovalModalAssertion } from '@/src/assertions/publishingApprovalModalAssertion'; import { SideBarEntityAssertion } from '@/src/assertions/sideBarEntityAssertion'; import dialTest, { stateFilePath } from '@/src/core/dialFixtures'; @@ -27,14 +29,17 @@ import { LocalStorageManager } from '@/src/core/localStorageManager'; import { AppContainer } from '@/src/ui/webElements/appContainer'; import { ApproveRequiredConversationsTree, + ApproveRequiredPrompts, ConversationsToApproveTree, ConversationsTree, FolderConversationsToApprove, FolderPrompts, Folders, OrganizationConversationsTree, + PromptsToApproveTree, PromptsTree, } from '@/src/ui/webElements/entityTree'; +import { PublishedPromptPreviewModal } from '@/src/ui/webElements/publishedPromptPreviewModal'; import { Tooltip } from '@/src/ui/webElements/tooltip'; import { Page } from '@playwright/test'; @@ -50,13 +55,18 @@ const dialAdminTest = dialTest.extend<{ adminConversations: ConversationsTree; adminPrompts: PromptsTree; adminApproveRequiredConversations: ApproveRequiredConversationsTree; + adminApproveRequiredPrompts: ApproveRequiredPrompts; adminOrganizationFolderConversations: Folders; adminConversationsToApprove: ConversationsToApproveTree; + adminPromptsToApprove: PromptsToApproveTree; adminPublishingApprovalModal: PublishingApprovalModal; + adminPublishedPromptPreviewModal: PublishedPromptPreviewModal; adminApproveRequiredConversationsAssertion: FolderAssertion; + adminApproveRequiredPromptsAssertion: FolderAssertion; adminOrganizationFolderConversationAssertions: FolderAssertion; adminPublishingApprovalModalAssertion: PublishingApprovalModalAssertion; adminConversationToApproveAssertion: ConversationToApproveAssertion; + adminPromptToApproveAssertion: PromptToApproveAssertion; adminFolderToApproveAssertion: PublishFolderAssertion; adminPublicationReviewControl: PublicationReviewControl; adminChatHeader: ChatHeader; @@ -71,7 +81,24 @@ const dialAdminTest = dialTest.extend<{ adminApproveRequiredConversationDropdownMenuAssertion: MenuAssertion; adminTooltipAssertion: TooltipAssertion; adminOrganizationConversationAssertion: SideBarEntityAssertion; + adminPublishedPromptPreviewModalAssertion: PublishedPromptPreviewModalAssertion; }>({ + adminPublishedPromptPreviewModalAssertion: async ( + { adminPublishedPromptPreviewModal }, + use, + ) => { + const adminPublishedPromptPreviewModalAssertion = + new PublishedPromptPreviewModalAssertion( + adminPublishedPromptPreviewModal, + ); + await use(adminPublishedPromptPreviewModalAssertion); + }, + adminPublishedPromptPreviewModal: async ({ adminPage }, use) => { + const publishedPromptPreviewModal = new PublishedPromptPreviewModal( + adminPage, + ); + await use(publishedPromptPreviewModal); + }, adminPage: async ({ browser }, use) => { const context = await browser.newContext({ storageState: stateFilePath(+config.workers! * 3), @@ -114,7 +141,8 @@ const dialAdminTest = dialTest.extend<{ await use(additionalShareUserPrompts); }, adminFolderPrompts: async ({ adminPromptBar }, use) => { - const additionalShareUserFolderPrompts = adminPromptBar.getFolderPrompts(); + const additionalShareUserFolderPrompts = + adminPromptBar.getPinnedFolderPrompts(); await use(additionalShareUserFolderPrompts); }, adminApproveRequiredConversations: async ({ adminChatBar }, use) => { @@ -122,6 +150,11 @@ const dialAdminTest = dialTest.extend<{ adminChatBar.getApproveRequiredConversationsTree(); await use(adminApproveRequiredConversations); }, + adminApproveRequiredPrompts: async ({ adminPromptBar }, use) => { + const adminApproveRequiredPrompts = + adminPromptBar.getApproveRequiredPrompts(); + await use(adminApproveRequiredPrompts); + }, adminOrganizationFolderConversations: async ({ adminChatBar }, use) => { const adminOrganizationFolderConversations = adminChatBar.getOrganizationFolderConversations(); @@ -135,6 +168,11 @@ const dialAdminTest = dialTest.extend<{ adminPublishingApprovalModal.getConversationsToApproveTree(); await use(adminConversationsToApprove); }, + adminPromptsToApprove: async ({ adminPublishingApprovalModal }, use) => { + const adminPromptsToApprove = + adminPublishingApprovalModal.getPromptsToApproveTree(); + await use(adminPromptsToApprove); + }, adminPublishingApprovalModal: async ({ adminPage }, use) => { const adminPublishingApprovalModal = new PublishingApprovalModal(adminPage); await use(adminPublishingApprovalModal); @@ -197,6 +235,14 @@ const dialAdminTest = dialTest.extend<{ ); await use(adminApproveRequiredConversationsAssertion); }, + adminApproveRequiredPromptsAssertion: async ( + { adminApproveRequiredPrompts }, + use, + ) => { + const adminApproveRequiredPromptsAssertion = + new FolderAssertion(adminApproveRequiredPrompts); + await use(adminApproveRequiredPromptsAssertion); + }, adminOrganizationFolderConversationAssertions: async ( { adminOrganizationFolderConversations }, use, @@ -222,6 +268,12 @@ const dialAdminTest = dialTest.extend<{ new ConversationToApproveAssertion(adminConversationsToApprove); await use(adminConversationToApproveAssertion); }, + adminPromptToApproveAssertion: async ({ adminPromptsToApprove }, use) => { + const adminPromptToApproveAssertion = new PromptToApproveAssertion( + adminPromptsToApprove, + ); + await use(adminPromptToApproveAssertion); + }, adminFolderToApproveAssertion: async ( { adminPublishingApprovalModal }, use, diff --git a/apps/chat-e2e/src/core/dialFixtures.ts b/apps/chat-e2e/src/core/dialFixtures.ts index 405bed34ca..8e6431d436 100644 --- a/apps/chat-e2e/src/core/dialFixtures.ts +++ b/apps/chat-e2e/src/core/dialFixtures.ts @@ -54,6 +54,7 @@ import { AddonsDialogAssertion } from '@/src/assertions/addonsDialogAssertion'; import { ConversationToPublishAssertion } from '@/src/assertions/conversationToPublishAssertion'; import { ManageAttachmentsAssertion } from '@/src/assertions/manageAttachmentsAssertion'; import { MessageTemplateModalAssertion } from '@/src/assertions/messageTemplateModalAssertion'; +import { PromptToPublishAssertion } from '@/src/assertions/promptToPublishAssertion'; import { RenameConversationModalAssertion } from '@/src/assertions/renameConversationModalAssertion'; import { SelectFolderModalAssertion } from '@/src/assertions/selectFolderModalAssertion'; import { SettingsModalAssertion } from '@/src/assertions/settingsModalAssertion'; @@ -92,9 +93,11 @@ import { FolderPrompts, Folders, OrganizationConversationsTree, + PromptsToPublishTree, PromptsTree, PublishFolder, } from '@/src/ui/webElements/entityTree'; +import { OrganizationPromptsTree } from '@/src/ui/webElements/entityTree/sidebar/organizationPromptsTree'; import { ErrorPopup } from '@/src/ui/webElements/errorPopup'; import { ErrorToast } from '@/src/ui/webElements/errorToast'; import { Filter } from '@/src/ui/webElements/filter'; @@ -164,7 +167,9 @@ const dialTest = test.extend< prompts: PromptsTree; folderConversations: FolderConversations; folderPrompts: FolderPrompts; + organizationFolderPrompts: FolderPrompts; organizationConversations: OrganizationConversationsTree; + organizationPrompts: OrganizationPromptsTree; organizationFolderConversations: Folders; conversationSettingsModal: ConversationSettingsModal; talkToAgentDialog: TalkToAgentDialog; @@ -229,7 +234,8 @@ const dialTest = test.extend< manageAttachmentsAssertion: ManageAttachmentsAssertion; settingsModal: SettingsModal; publishingRequestModal: PublishingRequestModal; - conversationsToPublish: ConversationsToPublishTree; + conversationsToPublishTree: ConversationsToPublishTree; + promptsToPublishTree: PromptsToPublishTree; folderConversationsToPublish: FolderConversationsToPublish; publicationApiHelper: PublicationApiHelper; adminPublicationApiHelper: PublicationApiHelper; @@ -238,6 +244,7 @@ const dialTest = test.extend< conversationAssertion: ConversationAssertion; chatBarFolderAssertion: FolderAssertion; organizationConversationAssertion: SideBarEntityAssertion; + organizationPromptAssertion: SideBarEntityAssertion; errorToastAssertion: ErrorToastAssertion; downloadAssertion: DownloadAssertion; promptModalAssertion: PromptModalAssertion; @@ -245,6 +252,7 @@ const dialTest = test.extend< confirmationDialogAssertion: ConfirmationDialogAssertion; chatBarAssertion: SideBarAssertion; promptBarFolderAssertion: FolderAssertion; + promptBarOrganizationFolderAssertion: FolderAssertion; promptAssertion: PromptAssertion; promptBarAssertion: SideBarAssertion; accountSettingsAssertion: AccountSettingsAssertion; @@ -278,6 +286,7 @@ const dialTest = test.extend< publishingRequestFolderConversationAssertion: FolderAssertion; talkToAgentDialogAssertion: TalkToAgentDialogAssertion; conversationToPublishAssertion: ConversationToPublishAssertion; + promptToPublishAssertion: PromptToPublishAssertion; folderToPublishAssertion: PublishFolderAssertion; organizationFolderConversationAssertions: FolderAssertion; messageTemplateModalAssertion: MessageTemplateModalAssertion; @@ -443,14 +452,22 @@ const dialTest = test.extend< await use(promptFilterDropdownMenu); }, folderPrompts: async ({ promptBar }, use) => { - const folderPrompts = promptBar.getFolderPrompts(); + const folderPrompts = promptBar.getPinnedFolderPrompts(); await use(folderPrompts); }, + organizationFolderPrompts: async ({ promptBar }, use) => { + const organizationFolderPrompts = promptBar.getOrganizationFolderPrompts(); + await use(organizationFolderPrompts); + }, organizationConversations: async ({ chatBar }, use) => { const organizationConversations = chatBar.getOrganizationConversationsTree(); await use(organizationConversations); }, + organizationPrompts: async ({ promptBar }, use) => { + const organizationPrompts = promptBar.getOrganizationPromptsTree(); + await use(organizationPrompts); + }, conversationSettingsModal: async ({ page }, use) => { const conversationSettingsModal = new ConversationSettingsModal(page); await use(conversationSettingsModal); @@ -728,11 +745,16 @@ const dialTest = test.extend< const publishingModal = new PublishingRequestModal(page); await use(publishingModal); }, - conversationsToPublish: async ({ publishingRequestModal }, use) => { + conversationsToPublishTree: async ({ publishingRequestModal }, use) => { const conversationsToPublishTree = publishingRequestModal.getConversationsToPublishTree(); await use(conversationsToPublishTree); }, + promptsToPublishTree: async ({ publishingRequestModal }, use) => { + const promptsToPublishTree = + publishingRequestModal.getPromptsToPublishTree(); + await use(promptsToPublishTree); + }, folderConversationsToPublish: async ({ publishingRequestModal }, use) => { const folderConversationsToPublish = publishingRequestModal.getFolderConversationsToPublish(); @@ -777,6 +799,11 @@ const dialTest = test.extend< ); await use(organizationConversationAssertion); }, + organizationPromptAssertion: async ({ organizationPrompts }, use) => { + const organizationPromptAssertion = + new SideBarEntityAssertion(organizationPrompts); + await use(organizationPromptAssertion); + }, chatBarFolderAssertion: async ({ folderConversations }, use) => { const chatBarFolderAssertion = new FolderAssertion( folderConversations, @@ -816,6 +843,14 @@ const dialTest = test.extend< ); await use(promptBarFolderAssertion); }, + promptBarOrganizationFolderAssertion: async ( + { organizationFolderPrompts }, + use, + ) => { + const promptBarOrganizationFolderAssertion = + new FolderAssertion(organizationFolderPrompts); + await use(promptBarOrganizationFolderAssertion); + }, promptAssertion: async ({ prompts }, use) => { const promptAssertion = new PromptAssertion(prompts); await use(promptAssertion); @@ -965,12 +1000,21 @@ const dialTest = test.extend< ); await use(talkToAgentDialogAssertion); }, - conversationToPublishAssertion: async ({ conversationsToPublish }, use) => { + conversationToPublishAssertion: async ( + { conversationsToPublishTree }, + use, + ) => { const conversationToPublishAssertion = new ConversationToPublishAssertion( - conversationsToPublish, + conversationsToPublishTree, ); await use(conversationToPublishAssertion); }, + promptToPublishAssertion: async ({ promptsToPublishTree }, use) => { + const promptToPublishAssertion = new PromptToPublishAssertion( + promptsToPublishTree, + ); + await use(promptToPublishAssertion); + }, folderToPublishAssertion: async ({ publishingRequestModal }, use) => { const folderToPublishAssertion = new PublishFolderAssertion( publishingRequestModal.getFolderConversationsToPublish(), diff --git a/apps/chat-e2e/src/core/dialSharedWithMeFixtures.ts b/apps/chat-e2e/src/core/dialSharedWithMeFixtures.ts index 36c2eb7418..c7261af6ef 100644 --- a/apps/chat-e2e/src/core/dialSharedWithMeFixtures.ts +++ b/apps/chat-e2e/src/core/dialSharedWithMeFixtures.ts @@ -54,7 +54,6 @@ import { ConversationsTree, FolderPrompts, PromptsTree, - SharedFolderPrompts, } from '@/src/ui/webElements/entityTree'; import { SharedFolderConversations } from '@/src/ui/webElements/entityTree/sidebar/sharedFolderConversations'; import { SharedWithMeConversationsTree } from '@/src/ui/webElements/entityTree/sidebar/sharedWithMeConversationsTree'; @@ -74,7 +73,7 @@ const dialSharedWithMeTest = dialTest.extend<{ additionalShareUserSharedWithMeConversations: SharedWithMeConversationsTree; additionalShareUserSharedFolderConversations: SharedFolderConversations; additionalShareUserSharedWithMePrompts: SharedWithMePromptsTree; - additionalShareUserSharedFolderPrompts: SharedFolderPrompts; + additionalShareUserSharedFolderPrompts: FolderPrompts; additionalShareUserChat: Chat; additionalShareUserConversationSettingsModal: ConversationSettingsModal; additionalShareUserAgentSettings: AgentSettings; @@ -111,7 +110,7 @@ const dialSharedWithMeTest = dialTest.extend<{ additionalShareUserSendMessageAssertion: SendMessageAssertion; additionalShareUserVariableModalAssertion: VariableModalAssertion; additionalShareUserConversationDropdownMenu: DropdownMenu; - additionalShareUserSharedFolderPromptsAssertions: FolderAssertion; + additionalShareUserSharedFolderPromptsAssertions: FolderAssertion; additionalShareUserPromptsDropdownMenuAssertion: MenuAssertion; additionalShareUserFolderDropdownMenuAssertion: MenuAssertion; additionalShareUserConfirmationDialogAssertion: ConfirmationDialogAssertion; @@ -445,7 +444,7 @@ const dialSharedWithMeTest = dialTest.extend<{ use, ) => { const additionalShareUserFolderPrompts = - additionalShareUserPromptBar.getFolderPrompts(); + additionalShareUserPromptBar.getPinnedFolderPrompts(); await use(additionalShareUserFolderPrompts); }, additionalShareUserFolderDropdownMenu: async ( @@ -570,7 +569,7 @@ const dialSharedWithMeTest = dialTest.extend<{ use, ) => { const additionalShareUserSharedFolderPromptsAssertions = - new FolderAssertion( + new FolderAssertion( additionalShareUserSharedFolderPrompts, ); await use(additionalShareUserSharedFolderPromptsAssertions); diff --git a/apps/chat-e2e/src/tests/monitoring/sharePrompt.test.ts b/apps/chat-e2e/src/tests/monitoring/sharePrompt.test.ts index b51afe7c51..a373247fe1 100644 --- a/apps/chat-e2e/src/tests/monitoring/sharePrompt.test.ts +++ b/apps/chat-e2e/src/tests/monitoring/sharePrompt.test.ts @@ -54,19 +54,19 @@ dialSharedWithMeTest( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptName( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptName( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptDescription( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptDescription( prompt.description, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptContent( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptContent( prompt.content!, ); }, diff --git a/apps/chat-e2e/src/tests/promptExportImport.test.ts b/apps/chat-e2e/src/tests/promptExportImport.test.ts index 3ccc5acc9b..a376658404 100644 --- a/apps/chat-e2e/src/tests/promptExportImport.test.ts +++ b/apps/chat-e2e/src/tests/promptExportImport.test.ts @@ -874,7 +874,7 @@ dialTest( await dialTest.step( 'Move 3rd level folder on the 1st level folder and import exported prompt', async () => { - await promptBar.drugAndDropFolderToFolder( + await promptBar.dragAndDropFolderToFolder( nestedFolders[levelsCount - 1].name, nestedFolders[0].name, { isHttpMethodTriggered: true }, diff --git a/apps/chat-e2e/src/tests/publishConversation.test.ts b/apps/chat-e2e/src/tests/publishConversation.test.ts index a99330ef4e..d9ad27e524 100644 --- a/apps/chat-e2e/src/tests/publishConversation.test.ts +++ b/apps/chat-e2e/src/tests/publishConversation.test.ts @@ -36,7 +36,7 @@ dialAdminTest( organizationConversations, conversationDropdownMenu, publishingRequestModal, - conversationsToPublish, + conversationsToPublishTree, publishingRequestModalAssertion, iconApiHelper, tooltipAssertion, @@ -137,7 +137,7 @@ dialAdminTest( 'Set publication request name, uncheck conversation and verify tooltip on hover "Send request" button', async () => { await publishingRequestModal.requestName.fillInInput(requestName); - await conversationsToPublish + await conversationsToPublishTree .getEntityCheckbox(conversation.name) .click(); await publishingRequestModal.sendRequestButton.hoverOver(); @@ -148,7 +148,9 @@ dialAdminTest( ); await dialTest.step('Check conversation and send request', async () => { - await conversationsToPublish.getEntityCheckbox(conversation.name).click(); + await conversationsToPublishTree + .getEntityCheckbox(conversation.name) + .click(); publishApiModels = await publishingRequestModal.sendPublicationRequest(); publicationsToUnpublish.push(publishApiModels.response); }); @@ -335,7 +337,7 @@ dialAdminTest( await conversations.openEntityDropdownMenu(conversation.name); await conversationDropdownMenu.selectMenuOption(MenuOptions.publish); await publishingRequestModal.requestName.fillInInput(requestName); - await conversationsToPublish + await conversationsToPublishTree .getEntityVersion(conversation.name) .fill(ExpectedConstants.defaultAppVersion); await publishingRequestModal.sendRequestButton.click(); diff --git a/apps/chat-e2e/src/tests/publishPrompt.test.ts b/apps/chat-e2e/src/tests/publishPrompt.test.ts new file mode 100644 index 0000000000..1c11f03338 --- /dev/null +++ b/apps/chat-e2e/src/tests/publishPrompt.test.ts @@ -0,0 +1,709 @@ +import { Prompt } from '@/chat/types/prompt'; +import { Publication, PublicationRequestModel } from '@/chat/types/publication'; +import dialAdminTest from '@/src/core/dialAdminFixtures'; +import dialTest from '@/src/core/dialFixtures'; +import { + API, + ExpectedConstants, + ExpectedMessages, + MenuOptions, + PublishPath, +} from '@/src/testData'; +import { Colors } from '@/src/ui/domData'; +import { GeneratorUtil } from '@/src/utils'; + +const publicationsToUnpublish: Publication[] = []; + +dialAdminTest( + 'Publish single prompt: select folder in Organization path\n' + + 'Publish prompt: create folder in Organization path\n' + + 'Publish single prompt: rename folder in Organization\n' + + 'Publish prompt:add, rename and delete options for new folder in Change path\n' + + 'Publication request name: Spaces at the beginning or end of chat name are removed\n' + + 'Publication request name: spaces in the middle of request name stay', + async ({ + dialHomePage, + promptData, + dataInjector, + prompts, + promptDropdownMenu, + publishingRequestModal, + selectFolderModal, + adminDialHomePage, + adminApproveRequiredPromptsAssertion, + adminApproveRequiredPrompts, + adminPublishingApprovalModal, + adminPublishingApprovalModalAssertion, + setTestIds, + baseAssertion, + selectFolders, + adminPublishedPromptPreviewModal, + adminPromptToApproveAssertion, + adminPublishedPromptPreviewModalAssertion, + promptBarOrganizationFolderAssertion, + organizationFolderPrompts, + confirmationDialog, + folderDropdownMenu, + }) => { + dialAdminTest.slow(); + setTestIds( + 'EPMRTC-3305', + 'EPMRTC-3595', + 'EPMRTC-3313', + 'EPMRTC-3596', + 'EPMRTC-3604', + 'EPMRTC-3606', + ); + let prompt1: Prompt; + let prompt2: Prompt; + const folderName = GeneratorUtil.randomString(10); + const requestName1WithoutLeadingAndTrailingSpaces = `${GeneratorUtil.randomPublicationRequestName()} ${GeneratorUtil.randomString(7)}`; + const requestName1WithSpaces = ` ${requestName1WithoutLeadingAndTrailingSpaces} `; + const requestName2 = GeneratorUtil.randomPublicationRequestName(); + let publishApiModels: { + request: PublicationRequestModel; + response: Publication; + }; + + await dialTest.step('Prepare 2 prompts', async () => { + prompt1 = promptData.prepareDefaultPrompt(); + promptData.resetData(); + prompt2 = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt1, prompt2]); + }); + + await dialTest.step('Publish a single prompt', async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await prompts.openEntityDropdownMenu(prompt1.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.publish); + await baseAssertion.assertElementState(publishingRequestModal, 'visible'); + }); + + await dialTest.step( + 'User clicks on "Change path", hover 3 dots on folder1_new, create folder2, then delete it', + async () => { + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + await selectFolderModal.newFolderButton.click(); + await selectFolders.editFolderNameWithEnter(folderName); + await selectFolders.openFolderDropdownMenu(folderName); + await folderDropdownMenu.selectMenuOption(MenuOptions.addNewFolder); + await selectFolders.editFolderNameWithEnter(`${folderName} 2`); + await selectFolders.openFolderDropdownMenu(`${folderName} 2`); + await folderDropdownMenu.selectMenuOption(MenuOptions.delete); + await confirmationDialog.confirm(); + await selectFolders + .getFolderByName(`${folderName} 2`) + .waitFor({ state: 'hidden' }); + }, + ); + + await dialTest.step( + 'User reloads the page and reopens the modal in order to workaround the 2803 issue', + async () => { + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + await prompts.openEntityDropdownMenu(prompt1.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.publish); + await baseAssertion.assertElementState( + publishingRequestModal, + 'visible', + ); + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + }, + ); + + await dialTest.step( + 'User creates folder and rename it under Organization, user renames folder', + async () => { + await selectFolderModal.newFolderButton.click(); + await selectFolders.editFolderNameWithEnter(`${folderName}_rename`); + await selectFolders.openFolderDropdownMenu(`${folderName}_rename`); + await folderDropdownMenu.selectMenuOption(MenuOptions.rename); + await selectFolders.editFolderNameWithEnter(folderName); + }, + ); + + await dialTest.step( + 'User reloads the page and reopens the modal in order to workaround the 2803 issue', + async () => { + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + await prompts.openEntityDropdownMenu(prompt1.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.publish); + await baseAssertion.assertElementState( + publishingRequestModal, + 'visible', + ); + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + await selectFolderModal.newFolderButton.click(); + await selectFolders.editFolderNameWithEnter(folderName); + }, + ); + + await dialTest.step('User selects renamed folder', async () => { + await selectFolderModal.selectFolder(folderName); + await selectFolderModal.clickSelectFolderButton({ + triggeredApiHost: API.publicationRulesList, + }); + }); + + await dialTest.step( + 'Set publication request name, check prompt to publish and send request', + async () => { + await publishingRequestModal.requestName.fillInInput( + requestName1WithSpaces, + ); + await baseAssertion.assertElementText( + publishingRequestModal.getChangePublishToPath().path, + `${PublishPath.Organization}/${folderName}`, + ); + publishApiModels = + await publishingRequestModal.sendPublicationRequest(); + publicationsToUnpublish.push(publishApiModels.response); + }, + ); + + await dialAdminTest.step( + 'Login as admin and verify conversation publishing request is displayed under "Approve required" section', + async () => { + await adminDialHomePage.openHomePage(); + await adminDialHomePage.waitForPageLoaded(); + await adminApproveRequiredPromptsAssertion.assertFolderState( + { name: requestName1WithoutLeadingAndTrailingSpaces }, + 'visible', + ); + }, + ); + + await dialAdminTest.step( + 'Expand request folder and verify "Publication approval" modal is displayed', + async () => { + await adminApproveRequiredPrompts.expandApproveRequiredFolder( + requestName1WithoutLeadingAndTrailingSpaces, + ); + await adminApproveRequiredPromptsAssertion.assertFolderEntityState( + { name: requestName1WithoutLeadingAndTrailingSpaces }, + { name: prompt1.name }, + 'visible', + ); + await adminPublishingApprovalModalAssertion.assertElementState( + adminPublishingApprovalModal, + 'visible', + ); + await adminPublishingApprovalModalAssertion.assertElementText( + adminPublishingApprovalModal.publishToPath, + `Organization/${folderName}`, + ); + await adminPublishingApprovalModalAssertion.assertRequestCreationDate( + publishApiModels.response, + ); + await adminPromptToApproveAssertion.assertEntityState( + { name: prompt1.name }, + 'visible', + ); + await adminPromptToApproveAssertion.assertEntityColor( + { name: prompt1.name }, + Colors.textPrimary, + ); + await adminPromptToApproveAssertion.assertEntityVersion( + { name: prompt1.name }, + ExpectedConstants.defaultAppVersion, + ); + await adminPromptToApproveAssertion.assertEntityVersionColor( + { name: prompt1.name }, + Colors.textPrimary, + ); + //TODO + // await adminPromptToApproveAssertion.assertTreeEntityIcon( + // { name: prompt1.name }, + // expectedConversationIcon, + // ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.goToReviewButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.approveButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementActionabilityState( + adminPublishingApprovalModal.approveButton, + 'disabled', + ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.rejectButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementActionabilityState( + adminPublishingApprovalModal.rejectButton, + 'enabled', + ); + }, + ); + + await dialAdminTest.step( + 'Click on "Go to a review" button and verify conversation details are displayed', + async () => { + await adminPublishingApprovalModal.goToEntityReview({ + isHttpMethodTriggered: false, + }); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalState( + 'visible', + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( + prompt1.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptName( + prompt1.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptContent( + prompt1.content!, + ); + for (const element of [ + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .previousButton, + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .nextButton, + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .backToPublicationRequestButton, + adminPublishedPromptPreviewModal.promptExportButton, + ]) { + await baseAssertion.assertElementState(element, 'visible'); + } + await adminPublishedPromptPreviewModal + .getPublicationReviewControl() + .backToPublicationRequestButton.click(); + await adminPublishingApprovalModal.approveRequest(); + }, + ); + + await dialTest.step( + 'by user1 reload page and check prompt in Organization section inside folder1', + async () => { + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + await promptBarOrganizationFolderAssertion.assertFolderState( + { name: folderName }, + 'visible', + ); + await organizationFolderPrompts.expandFolder(folderName); + await promptBarOrganizationFolderAssertion.assertFolderEntityState( + { name: folderName }, + { name: prompt1.name }, + 'visible', + ); + }, + ); + + await dialTest.step( + 'Publish a second prompt to an existing folder', + async () => { + await prompts.openEntityDropdownMenu(prompt2.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.publish); + await baseAssertion.assertElementState( + publishingRequestModal, + 'visible', + ); + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + await selectFolderModal.selectFolder(folderName); + await selectFolderModal.clickSelectFolderButton({ + triggeredApiHost: API.publicationRulesList, + }); + }, + ); + + await dialTest.step( + 'Set publication request name, check prompt to publish and send request', + async () => { + await publishingRequestModal.requestName.fillInInput(requestName2); + publishApiModels = + await publishingRequestModal.sendPublicationRequest(); + publicationsToUnpublish.push(publishApiModels.response); + }, + ); + await dialAdminTest.step( + 'Login as admin and verify conversation publishing request is displayed under "Approve required" section', + async () => { + await adminDialHomePage.reloadPage(); + await adminDialHomePage.waitForPageLoaded(); + await adminApproveRequiredPromptsAssertion.assertFolderState( + { name: requestName2 }, + 'visible', + ); + }, + ); + + await dialAdminTest.step( + 'Expand request folder and verify "Publication approval" modal is displayed', + async () => { + await adminApproveRequiredPrompts.expandApproveRequiredFolder( + requestName2, + ); + await adminApproveRequiredPromptsAssertion.assertFolderEntityState( + { name: requestName2 }, + { name: prompt2.name }, + 'visible', + ); + await adminPublishingApprovalModalAssertion.assertElementState( + adminPublishingApprovalModal, + 'visible', + ); + await adminPublishingApprovalModalAssertion.assertElementText( + adminPublishingApprovalModal.publishToPath, + `Organization/${folderName}`, + ); + await adminPublishingApprovalModalAssertion.assertRequestCreationDate( + publishApiModels.response, + ); + await adminPromptToApproveAssertion.assertEntityState( + { name: prompt2.name }, + 'visible', + ); + await adminPromptToApproveAssertion.assertEntityColor( + { name: prompt2.name }, + Colors.textPrimary, + ); + await adminPromptToApproveAssertion.assertEntityVersion( + { name: prompt2.name }, + ExpectedConstants.defaultAppVersion, + ); + await adminPromptToApproveAssertion.assertEntityVersionColor( + { name: prompt2.name }, + Colors.textPrimary, + ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.goToReviewButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.approveButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementActionabilityState( + adminPublishingApprovalModal.approveButton, + 'disabled', + ); + await adminPromptToApproveAssertion.assertElementState( + adminPublishingApprovalModal.rejectButton, + 'visible', + ); + await adminPromptToApproveAssertion.assertElementActionabilityState( + adminPublishingApprovalModal.rejectButton, + 'enabled', + ); + }, + ); + + await dialAdminTest.step( + 'Click on "Go to a review" button and verify conversation details are displayed', + async () => { + await adminPublishingApprovalModal.goToEntityReview({ + isHttpMethodTriggered: false, + }); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalState( + 'visible', + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( + prompt2.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptName( + prompt2.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptContent( + prompt2.content!, + ); + for (const element of [ + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .previousButton, + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .nextButton, + adminPublishedPromptPreviewModal.getPublicationReviewControl() + .backToPublicationRequestButton, + adminPublishedPromptPreviewModal.promptExportButton, + ]) { + await baseAssertion.assertElementState(element, 'visible'); + } + await adminPublishedPromptPreviewModal + .getPublicationReviewControl() + .backToPublicationRequestButton.click(); + await adminPublishingApprovalModal.approveRequest(); + }, + ); + }, +); + +dialAdminTest( + 'Publish prompt: add new folder inside nested folder structure with depth 4\n' + + 'Publish prompt into nested folder structure inside Organization section\n' + + 'Publish request name: tab is changed to space if to use it in chat name\n' + + 'The first 160 symbols from the input text is used as publication request name #1661\n' + + 'Publication request name can not be blank\n' + + 'Publication request name with hieroglyph, specific letters', + async ({ + dialHomePage, + promptData, + dataInjector, + prompts, + promptDropdownMenu, + publishingRequestModal, + selectFolderModal, + adminDialHomePage, + adminApproveRequiredPromptsAssertion, + adminApproveRequiredPrompts, + adminPublishingApprovalModal, + adminPublishingApprovalModalAssertion, + setTestIds, + baseAssertion, + selectFolders, + adminPublishedPromptPreviewModal, + adminPromptToApproveAssertion, + adminPublishedPromptPreviewModalAssertion, + promptBarOrganizationFolderAssertion, + organizationFolderPrompts, + folderDropdownMenu, + errorToastAssertion, + errorToast, + publishingRequestModalAssertion, + tooltipAssertion, + }) => { + dialAdminTest.slow(); + setTestIds( + 'EPMRTC-3599', + 'EPMRTC-3600', + 'EPMRTC-3601', + 'EPMRTC-3602', + 'EPMRTC-3603', + 'EPMRTC-3605', + ); + let prompt1: Prompt; + const folderNameTemplate = GeneratorUtil.randomString(10); + let folderName = folderNameTemplate; + const publicationPath = `${PublishPath.Organization}/${folderNameTemplate} 1/${folderNameTemplate} 2/${folderNameTemplate} 3/${folderNameTemplate} 4`; + const requestName = GeneratorUtil.randomPublicationRequestName(); + const requestNameWithTabs = `${requestName} Name\ttext\t1 한글이라는 고유한 문자 시스템을 사용하는데`; + const requestNameWithoutTabs = `${requestName} Name text 1 한글이라는 고유한 문자 시스템을 사용하는데`; + let publishApiModels: { + request: PublicationRequestModel; + response: Publication; + }; + + await dialTest.step('Prepare a new prompt', async () => { + prompt1 = promptData.prepareDefaultPrompt(); + await dataInjector.createPrompts([prompt1]); + }); + + await dialTest.step('Publish a single prompt', async () => { + await dialHomePage.openHomePage(); + await dialHomePage.waitForPageLoaded(); + await prompts.openEntityDropdownMenu(prompt1.name); + await promptDropdownMenu.selectMenuOption(MenuOptions.publish); + await baseAssertion.assertElementState(publishingRequestModal, 'visible'); + }); + + await dialTest.step( + 'User clicks on "Change path, creates new folder structure : Folder1->Folder1.1->Folder1.1.1-Folder1.1.1.1', + async () => { + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + await selectFolderModal.newFolderButton.click(); + await selectFolders.editFolderNameWithEnter(`${folderNameTemplate} 1`); + for (let i = 1; i < 4; i++) { + await selectFolders.openFolderDropdownMenu( + `${folderNameTemplate} ${i}`, + ); + await folderDropdownMenu.selectMenuOption(MenuOptions.addNewFolder); + await selectFolders.editFolderNameWithEnter( + `${folderNameTemplate} ${i + 1}`, + ); + } + await selectFolders.openFolderDropdownMenu(`${folderNameTemplate} 4`); + await folderDropdownMenu.selectMenuOption(MenuOptions.addNewFolder); + // Assertions + await errorToastAssertion.assertToastIsVisible(); + await errorToastAssertion.assertToastMessage( + ExpectedConstants.tooManyNestedFolders, + ExpectedMessages.tooManyNestedFolders, + ); + // Bug that closing the toast leads to the closing the modal + await errorToast.closeToast(); + await publishingRequestModal + .getChangePublishToPath() + .changeButton.click(); + await selectFolders + .getFolderByName(folderNameTemplate) + .waitFor({ state: 'visible' }); + for (let i = 1; i < 4; i++) { + await selectFolders + .getFolderByName(`${folderNameTemplate} ${i}`) + .waitFor({ state: 'visible' }); + } + folderName = `${folderNameTemplate} 4`; + }, + ); + + await dialTest.step('User selects nested folder', async () => { + await selectFolderModal.selectFolder(folderName); + await selectFolderModal.clickSelectFolderButton({ + triggeredApiHost: API.publicationRulesList, + }); + }); + + //TODO + //Blocked by 1661 + // await dialTest.step( + // 'Type long solid text of 200 symbols with spaces without enters, it should be truncated to 160 symbols', + // async () => { + // const longName = `${GeneratorUtil.randomString(50)} ${GeneratorUtil.randomString(49)} ${GeneratorUtil.randomString(99)}`; + // await publishingRequestModal.requestName.fillInInput(longName); + // await publishingRequestModal.getChangePublishToPath().changeButton.click(); // Click "Change Path" to move focus + // const truncatedName = await publishingRequestModal.requestName.getElementLocator().inputValue(); + // await baseAssertion.assertStringTruncatedTo160(longName, truncatedName); + // }, + // ); + + await dialTest.step('Check empty publication request name', async () => { + await publishingRequestModalAssertion.assertSendRequestButtonIsDisabled(); + await publishingRequestModal.sendRequestButton.hoverOver(); + await tooltipAssertion.assertTooltipContent( + ExpectedConstants.noPublishNameTooltip, + ); + await publishingRequestModal.requestName.fillInInput(' '); + await publishingRequestModalAssertion.assertSendRequestButtonIsDisabled(); + await publishingRequestModal.sendRequestButton.hoverOver(); + await tooltipAssertion.assertTooltipContent( + ExpectedConstants.noPublishNameTooltip, + ); + await publishingRequestModal.requestName.fillInInput(''); // Clear the input field + }); + + await dialTest.step( + 'Set publication request name, check prompt to publish and send request', + async () => { + await publishingRequestModal.requestName.fillInInput( + requestNameWithTabs, + ); + await baseAssertion.assertElementText( + publishingRequestModal.getChangePublishToPath().path, + publicationPath, + ); + publishApiModels = + await publishingRequestModal.sendPublicationRequest(); + publicationsToUnpublish.push(publishApiModels.response); + }, + ); + + await dialAdminTest.step( + 'Login as admin and verify conversation publishing request is displayed under "Approve required" section', + async () => { + await adminDialHomePage.openHomePage(); + await adminDialHomePage.waitForPageLoaded(); + await adminApproveRequiredPromptsAssertion.assertFolderState( + { name: requestNameWithoutTabs }, + 'visible', + ); + }, + ); + + await dialAdminTest.step( + 'Expand request folder and verify "Publication approval" modal is displayed', + async () => { + await adminApproveRequiredPrompts.expandApproveRequiredFolder( + requestNameWithoutTabs, + ); + await adminApproveRequiredPromptsAssertion.assertFolderEntityState( + { name: requestNameWithoutTabs }, + { name: prompt1.name }, + 'visible', + ); + await adminPublishingApprovalModalAssertion.assertElementState( + adminPublishingApprovalModal, + 'visible', + ); + await adminPromptToApproveAssertion.assertEntityState( + { name: prompt1.name }, + 'visible', + ); + await adminPromptToApproveAssertion.assertEntityColor( + { name: prompt1.name }, + Colors.textPrimary, + ); + await adminPromptToApproveAssertion.assertEntityVersion( + { name: prompt1.name }, + ExpectedConstants.defaultAppVersion, + ); + await adminPromptToApproveAssertion.assertEntityVersionColor( + { name: prompt1.name }, + Colors.textPrimary, + ); + }, + ); + + await dialAdminTest.step( + 'Click on "Go to a review" button and verify conversation details are displayed', + async () => { + await adminPublishingApprovalModal.goToEntityReview({ + isHttpMethodTriggered: false, + }); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalState( + 'visible', + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( + prompt1.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptName( + prompt1.name, + ); + await adminPublishedPromptPreviewModalAssertion.assertPromptContent( + prompt1.content!, + ); + await adminPublishedPromptPreviewModal + .getPublicationReviewControl() + .backToPublicationRequestButton.click(); + await adminPublishingApprovalModal.approveRequest(); + }, + ); + + await dialTest.step( + 'by user1 reload page and check prompt in Organization section inside folder1', + async () => { + await dialHomePage.reloadPage(); + await dialHomePage.waitForPageLoaded(); + for (let i = 1; i < 4; i++) { + await organizationFolderPrompts.expandFolder( + `${folderNameTemplate} ${i}`, + ); + } + await promptBarOrganizationFolderAssertion.assertFolderState( + { name: folderName }, + 'visible', + ); + await organizationFolderPrompts.expandFolder(folderName); + await promptBarOrganizationFolderAssertion.assertFolderEntityState( + { name: folderName }, + { name: prompt1.name }, + 'visible', + ); + }, + ); + }, +); + +dialTest.afterAll( + async ({ publicationApiHelper, adminPublicationApiHelper }) => { + for (const publication of publicationsToUnpublish) { + const unpublishResponse = + await publicationApiHelper.createUnpublishRequest(publication); + await adminPublicationApiHelper.approveRequest(unpublishResponse); + } + }, +); diff --git a/apps/chat-e2e/src/tests/sharedPromptFolderIcons.test.ts b/apps/chat-e2e/src/tests/sharedPromptFolderIcons.test.ts index 0d9602b825..003b4c2751 100644 --- a/apps/chat-e2e/src/tests/sharedPromptFolderIcons.test.ts +++ b/apps/chat-e2e/src/tests/sharedPromptFolderIcons.test.ts @@ -80,7 +80,7 @@ dialTest( 'Add a new empty folder to a folder that gonna be shared', async () => { await promptBar.createNewFolder(); - await promptBar.drugAndDropFolderToFolder( + await promptBar.dragAndDropFolderToFolder( ExpectedConstants.newFolderWithIndexTitle(1), nestedFolders[sharedFolderIndex].name, ); diff --git a/apps/chat-e2e/src/tests/sharedPromptView.test.ts b/apps/chat-e2e/src/tests/sharedPromptView.test.ts index 8a1f53a570..fe3100a8d9 100644 --- a/apps/chat-e2e/src/tests/sharedPromptView.test.ts +++ b/apps/chat-e2e/src/tests/sharedPromptView.test.ts @@ -56,19 +56,19 @@ dialSharedWithMeTest( await dialSharedWithMeTest.step( 'Verify prompt preview modal is opened, prompt parameters are valid', async () => { - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptName( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptName( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptDescription( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptDescription( prompt.description, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptContent( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptContent( prompt.content!, ); }, diff --git a/apps/chat-e2e/src/tests/sharedWithMePromptFolders.test.ts b/apps/chat-e2e/src/tests/sharedWithMePromptFolders.test.ts index a42909a963..23550d4b51 100644 --- a/apps/chat-e2e/src/tests/sharedWithMePromptFolders.test.ts +++ b/apps/chat-e2e/src/tests/sharedWithMePromptFolders.test.ts @@ -68,7 +68,7 @@ dialSharedWithMeTest( await additionalShareUserDialHomePage.waitForPageLoaded({ isPromptShared: true, }); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); await additionalShareUserPromptPreviewModal.closeButton.click(); @@ -91,7 +91,7 @@ dialSharedWithMeTest( await additionalShareUserDialHomePage.waitForPageLoaded({ isPromptShared: true, }); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); await additionalShareUserPromptPreviewModal.closeButton.click(); @@ -160,10 +160,10 @@ dialSharedWithMeTest( await additionalShareUserDialHomePage.waitForPageLoaded({ isPromptShared: true, }); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( nestedPrompts[sharedFolderIndex].name, ); await additionalShareUserPromptPreviewModal.closeButton.click(); @@ -230,10 +230,10 @@ dialSharedWithMeTest( await additionalShareUserDialHomePage.waitForPageLoaded({ isPromptShared: true, }); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( nestedPrompts[sharedFolderIndex].name, ); await additionalShareUserPromptPreviewModal.closeButton.click(); @@ -304,19 +304,19 @@ dialSharedWithMeTest( await additionalShareUserDialHomePage.waitForPageLoaded({ isPromptShared: true, }); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( nestedPrompts[sharedFolderIndex].name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptName( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptName( nestedPrompts[sharedFolderIndex].name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptDescription( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptDescription( nestedPrompts[sharedFolderIndex].description, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptContent( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptContent( nestedPrompts[sharedFolderIndex].content!, ); await additionalShareUserPromptPreviewModal.closeButton.click(); diff --git a/apps/chat-e2e/src/tests/sharedWithMePrompts.test.ts b/apps/chat-e2e/src/tests/sharedWithMePrompts.test.ts index 437322fda4..4e87dd91d2 100644 --- a/apps/chat-e2e/src/tests/sharedWithMePrompts.test.ts +++ b/apps/chat-e2e/src/tests/sharedWithMePrompts.test.ts @@ -64,19 +64,19 @@ dialSharedWithMeTest( { name: prompt.name }, Colors.backgroundAccentTertiaryAlphaDark, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalState( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalState( 'visible', ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptPreviewModalTitle( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptPreviewModalTitle( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptName( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptName( prompt.name, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptDescription( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptDescription( promptDescription, ); - await additionalShareUserSharedPromptPreviewModalAssertion.assertSharedPromptContent( + await additionalShareUserSharedPromptPreviewModalAssertion.assertPromptContent( promptContent, ); }, diff --git a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts index 4335e15af8..cc556b474e 100644 --- a/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts +++ b/apps/chat-e2e/src/tests/sidePanelEntityDragAndDrop.test.ts @@ -351,7 +351,7 @@ dialTest( ), ); - await promptBar.drugPromptToFolder( + await promptBar.dragPromptToFolder( ExpectedConstants.newFolderWithIndexTitle(1), prompt.name, ); @@ -422,7 +422,7 @@ dialTest( await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); await folderPrompts.expandFolder(promptInFolder.folders.name); - await promptBar.drugAndDropPromptToFolderPrompt( + await promptBar.dragAndDropPromptToFolderPrompt( promptInFolder.folders.name, promptInFolder.prompts[0].name, prompt.name, diff --git a/apps/chat-e2e/src/ui/selectors/sideBarSelectors.ts b/apps/chat-e2e/src/ui/selectors/sideBarSelectors.ts index 230068f495..1ca6855617 100644 --- a/apps/chat-e2e/src/ui/selectors/sideBarSelectors.ts +++ b/apps/chat-e2e/src/ui/selectors/sideBarSelectors.ts @@ -47,12 +47,14 @@ export const PromptBarSelectors = { prompts: '[data-qa="prompts-section-container"] >> [data-qa="prompts"]', prompt: '[data-qa="prompt"]', deletePrompts: '[data-qa="delete-prompts"]', - pinnedChats: () => + pinnedPrompts: () => `${PromptBarSelectors.promptFolders} > [data-qa="pinned-prompts-container"]`, sharedWithMePrompts: () => `${PromptBarSelectors.promptFolders} > ${SideBarSelectors.sharedWithMeContainer}`, approveRequiredPrompts: () => `${PromptBarSelectors.promptFolders} > ${SideBarSelectors.approveRequiredContainer}`, + organizationPrompts: () => + `${PromptBarSelectors.promptFolders} > ${SideBarSelectors.organizationContainer}`, leftResizeIcon: '[data-qa="left-resize-icon"]', newEntity: '[data-qa="new-entity"]', }; diff --git a/apps/chat-e2e/src/ui/webElements/chatBar.ts b/apps/chat-e2e/src/ui/webElements/chatBar.ts index bf6786f21d..531fd85f1e 100644 --- a/apps/chat-e2e/src/ui/webElements/chatBar.ts +++ b/apps/chat-e2e/src/ui/webElements/chatBar.ts @@ -9,7 +9,6 @@ import { MenuOptions } from '@/src/testData'; import { DropdownMenu } from '@/src/ui/webElements/dropdownMenu'; import { ApproveRequiredConversationsTree, - ApproveRequiredPrompts, ConversationsTree, FolderConversations, Folders, @@ -31,7 +30,6 @@ export class ChatBar extends SideBar { private sharedFolderConversations!: SharedFolderConversations; private approveRequiredConversationsTree!: ApproveRequiredConversationsTree; private organizationFolderConversations!: Folders; - private approveRequiredPrompts!: ApproveRequiredPrompts; private organizationConversations!: OrganizationConversationsTree; private bottomDropdownMenu!: DropdownMenu; public compareButton = this.getChildElementBySelector( @@ -107,16 +105,6 @@ export class ChatBar extends SideBar { return this.organizationFolderConversations; } - getApproveRequiredPrompts(): ApproveRequiredPrompts { - if (!this.approveRequiredPrompts) { - this.approveRequiredPrompts = new ApproveRequiredPrompts( - this.page, - this.getElementLocator(), - ); - } - return this.approveRequiredPrompts; - } - getOrganizationConversationsTree(): OrganizationConversationsTree { if (!this.organizationConversations) { this.organizationConversations = new OrganizationConversationsTree( diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/index.ts b/apps/chat-e2e/src/ui/webElements/entityTree/index.ts index bfb3e7f020..bfba303652 100644 --- a/apps/chat-e2e/src/ui/webElements/entityTree/index.ts +++ b/apps/chat-e2e/src/ui/webElements/entityTree/index.ts @@ -13,7 +13,6 @@ export * from './sidebar/folderConversations'; export * from './sidebar/folderPrompts'; export * from './sidebar/sharedFolderConversations'; export * from './sidebar/sharedWithMePromptsTree'; -export * from './sidebar/sharedFolderPrompts'; export * from './sidebar/approveRequiredConversationsTree'; export * from './sidebar/approveRequiredPrompts'; export * from './sidebar/organizationConversationsTree'; diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredConversationsTree.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredConversationsTree.ts index 174a7c0b59..6fd7a9712b 100644 --- a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredConversationsTree.ts +++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredConversationsTree.ts @@ -1,9 +1,9 @@ -import { API } from '@/src/testData'; +import { ApproveRequiredEntitiesTree } from './approveRequiredEntitiesTree'; + import { ChatBarSelectors, EntitySelectors } from '@/src/ui/selectors'; -import { Folders } from '@/src/ui/webElements/entityTree'; import { Locator, Page } from '@playwright/test'; -export class ApproveRequiredConversationsTree extends Folders { +export class ApproveRequiredConversationsTree extends ApproveRequiredEntitiesTree { constructor(page: Page, parentLocator: Locator) { super( page, @@ -12,25 +12,4 @@ export class ApproveRequiredConversationsTree extends Folders { EntitySelectors.conversation, ); } - - public async expandApproveRequiredFolder( - requestName: string, - options: { isHttpMethodTriggered?: boolean; httpHost?: string } = { - isHttpMethodTriggered: true, - httpHost: API.publicationRequestDetails, - }, - ) { - await this.expandFolder(requestName, options); - } - - public async selectRequestConversation( - requestName: string, - conversationName: string, - ) { - const responsePromise = this.page.waitForResponse( - (r) => r.request().method() === 'GET', - ); - await this.selectFolderEntity(requestName, conversationName); - await responsePromise; - } } diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts new file mode 100644 index 0000000000..05f050f138 --- /dev/null +++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts @@ -0,0 +1,32 @@ +import { API } from '@/src/testData'; +import { Folders } from '@/src/ui/webElements/entityTree'; +import { Locator, Page } from '@playwright/test'; + +export class ApproveRequiredEntitiesTree extends Folders { + constructor( + page: Page, + parentLocator: Locator, + selector: string, + entitySelector: string, + ) { + super(page, parentLocator, selector, entitySelector); + } + + public async expandApproveRequiredFolder( + requestName: string, + options: { isHttpMethodTriggered?: boolean; httpHost?: string } = { + isHttpMethodTriggered: true, + httpHost: API.publicationRequestDetails, + }, + ) { + await this.expandFolder(requestName, options); + } + + public async selectRequestEntity(requestName: string, entityName: string) { + const responsePromise = this.page.waitForResponse( + (r) => r.request().method() === 'GET', + ); + await this.selectFolderEntity(requestName, entityName); + await responsePromise; + } +} diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredPrompts.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredPrompts.ts index 81931e01e9..2b51d357bf 100644 --- a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredPrompts.ts +++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredPrompts.ts @@ -1,8 +1,9 @@ +import { ApproveRequiredEntitiesTree } from './approveRequiredEntitiesTree'; + import { EntitySelectors, PromptBarSelectors } from '@/src/ui/selectors'; -import { Folders } from '@/src/ui/webElements/entityTree'; import { Locator, Page } from '@playwright/test'; -export class ApproveRequiredPrompts extends Folders { +export class ApproveRequiredPrompts extends ApproveRequiredEntitiesTree { constructor(page: Page, parentLocator: Locator) { super( page, diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/folderPrompts.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/folderPrompts.ts index 64374b5c91..f348c6a0e4 100644 --- a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/folderPrompts.ts +++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/folderPrompts.ts @@ -3,13 +3,32 @@ import { EntitySelectors, PromptBarSelectors } from '../../../selectors'; import { Folders } from '@/src/ui/webElements/entityTree/folders'; import { Locator, Page } from '@playwright/test'; +export enum PromptBarSection { + Organization = 'Organization', + PinnedPrompts = 'PinnedPrompts', + SharedWithMe = 'SharedWithMe', + ApproveRequired = 'ApproveRequired', +} + export class FolderPrompts extends Folders { - constructor(page: Page, parentLocator: Locator) { - super( - page, - parentLocator, - PromptBarSelectors.pinnedChats(), - EntitySelectors.prompt, - ); + constructor(page: Page, parentLocator: Locator, section?: PromptBarSection) { + let selector: string; + switch (section) { + case PromptBarSection.Organization: + selector = PromptBarSelectors.organizationPrompts(); + break; + case PromptBarSection.PinnedPrompts: + selector = PromptBarSelectors.pinnedPrompts(); + break; + case PromptBarSection.SharedWithMe: + selector = PromptBarSelectors.sharedWithMePrompts(); + break; + case PromptBarSection.ApproveRequired: + selector = PromptBarSelectors.approveRequiredPrompts(); + break; + default: + selector = PromptBarSelectors.pinnedPrompts(); + } + super(page, parentLocator, selector, EntitySelectors.prompt); } } diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedFolderPrompts.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/organizationPromptsTree.ts similarity index 52% rename from apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedFolderPrompts.ts rename to apps/chat-e2e/src/ui/webElements/entityTree/sidebar/organizationPromptsTree.ts index e2e54adb56..7b7422a6f5 100644 --- a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedFolderPrompts.ts +++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/organizationPromptsTree.ts @@ -1,14 +1,14 @@ import { EntitySelectors, PromptBarSelectors } from '../../../selectors'; -import { Folders } from '@/src/ui/webElements/entityTree'; +import { BaseSideBarConversationTree } from '@/src/ui/webElements/entityTree/sidebar/baseSideBarConversationTree'; import { Locator, Page } from '@playwright/test'; -export class SharedFolderPrompts extends Folders { +export class OrganizationPromptsTree extends BaseSideBarConversationTree { constructor(page: Page, parentLocator: Locator) { super( page, parentLocator, - PromptBarSelectors.sharedWithMePrompts(), + PromptBarSelectors.organizationPrompts(), EntitySelectors.prompt, ); } diff --git a/apps/chat-e2e/src/ui/webElements/promptBar.ts b/apps/chat-e2e/src/ui/webElements/promptBar.ts index aa4fe6586d..874a33174d 100644 --- a/apps/chat-e2e/src/ui/webElements/promptBar.ts +++ b/apps/chat-e2e/src/ui/webElements/promptBar.ts @@ -2,11 +2,13 @@ import { PromptBarSelectors, SideBarSelectors } from '../selectors'; import { Styles, removeAlpha } from '@/src/ui/domData'; import { + ApproveRequiredPrompts, FolderPrompts, + PromptBarSection, PromptsTree, - SharedFolderPrompts, SharedWithMePromptsTree, } from '@/src/ui/webElements/entityTree'; +import { OrganizationPromptsTree } from '@/src/ui/webElements/entityTree/sidebar/organizationPromptsTree'; import { SideBar } from '@/src/ui/webElements/sideBar'; import { Page } from '@playwright/test'; @@ -16,18 +18,23 @@ export class PromptBar extends SideBar { } private promptsTree!: PromptsTree; - private folderPrompts!: FolderPrompts; private sharedWithMePromptsTree!: SharedWithMePromptsTree; - private sharedFolderPrompts!: SharedFolderPrompts; + private approveRequiredPrompts!: ApproveRequiredPrompts; + private organizationPrompts!: OrganizationPromptsTree; - getFolderPrompts(): FolderPrompts { - if (!this.folderPrompts) { - this.folderPrompts = new FolderPrompts( + private pinnedFolderPrompts!: FolderPrompts; + private sharedFolderPrompts!: FolderPrompts; + private organizationFolderPrompts!: FolderPrompts; + private approveRequiredFolderPrompts!: FolderPrompts; + + getApproveRequiredPrompts(): ApproveRequiredPrompts { + if (!this.approveRequiredPrompts) { + this.approveRequiredPrompts = new ApproveRequiredPrompts( this.page, this.getElementLocator(), ); } - return this.folderPrompts; + return this.approveRequiredPrompts; } getPromptsTree(): PromptsTree { @@ -37,24 +44,24 @@ export class PromptBar extends SideBar { return this.promptsTree; } - getSharedWithMePromptsTree(): SharedWithMePromptsTree { - if (!this.sharedWithMePromptsTree) { - this.sharedWithMePromptsTree = new SharedWithMePromptsTree( + getOrganizationPromptsTree(): OrganizationPromptsTree { + if (!this.organizationPrompts) { + this.organizationPrompts = new OrganizationPromptsTree( this.page, - this.rootLocator, + this.getElementLocator(), ); } - return this.sharedWithMePromptsTree; + return this.organizationPrompts; } - getSharedFolderPrompts(): SharedFolderPrompts { - if (!this.sharedFolderPrompts) { - this.sharedFolderPrompts = new SharedFolderPrompts( + getSharedWithMePromptsTree(): SharedWithMePromptsTree { + if (!this.sharedWithMePromptsTree) { + this.sharedWithMePromptsTree = new SharedWithMePromptsTree( this.page, - this.getElementLocator(), + this.rootLocator, ); } - return this.sharedFolderPrompts; + return this.sharedWithMePromptsTree; } public newEntityButton = this.getChildElementBySelector( @@ -82,12 +89,56 @@ export class PromptBar extends SideBar { return this.newEntityButton.getComputedStyleProperty(Styles.cursor); } + getSharedFolderPrompts(): FolderPrompts { + if (!this.sharedFolderPrompts) { + this.sharedFolderPrompts = new FolderPrompts( + this.page, + this.getElementLocator(), + PromptBarSection.SharedWithMe, + ); + } + return this.sharedFolderPrompts; + } + + getPinnedFolderPrompts(): FolderPrompts { + if (!this.pinnedFolderPrompts) { + this.pinnedFolderPrompts = new FolderPrompts( + this.page, + this.getElementLocator(), + PromptBarSection.PinnedPrompts, + ); + } + return this.pinnedFolderPrompts; + } + + getOrganizationFolderPrompts(): FolderPrompts { + if (!this.organizationFolderPrompts) { + this.organizationFolderPrompts = new FolderPrompts( + this.page, + this.getElementLocator(), + PromptBarSection.Organization, + ); + } + return this.organizationFolderPrompts; + } + + getApproveRequiredFolderPrompts(): FolderPrompts { + if (!this.approveRequiredFolderPrompts) { + this.approveRequiredFolderPrompts = new FolderPrompts( + this.page, + this.getElementLocator(), + PromptBarSection.ApproveRequired, + ); + } + return this.approveRequiredFolderPrompts; + } + public async dragAndDropPromptFromFolder( folderName: string, promptName: string, { isHttpMethodTriggered = false }: { isHttpMethodTriggered?: boolean } = {}, ) { - const folderPrompt = this.getFolderPrompts().getFolderEntity( + const folderPrompt = this.getPinnedFolderPrompts().getFolderEntity( folderName, promptName, ); @@ -96,19 +147,19 @@ export class PromptBar extends SideBar { }); } - public async drugPromptToFolder(folderName: string, promptName: string) { - const folder = this.getFolderPrompts().getFolderByName(folderName); + public async dragPromptToFolder(folderName: string, promptName: string) { + const folder = this.getPinnedFolderPrompts().getFolderByName(folderName); const prompt = this.getPromptsTree().getEntityByName(promptName); await this.dragEntityToFolder(prompt, folder); } - public async drugAndDropPromptToFolderPrompt( + public async dragAndDropPromptToFolderPrompt( folderName: string, folderPromptName: string, promptName: string, { isHttpMethodTriggered = false }: { isHttpMethodTriggered?: boolean } = {}, ) { - const folderPrompt = this.getFolderPrompts().getFolderEntity( + const folderPrompt = this.getPinnedFolderPrompts().getFolderEntity( folderName, folderPromptName, ); @@ -118,12 +169,12 @@ export class PromptBar extends SideBar { }); } - public async drugAndDropFolderToFolder( + public async dragAndDropFolderToFolder( folderNameToMove: string, folderNameToMoveTo: string, { isHttpMethodTriggered = false }: { isHttpMethodTriggered?: boolean } = {}, ) { - const folderPrompts = this.getFolderPrompts(); + const folderPrompts = this.getPinnedFolderPrompts(); const folderToMove = folderPrompts.getFolderByName(folderNameToMove); const folderToMoveTo = folderPrompts.getFolderByName(folderNameToMoveTo); await this.dragAndDropEntityToFolder(folderToMove, folderToMoveTo, { diff --git a/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts b/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts new file mode 100644 index 0000000000..16c550bbce --- /dev/null +++ b/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts @@ -0,0 +1,27 @@ +import { IconSelectors } from '@/src/ui/selectors'; +import { PromptPreviewModal } from '@/src/ui/selectors/dialogSelectors'; +import { BaseElement } from '@/src/ui/webElements/baseElement'; +import { Page } from '@playwright/test'; + +export class PromptPreviewModalWindow extends BaseElement { + constructor(page: Page) { + super(page, PromptPreviewModal.promptPreviewModal); + } + + public modalTitle = this.getChildElementBySelector( + PromptPreviewModal.promptPreviewModalTitle, + ); + public promptDescription = this.getChildElementBySelector( + PromptPreviewModal.promptPreviewDescription, + ); + public promptName = this.getChildElementBySelector( + PromptPreviewModal.promptPreviewName, + ); + public promptContent = this.getChildElementBySelector( + PromptPreviewModal.promptPreviewContent, + ); + public promptExportButton = this.getChildElementBySelector( + PromptPreviewModal.promptExportButton, + ); + public closeButton = this.getChildElementBySelector(IconSelectors.cancelIcon); +} diff --git a/apps/chat-e2e/src/ui/webElements/publishedPromptPreviewModal.ts b/apps/chat-e2e/src/ui/webElements/publishedPromptPreviewModal.ts new file mode 100644 index 0000000000..f180f02b1b --- /dev/null +++ b/apps/chat-e2e/src/ui/webElements/publishedPromptPreviewModal.ts @@ -0,0 +1,21 @@ +import { PromptPreviewModalWindow } from '@/src/ui/webElements/promptPreviewModalWindow'; +import { PublicationReviewControl } from '@/src/ui/webElements/publicationReviewControl'; +import { Page } from 'playwright-chromium'; + +export class PublishedPromptPreviewModal extends PromptPreviewModalWindow { + constructor(page: Page) { + super(page); + } + + private publicationReviewControl: PublicationReviewControl; + + getPublicationReviewControl(): PublicationReviewControl { + if (!this.publicationReviewControl) { + this.publicationReviewControl = new PublicationReviewControl( + this.page, + this.rootLocator, + ); + } + return this.publicationReviewControl; + } +} diff --git a/apps/chat-e2e/src/ui/webElements/sharedPromptPreviewModal.ts b/apps/chat-e2e/src/ui/webElements/sharedPromptPreviewModal.ts index ceccf2f9ce..fc8ecc498f 100644 --- a/apps/chat-e2e/src/ui/webElements/sharedPromptPreviewModal.ts +++ b/apps/chat-e2e/src/ui/webElements/sharedPromptPreviewModal.ts @@ -1,36 +1,17 @@ import { isApiStorageType } from '@/src/hooks/global-setup'; -import { IconSelectors } from '@/src/ui/selectors'; import { PromptPreviewModal } from '@/src/ui/selectors/dialogSelectors'; -import { BaseElement } from '@/src/ui/webElements/baseElement'; -import { Page } from '@playwright/test'; +import { PromptPreviewModalWindow } from '@/src/ui/webElements/promptPreviewModalWindow'; -export class SharedPromptPreviewModal extends BaseElement { - constructor(page: Page) { - super(page, PromptPreviewModal.promptPreviewModal); - } - - public modalTitle = this.getChildElementBySelector( - PromptPreviewModal.promptPreviewModalTitle, - ); - public promptName = this.getChildElementBySelector( - PromptPreviewModal.promptPreviewName, - ); +export class SharedPromptPreviewModal extends PromptPreviewModalWindow { public promptDescription = this.getChildElementBySelector( PromptPreviewModal.promptPreviewDescription, ); - public promptContent = this.getChildElementBySelector( - PromptPreviewModal.promptPreviewContent, - ); - public promptExportButton = this.getChildElementBySelector( - PromptPreviewModal.promptExportButton, - ); public promptDeleteButton = this.getChildElementBySelector( PromptPreviewModal.promptDeleteButton, ); public promptDuplicateButton = this.getChildElementBySelector( PromptPreviewModal.promptDuplicateButton, ); - public closeButton = this.getChildElementBySelector(IconSelectors.cancelIcon); public async duplicatePrompt({ isHttpMethodTriggered = true,