# 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 15000ms waiting for expect(locator).toBeVisible()

Locator: locator('//div[@id=\'root\' and @class=\'dashboard-index\']')
Expected: visible
Received: <element(s) not found>
Call log:
  - expect.toBeVisible with timeout 15000ms
  - waiting for locator('//div[@id=\'root\' and @class=\'dashboard-index\']')

    at /root/code/portal-automation-test/tests/request/function.spec.ts:27:60
```

# Page snapshot

```yaml
- text: Email Address
- textbox "your@email.com": portal_auto_lawyer@testmail.loprx.com
- text: These credentials do not match our records. Password
- textbox "Your password"
- img
- checkbox "Remember me for 30 days"
- text: Remember me for 30 days
- button:
  - img
- button "Log in"
- paragraph:
  - text: By continuing, you agree to the
  - link "Terms of Use":
    - /url: https://portalassistant.com/terms-of-service/
  - text: ","
  - link "Privacy Policy":
    - /url: https://portalassistant.com/privacy-policy/
  - text: and
  - link "Business Associate Agreement":
    - /url: https://portalassistant.com/baa/
- link "Forgot Password":
  - /url: https://qa.loprx.com/forgot-password
- link "Login with passcode":
  - /url: https://qa.loprx.com/sign-in-with-passcode
```

# Test source

```ts
   1 | import { test, expect } from '../../fixtures/index';
   2 | import { RequestPage } from '../../pom/request/request.page';
   3 | import { LoginPage } from '../../pom/login.page';
   4 | import path from 'path';
   5 | import { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';
   6 | import { SharedRequestPage } from '../../pom/share-request.page';
   7 | import { getTodayInTimeZone } from '../../pom/utils/utlisFunc';
   8 | import { extractNumber, getRandomNumberInRange, randomString } from '../../utils/array';
   9 | import { Mail } from '../../pom/utils/mail.page';
   10 | import { CasePage } from '../../pom/case/case.page';
   11 | import { authenticator } from 'otplib'
   12 | import fs from 'fs';
   13 |
   14 | test.describe('Feature case for request-listing', () => {
   15 |     let loginPage: LoginPage;
   16 |     let requestPage: RequestPage;
   17 |     let msgOffNoti: string = "";
   18 |     let msgOnNoti: string = "";
   19 |     let listMailCheck: string[] = [];
   20 |     test.beforeEach(async ({ page, conf }) => {
   21 |         loginPage = new LoginPage(page);
   22 |         requestPage = new RequestPage(page);
   23 |         requestPage.loadBusinessNames(conf.data.business_singular, conf.data.business_plural);
   24 |
   25 |         await loginPage.open();
   26 |         await loginPage.login(conf.data.username, conf.data.password);
>  27 |         await expect(loginPage.baseLoc.dashboardContainer).toBeVisible({ timeout: 15_000 });
      |                                                            ^ Error: Timed out 15000ms waiting for expect(locator).toBeVisible()
   28 |         await requestPage.open();
   29 |     });
   30 |
   31 |     test('REQ_005 - Verify feature sort', {
   32 |         tag: ['@REQ_005', '@request', '@feature']
   33 |     }, async () => {
   34 |         const displayNames = ['Request #', 'Client Name', 'Creator', 'Directed To'];
   35 |         const sortedFieldName = ['id', 'customer_name', 'from_contact_name', 'to_contact_name']
   36 |         const propertyNames = ['id', 'customer_name', 'from_business', 'to_business'];
   37 |         const directions = ['asc', 'asc', 'asc', 'asc'];
   38 |         for (let i = 0; i < displayNames.length; i++) {
   39 |             await expect(requestPage.dashboardLoc.table.headingColumn(displayNames[i])).toBeVisible();
   40 |             await requestPage.dashboardLoc.table.headingColumn(displayNames[i]).click();
   41 |             await expect(requestPage.page).toHaveURL(
   42 |                 new RegExp(`.*sort=${sortedFieldName[i]}&direction=${directions[i]}`)
   43 |             );
   44 |
   45 |             let apiDataUrl = `api/v1/requests?return_type=json&is_archived=false&sort=${sortedFieldName[i]}&direction=${directions[i]}`;
   46 |             const data = await requestPage.getDataInTable(displayNames[i], propertyNames[i], apiDataUrl);
   47 |             console.log(`Sort by: ${displayNames[i]}, direction: ${directions[i]}, property: ${propertyNames[i]}`)
   48 |             expect(data.dataApi).toEqual(data.dataUI);
   49 |         }
   50 |     });
   51 |
   52 |     test('REQ_006 - Verify feature filter', {
   53 |         tag: ['@REQ_006', '@request', '@feature']
   54 |     }, async ({ conf }) => {
   55 |         const filterFields = requestPage.requestProps.filterProperties;
   56 |         for (let i = 0; i < filterFields.length; i++) {
   57 |             // clear filter
   58 |             await requestPage.open();
   59 |             await requestPage.waitForSecond(3);
   60 |
   61 |             // prepare locator
   62 |             let fieldLocator;
   63 |             switch (filterFields[i].type) {
   64 |                 case 'input':
   65 |                     fieldLocator = requestPage.dashboardLoc.search.filter.popup.inputField(filterFields[i].name);
   66 |                     break;
   67 |                 default:
   68 |                     throw new Error(`Unsupported filter type: ${filterFields[i].type}`);
   69 |             }
   70 |
   71 |             // Fill invalid value
   72 |             await requestPage.dashboardLoc.search.filter.btn.click();
   73 |             await expect(requestPage.dashboardLoc.search.filter.popup.container).toBeVisible();
   74 |             await fieldLocator.fill(conf.data.filter_data[filterFields[i].name].invalid_data);
   75 |             await requestPage.dashboardLoc.search.filter.popup.btnApply.click();
   76 |             await expect(requestPage.dashboardLoc.table.noResult).toBeVisible();
   77 |
   78 |             // Fill valid value
   79 |             await requestPage.dashboardLoc.search.filter.btn.click();
   80 |             await expect(requestPage.dashboardLoc.search.filter.popup.container).toBeVisible();
   81 |             await fieldLocator.fill(conf.data.filter_data[filterFields[i].name].valid_data);
   82 |             await requestPage.dashboardLoc.search.filter.popup.btnApply.click();
   83 |             await expect(requestPage.dashboardLoc.table.noResult).not.toBeVisible();
   84 |         }
   85 |     });
   86 |
   87 |     test('REQ_007 - Verify feature Pin', {
   88 |         tag: ['@REQ_007', '@request', '@feature']
   89 |     }, async ({ conf }) => {
   90 |         await test.step('Search and verify icon Pin visible', async () => {
   91 |             //Search
   92 |             await requestPage.requestLoc.inputSearch.fill(conf.data.case_number);
   93 |             await expect(requestPage.requestLoc.tableHeadingColumn('Pin')).toBeVisible();
   94 |
   95 |             //verify icon Pin visible
   96 |             await expect(requestPage.requestLoc.pinIcon(conf.data.case_number)).toBeVisible()
   97 |         });
   98 |         await test.step('Verify Pin and unpin feature', async () => {
   99 |             //Click Pin icon and verify
  100 |             await requestPage.requestLoc.pinIcon(conf.data.case_number).click();
  101 |             await expect(requestPage.requestLoc.pinnedIcon(conf.data.case_number)).toBeVisible();
  102 |             await expect(requestPage.requestLoc.firstCaseNumber(conf.data.case_number)).toBeVisible();
  103 |
  104 |             // Click unpin
  105 |             await requestPage.requestLoc.pinnedIcon(conf.data.case_number).click()
  106 |             await expect(requestPage.requestLoc.pinIcon(conf.data.case_number)).toBeVisible();
  107 |
  108 |         });
  109 |     });
  110 |
  111 |     test('REQ_008 - Verify feature customized columns', {
  112 |         tag: ['@REQ_008', '@request', '@ui']
  113 |     }, async () => {
  114 |         const customThreeDotLocator = requestPage.genLoc("//div[contains(@class, 'card-header')]//span[contains(@class, 'cursor-pointer')]").nth(0);
  115 |         // Verify default columns displayed
  116 |         await test.step("Verify default columns displayed", async () => {
  117 |             const customizedColumns = requestPage.requestProps.customizedColumns;
  118 |             for (let i = 0; i < customizedColumns.length; i++) {
  119 |                 if (customizedColumns[i].default) {
  120 |                     await expect(requestPage.dashboardLoc.listing.heading.headingColumn(customizedColumns[i].tableDisplayName)).toBeVisible();
  121 |                 }
  122 |             }
  123 |         });
  124 |
  125 |         // Verify customized column show disable items and active items
  126 |         await test.step("Verify customized columns popup state", async () => {
  127 |             await requestPage.openThreedotMenu(requestPage.requestProps.threeDotDropdownMenus.customizedColumn, customThreeDotLocator);
```