# Test info

- Name: Function two factor tests >> PROFILE_007 - Verify màn two-factor function
- Location: /root/code/portal-automation-test/tests/profile/two-factor.spec.ts:67: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/two-factor.spec.ts:60:64
```

# Page snapshot

```yaml
- heading "Two-factor authentication" [level=2]
- paragraph: Enter the 6 digits from your authenticator app and press confirm.
- textbox
- textbox
- textbox
- text: "-"
- textbox
- textbox
- textbox
- link "Cancel":
  - /url: https://qa.loprx.com/logout
- button "Confirm":
  - img
  - text: Confirm
```

# 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 { takeScreenshot, verifyScreenshot } from '../../utils/screenshot';
   5 | import { authenticator } from 'otplib'
   6 | import * as fs from 'fs';
   7 |
   8 | test.describe('UI two factor tests', async () => {
   9 |     let loginPage: LoginPage;
   10 |     let profilePage: ProfilePage;
   11 |
   12 |     test.beforeEach(async ({ page, conf }) => {
   13 |         loginPage = new LoginPage(page);
   14 |         profilePage = new ProfilePage(page);
   15 |
   16 |         await loginPage.open();
   17 |         await loginPage.login(conf.data.username, conf.data.password);
   18 |         await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
   19 |     });
   20 |
   21 |     test('PROFILE_006 - Verify màn two-factor UI', {
   22 |         tag: ['@PROFILE_006', '@profile', '@ui']
   23 |     }, async ({ conf }) => {
   24 |         // 1. Click sang menu "Two-factor authentication"
   25 |         await test.step('Click sang menu "Two-factor authentication"', async () => {
   26 |             await profilePage.navigateToMenu("Profile");
   27 |             await profilePage.profileLoc.twoFactorMenu.click();
   28 |             await expect(profilePage.profileLoc.title).toContainText('Two-factor Authentication');
   29 |         });
   30 |
   31 |         await test.step('Verify màn two-factor UI khi chưa setup MFA', async () => {
   32 |             await verifyScreenshot('two-factor-not-setup.png', profilePage.profileLoc.mainContainer, [], 0.02);
   33 |         });
   34 |
   35 |         await test.step('Verify màn two-factor UI khi đang setup MFA', async () => {
   36 |             await profilePage.profileLoc.setup2FaButton.click();
   37 |             await expect(profilePage.page).toHaveURL(/.*\?tab=2fa&action=setup/);
   38 |             await verifyScreenshot('two-factor-setting-up.png', profilePage.profileLoc.mainContainer,
   39 |                 [
   40 |                     profilePage.profileLoc.twoFactorSetupQR,
   41 |                     profilePage.profileLoc.mfaSecretInput
   42 |                 ], 0.02
   43 |             );
   44 |
   45 |             await expect(profilePage.profileLoc.mfaSecretInput).not.toBeEmpty();
   46 |         });
   47 |     });
   48 | });
   49 |
   50 | test.describe('Function two factor tests', async () => {
   51 |     let loginPage: LoginPage;
   52 |     let profilePage: ProfilePage;
   53 |     test.beforeEach(async ({ page, conf }, testInfo) => {
   54 |         loginPage = new LoginPage(page);
   55 |         profilePage = new ProfilePage(page);
   56 |
   57 |         await loginPage.open();
   58 |         await loginPage.login(conf.data.username, conf.data.password);
   59 |         if (testInfo.title !== "Verify màn two-factor function") {
>  60 |             await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
      |                                                                ^ Error: Timed out 10000ms waiting for expect(locator).toBeVisible()
   61 |         }
   62 |         await profilePage.navigateToMenu("Profile");
   63 |         await profilePage.profileLoc.twoFactorMenu.click();
   64 |     });
   65 |
   66 |     //Skip tạm thời để check vs client
   67 |     test('PROFILE_007 - Verify màn two-factor function', {
   68 |         tag: ['@PROFILE_007', '@profile', '@function']
   69 |     }, async ({ conf }) => {
   70 |         // 1. Thực hiện điền authentication code
   71 |         // 2. Logout ra và login lại
   72 |         // 3. Điền code sai
   73 |         // 4. Điền code đúng
   74 |         let secret: string;
   75 |         await test.step('Thực hiện điền authentication code', async () => {
   76 |             await expect(profilePage.profileLoc.setup2FaButton).toBeVisible();
   77 |             await profilePage.profileLoc.setup2FaButton.click();
   78 |
   79 |             await expect(profilePage.profileLoc.mfaSecretInput).not.toBeEmpty();
   80 |             secret = await profilePage.profileLoc.mfaSecretInput.inputValue();
   81 |             console.log('Scret value: ');
   82 |             console.log(secret);
   83 |             const code = authenticator.generate(secret);
   84 |             // Write secret to file (append new line)
   85 |             fs.appendFileSync('two-factor-secret.txt', `${secret}\n`);
   86 |
   87 |             // Split code into 6 digits
   88 |             const digits = code.split('');
   89 |             for (let i = 0; i < 6; i++) {
   90 |                 await profilePage.profileLoc.digitInput(i).press(digits[i], {
   91 |                     delay: 200,
   92 |                 });
   93 |             }
   94 |             await profilePage.dashboardLoc.buttonByText("Submit").first().click();
   95 |             await profilePage.waitAllRequestCompeleted();
   96 |         });
   97 |
   98 |         await test.step('Logout ra và login lại', async () => {
   99 |             await profilePage.logout();
  100 |             await loginPage.open();
  101 |             await loginPage.login(conf.data.username, conf.data.password);
  102 |             await expect(loginPage.page).toHaveURL(/2fa-verification/)
  103 |             await expect(loginPage.loginLoc.twoFaLoginHeading).toBeVisible();
  104 |
  105 |             const code = authenticator.generate(secret);
  106 |             // Split code into 6 digits
  107 |             const digits = code.split('');
  108 |             for (let i = 0; i < 6; i++) {
  109 |                 await loginPage.loginLoc.digitInput(i+1).press(digits[i], {
  110 |                     delay: 200,
  111 |                 });
  112 |             }
  113 |             await loginPage.loginLoc.confirmButton.click();
  114 |             await profilePage.waitAllRequestCompeleted();
  115 |             await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
  116 |         });
  117 |
  118 |         await test.step('Remove 2FA code và login lại', async () => {
  119 |             await profilePage.openTwoFactorDisable();
  120 |             await expect(profilePage.page).toHaveURL(/.*\/profile\?tab=2fa/);
  121 |
  122 |             await profilePage.profileLoc.disable2FaButton.click();
  123 |
  124 |             const code = authenticator.generate(secret);
  125 |             // Split code into 6 digits
  126 |             const digits = code.split('');
  127 |             for (let i = 0; i < 6; i++) {
  128 |                 await profilePage.profileLoc.digitInput(i).press(digits[i], {
  129 |                     delay: 200,
  130 |                 });
  131 |             }
  132 |             await profilePage.dashboardLoc.buttonByText("Confirm").click();
  133 |             await profilePage.waitAllRequestCompeleted();
  134 |             await expect(profilePage.profileLoc.setup2FaButton).toBeVisible();
  135 |
  136 |             await profilePage.logout();
  137 |             await loginPage.open();
  138 |             await loginPage.login(conf.data.username, conf.data.password);
  139 |             await expect(loginPage.baseLoc.dashboardContainer).toBeVisible();
  140 |         });
  141 |     });
  142 | });
```