# Test info

- Name: Function profile tests >> PROFILE_003 - Verify màn my profile function
- Location: /root/code/portal-automation-test/tests/profile/profile.spec.ts:99:9

# Error details

```
Error: Timed out 10000ms 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 10000ms
  - waiting for locator('//div[@id=\'root\' and @class=\'dashboard-index\']')

    at /root/code/portal-automation-test/tests/profile/profile.spec.ts:57: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 { LoginPage } from '../../pom/login.page';
   3 | import { ProfilePage } from '../../pom/profile/profile.page';
   4 | import { prepareFile, getFileDownloadedPathFromUrl } from '../../utils/file';
   5 | import { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';
   6 |
   7 | test.describe('UI profile tests', async () => {
   8 |     let loginPage: LoginPage;
   9 |     let profilePage: ProfilePage;
   10 |
   11 |     test.beforeEach(async ({ page, conf }) => {
   12 |         loginPage = new LoginPage(page);
   13 |         profilePage = new ProfilePage(page);
   14 |
   15 |         await loginPage.open();
   16 |         await loginPage.login(conf.data.username, conf.data.password);
   17 |         await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
   18 |     });
   19 |
   20 |     test('PROFILE_001 - Verify màn my profile UI', {
   21 |         tag: ['@PROFILE_001', '@profile', '@ui']
   22 |     }, async ({ conf }) => {
   23 |         await test.step('Click menu profile, verify các field', async () => {
   24 |             const avatarPromise = profilePage.page.waitForResponse(RegExp(`${profilePage.baseUrl}storage/images/avatar.*`));
   25 |             await profilePage.navigateToMenu('Profile');
   26 |             await expect(profilePage.profileLoc.title).toBeVisible();
   27 |
   28 |             // Wait avatar loaded
   29 |             await avatarPromise;
   30 |
   31 |             // Verify screenshot
   32 |             await verifyScreenshot('profile.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail], 0.02);
   33 |             await expect(profilePage.profileLoc.inputEmail).toBeDisabled();
   34 |             await expect(profilePage.profileLoc.inputEmail).toHaveValue(conf.data.username);
   35 |         });
   36 |
   37 |         await test.step('Xoá first name và last name, bấm save', async () => {
   38 |             await profilePage.profileLoc.firstNameInput.clear();
   39 |             await profilePage.profileLoc.lastNameInput.clear();
   40 |             await profilePage.waitForSecond(2);
   41 |             await profilePage.dashboardLoc.buttonByText("Update").click();
   42 |             await verifyScreenshot('validation.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail], 0.02);
   43 |         });
   44 |     });
   45 | });
   46 |
   47 | test.describe('Function profile tests', async () => {
   48 |     let loginPage: LoginPage;
   49 |     let profilePage: ProfilePage;
   50 |
   51 |     test.beforeEach(async ({ page, conf }) => {
   52 |         loginPage = new LoginPage(page);
   53 |         profilePage = new ProfilePage(page);
   54 |
   55 |         await loginPage.open();
   56 |         await loginPage.login(conf.data.username, conf.data.password);
>  57 |         await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
      |                                                            ^ Error: Timed out 10000ms waiting for expect(locator).toBeVisible()
   58 |
   59 |         await profilePage.open();
   60 |     });
   61 |
   62 |     test('PROFILE_002 - Verify upload avatar', {
   63 |         tag: ['@PROFILE_002', '@profile', '@ui']
   64 |     }, async ({ conf }) => {
   65 |         await prepareFile(conf.data.avatar)
   66 |         await prepareFile(conf.data.wrong_file)
   67 |         await prepareFile(conf.data.big_file)
   68 |
   69 |         await test.step('Upload with wrong file type', async () => {
   70 |             await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.wrong_file)]);
   71 |             await expect(profilePage.profileLoc.avatarErrorMessage).toBeVisible();
   72 |             await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('Only image files are allowed (jpg, jpeg, png).');
   73 |             // await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('The avatar field must be a file of type: jpeg, png, jpg, webp.');
   74 |         });
   75 |
   76 |         await test.step('Upload with big file', async () => {
   77 |             await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.big_file)]);
   78 |             await expect(profilePage.profileLoc.avatarErrorMessage).toBeVisible();
   79 |             await expect(profilePage.profileLoc.avatarErrorMessage).toContainText('Maximum file size allowed is 5MB. "big-file.png" is too large.', {
   80 |                 timeout: 30_000,
   81 |             });
   82 |         });
   83 |
   84 |         await test.step('Upload with correct file', async () => {
   85 |             // const avatarPromise = profilePage.page.waitForResponse(
   86 |             //     response => response.url().includes('storage/images/avatar') && response.status() === 200,
   87 |             //     { timeout: 30_000 }
   88 |             // );
   89 |
   90 |             await profilePage.profileLoc.inputAvatar.setInputFiles([getFileDownloadedPathFromUrl(conf.data.avatar)]);
   91 |
   92 |             // await avatarPromise;
   93 |             await profilePage.waitForSecond(1);
   94 |
   95 |             await verifyScreenshot('avatar.png', profilePage.profileLoc.userProfileAvatar);
   96 |         });
   97 |     });
   98 |
   99 |     test('PROFILE_003 - Verify màn my profile function', {
  100 |         tag: ['@PROFILE_003', '@profile', '@function']
  101 |     }, async ({ conf }) => {
  102 |         test.slow();
  103 |
  104 |         await test.step('Bấm save, save thành công', async () => {
  105 |             await profilePage.waitForSecond(2); // TODO: page need stable. fix me later
  106 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  107 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  108 |             await profilePage.profileLoc.btnCloseNotification.click();
  109 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  110 |         });
  111 |
  112 |         await test.step('Fill lần lượt các field, verify lưu thành công', async () => {
  113 |             // // Phone number
  114 |             await profilePage.profileLoc.inputPhone.fill(conf.data.phone);
  115 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  116 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  117 |             await profilePage.profileLoc.btnCloseNotification.click();
  118 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  119 |
  120 |             // // Address
  121 |             await profilePage.profileLoc.inputAddress.fill(conf.data.address);
  122 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  123 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  124 |             await profilePage.profileLoc.btnCloseNotification.click();
  125 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  126 |
  127 |             // // Suite
  128 |             await profilePage.profileLoc.inputSuite.fill(conf.data.suite);
  129 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  130 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  131 |             await profilePage.profileLoc.btnCloseNotification.click();
  132 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  133 |
  134 |             // // City
  135 |             await profilePage.profileLoc.inputCity.fill(conf.data.city);
  136 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  137 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  138 |             await profilePage.profileLoc.btnCloseNotification.click();
  139 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  140 |
  141 |             // State
  142 |             await profilePage.dashboardLoc.modal.inputByID("autocomplete_state_code").fill(conf.data.state);
  143 |             await expect(profilePage.profileLoc.optionStateByName(conf.data.state)).toBeVisible();
  144 |             await profilePage.profileLoc.optionStateByName(conf.data.state).click();
  145 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  146 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  147 |             await profilePage.profileLoc.btnCloseNotification.click();
  148 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  149 |
  150 |             // Zip/postal code
  151 |             await profilePage.profileLoc.inputZip.fill(conf.data.zip);
  152 |             await profilePage.dashboardLoc.buttonByText("Update").click();
  153 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeVisible();
  154 |             await profilePage.profileLoc.btnCloseNotification.click();
  155 |             await expect(profilePage.profileLoc.profileUpdateSuccessNotification).toBeHidden();
  156 |
  157 |             await verifyScreenshot('profile_updated.png', profilePage.profileLoc.mainContainer, [profilePage.profileLoc.inputEmail], 0.02)
```