Repository: epam/ai-dial-chat
Pull request #3747: feat(chat-e2e): use prompt not found page tests
Author: login: irinakartun
Created: 2025-04-29T15:45:07Z | Merged: 2025-05-14T13:13:48Z

**Description:**

implemented use prompt, not found page tests

**Checklist:**

- [x] the pull request name complies with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [x] the pull request name starts with `fix(<scope>):`, `feat(<scope>):`, `feature(<scope>):`, `chore(<scope>):`, `hotfix(<scope>):` or `e2e(<scope>):`. If contains breaking changes then the pull request name must start with `fix(<scope>)!:`, `feat(<scope>)!:`, `feature(<scope>)!:`, `chore(<scope>)!:`, `hotfix(<scope>)!:` or `e2e(<scope>)!:` where `<scope>` is name of affected project: `chat`, `chat-e2e`, `overlay`, `shared`, `sandbox-overlay`, etc.
- [ ] the pull request name ends with `(Issue #<TICKET_ID>)` (comma-separated list of issues)
- [x] I confirm that do not share any confidential information like API keys or any other secrets and private URLs



Diff:
diff --git a/apps/chat-e2e/src/assertions/promptModalAssertion.ts b/apps/chat-e2e/src/assertions/promptModalAssertion.ts
index a82a413172..c65d8d56fa 100644
--- a/apps/chat-e2e/src/assertions/promptModalAssertion.ts
+++ b/apps/chat-e2e/src/assertions/promptModalAssertion.ts
@@ -1,34 +1,43 @@
+import { BaseAssertion } from '@/src/assertions/base/baseAssertion';
 import { ExpectedMessages } from '@/src/testData';
-import { Colors } from '@/src/ui/domData';
-import { PromptModalDialog } from '@/src/ui/webElements';
+import { ThemeColorAttributes } from '@/src/ui/domData';
+import { BaseElement, PromptModalDialog } from '@/src/ui/webElements';
+import { ThemesUtil } from '@/src/utils/themesUtil';
 import { expect } from '@playwright/test';
 
-export class PromptModalAssertion {
+export class PromptModalAssertion extends BaseAssertion {
   readonly promptModalDialog: PromptModalDialog;
 
   constructor(promptModalDialog: PromptModalDialog) {
+    super();
     this.promptModalDialog = promptModalDialog;
   }
 
-  public async assertNameFieldIsInvalid(expectedErrorMessage: string) {
-    const nameBorderColors =
-      await this.promptModalDialog.name.getAllBorderColors();
-    Object.values(nameBorderColors).forEach((borders) => {
-      borders.forEach((borderColor) => {
-        expect
-          .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithRed)
-          .toBe(Colors.textError);
-      });
-    });
+  public async assertFieldIsInvalid(
+    element: BaseElement,
+    expectedErrorMessage: string,
+  ) {
+    await this.assertElementBorderColors(
+      element,
+      ThemesUtil.getRgbColorByKey(ThemeColorAttributes.textError),
+    );
+    const nameFieldErrorMessage =
+      this.promptModalDialog.getFieldBottomMessage(element);
+    await this.assertElementText(nameFieldErrorMessage, expectedErrorMessage);
+  }
 
-    const nameFieldErrorMessage = this.promptModalDialog.getFieldBottomMessage(
+  public async assertNameFieldIsInvalid(expectedErrorMessage: string) {
+    await this.assertFieldIsInvalid(
       this.promptModalDialog.name,
+      expectedErrorMessage,
     );
-    await nameFieldErrorMessage.waitFor();
+  }
 
-    await expect
-      .soft(nameFieldErrorMessage, ExpectedMessages.promptNameInvalid)
-      .toHaveText(expectedErrorMessage);
+  public async assertPromptFieldIsInvalid(expectedErrorMessage: string) {
+    await this.assertFieldIsInvalid(
+      this.promptModalDialog.prompt,
+      expectedErrorMessage,
+    );
   }
 
   public async assertNameFieldIsEmpty() {
diff --git a/apps/chat-e2e/src/core/dialFixtures.ts b/apps/chat-e2e/src/core/dialFixtures.ts
index f1c952cfcb..35b427ad09 100644
--- a/apps/chat-e2e/src/core/dialFixtures.ts
+++ b/apps/chat-e2e/src/core/dialFixtures.ts
@@ -85,6 +85,7 @@ import { PublicationApiHelper } from '@/src/testData/api/publicationApiHelper';
 import { ApiInjector } from '@/src/testData/injector/apiInjector';
 import { BrowserStorageInjector } from '@/src/testData/injector/browserStorageInjector';
 import { DataInjectorInterface } from '@/src/testData/injector/dataInjectorInterface';
+import { DialErrorPage } from '@/src/ui/pages/DialErrorPage';
 import { AccountSettings } from '@/src/ui/webElements/accountSettings';
 import { Addons } from '@/src/ui/webElements/addons';
 import { AddonsDialog } from '@/src/ui/webElements/addonsDialog';
@@ -152,6 +153,7 @@ export const stateFilePath = (index: number) =>
 const dialTest = test.extend<{
   beforeTestCleanup: string;
   dialHomePage: DialHomePage;
+  dialErrorPage: DialErrorPage;
   marketplacePage: MarketplacePage;
   appEditorPage: AppEditorPage;
   appContainer: AppContainer;
@@ -409,6 +411,10 @@ const dialTest = test.extend<{
     const dialHomePage = new DialHomePage(page);
     await use(dialHomePage);
   },
+  dialErrorPage: async ({ page }, use) => {
+    const dialErrorPage = new DialErrorPage(page);
+    await use(dialErrorPage);
+  },
   marketplacePage: async ({ page }, use) => {
     const marketplacePage = new MarketplacePage(page);
     await use(marketplacePage);
diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts
index 8f1bd7faec..5b483c9f14 100644
--- a/apps/chat-e2e/src/testData/expectedConstants.ts
+++ b/apps/chat-e2e/src/testData/expectedConstants.ts
@@ -232,6 +232,9 @@ export const ExpectedConstants = {
   copiedLinkText: 'Copied!',
   copyLinkText: 'Copy link',
   copiedToastMessage: 'Link copied!',
+  notFoundHeader: '404',
+  notFoundTitle: 'Page not found',
+  notFoundDescription: `It seems like the page you're looking for doesn't exist or you don't have access.`,
 };
 
 export enum Types {
diff --git a/apps/chat-e2e/src/tests/agentSelection.test.ts b/apps/chat-e2e/src/tests/agentSelection.test.ts
index 7e741ab1b2..5d9d31fdbd 100644
--- a/apps/chat-e2e/src/tests/agentSelection.test.ts
+++ b/apps/chat-e2e/src/tests/agentSelection.test.ts
@@ -12,6 +12,7 @@ const publicationsToUnpublish: Publication[] = [];
 dialTest(
   'Previously used model is selected for New conversation: change model in "Change agent"\n' +
     'Previously used model is selected for New conversation: change model in My workspace through Use model\n' +
+    `[Select an agent for conversation] My workspace tab is opened by default if to click on 'Go to My workspace' from 'Select an agent for conversation' window.\n` +
     'RecentModelIds[0] is updated if remove latest used model from My applications\n' +
     'RecentModelIds updated when click "Add the agent to My workspace to continue"',
   async ({
@@ -38,7 +39,13 @@ dialTest(
     toast,
   }) => {
     dialTest.slow();
-    setTestIds('EPMRTC-4878', 'EPMRTC-4880', 'EPMRTC-4356', 'EPMRTC-5168');
+    setTestIds(
+      'EPMRTC-4878',
+      'EPMRTC-4880',
+      'EPMRTC-4386',
+      'EPMRTC-4356',
+      'EPMRTC-5168',
+    );
     const models = GeneratorUtil.randomArrayElements(
       ModelsUtil.getLatestModels().filter((m) => m.iconUrl !== undefined),
       2,
diff --git a/apps/chat-e2e/src/tests/newConversation.test.ts b/apps/chat-e2e/src/tests/newConversation.test.ts
index 9d79ec84e2..ae41a291a6 100644
--- a/apps/chat-e2e/src/tests/newConversation.test.ts
+++ b/apps/chat-e2e/src/tests/newConversation.test.ts
@@ -6,6 +6,7 @@ import {
   MenuOptions,
   MockedChatApiResponseBodies,
 } from '@/src/testData';
+import { NotFound } from '@/src/ui/webElements';
 import { GeneratorUtil, ModelsUtil } from '@/src/utils';
 import { expect } from '@playwright/test';
 
@@ -584,3 +585,69 @@ dialTest(
     );
   },
 );
+
+dialTest(
+  'New conversation screen is shown when user clicks on the corresponding button on Error page',
+  async ({
+    dialHomePage,
+    dialErrorPage,
+    baseAssertion,
+    setTestIds,
+    sendMessage,
+    chat,
+    localStorageManager,
+  }) => {
+    setTestIds('EPMRTC-5819');
+    let notFoundElement: NotFound;
+
+    await dialTest.step(
+      'Open Dial non existent page and verify messages and "New Conversation" btn is available',
+      async () => {
+        await localStorageManager.setShowSideBarPanels();
+        await dialErrorPage.navigateToUrl('/errorpage');
+        notFoundElement = dialErrorPage.getNotFound();
+        await baseAssertion.assertElementText(
+          notFoundElement.header,
+          ExpectedConstants.notFoundHeader,
+        );
+        await baseAssertion.assertElementText(
+          notFoundElement.title,
+          ExpectedConstants.notFoundTitle,
+        );
+        await baseAssertion.assertElementText(
+          notFoundElement.description,
+          ExpectedConstants.notFoundDescription,
+        );
+        await baseAssertion.assertElementState(
+          notFoundElement.newConversationButton,
+          'visible',
+        );
+        await baseAssertion.assertElementActionabilityState(
+          notFoundElement.newConversationButton,
+          'enabled',
+        );
+      },
+    );
+
+    await dialTest.step(
+      'Click on "+" button and verify new conversation is created, dial home is opened',
+      async () => {
+        await notFoundElement.newConversationButton.click();
+        await dialHomePage.waitForPageLoaded();
+        await baseAssertion.assertElementState(notFoundElement, 'hidden');
+        await baseAssertion.assertElementState(
+          chat.configureSettingsButton,
+          'visible',
+        );
+        await baseAssertion.assertElementState(
+          chat.changeAgentButton,
+          'visible',
+        );
+        await baseAssertion.assertElementState(
+          sendMessage.messageInput,
+          'visible',
+        );
+      },
+    );
+  },
+);
diff --git a/apps/chat-e2e/src/tests/promptUsage.test.ts b/apps/chat-e2e/src/tests/promptUsage.test.ts
index 9d1d33916d..663ea327f1 100644
--- a/apps/chat-e2e/src/tests/promptUsage.test.ts
+++ b/apps/chat-e2e/src/tests/promptUsage.test.ts
@@ -136,6 +136,7 @@ dialTest(
     variableModalDialog,
     setTestIds,
     localStorageManager,
+    chat,
   }) => {
     setTestIds('EPMRTC-3823', 'EPMRTC-3803', 'EPMRTC-4371');
     let simplePrompt: Prompt;
@@ -199,7 +200,7 @@ dialTest(
         await dialHomePage.mockChatTextResponse(
           MockedChatApiResponseBodies.simpleTextBody,
         );
-        await sendMessage.sendMessageButton.click();
+        await chat.sendRequestWithButton();
         await chatMessages.openMessageTemplateModal(1);
 
         await messageTemplateModalAssertion.assertElementState(
@@ -728,3 +729,70 @@ dialSharedWithMeTest(
     );
   },
 );
+
+dialTest(
+  `View prompt: on 'Use prompt' button click the prompt parameters modal is opened. Prompt contains parameters.`,
+  async ({
+    dialHomePage,
+    promptData,
+    dataInjector,
+    variableModalAssertion,
+    sendMessageAssertion,
+    variableModalDialog,
+    prompts,
+    promptDropdownMenu,
+    promptPreviewModal,
+    setTestIds,
+    localStorageManager,
+  }) => {
+    setTestIds('EPMRTC-6108');
+    let prompt: Prompt;
+    const aVar = 'a';
+    const aVarDefaultValue = '5';
+    const bVar = 'b';
+    const bVarDefaultValue = '4';
+    const promptTemplate = (a: string, b: string) => `${a} - ${b} = `;
+    const promptContent = promptTemplate(
+      `{{${aVar}|${aVarDefaultValue}}}`,
+      `{{${bVar}|${bVarDefaultValue}}}`,
+    );
+
+    await dialTest.step('Prepare a prompt with vars', async () => {
+      prompt = promptData.preparePrompt(promptContent);
+      await dataInjector.createPrompts([prompt]);
+      await localStorageManager.setShowSideBarPanels();
+    });
+
+    await dialTest.step(
+      `Open prompt view modal, click on "Use prompt" button and verify variable modal with default values is displayed`,
+      async () => {
+        await dialHomePage.openHomePage();
+        await dialHomePage.waitForPageLoaded();
+        await prompts.openEntityDropdownMenu(prompt.name);
+        await promptDropdownMenu.selectMenuOption(MenuOptions.view, {
+          triggeredHttpMethod: 'GET',
+        });
+        await promptPreviewModal.usePromptButton.click();
+        await variableModalAssertion.assertVariableModalState('visible');
+        await variableModalAssertion.assertPromptVariableValue(
+          aVar,
+          aVarDefaultValue,
+        );
+        await variableModalAssertion.assertPromptVariableValue(
+          bVar,
+          bVarDefaultValue,
+        );
+      },
+    );
+
+    await dialTest.step(
+      'Submit and verify prompt is applied in the field',
+      async () => {
+        await variableModalDialog.submitButton.click();
+        await sendMessageAssertion.assertMessageValue(
+          promptTemplate(aVarDefaultValue, bVarDefaultValue),
+        );
+      },
+    );
+  },
+);
diff --git a/apps/chat-e2e/src/tests/prompts.test.ts b/apps/chat-e2e/src/tests/prompts.test.ts
index c1b00549c0..14b0c51b70 100644
--- a/apps/chat-e2e/src/tests/prompts.test.ts
+++ b/apps/chat-e2e/src/tests/prompts.test.ts
@@ -8,7 +8,7 @@ import {
   ExpectedMessages,
   MenuOptions,
 } from '@/src/testData';
-import { Colors, Cursors, ThemeColorAttributes } from '@/src/ui/domData';
+import { Cursors, ThemeColorAttributes } from '@/src/ui/domData';
 import { ThemesUtil } from '@/src/utils/themesUtil';
 import { expect } from '@playwright/test';
 
@@ -17,18 +17,35 @@ const newDescr = 'test description';
 const newValue = 'what is {{}}';
 
 dialTest(
-  'Create new prompt',
+  'Create new prompt.\n' +
+    'Prompt name can not be empty.\n' +
+    'Prompt body can not be empty.\n' +
+    `View prompt: 'Use prompt' button is enabled for just created new prompt if there is a chat with available input field selected.\n` +
+    `View prompt: on 'Use prompt' button click the modal is closed, the prompt is entered to the input user field. Prompt is without parameters.`,
   async ({
     dialHomePage,
     promptBar,
-    prompts,
     promptModalDialog,
     setTestIds,
     header,
     baseAssertion,
     promptPreviewModal,
+    promptModalAssertion,
+    promptPreviewModalAssertion,
+    promptAssertion,
+    sendMessageAssertion,
   }) => {
-    setTestIds('EPMRTC-945', 'EPMRTC-956', 'EPMRTC-1452');
+    setTestIds(
+      'EPMRTC-945',
+      'EPMRTC-956',
+      'EPMRTC-1452',
+      'EPMRTC-6043',
+      'EPMRTC-6044',
+    );
+    const expectedValidFieldBorderColor = ThemesUtil.getRgbColorByKey(
+      ThemeColorAttributes.textAccentPrimary,
+    );
+
     await dialTest.step(
       'Hover over "New prompt" button and verify cursor type and color highlight.\n' +
         'Prompt name can not be empty.\n' +
@@ -81,32 +98,13 @@ dialTest(
       async () => {
         await promptModalDialog.setField(promptModalDialog.name, '');
         await promptModalDialog.description.click();
-        const nameBorderColors =
-          await promptModalDialog.name.getAllBorderColors();
-        Object.values(nameBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithRed)
-              .toBe(Colors.textError);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.name)
-          .waitFor();
-        await expect
-          .soft(
-            promptModalDialog.getFieldBottomMessage(promptModalDialog.name),
-            ExpectedMessages.fieldIsHighlightedWithRed,
-          )
-          .toHaveText(ExpectedConstants.requiredFieldErrorMessage);
-
-        expect
-          .soft(
-            await promptModalDialog.saveButton.isElementEnabled(),
-            ExpectedMessages.buttonIsDisabled,
-          )
-          .toBeFalsy();
+        await promptModalAssertion.assertNameFieldIsInvalid(
+          ExpectedConstants.requiredFieldErrorMessage,
+        );
+        await promptModalAssertion.assertElementActionabilityState(
+          promptModalDialog.saveButton,
+          'disabled',
+        );
       },
     );
 
@@ -115,38 +113,14 @@ dialTest(
       async () => {
         await promptModalDialog.setField(promptModalDialog.name, '   ');
         await promptModalDialog.description.click();
-        const nameBorderColors =
-          await promptModalDialog.name.getAllBorderColors();
-        Object.values(nameBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithRed)
-              .toBe(Colors.textError);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.name)
-          .waitFor();
-        await expect
-          .soft(
-            promptModalDialog.getFieldBottomMessage(promptModalDialog.name),
-            ExpectedMessages.fieldIsHighlightedWithRed,
-          )
-          .toHaveText(ExpectedConstants.requiredFieldErrorMessage);
-
-        expect
-          .soft(
-            await promptModalDialog.getName(),
-            ExpectedMessages.promptNameUpdated,
-          )
-          .toBe('');
-        expect
-          .soft(
-            await promptModalDialog.saveButton.isElementEnabled(),
-            ExpectedMessages.buttonIsDisabled,
-          )
-          .toBeFalsy();
+        await promptModalAssertion.assertNameFieldIsInvalid(
+          ExpectedConstants.requiredFieldErrorMessage,
+        );
+        await promptModalAssertion.assertNameFieldIsEmpty();
+        await promptModalAssertion.assertElementActionabilityState(
+          promptModalDialog.saveButton,
+          'disabled',
+        );
       },
     );
 
@@ -154,19 +128,14 @@ dialTest(
       'Type value in Name field and verify error message disappears, field has blue border, Save button is enabled',
       async () => {
         await promptModalDialog.setField(promptModalDialog.name, newName);
-        const nameBorderColors =
-          await promptModalDialog.name.getAllBorderColors();
-        Object.values(nameBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithBlue)
-              .toBe(Colors.controlsBackgroundAccent);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.name)
-          .waitFor({ state: 'hidden' });
+        await promptModalAssertion.assertElementBorderColors(
+          promptModalDialog.name,
+          expectedValidFieldBorderColor,
+        );
+        await promptModalAssertion.assertElementState(
+          promptModalDialog.getFieldBottomMessage(promptModalDialog.name),
+          'hidden',
+        );
       },
     );
 
@@ -175,32 +144,13 @@ dialTest(
       async () => {
         await promptModalDialog.setField(promptModalDialog.prompt, '');
         await promptModalDialog.description.click();
-        const promptBorderColors =
-          await promptModalDialog.prompt.getAllBorderColors();
-        Object.values(promptBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithRed)
-              .toBe(Colors.textError);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.prompt)
-          .waitFor();
-        await expect
-          .soft(
-            promptModalDialog.getFieldBottomMessage(promptModalDialog.prompt),
-            ExpectedMessages.fieldIsHighlightedWithRed,
-          )
-          .toHaveText(ExpectedConstants.requiredFieldErrorMessage);
-
-        expect
-          .soft(
-            await promptModalDialog.saveButton.isElementEnabled(),
-            ExpectedMessages.buttonIsDisabled,
-          )
-          .toBeFalsy();
+        await promptModalAssertion.assertPromptFieldIsInvalid(
+          ExpectedConstants.requiredFieldErrorMessage,
+        );
+        await promptModalAssertion.assertElementActionabilityState(
+          promptModalDialog.saveButton,
+          'disabled',
+        );
       },
     );
 
@@ -209,38 +159,17 @@ dialTest(
       async () => {
         await promptModalDialog.setField(promptModalDialog.prompt, '   ');
         await promptModalDialog.description.click();
-        const promptBorderColors =
-          await promptModalDialog.prompt.getAllBorderColors();
-        Object.values(promptBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithRed)
-              .toBe(Colors.textError);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.prompt)
-          .waitFor();
-        await expect
-          .soft(
-            promptModalDialog.getFieldBottomMessage(promptModalDialog.prompt),
-            ExpectedMessages.fieldIsHighlightedWithRed,
-          )
-          .toHaveText(ExpectedConstants.requiredFieldErrorMessage);
-
-        expect
-          .soft(
-            await promptModalDialog.getPrompt(),
-            ExpectedMessages.promptValueUpdated,
-          )
-          .toBe('');
-        expect
-          .soft(
-            await promptModalDialog.saveButton.isElementEnabled(),
-            ExpectedMessages.buttonIsDisabled,
-          )
-          .toBeFalsy();
+        await promptModalAssertion.assertPromptFieldIsInvalid(
+          ExpectedConstants.requiredFieldErrorMessage,
+        );
+        await promptModalAssertion.assertElementText(
+          promptModalDialog.prompt,
+          '',
+        );
+        await promptModalAssertion.assertElementActionabilityState(
+          promptModalDialog.saveButton,
+          'disabled',
+        );
       },
     );
 
@@ -248,39 +177,67 @@ dialTest(
       'Type value in Prompt field and verify error message disappears, field has blue border, Save button is enabled',
       async () => {
         await promptModalDialog.setField(promptModalDialog.prompt, newValue);
-        const promptBorderColors =
-          await promptModalDialog.prompt.getAllBorderColors();
-        Object.values(promptBorderColors).forEach((borders) => {
-          borders.forEach((borderColor) => {
-            expect
-              .soft(borderColor, ExpectedMessages.fieldIsHighlightedWithBlue)
-              .toBe(Colors.controlsBackgroundAccent);
-          });
-        });
-
-        await promptModalDialog
-          .getFieldBottomMessage(promptModalDialog.prompt)
-          .waitFor({ state: 'hidden' });
-
-        expect
-          .soft(
-            await promptModalDialog.saveButton.isElementEnabled(),
-            ExpectedMessages.buttonIsEnabled,
-          )
-          .toBeTruthy();
+        await promptModalAssertion.assertElementBorderColors(
+          promptModalDialog.prompt,
+          expectedValidFieldBorderColor,
+        );
+        await promptModalAssertion.assertElementState(
+          promptModalDialog.getFieldBottomMessage(promptModalDialog.prompt),
+          'hidden',
+        );
+        await promptModalAssertion.assertElementActionabilityState(
+          promptModalDialog.saveButton,
+          'enabled',
+        );
       },
     );
 
     await dialTest.step(
-      'Set Description field value, click Save and verify prompt is created',
+      'Set Description field value, click Save and verify prompt is created, prompt view modal is opened',
       async () => {
         await promptModalDialog.setField(
           promptModalDialog.description,
           newDescr,
         );
         await promptModalDialog.saveButton.click();
-        await promptPreviewModal.closeButton.click();
-        await prompts.getEntityByName(newName).waitFor();
+        await promptPreviewModalAssertion.assertElementState(
+          promptPreviewModal,
+          'visible',
+        );
+        await promptAssertion.assertEntityState({ name: newName }, 'visible');
+        await promptPreviewModalAssertion.assertElementActionabilityState(
+          promptPreviewModal.usePromptButton,
+          'enabled',
+        );
+        await promptPreviewModalAssertion.assertElementBackgroundColors(
+          promptPreviewModal.usePromptButton,
+          ThemesUtil.getRgbColorByKey(ThemeColorAttributes.bgAccentPrimary),
+        );
+      },
+    );
+
+    await dialTest.step(
+      'Hover over "Use prompt" button and verify its color changes',
+      async () => {
+        await promptPreviewModal.usePromptButton.hoverOver();
+        await promptPreviewModalAssertion.assertElementBackgroundColors(
+          promptPreviewModal.usePromptButton,
+          ThemesUtil.getRgbColorByKey(
+            ThemeColorAttributes.controlsBgAccentHover,
+          ),
+        );
+      },
+    );
+
+    await dialTest.step(
+      'Click on "Use prompt" button and verify modal is closed, prompt content is set in the request field',
+      async () => {
+        await promptPreviewModal.usePromptButton.click();
+        await promptPreviewModalAssertion.assertElementState(
+          promptPreviewModal.usePromptButton,
+          'hidden',
+        );
+        await sendMessageAssertion.assertMessageValue(newValue);
       },
     );
   },
diff --git a/apps/chat-e2e/src/tests/usePromptNewConversation.test.ts b/apps/chat-e2e/src/tests/usePromptNewConversation.test.ts
index d2fd7df4dc..655e9bd2e4 100644
--- a/apps/chat-e2e/src/tests/usePromptNewConversation.test.ts
+++ b/apps/chat-e2e/src/tests/usePromptNewConversation.test.ts
@@ -316,7 +316,9 @@ const publicationsToUnpublish: Publication[] = [];
 
 dialAdminTest(
   'Use prompt not available for chat from Organization\n' +
-    'Use prompt not available for chat from Approve required',
+    'Use prompt not available for chat from Approve required.\n' +
+    'Use prompt option is not available when publication request is selected.\n' +
+    'Use prompt option is available for new conversation when publication request was previously selected',
   async ({
     dialHomePage,
     organizationConversations,
@@ -332,12 +334,14 @@ dialAdminTest(
     adminPublicationApiHelper,
     adminDialHomePage,
     adminApproveRequiredConversations,
+    adminChatBar,
+    adminChat,
     localStorageManager,
     adminLocalStorageManager,
     adminPrompts,
     adminPromptDropdownMenuAssertion,
   }) => {
-    setTestIds('EPMRTC-5499', 'EPMRTC-5500');
+    setTestIds('EPMRTC-5499', 'EPMRTC-5500', 'EPMRTC-5496', 'EPMRTC-6037');
     const prompt = promptData.prepareDefaultPrompt();
     promptData.resetData();
     const adminPrompt = promptData.prepareDefaultPrompt();
@@ -413,6 +417,37 @@ dialAdminTest(
         );
       },
     );
+
+    await dialAdminTest.step(
+      'Select publication request, open prompt dropdown menu and verify "Use" option is disabled',
+      async () => {
+        await adminApproveRequiredConversations.selectRequest(
+          notApprovedPublication.name!,
+        );
+        await adminPrompts.openEntityDropdownMenu(adminPrompt.name);
+        await adminPromptDropdownMenuAssertion.assertMenuOptionActionabilityState(
+          MenuOptions.use,
+          'disabled',
+        );
+      },
+    );
+
+    await dialAdminTest.step(
+      'Select publication request, create new conversation, open prompt dropdown menu and verify "Use" option is enabled',
+      async () => {
+        await adminApproveRequiredConversations.selectRequest(
+          notApprovedPublication.name!,
+        );
+        await adminChatBar.createNewEntity();
+        await adminChat.configureSettingsButton.waitForState();
+        await adminChat.changeAgentButton.waitForState();
+        await adminPrompts.openEntityDropdownMenu(adminPrompt.name);
+        await adminPromptDropdownMenuAssertion.assertMenuOptionActionabilityState(
+          MenuOptions.use,
+          'enabled',
+        );
+      },
+    );
   },
 );
 
@@ -551,11 +586,14 @@ dialTest(
 
 dialSharedWithMeTest(
   'Use prompt not available for chat from Shared with me\n' +
+    `View prompt: 'Use prompt' button is disabled for just created new prompt if there is a chat without available input field selected.\n` +
     'Use prompt from "Shared with me" section for chat with history',
   async ({
     dialHomePage,
     sharedWithMeConversations,
     prompts,
+    promptBar,
+    promptModalDialog,
     promptDropdownMenuAssertion,
     setTestIds,
     promptData,
@@ -569,8 +607,10 @@ dialSharedWithMeTest(
     sendMessageAssertion,
     chatBar,
     promptDropdownMenu,
+    promptPreviewModal,
+    promptPreviewModalAssertion,
   }) => {
-    setTestIds('EPMRTC-5498', 'EPMRTC-5488');
+    setTestIds('EPMRTC-5498', 'EPMRTC-6042', 'EPMRTC-5488');
     const prompt = promptData.prepareDefaultPrompt();
     const model = GeneratorUtil.randomArrayElement(
       ModelsUtil.getLatestModels().filter((m) => m.iconUrl !== undefined),
@@ -607,6 +647,27 @@ dialSharedWithMeTest(
       },
     );
 
+    await dialSharedWithMeTest.step(
+      'Create a new prompt and verify "Use" prompt button is disabled within "View prompt" modal',
+      async () => {
+        await promptBar.createNewEntity();
+        await promptModalDialog.fillPromptDetails(
+          GeneratorUtil.randomString(5),
+          undefined,
+          GeneratorUtil.randomString(5),
+        );
+        await promptModalDialog.saveButton.click();
+        await promptPreviewModalAssertion.assertPromptPreviewModalState(
+          'visible',
+        );
+        await promptPreviewModalAssertion.assertElementActionabilityState(
+          promptPreviewModal.usePromptButton,
+          'disabled',
+        );
+        await promptPreviewModal.closeButton.click();
+      },
+    );
+
     await dialSharedWithMeTest.step(
       'Type message and use prompt from Shared with me',
       async () => {
diff --git a/apps/chat-e2e/src/ui/domData/colors.ts b/apps/chat-e2e/src/ui/domData/colors.ts
index 549f1e9dba..42c3a47ab5 100644
--- a/apps/chat-e2e/src/ui/domData/colors.ts
+++ b/apps/chat-e2e/src/ui/domData/colors.ts
@@ -45,6 +45,7 @@ export enum ThemeColorAttributes {
   textAccentTertiary = 'text-accent-tertiary',
   textAccentPrimary = 'text-accent-primary',
   bgLayer3 = 'bg-layer-3',
+  bgAccentPrimary = 'bg-accent-primary',
   bgAccentPrimaryAlpha = 'bg-accent-primary-alpha',
   textPrimary = 'text-primary',
   textError = 'text-error',
@@ -54,4 +55,5 @@ export enum ThemeColorAttributes {
   bgAccentSecondary = 'bg-accent-secondary',
   controlsTextDisable = 'controls-text-disable',
   textAccentSecondary = 'text-accent-secondary',
+  controlsBgAccentHover = 'controls-bg-accent-hover',
 }
diff --git a/apps/chat-e2e/src/ui/pages/DialErrorPage.ts b/apps/chat-e2e/src/ui/pages/DialErrorPage.ts
new file mode 100644
index 0000000000..66d351b1f5
--- /dev/null
+++ b/apps/chat-e2e/src/ui/pages/DialErrorPage.ts
@@ -0,0 +1,13 @@
+import { BasePage } from '@/src/ui/pages/basePage';
+import { NotFound } from '@/src/ui/webElements';
+
+export class DialErrorPage extends BasePage {
+  private notFound!: NotFound;
+
+  public getNotFound(): NotFound {
+    if (!this.notFound) {
+      this.notFound = new NotFound(this.page);
+    }
+    return this.notFound;
+  }
+}
diff --git a/apps/chat-e2e/src/ui/selectors/notFoundSelectors.ts b/apps/chat-e2e/src/ui/selectors/notFoundSelectors.ts
new file mode 100644
index 0000000000..16fe5aeab3
--- /dev/null
+++ b/apps/chat-e2e/src/ui/selectors/notFoundSelectors.ts
@@ -0,0 +1,7 @@
+export const NotFoundSelectors = {
+  container: '[data-qa="not-found-container"]',
+  header: '[data-qa="not-found-header"]',
+  title: '[data-qa="not-found-title"]',
+  description: '[data-qa="not-found-description"]',
+  newConversationButton: '[data-qa="new-conversation-btn"]',
+};
diff --git a/apps/chat-e2e/src/ui/webElements/chat.ts b/apps/chat-e2e/src/ui/webElements/chat.ts
index 83250ec3d5..732343414d 100644
--- a/apps/chat-e2e/src/ui/webElements/chat.ts
+++ b/apps/chat-e2e/src/ui/webElements/chat.ts
@@ -257,7 +257,7 @@ export class Chat extends BaseElement {
     return request?.postDataJSON();
   }
 
-  public async sendRequestWithButton(message: string, waitForAnswer = true) {
+  public async sendRequestWithButton(message?: string, waitForAnswer = true) {
     return this.sendRequest(
       message,
       () => this.getSendMessage().send(message),
diff --git a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts
index 05f050f138..537c0e0b9e 100644
--- a/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts
+++ b/apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredEntitiesTree.ts
@@ -29,4 +29,8 @@ export class ApproveRequiredEntitiesTree extends Folders {
     await this.selectFolderEntity(requestName, entityName);
     await responsePromise;
   }
+
+  public async selectRequest(requestName: string) {
+    await this.getFolderName(requestName).click();
+  }
 }
diff --git a/apps/chat-e2e/src/ui/webElements/index.ts b/apps/chat-e2e/src/ui/webElements/index.ts
index 5ab7a86619..bef22383d0 100644
--- a/apps/chat-e2e/src/ui/webElements/index.ts
+++ b/apps/chat-e2e/src/ui/webElements/index.ts
@@ -61,3 +61,4 @@ export * from './appEditor/appEditorHeader';
 export * from './appEditor/appEditorGeneralForm';
 export * from './appEditor/appEditorPreview';
 export * from './appEditor/appEditorViewForm';
+export * from './notFound';
diff --git a/apps/chat-e2e/src/ui/webElements/notFound.ts b/apps/chat-e2e/src/ui/webElements/notFound.ts
new file mode 100644
index 0000000000..3eb939c518
--- /dev/null
+++ b/apps/chat-e2e/src/ui/webElements/notFound.ts
@@ -0,0 +1,18 @@
+import { NotFoundSelectors } from '@/src/ui/selectors/notFoundSelectors';
+import { BaseElement } from '@/src/ui/webElements/baseElement';
+import { Page } from '@playwright/test';
+
+export class NotFound extends BaseElement {
+  constructor(page: Page) {
+    super(page, NotFoundSelectors.container);
+  }
+
+  public header = this.getChildElementBySelector(NotFoundSelectors.header);
+  public title = this.getChildElementBySelector(NotFoundSelectors.title);
+  public description = this.getChildElementBySelector(
+    NotFoundSelectors.description,
+  );
+  public newConversationButton = this.getChildElementBySelector(
+    NotFoundSelectors.newConversationButton,
+  );
+}
diff --git a/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts b/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts
index 3a1c58a8b2..db11697c62 100644
--- a/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts
+++ b/apps/chat-e2e/src/ui/webElements/promptPreviewModalWindow.ts
@@ -29,5 +29,8 @@ export class PromptPreviewModalWindow extends BaseElement {
   public editPromptButton = this.getChildElementBySelector(
     PromptPreviewModal.editPromptButton,
   );
+  public usePromptButton = this.getChildElementBySelector(
+    PromptPreviewModal.usePromptButton,
+  );
   public closeButton = this.getChildElementBySelector(IconSelectors.cancelIcon);
 }
diff --git a/apps/chat/src/pages/404.tsx b/apps/chat/src/pages/404.tsx
index 08484d56c5..7a487f7900 100644
--- a/apps/chat/src/pages/404.tsx
+++ b/apps/chat/src/pages/404.tsx
@@ -10,13 +10,20 @@ function Custom404() {
   const { t } = useTranslation(Translation.Common);
 
   return (
-    <div className="flex h-screen w-screen flex-col items-center justify-center space-y-4 px-4 text-center">
+    <div
+      className="flex h-screen w-screen flex-col items-center justify-center space-y-4 px-4 text-center"
+      data-qa="not-found-container"
+    >
       <Title />
-      <h1 className="text-6xl font-bold md:text-7xl">{t('404')}</h1>
+      <h1 className="text-6xl font-bold md:text-7xl" data-qa="not-found-header">
+        {t('404')}
+      </h1>
 
       <div className="space-y-2">
-        <p className="text-xl font-bold md:text-2xl">{t('Page not found')}</p>
-        <p className="text-base text-secondary">
+        <p className="text-xl font-bold md:text-2xl" data-qa="not-found-title">
+          {t('Page not found')}
+        </p>
+        <p className="text-base text-secondary" data-qa="not-found-description">
           {t(
             "It seems like the page you're looking for doesn't exist or you don't have access.",
           )}
@@ -26,6 +33,7 @@ function Custom404() {
       <a
         className="button button-secondary flex items-center gap-2 rounded"
         href={`/`}
+        data-qa="new-conversation-btn"
       >
         <IconPlus size={18} />
         {t('New Conversation')}


Reviews:
user: login: nartovm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T19:35:45Z
user: login: irinakartun
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T08:43:16Z
user: login: nartovm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T11:42:01Z
user: login: IlyaBondar
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T13:13:10Z

Review comments:
diff_hunk: @@ -584,3 +585,69 @@ dialTest(
     );
   },
 );
+
+dialTest(
+  'New conversation screen is shown when user clicks on the corresponding button on Error page',
+  async ({
+    dialHomePage,
+    dialErrorPage,
+    baseAssertion,
+    setTestIds,
+    sendMessage,
+    chat,
+    localStorageManager,
+  }) => {
+    setTestIds('EPMRTC-5819');
+    let notFoundElement: NotFound;
+
+    await dialTest.step(
+      'Open Dial non existent page and verify messages and "New Conversation" btn is available',
+      async () => {
+        await localStorageManager.setShowSideBarPanels();
+        await dialErrorPage.navigateToUrl('/errorpage');
path: apps/chat-e2e/src/tests/newConversation.test.ts
user: login: nartovm
body: What do you think about updating the navigateToUrl() method to wait for the update of getPublishedApplications, etc?
created_at: 2025-05-13T19:35:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -584,3 +585,69 @@ dialTest(
     );
   },
 );
+
+dialTest(
+  'New conversation screen is shown when user clicks on the corresponding button on Error page',
+  async ({
+    dialHomePage,
+    dialErrorPage,
+    baseAssertion,
+    setTestIds,
+    sendMessage,
+    chat,
+    localStorageManager,
+  }) => {
+    setTestIds('EPMRTC-5819');
+    let notFoundElement: NotFound;
+
+    await dialTest.step(
+      'Open Dial non existent page and verify messages and "New Conversation" btn is available',
+      async () => {
+        await localStorageManager.setShowSideBarPanels();
+        await dialErrorPage.navigateToUrl('/errorpage');
path: apps/chat-e2e/src/tests/newConversation.test.ts
user: login: irinakartun
body: The same set of APIs is not called in all cases where `navigateToUrl` is invoked. I will implement this logic in a separate MR after merging your changes regarding navigation to workspace/marketplace pages.
created_at: 2025-05-14T08:43:16Z
author_association: CONTRIBUTOR

PR comments:
user: login: irinakartun
created_at: 2025-04-29T15:48:35Z
body: /deploy-review
>Environment: [review-environment](https://chat-ai-dial-chat-pr-3747.nightly-test.deltixhub.io) | [pipeline](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/pipelines/603391)
>Overlay E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1815300)
>Chat E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1815299)
author_association: CONTRIBUTOR
user: login: irinakartun
created_at: 2025-05-02T13:25:00Z
body: /deploy-review
>Environment: [review-environment](https://chat-ai-dial-chat-pr-3747.nightly-test.deltixhub.io) | [pipeline](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/pipelines/604443)
>Overlay E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1820863)
>Chat E2E tests status: [failed](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1820862)
>Chat E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1821194)
author_association: CONTRIBUTOR
user: login: irinakartun
created_at: 2025-05-05T07:09:57Z
body: /deploy-review
>Environment: [review-environment](https://chat-ai-dial-chat-pr-3747.nightly-test.deltixhub.io) | [pipeline](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/pipelines/604777)
>Overlay E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1822420)
>Chat E2E tests status: [failed](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1822419)
author_association: CONTRIBUTOR
user: login: irinakartun
created_at: 2025-05-14T11:53:53Z
body: /deploy-review
>Environment: [review-environment](https://chat-ai-dial-chat-pr-3747.nightly-test.deltixhub.io) | [pipeline](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/pipelines/609918)
>Overlay E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1849879)
>Chat E2E tests status: [success](https://gitlab.deltixhub.com/Clients/deltix/nightly-test/dial/review/-/jobs/1849878)
author_association: CONTRIBUTOR