# Test info

- Name: Feature case for request-listing >> REQ_021 - Verify Snapshot in request had action type Letter of Protection
- Location: /root/code/portal-automation-test/tests/request/function.spec.ts:636:9

# Error details

```
Error: locator.waitFor: Test timeout of 200000ms exceeded.
Call log:
  - waiting for locator('//p[text()=\'Added New Successfully!\']') to be visible

    at RequestPage.respondToRequest (/root/code/portal-automation-test/pom/request/request.page.ts:313:47)
    at /root/code/portal-automation-test/tests/request/function.spec.ts:647:13
    at /root/code/portal-automation-test/tests/request/function.spec.ts:645: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:
    - 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: "#850776 Letter of Protection"
- img
- img
- img
- link "Danel Jackson":
  - /url: /clients/87944623-210f-450c-8e57-5fab39f7ace6
- text: "-"
- 'link "DOB: __/__/____"':
  - /url: /clients/87944623-210f-450c-8e57-5fab39f7ace6
- 'link "Case: #386406"':
  - /url: /cases/386406
- text: "-"
- 'link "DOI: 12/02/2025"':
  - /url: /cases/386406
- 'link "Category: Unspecified Accident"':
  - /url: /cases/386406
- 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: Tri01 Duc
- text: Posted
- paragraph: 01/31/2026
- img
- list:
  - listitem
- textbox "Message"
- button [disabled]:
  - img
- paragraph: Minh Phong
- text: Posted
- paragraph: 01/31/2026
- img
- img
- list:
  - listitem
- textbox "Comment..."
- button [disabled]:
  - img
- paragraph: Minh Phong
- text: Posted
- paragraph: 01/31/2026
- img
- img
- list:
  - listitem
- textbox "Comment..."
- button [disabled]:
  - img
- paragraph: Minh Phong
- text: Posted
- paragraph: 01/30/2026
- img
- img
- list:
  - listitem
- textbox "Comment..."
- button [disabled]:
  - img
- paragraph: Minh Phong
- text: Posted
- paragraph: 01/30/2026
- img
- img
- list:
  - listitem
- textbox "Comment..."
- button [disabled]:
  - img
- heading "Snapshot" [level=2]
- list:
  - listitem: Tri01 Duc 1 day ago Responded Respond
  - listitem: Minh Phong 1 day ago Responded
  - listitem: Minh Phong 1 day ago Responded
  - listitem: Minh Phong 1 day ago Responded
  - listitem: Minh Phong 01/30/2026 Responded
  - listitem: Tri01 Duc 01/29/2026 Responded
  - listitem: Minh Phong 01/29/2026 Responded
  - listitem: Tri01 Duc 01/29/2026 Responded
  - listitem: Minh Phong 01/29/2026 Responded
  - listitem: Minh Phong 01/29/2026 Responded
  - listitem: Tri01 Duc 01/28/2026 Responded
  - listitem: Minh Phong 01/28/2026 Responded
  - listitem: Tri01 Duc 01/28/2026 Responded
  - listitem: Minh Phong 01/28/2026 Responded
  - listitem: Minh Phong 01/27/2026 Responded
  - listitem: Tri01 Duc 01/27/2026 Responded
  - listitem: Minh Phong 01/27/2026 Responded
  - listitem: Tri01 Duc 01/26/2026 Responded
  - listitem: Minh Phong 01/26/2026 Responded
  - listitem: Minh Phong 01/26/2026 Responded
  - listitem: Minh Phong 01/25/2026 Responded
  - listitem: Tri01 Duc 01/25/2026 Responded
  - listitem: Minh Phong 01/25/2026 Responded
  - listitem: Tri01 Duc 01/24/2026 Responded
  - listitem: Minh Phong 01/24/2026 Responded
  - listitem: Minh Phong 01/24/2026 Responded
  - listitem: Minh Phong 01/23/2026 Responded
  - listitem: Minh Phong 01/23/2026 Responded
  - listitem: Minh Phong 01/22/2026 Responded
  - listitem: Minh Phong 01/22/2026 Responded
  - listitem: Minh Phong 01/21/2026 Responded
  - listitem: Minh Phong 01/21/2026 Responded
  - listitem: Tri01 Duc 01/21/2026 Responded
  - listitem: Minh Phong 01/21/2026 Responded
  - listitem: Tri01 Duc 01/20/2026 Responded
  - listitem: Minh Phong 01/20/2026 Responded
  - listitem: Minh Phong 01/20/2026 Responded
  - listitem: Minh Phong 01/19/2026 Responded
  - listitem: Minh Phong 01/19/2026 Responded
  - listitem: Minh Phong 01/18/2026 Responded
  - listitem: Minh Phong 01/18/2026 Responded
  - listitem: Minh Phong 01/17/2026 Responded
  - listitem: Minh Phong 01/17/2026 Responded
  - listitem: Minh Phong 01/16/2026 Responded
  - listitem: Minh Phong 01/16/2026 Responded
  - listitem: Minh Phong 01/15/2026 Responded
  - listitem: Minh Phong 01/15/2026 Responded
  - listitem: Minh Phong 01/14/2026 Responded
  - listitem: Tri01 Duc 01/14/2026 Responded
  - listitem: Minh Phong 01/14/2026 Responded
  - listitem: Tri01 Duc 01/13/2026 Responded
  - listitem: Minh Phong 01/13/2026 Responded
  - listitem: Tri01 Duc 01/13/2026 Responded
  - listitem: Minh Phong 01/13/2026 Responded
  - listitem: Tri01 Duc 01/12/2026 Responded
  - listitem: Minh Phong 01/12/2026 Responded
  - listitem: Tri01 Duc 01/12/2026 Responded
  - listitem: Minh Phong 01/12/2026 Responded
  - listitem: Tri01 Duc 01/11/2026 Responded
  - listitem: Minh Phong 01/11/2026 Responded
  - listitem: Tri01 Duc 01/11/2026 Responded
  - listitem: Minh Phong 01/11/2026 Responded
  - listitem: Tri01 Duc 01/10/2026 Responded
  - listitem: Minh Phong 01/10/2026 Responded
  - listitem: Tri01 Duc 01/10/2026 Responded
  - listitem: Minh Phong 01/10/2026 Responded
  - listitem: Tri01 Duc 01/09/2026 Responded
  - listitem: Minh Phong 01/09/2026 Responded
  - listitem: Tri01 Duc 01/09/2026 Responded
  - listitem: Minh Phong 01/09/2026 Responded
  - listitem: Tri01 Duc 01/08/2026 Responded
  - listitem: Minh Phong 01/08/2026 Responded
  - listitem: Tri01 Duc 01/08/2026 Responded
  - listitem: Minh Phong 01/08/2026 Responded
  - listitem: Tri01 Duc 01/08/2026 Responded
  - listitem: Minh Phong 01/08/2026 Responded
  - listitem: Tri01 Duc 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Tri01 Duc 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Tri01 Duc 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Tri01 Duc 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Tri01 Duc 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/07/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/06/2026 Responded
  - listitem: Minh Phong 01/05/2026 Responded
  - listitem: Minh Phong 01/05/2026 Responded
  - listitem: Tri01 Duc 01/04/2026 Responded
  - listitem: Minh Phong 01/04/2026 Responded
  - listitem: Tri01 Duc 01/04/2026 Responded
  - listitem: Minh Phong 01/04/2026 Responded
  - listitem: Tri01 Duc 01/03/2026 Responded
  - listitem: Minh Phong 01/03/2026 Responded
  - listitem: Tri01 Duc 01/03/2026 Responded
  - listitem: Minh Phong 01/03/2026 Responded
  - listitem: Tri01 Duc 01/02/2026 Responded
  - listitem: Minh Phong 01/02/2026 Responded
  - listitem: Tri01 Duc 01/02/2026 Responded
  - listitem: Minh Phong 01/02/2026 Responded
  - listitem: Tri01 Duc 01/01/2026 Responded
  - listitem: Minh Phong 01/01/2026 Responded
  - listitem: Tri01 Duc 01/01/2026 Responded
  - listitem: Minh Phong 01/01/2026 Responded
  - listitem: Tri01 Duc 12/31/2025 Responded
  - listitem: Minh Phong 12/31/2025 Responded
  - listitem: Tri01 Duc 12/31/2025 Responded
  - listitem: Minh Phong 12/31/2025 Responded
  - listitem: Tri01 Duc 12/30/2025 Responded
  - listitem: Minh Phong 12/30/2025 Responded
  - listitem: Tri01 Duc 12/30/2025 Responded
  - listitem: Minh Phong 12/30/2025 Responded
  - listitem: Tri01 Duc 12/29/2025 Responded
  - listitem: Minh Phong 12/29/2025 Responded
  - listitem: Tri01 Duc 12/29/2025 Responded
  - listitem: Minh Phong 12/29/2025 Responded
  - listitem: Tri01 Duc 12/28/2025 Responded
  - listitem: Minh Phong 12/28/2025 Responded
  - listitem: Tri01 Duc 12/28/2025 Responded
  - listitem: Minh Phong 12/28/2025 Responded
  - listitem: Tri01 Duc 12/27/2025 Responded
  - listitem: Minh Phong 12/27/2025 Responded
  - listitem: Tri01 Duc 12/27/2025 Responded
  - listitem: Minh Phong 12/27/2025 Responded
  - listitem: Tri01 Duc 12/26/2025 Responded
  - listitem: Minh Phong 12/26/2025 Responded
  - listitem: Tri01 Duc 12/26/2025 Responded
  - listitem: Minh Phong 12/26/2025 Responded
  - listitem: Tri01 Duc 12/25/2025 Responded
  - listitem: Minh Phong 12/25/2025 Responded
  - listitem: Tri01 Duc 12/25/2025 Responded
  - listitem: Minh Phong 12/25/2025 Responded
  - listitem: Tri01 Duc 12/24/2025 Responded
  - listitem: Minh Phong 12/24/2025 Responded
  - listitem: Tri01 Duc 12/24/2025 Responded
  - listitem: Minh Phong 12/24/2025 Responded
  - listitem: Tri01 Duc 12/23/2025 Responded
  - listitem: Minh Phong 12/23/2025 Responded
  - listitem: Tri01 Duc 12/23/2025 Responded
  - listitem: Minh Phong 12/23/2025 Responded
  - listitem: Tri01 Duc 12/22/2025 Responded
  - listitem: Minh Phong 12/22/2025 Responded
  - listitem: Tri01 Duc 12/22/2025 Responded
  - listitem: Minh Phong 12/22/2025 Responded
  - listitem: Tri01 Duc 12/21/2025 Responded
  - listitem: Minh Phong 12/21/2025 Responded
  - listitem: Tri01 Duc 12/20/2025 Responded
  - listitem: Minh Phong 12/20/2025 Responded
  - listitem: Tri01 Duc 12/19/2025 Responded
  - listitem: Minh Phong 12/19/2025 Responded
  - listitem: Tri01 Duc 12/19/2025 Responded
  - listitem: Minh Phong 12/19/2025 Responded
  - listitem: Tri01 Duc 12/18/2025 Responded
  - listitem: Minh Phong 12/18/2025 Responded
  - listitem: Tri01 Duc 12/18/2025 Responded
  - listitem: Minh Phong 12/18/2025 Responded
  - listitem: Tri01 Duc 12/17/2025 Responded
  - listitem: Minh Phong 12/17/2025 Responded
  - listitem: Tri01 Duc 12/17/2025 Responded
  - listitem: Minh Phong 12/17/2025 Responded
  - listitem: Tri01 Duc 12/16/2025 Responded
  - listitem: Minh Phong 12/16/2025 Responded
  - listitem: Tri01 Duc 12/16/2025 Responded
  - listitem: Minh Phong 12/16/2025 Responded
  - listitem: Tri01 Duc 12/15/2025 Responded
  - listitem: Minh Phong 12/15/2025 Responded
  - listitem: Tri01 Duc 12/15/2025 Responded
  - listitem: Minh Phong 12/15/2025 Responded
  - listitem: Tri01 Duc 12/14/2025 Responded
  - listitem: Minh Phong 12/14/2025 Responded
  - listitem: Tri01 Duc 12/14/2025 Responded
  - listitem: Minh Phong 12/14/2025 Responded
  - listitem: Tri01 Duc 12/14/2025 Responded
  - listitem: Minh Phong 12/14/2025 Responded
  - listitem: Tri01 Duc 12/13/2025 Responded
  - listitem: Minh Phong 12/13/2025 Responded
  - listitem: Tri01 Duc 12/13/2025 Responded
  - listitem: Minh Phong 12/13/2025 Responded
  - listitem: Tri01 Duc 12/12/2025 Responded
  - listitem: Minh Phong 12/12/2025 Responded
  - listitem: Tri01 Duc 12/12/2025 Responded
  - listitem: Minh Phong 12/12/2025 Responded
  - listitem: Tri01 Duc 12/11/2025 Responded
  - listitem: Minh Phong 12/11/2025 Responded
  - listitem: Tri01 Duc 12/11/2025 Responded
  - listitem: Minh Phong 12/11/2025 Responded
  - listitem: Tri01 Duc 12/11/2025 Responded
  - listitem: Minh Phong 12/11/2025 Responded
  - listitem: Minh Phong 12/11/2025 Responded
  - listitem: Minh Phong 12/11/2025 Submitted a request
- 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 "Message" [level=3]
- button "Close"
- paragraph: Use the suggested content to jump right in, or type or upload your own content.
- listitem: Type New
- listitem: Upload
- text: Click on
- img
- text: to expand the editor to full screen
- listitem "Font family":
  - button:
    - img
  - img
- listitem "Font size":
  - button [pressed]:
    - img
  - img
- listitem "Fill color or set the text color":
  - button:
    - img
  - img
- listitem "Bold":
  - button:
    - img
- listitem "Italic":
  - button:
    - img
- listitem "Underline":
  - button:
    - img
- listitem "Strike through":
  - button:
    - img
- listitem "Insert Unordered List":
  - button:
    - img
  - img
- listitem "Insert Ordered List":
  - button:
    - img
  - img
- listitem "Align":
  - button:
    - img
  - img
- listitem "Insert Image":
  - button:
    - img
- listitem "Insert table":
  - button:
    - img
- listitem "Open in fullsize":
  - button:
    - img
- paragraph: Hello world
- text: "Chars: 10 Words: 2"
- listitem "Select all":
  - button:
    - img
- button "p"
- text: You can upload up to 50 files, with a total combined size of up to 50MB. Only PDF and image (jpg,jpeg,png) files are accepted.
- paragraph: Browse or Drop
- paragraph: files here
- button "Cancel"
- button "Submit"
```

# Test source

```ts
  213 |         },
  214 |
  215 |         discussion: {
  216 |           chatOnlyYou: (accountName: string) => this.genLoc(`//span[@class='title-conversation' and text()='${accountName} (You)']`),
  217 |           btnThreeDotsActionDiscussion: this.genLoc("//div[@class='dropdown ms-auto']"),
  218 |           btnThreeDotsReplyMessage: this.genLoc("//div[contains(@class,'icon-more-message')]"),
  219 |           btnDeleteMessage: this.genLoc("//span[@class='dropdown-item btn-message-discussion btn-remove-message-discussion cursor-pointer']"),
  220 |           btnReplyMessage: this.genLoc("//div[@class='dropdown-menu dropdown-menu-end box-dropdown-btn show']"),
  221 |           contentReply: this.genLoc("//p[@class='content-reply']"),
  222 |           labelWasReply: (message: string) => this.genLoc(`//div[text()='${message}']/ancestor::div[@class='item-message']/descendant::span[@class='reply-owner']`),
  223 |           btnCreateDiscussion: this.genLoc("(//span[@data-user-tracking='BTN_SHOW_CREATE_REQUEST_DISCUSSION_MODAL'])[1]"),
  224 |           inputTitle: this.genLoc("//input[@name='title']"),
  225 |           inputMessage: this.genLoc("//input[@placeholder='Message']"),
  226 |           titleInDiscussion: (title: string) => this.genLoc(`//span[text()='${title}']/ancestor::div[@class='request-discussion-wrapper']`),
  227 |           titleDiscussion: (title: string) => this.genLoc(`//span[text()='${title}']/ancestor::div[@class='request-discussion-wrapper']`),
  228 |           titleDiscussionToClick: (title: string) => this.genLoc(`//span[text()='${title}']/ancestor::div[@class='request-discussion-wrapper']/descendant::span[text()='${title}']`),
  229 |           messageInDiscussion: (message: string) => this.genLoc(`//div[text()='${message}']`),
  230 |           newestDiscussion: this.genLoc("(//div[contains(@class,'item-content')])[1]"),
  231 |           inputMsgDis: this.genLoc("//input[@placeholder='Message']"),
  232 |           btnSendMsg: this.genLoc("//button[@class='btn-send-message btn-message']"),
  233 |           msgFirstDis: this.genLoc("(//textarea[@name='content'])[2]")
  234 |         },
  235 |       },
  236 |
  237 |       create: {
  238 |         optionMember: (member: string) => this.genLoc(`//span[text()='${member}']/ancestor::span[contains(@class,'date-option')]`),
  239 |         btnCloseAction: this.genLoc("//span[@class='closed-action']"),
  240 |         btnAddNewOption: (option: string) => this.genLoc(`//button[contains(.,'${option}')]`),
  241 |         closeModalMessage: this.genLoc("(//span[@class='closed-action'])[4]"),
  242 |         textEditorCreateFast: this.genLoc("//div[@class='jodit-wysiwyg']"),
  243 |         arrowIcon: this.genLoc("//span[@class='arrow-icon']"),
  244 |         inputDOIInStep2: this.genLoc("//input[@id='date_time_rows.1.date_of_injury']"),
  245 |         itemRow2: this.genLoc("(//div[@class='apply-all item item-steps-2 position-relative'])[2]"),
  246 |         tableRowUI: this.genLoc("//div[@class='add-rows-request']/ancestor::div[@class='mb-3']"),
  247 |         dataPreview: (type: string) => this.genLoc(`(//label[text()='${type}']/following::div[@class='note'])[1]`),
  248 |         boxTextBusiness: (business: string) => this.genLoc(`//div[@class='box-text box-text-business' and contains(.,'${business}')]`),
  249 |         inputByPlaceholder: (placeholder: string) => this.genLoc(`//input[@placeholder='${placeholder}']`),
  250 |         headerInCreateStep: (headerName: string) => this.genLoc(`//div[contains(@class,'title-header')]/descendant::span[text()='${headerName}']`),
  251 |         dropdownMemberShare: (member: string) => this.genLoc(`//div[text()='${member}']/parent::div[contains(@class,'box-text box-text-business')]`),
  252 |         dropdownMemberShareNew: (member: string) => this.genLoc(`//strong[contains(text(),'${member}')]/ancestor::div[@class='dropdown-menu-wrapper']`),
  253 |         btnCreateAndShare: this.genLoc("//a[text()='Create & Share']"),
  254 |         caseIDRequest: this.genLoc("//div[@class='list-info-name-pin pin-item']"),
  255 |         boxCreateMultiRequests: this.genLoc("//div[@class='box-items box-apply-all box-select position-relative row-normal']"),
  256 |         itemStep: (step: number) => this.genLoc(`//div[contains(@class,'item-steps-${step}')]`),
  257 |         inputCheckAll: (name: string) => this.genLoc(`//input[@name='check-box-apply-all-${name}']`),
  258 |         viewRequest: this.genLoc("//a[@class='view-request-success']"),
  259 |         overviewCreateFast: this.genLoc("//div[@class='new-request request-multi send-new-request-multi row justify-content-center']")
  260 |       },
  261 |       btnTakeActions: this.genLoc("(//button[@class='btn d-flex align-items-center ga-8 btn-soft-primary pr-8px'])[1]"),
  262 |       mainContainer: this.genLoc(`//div[@id='root']`),
  263 |       heading: this.genLoc(`//div[@id='root']//span[contains(text(), 'Requests')]`),
  264 |       inputSearch: this.genLoc(`//div[contains(@class, 'personal-search')]//input[@placeholder='Search...']`),
  265 |       tableHeadingColumn: (nameHeading: string) => this.genLoc(`//th[contains(@class, 'title-table')]//span[contains(normalize-space(),'${nameHeading}')]`),
  266 |       pinIcon: (caseNumber: string) => this.genLoc(`//a[normalize-space()=${caseNumber}]//ancestor::tr//a[@data-tooltip-content='Click here to pin!']`),
  267 |       pinnedIcon: (caseNumber: string) => this.genLoc(`//a[normalize-space()=${caseNumber}]//ancestor::tr//a[@data-tooltip-content='Click here to unpin!']`),
  268 |       firstCaseNumber: (caseNumber: string) => this.genLoc(`//div[contains(@class, 'card pin-card')]//a[@href='/requests/${caseNumber}']`),
  269 |       btnNewRequest: this.genLoc(`//div[@id='root']//button[contains(text(), 'New Request')]`),
  270 |       btnFilter: this.genLoc(`//div[@id='root']//button[contains(text(), 'Filter')]`),
  271 |       btnBulkEdit: this.genLoc(`//div[@id='root']//button[contains(text(), 'Bulk Edit')]`),
  272 |       inputShow: this.genLoc(`//input[@class='form-control show-record-number ']`),
  273 |       caseAlreadyExist: (caseID: string) => this.genLoc(`//td/a[text()='${caseID}'] | //span[text()='${caseID}']`),
  274 |       buttonRepond: this.genLoc("//a[text()='Respond']"),
  275 |       caseIDDetail: this.genLoc("//span[contains(@class,'business-contact-name')]"),
  276 |       headerModalNewPost: this.genLoc("//h3[text()='New Post: Minimize Previous Post?']"),
  277 |       buttonLeaveIt: this.genLoc("//button[text()='Leave it']"),
  278 |       messageRepondSucces: this.genLoc("//p[text()='Added New Successfully!']"),
  279 |       buttonSubmitTextEditor: this.genLoc("(//div[@class='box-btn-reset-apply-filter']/button[text()='Submit'])[2]"),
  280 |       thumbImagePosted: this.genLoc("//div[@class='letter-thumb-image']"),
  281 |       detailPostedAttachment: this.genLoc(".tab-detail-attachment"),
  282 |       siteCreateNewRequest: this.genLoc("//div[@class='request-index']"),
  283 |       btnNextStep: this.genLoc("//a[text()='Next']"),
  284 |       actionLetterOfProtection: this.genLoc("//p[text()='Letter of Protection']"),
  285 |       listPatientSuggested: this.genLoc("//div[@class='steps step-2']/descendant::div[contains(@class, 'item action-items')][1]"),
  286 |       listBusinessSuggested: this.genLoc("//div[@class='steps step-3']/descendant::div[contains(@class, 'item action-items')][1]"),
  287 |       modalChoosePatient: this.genLoc("//span[text()='Selection of patients']/parent::div"),
  288 |       modalChooseBusiness: this.genLoc("//span[text()='Selection of businesses']/parent::div"),
  289 |       textEditorCreateCaseArea: this.genLoc("(//div[@class='jodit-react-container']/descendant::div[@class='jodit-wysiwyg'])[2]"),
  290 |       btnItalicEditorCreate: this.genLoc("(//span[@data-ref='italic']/button)[2]"),
  291 |       btnBoldEditorCreate: this.genLoc("(//span[@data-ref='bold']/button[@class='jodit-toolbar-button__button'])[2]"),
  292 |       btnListNumberTypeCreate: this.genLoc("(//span[@role='listitem' and @data-ref='ol']/button)[2]"),
  293 |       btnListDotTypeCreate: this.genLoc("(//span[@role='listitem' and @data-ref='ul']/button)[2]"),
  294 |       btnCreateOnly: this.genLoc("//a[text()='Create Only']"),
  295 |     };
  296 |   }
  297 |
  298 |   async open(): Promise<void> {
  299 |     await this.page.goto("requests");
  300 |   }
  301 |
  302 |   async gotoCreateRequest(type: string): Promise<void> {
  303 |     await this.page.goto(`requests/create?switch=${type}`);
  304 |   }
  305 |
  306 |   // Respond to a request with a message
  307 |   async respondToRequest(message: string): Promise<void> {
  308 |     const textEditorBody = this.requestLoc.textEditorCreateCaseArea;
  309 |     await this.requestLoc.buttonRepond.click();
  310 |     await textEditorBody.waitFor({ state: 'visible' });
  311 |     await textEditorBody.type(message, { delay: 20 });
  312 |     await this.requestLoc.detail.btnSubmitMessage.click();
> 313 |     await this.requestLoc.messageRepondSucces.waitFor({ state: 'visible' });
      |                                               ^ Error: locator.waitFor: Test timeout of 200000ms exceeded.
  314 |     await textEditorBody.waitFor({ state: 'hidden' });
  315 |   }
  316 |
  317 |   // Edit business and share request with another member
  318 |   async editBusinessAndShare(business: string, memberToAdd: string, nameMemberAdd: string): Promise<void> {
  319 |     await this.requestLoc.detail.btnDropdownEditBusiness.waitFor({ state: 'visible' });
  320 |     await this.waitForSecond(1);
  321 |     await this.requestLoc.detail.btnDropdownEditBusiness.click();
  322 |     await this.requestLoc.detail.btnEdit.click();
  323 |     await assertionHelper.verifyModalVisible(this.dashboardLoc.modal.headerModal("Edit Business"));
  324 |     await this.requestLoc.detail.inputSearchChangeBusiness.fill(business);
  325 |     await this.requestLoc.create.boxTextBusiness(business).click();
  326 |     await this.dashboardLoc.buttonByText("Update").first().click();
  327 |     await assertionHelper.verifyModalVisible(this.dashboardLoc.notificationUpdateSuccess);
  328 |     await this.dashboardLoc.buttonByText("Share").click();
  329 |     await assertionHelper.verifyModalVisible(this.dashboardLoc.modal.headerModal("Share with others"));
  330 |     await this.requestLoc.detail.btnDelteMember.click();
  331 |     await this.requestLoc.detail.btnCofirmRemove.click();
  332 |     await assertionHelper.verifyModalVisible(this.dashboardLoc.notificationUpdateSuccess);
  333 |     await this.requestLoc.detail.inputSeachMember.fill(memberToAdd);
  334 |     await this.waitForSecond(2);
  335 |     await this.requestLoc.create.dropdownMemberShare(nameMemberAdd).click();
  336 |     await this.dashboardLoc.buttonByText("Done").first().click();
  337 |     await assertionHelper.verifyModalVisible(this.dashboardLoc.notificationUpdateSuccess);
  338 |   }
  339 |
  340 |   // Fill data in create request form
  341 |   async fillDataCreateRequest(inputPlaceHolder: string, preview: string, data: string): Promise<any> {
  342 |     await this.requestLoc.create.inputByPlaceholder(inputPlaceHolder).first().fill(data);
  343 |     const infoPatient = await this.requestLoc.create.boxTextBusiness(data).innerText();
  344 |     await this.waitForSecond(2);
  345 |     await this.requestLoc.create.boxTextBusiness(data).click({ force: true });
  346 |     const infoPatientPreview = await this.requestLoc.create.dataPreview(preview).innerText();
  347 |     const address = infoPatientPreview.split('\n')[0].replace('Address:', '').trim();
  348 |     return { infoPatient, address }
  349 |   }
  350 |
  351 |   // Render a list in the text editor
  352 |   async rendListTextEditor(text: string): Promise<void> {
  353 |     const textEditorBody = this.requestLoc.textEditorCreateCaseArea;
  354 |     for (let i = 0; i < 3; i++) {
  355 |       await textEditorBody.type(text, { delay: 20 });
  356 |       await textEditorBody.press('Enter');
  357 |     }
  358 |     await textEditorBody.press('Enter');
  359 |   }
  360 |
  361 |   //Open notification and the latest post, then run an optional callback
  362 |   async verifyAndOpenNotification(gotoDetail: boolean): Promise<void> {
  363 |     await this.dashboardLoc.notiCard.waitFor({ state: 'visible' });
  364 |     await this.dashboardLoc.notiCard.click();
  365 |     if (gotoDetail) {
  366 |       await this.requestLoc.thumbImagePosted.first().waitFor({ state: 'visible' });
  367 |       await this.requestLoc.thumbImagePosted.first().click();
  368 |     }
  369 |     await this.waitForSecond(2);
  370 |   }
  371 |
  372 |   // Open the latest post and wait for it to load
  373 |   async verifyPostSnapshot(): Promise<void> {
  374 |     await this.requestLoc.thumbImagePosted.first().waitFor({ state: 'visible' });
  375 |     await this.requestLoc.thumbImagePosted.first().click();
  376 |     await this.waitForSecond(2);
  377 |   }
  378 |
  379 |   //Go back to the request list if the button is visible
  380 |   async backToRequestList(): Promise<void> {
  381 |     if (await this.requestLoc.detail.btnBackToReq.isVisible()) {
  382 |       await this.requestLoc.detail.btnBackToReq.click();
  383 |     }
  384 |   }
  385 |
  386 |   //Verify if a request is shared with a member (in a new browser context)
  387 |   async verifyShareRequest(browser: Browser, conf: any, memberKey: string, shouldBeVisible: boolean): Promise<void> {
  388 |     const context = await browser.newContext();
  389 |     const page = await context.newPage();
  390 |     const loginPage = new LoginPage(page);
  391 |     const shareWithMePage = new SharedRequestPage(page);
  392 |     try {
  393 |       await loginPage.open();
  394 |       await loginPage.login(conf.data.user[memberKey], conf.data.password);
  395 |       await shareWithMePage.open();
  396 |       await shareWithMePage.search(conf.data.case);
  397 |       await shareWithMePage.waitForSecond(2);
  398 |       const isVisible = await shareWithMePage.dashboardLoc.table.noResult.isVisible();
  399 |       if (isVisible !== shouldBeVisible) {
  400 |         throw new Error(`Unexpected visibility for ${memberKey}: expected ${shouldBeVisible}, got ${isVisible}`);
  401 |       }
  402 |     } finally {
  403 |       await context.close();
  404 |     }
  405 |   }
  406 |
  407 |   // Login as another user in a new browser context and return the new RequestPage
  408 |   async loginInAnotherBrowser(browser: Browser, username: string, password: string): Promise<{ context: BrowserContext; page: Page; requestPage: RequestPage }> {
  409 |     const context = await browser.newContext();
  410 |     const page = await context.newPage();
  411 |     const loginPage = new LoginPage(page);
  412 |     await loginPage.open();
  413 |     await loginPage.login(username, password);
```