# Test info

- Name: Feature case for request-listing >> REQ_030 - Verify when clone request without archive
- Location: /root/code/portal-automation-test/tests/request/function.spec.ts:1007:9

# Error details

```
Error: Timed out 25000ms waiting for expect(locator).toBeVisible()

Locator: locator('//p[text()=\'Cloned Request Successfully!\']')
Expected: visible
Received: <element(s) not found>
Call log:
  - expect.toBeVisible with timeout 25000ms
  - waiting for locator('//p[text()=\'Cloned Request Successfully!\']')

    at /root/code/portal-automation-test/tests/request/function.spec.ts:1021:85
    at /root/code/portal-automation-test/tests/request/function.spec.ts:1019:9
```

# Page snapshot

```yaml
- complementary:
  - img
  - link "(Portal-Auto-Lawyer) Portal QA":
    - /url: /
    - paragraph: (Portal-Auto-Lawyer)
    - paragraph: Portal QA
  - list:
    - listitem:
      - link "Home":
        - /url: https://qa.loprx.com
        - img
        - text: Home
    - listitem:
      - link "Case":
        - /url: https://qa.loprx.com/cases
        - img
        - text: Case
    - listitem:
      - link "Request":
        - /url: https://qa.loprx.com/requests
        - img
        - text: Request
    - listitem:
      - link "Client":
        - /url: https://qa.loprx.com/clients
        - img
        - text: Client
    - listitem:
      - button "Business/Contact":
        - img
        - text: Business/Contact
    - listitem:
      - button "Inbox/Sent":
        - img
        - text: Inbox/Sent
    - listitem:
      - button "Settings":
        - img
        - text: Settings
  - list:
    - listitem:
      - link "Shared with me":
        - /url: https://qa.loprx.com/shared/requests
        - img
        - text: Shared with me
- banner:
  - button:
    - img
  - button [disabled]:
    - img
  - img
  - text: Tri01 Duc shared some information about Test Request Letter of Protection. Find out what it says. 6 days ago
  - img
  - text: What did Tri01 Duc say? Their response to Test Request Letter of Protection is waiting. 6 days ago
  - img
  - text: Link Case First shared some information about New Case 123 Letter of Protection. Find out what it says. 1 week ago
  - img
  - text: What did Tri01 Duc say? Their response to Test Request Letter of Protection is waiting. 6 days ago
  - img
  - img
  - textbox "Search..."
  - img
  - img
  - paragraph: No notifications yet
  - paragraph: When you get notifications, they'll show up here
  - button "Refresh"
  - list:
    - listitem:
      - img
      - paragraph: Pause notifications...
      - list:
        - listitem: For 30 minutes
        - listitem: For 1 hour
        - listitem: For 2 hours
        - listitem: Until tomorrow
    - listitem:
      - img
    - listitem:
      - img
    - listitem:
      - img
    - listitem:
      - img
    - listitem:
      - img
    - listitem:
      - img
  - img
  - button "4 Cart":
    - img
    - text: 4 Cart
  - text: Feedback
  - img
  - link "Open user menu":
    - /url: "#"
    - text: Minh
- img
- text: "#554429 Letter of Protection"
- img
- img
- img
- link "Test Request":
  - /url: /clients/4dfe6c2b-b978-4bbd-9b29-04f2c444c8f8
- text: "-"
- 'link "DOB: 03/01/1999"':
  - /url: /clients/4dfe6c2b-b978-4bbd-9b29-04f2c444c8f8
- 'link "Case: #990951"':
  - /url: /cases/990951
- text: "-"
- 'link "DOI: __/__/____"':
  - /url: /cases/990951
- 'link "Category: Unspecified Accident"':
  - /url: /cases/990951
- text: Tag
- img
- 'button "Status: Open"'
- button "Status Details:":
  - text: "Status Details:"
  - listbox:
    - listitem:
      - text: Awaiting
      - img
  - img
- 'button "Assignee: --"':
  - text: "Assignee: --"
  - img
- button:
  - img
- button:
  - img
- button "Activity":
  - img
  - text: Activity
- button "Share":
  - img
  - text: Share
- paragraph: Minh Phong
- text: Posted
- paragraph: 07/08/2025
- img
- list:
  - listitem
- textbox "Message"
- button [disabled]:
  - img
- heading "Snapshot" [level=2]
- list:
  - listitem: Minh Phong 07/08/2025 Submitted a request Respond
- heading "Discussion" [level=2]
- text: Start a discussion
- img
- heading "Minh Phong (You)" [level=4]
- img
- heading "Team Discussion" [level=4]
- img
- heading "Discussion" [level=2]
- text: Start a discussion
- img
- heading "Minh Phong (You)" [level=4]
- img
- heading "Team Discussion" [level=4]
- img
- img "image-share-this-request"
- paragraph: Share this request using the Share button.
- text: Share
- heading "Clone Request" [level=3]
- button "Close"
- heading "To which business should we direct this new request?" [level=4]:
  - text: To which business should we direct this new request?
  - img
- text: Business
- textbox "Business" [disabled]: A Taylor Law Firm
- text: People Tri01 Duc triducgog0301+1@gmail.com
- img
- textbox "Select or type an email address" [disabled]
- text: Archive
- textbox "Archive" [disabled]: "No"
- button "Cancel"
- button "Submit"
```

# Test source

```ts
   921 |     //         );
   922 |     //         await requestPage27.page.reload();
   923 |     //         await expect(requestPage27.dashboardLoc.notiCard).not.toBeVisible();
   924 |     //         await requestPage27.getDetailCase(conf.data.case);
   925 |     //     });
   926 |
   927 |     //     await test.step(`User A turns ON ${notiType.name}`, async () => {
   928 |     //         await requestPage27.toggleNotification(notiType);
   929 |     //     });
   930 |
   931 |     //     await test.step(`Another member triggers ${notiType.name} and check user A does receive noti`, async () => {
   932 |     //         const uniqueMsgOn = uniqueMsg + "_on";
   933 |     //         await requestPage27.triggerNotificationFromAnotherUser(
   934 |     //             browser,
   935 |     //             conf.data.username_in_discussion,
   936 |     //             conf.data.password,
   937 |     //             conf.data.case,
   938 |     //             notiType,
   939 |     //             uniqueMsgOn
   940 |     //         );
   941 |     //         await requestPage27.page.reload();
   942 |     //         await requestPage27.checkNotification("New Discussion", true);
   943 |     //         await expect(requestPage27.dashboardLoc.discussion.messageInDiscussion(uniqueMsgOn)).toBeVisible({ timeout: 35_000 });
   944 |     //     });
   945 |     // });
   946 |
   947 |     // test.skip("REQ_028 - Verify when turnoff/turn on noti in mail", {
   948 |     //     tag: ["@REQ_028", "@request", "@function"]
   949 |     // }, async ({ conf, browser, requestPage27 }) => {
   950 |     //     test.setTimeout(200_000);
   951 |     //     for (let i = 0; i < requestPage27.notiEmail.length; i++) {
   952 |     //         const notiType = requestPage27.notiEmail[i];
   953 |     //         const uniqueMsg = `${conf.data.message}_${notiType.name}_${Date.now()}`;
   954 |
   955 |     //         await test.step(`Turn off ${notiType.name}`, async () => {
   956 |     //             await requestPage27.requestLoc.detail.notification.btnOpenModalNoti.nth(1).click();
   957 |     //             await requestPage27.requestLoc.detail.notification.btnToggleSettingNoti.nth(1).click();
   958 |     //             await requestPage27.waitForSecond(2);
   959 |     //             await requestPage27.requestLoc.detail.notification.inputNotiByName(notiType.name).click({ force: true });
   960 |     //             await requestPage27.waitForSecond(2);
   961 |     //             await requestPage27.dashboardLoc.buttonByText("Close").nth(2).click();
   962 |     //         });
   963 |
   964 |     //         await test.step(`Another member triggers ${notiType.name} and check user A does NOT receive noti in email`, async () => {
   965 |     //             msgOffNoti = uniqueMsg + " " + "OFF NOTI MAIL";
   966 |     //             const { context: contextB, requestPage: requestPageB } = await requestPage27.loginInAnotherBrowser(browser, conf.data.username_in_discussion, conf.data.password);
   967 |     //             await requestPageB.open();
   968 |     //             await requestPageB.getDetailCase(conf.data.case);
   969 |     //             await requestPageB.notiEmail[i].addNoti(msgOffNoti);
   970 |     //             await requestPageB.waitForSecond(2);
   971 |     //             await contextB.close();
   972 |     //         });
   973 |
   974 |     //         await test.step(`User A turns ON ${notiType.name}`, async () => {
   975 |     //             await requestPage27.requestLoc.detail.notification.btnOpenModalNoti.nth(1).click();
   976 |     //             await requestPage27.requestLoc.detail.notification.btnToggleSettingNoti.nth(1).click();
   977 |     //             await requestPage27.waitForSecond(2);
   978 |     //             await requestPage27.requestLoc.detail.notification.inputNotiByName(notiType.name).click({ force: true });
   979 |     //             await requestPage27.waitForSecond(2);
   980 |     //             await requestPage27.dashboardLoc.buttonByText("Close").nth(2).click();
   981 |     //         });
   982 |
   983 |     //         await test.step(`Another member triggers ${notiType.name} and check user A does NOT receive noti in email`, async () => {
   984 |     //             msgOnNoti = `${uniqueMsg} ON NOTI MAIL ${i + 1}`;
   985 |     //             const { context: contextB, requestPage: requestPageB } = await requestPage27.loginInAnotherBrowser(browser, conf.data.username_in_discussion, conf.data.password);
   986 |     //             await requestPageB.open();
   987 |     //             await requestPageB.getDetailCase(conf.data.case);
   988 |     //             await requestPageB.notiEmail[i].addNoti(msgOnNoti);
   989 |     //             listMailCheck.push(msgOnNoti);
   990 |     //             await requestPageB.waitForSecond(2);
   991 |     //             await contextB.close();
   992 |     //         });
   993 |     //     }
   994 |     // });
   995 |
   996 |     // test.skip("REQ_28A - Verify mail from REQ_28", {
   997 |     //     tag: ["@REQ_28A", "@request", "@function"]
   998 |     // }, async ({ conf, request, page }) => {
   999 |     //     let mail: Mail;
  1000 |     //     mail = new Mail(page, request);
  1001 |     //     for (let i = 0; i < listMailCheck.length; i++) {
  1002 |     //         const foundMail = await mail.findMail(listMailCheck[i], conf.data.username);
  1003 |     //         expect(foundMail).toBeTruthy();
  1004 |     //     }
  1005 |     // })
  1006 |
  1007 |     test("REQ_030 - Verify when clone request without archive", {
  1008 |         tag: ["@REQ_030", "@request", "@function"]
  1009 |     }, async ({ conf, browser }) => {
  1010 |         await test.step("Open clone request modal", async () => {
  1011 |             await requestPage.getDetailCase(conf.data.case);
  1012 |             await requestPage.openCloneRequestModal();
  1013 |         });
  1014 |
  1015 |         await test.step("Fill business and member info for clone", async () => {
  1016 |             await requestPage.fillCloneRequestForm(conf.data.business, conf.data.member, conf.data.archive);
  1017 |         });
  1018 |
  1019 |         await test.step("Verify when clone successfully", async () => {
  1020 |             await requestPage.submitCloneRequest();
> 1021 |             await expect(requestPage.requestLoc.detail.cloneRequest.msgCloneSucess).toBeVisible({ timeout: 25_000 });
       |                                                                                     ^ Error: Timed out 25000ms waiting for expect(locator).toBeVisible()
  1022 |             await requestPage.dashboardLoc.btnClosePopupNotification.click();
  1023 |             await requestPage.waitForSecond(2);
  1024 |             await verifyScreenshot('header-detail-request.png', requestPage.requestLoc.detail.headerDetail, [requestPage.requestLoc.detail.titleIdNameRequest], 0.02);
  1025 |         });
  1026 |
  1027 |         await test.step("Verify user B had noti and request in Share with me", async () => {
  1028 |             const { context: contextB, requestPage: requestPageB } = await requestPage.loginInAnotherBrowser(browser, conf.data.username_in_shared, conf.data.password);
  1029 |             await requestPageB.verifyAndOpenNotification(false);
  1030 |             await contextB.close();
  1031 |         });
  1032 |     });
  1033 |
  1034 |     test("REQ_031 - Verify when clone request and archive", {
  1035 |         tag: ["@REQ_031", "@request", "@function"]
  1036 |     }, async ({ conf, browser, requestPage31 }) => {
  1037 |         test.setTimeout(180_000);
  1038 |         let caseID: string = "";
  1039 |
  1040 |         await test.step("Open clone request modal", async () => {
  1041 |             await requestPage31.openCloneRequestModal();
  1042 |         });
  1043 |
  1044 |         await test.step("Fill business, member info and select archive option for clone", async () => {
  1045 |             await requestPage31.fillCloneRequestForm(conf.data.business, conf.data.member, conf.data.archive);
  1046 |         });
  1047 |
  1048 |         await test.step("Verify when clone successfully and verify old request had archived for the creator", async () => {
  1049 |             await requestPage31.submitCloneRequest();
  1050 |             await expect(requestPage31.requestLoc.detail.cloneRequest.msgCloneSucess).toBeVisible({ timeout: 60_000 }); // Increased timeout for clone process
  1051 |             await requestPage31.waitForSecond(3);
  1052 |             caseID = (await requestPage31.requestLoc.caseIDDetail.innerText()).replace(/^#(\d+)\b.*/, "$1");
  1053 |
  1054 |             // Verify request new request in list table
  1055 |             await requestPage31.open();
  1056 |             await requestPage31.search(caseID);
  1057 |             await expect(requestPage31.dashboardLoc.table.itemInRow(caseID)).toBeVisible();
  1058 |
  1059 |             // Verify request old request  not in list table
  1060 |             await requestPage31.search(conf.data.case);
  1061 |             await requestPage31.waitForSecond(2);
  1062 |             await expect(requestPage31.dashboardLoc.table.itemInRow(conf.data.case)).not.toBeVisible();
  1063 |         });
  1064 |
  1065 |         await test.step("Verify user B had noti and request in Share with me", async () => {
  1066 |             const { context: contextB, requestPage: requestPageB } = await requestPage31.loginInAnotherBrowser(browser, conf.data.username_in_shared, conf.data.password);
  1067 |             await requestPageB.verifyAndOpenNotification(false);
  1068 |             expect((await requestPageB.requestLoc.caseIDDetail.innerText()).replace(/^#(\d+)\b.*/, "$1")).toBe(caseID);
  1069 |             await contextB.close();
  1070 |         });
  1071 |     });
  1072 |
  1073 |     test("REQ_033 - Verify deletion or add of unlinked case members", {
  1074 |         tag: ["@REQ_033", "@request", "@function"]
  1075 |     }, async ({ conf, browser, requestPage33 }) => {
  1076 |         test.setTimeout(180_000);
  1077 |         await test.step("Verify UI user triduc (not a person who share request)", async () => {
  1078 |             const { context: contextB, requestPage: requestPageB } = await requestPage33.loginInAnotherBrowser(browser, conf.data.username_member_a, conf.data.password);
  1079 |             await requestPageB.open();
  1080 |             await requestPageB.getDetailCase(conf.data.case);
  1081 |             await requestPageB.dashboardLoc.buttonByText("Share").click();
  1082 |             await expect(requestPageB.page.locator('#modal-share')).toMatchAriaSnapshot(`
  1083 |               - text: "To:"
  1084 |               - textbox "To Add People People"
  1085 |               - text: Cc Bcc
  1086 |               - checkbox "Send email notification" [checked]
  1087 |               - text: Send email notification Message
  1088 |               - textbox "Message"
  1089 |               - paragraph: People with access
  1090 |               - link "Sent Summary":
  1091 |                 - /url: /requests/sent?request_id=275078
  1092 |               - paragraph: Auto Test.Pharmacy
  1093 |               - paragraph: "***********************************.com"
  1094 |               - paragraph: Tri01 Duc
  1095 |               - paragraph: triducgog0301+1@gmail.com (You)
  1096 |               - text: Unfollow
  1097 |               - paragraph: Minh Phong
  1098 |               - paragraph: minhphong.simple@gmail.com
  1099 |               - paragraph: Creator
  1100 |               `);
  1101 |             await contextB.close();
  1102 |         })
  1103 |
  1104 |         await test.step("Verify when delete user portal from request", async () => {
  1105 |             await requestPage33.open();
  1106 |             await requestPage33.getDetailCase(conf.data.case);
  1107 |             await requestPage33.dashboardLoc.buttonByText("Share").click();
  1108 |             await requestPage33.requestLoc.detail.share.btnDeleteByMemberName(conf.data.member_name_delete).click();
  1109 |             await requestPage33.requestLoc.detail.btnCofirmRemove.click();
  1110 |         })
  1111 |
  1112 |         await test.step("Verify request not exist in Share with me of user had deleted", async () => {
  1113 |             const { context: contextC, requestPage: requestPageC } = await requestPage33.loginInAnotherBrowser(browser, conf.data.username_member_delete, conf.data.password);
  1114 |             let shareWithMePage = new SharedRequestPage(requestPageC.page);
  1115 |             await shareWithMePage.open();
  1116 |             await shareWithMePage.search(conf.data.case);
  1117 |             await expect(shareWithMePage.dashboardLoc.table.noResult).toBeVisible();
  1118 |             await contextC.close();
  1119 |         })
  1120 |
  1121 |         await test.step("Verify when add user C again", async () => {
```