Files

9.2 KiB

Instructions

  • Following Playwright test failed.
  • Explain why, be concise, respect Playwright best practices.
  • Provide a snippet of code with the fix, if possible.

Test info

  • Name: 1-login.spec.ts >> Login Workflow >> should allow switching between LDAP and local login tabs
  • Location: e2e/workflows/1-login.spec.ts:146:7

Error details

Error: expect(locator).toBeVisible() failed

Locator: locator('[data-testid="ldap-login-form"]')
Expected: visible
Timeout: 5000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" with timeout 5000ms
  - waiting for locator('[data-testid="ldap-login-form"]')

Page snapshot

- generic [active] [ref=e1]:
  - generic [ref=e3]:
    - generic [ref=e4]:
      - img [ref=e6]
      - heading "Identity Check" [level=2] [ref=e9]
      - paragraph [ref=e10]: Select operator profile or use direct login
    - generic [ref=e11]:
      - button "newuser user" [ref=e12] [cursor=pointer]:
        - generic [ref=e13]:
          - img [ref=e15]
          - generic [ref=e18]:
            - paragraph [ref=e19]: newuser
            - paragraph [ref=e20]: user
        - img [ref=e21]
      - generic [ref=e23]:
        - button "Enterprise" [ref=e24] [cursor=pointer]:
          - img [ref=e25]
          - text: Enterprise
        - button "Manual Login" [ref=e28] [cursor=pointer]:
          - img [ref=e29]
          - text: Manual Login
  - button "Open Next.js Dev Tools" [ref=e37] [cursor=pointer]:
    - img [ref=e38]
  - alert [ref=e41]

Test source

  52  |   test('should successfully login with valid LDAP credentials', async ({ page }) => {
  53  |     // Skip if LDAP is not configured in test environment
  54  |     test.skip(process.env.SKIP_LDAP === 'true', 'LDAP not available in test environment');
  55  | 
  56  |     await auth.loginWithLdap(page, LDAP_USERS.valid, BASE_URL);
  57  | 
  58  |     // Verify we're authenticated
  59  |     await assertions.assertUserAuthenticated(page, BASE_URL);
  60  | 
  61  |     // Verify token is stored
  62  |     const token = await auth.getAuthToken(page);
  63  |     expect(token).toBeTruthy();
  64  |   });
  65  | 
  66  |   test('should reject invalid local user credentials', async ({ page }) => {
  67  |     // Switch to local user tab
  68  |     const localTab = page.locator('[data-testid="local-login-tab"]');
  69  |     await localTab.click();
  70  | 
  71  |     // Try to login with invalid credentials
  72  |     await page.fill('[data-testid="local-username-input"]', 'invalid_user');
  73  |     await page.fill('[data-testid="local-password-input"]', 'wrong_password');
  74  |     await page.click('[data-testid="local-login-submit"]');
  75  | 
  76  |     // Should show error
  77  |     const errorToast = page.locator('[data-testid="toast-error"]');
  78  |     await expect(errorToast).toBeVisible({ timeout: 5000 });
  79  |   });
  80  | 
  81  |   test('should successfully login with valid local user credentials', async ({ page }) => {
  82  |     // Switch to local user tab
  83  |     const localTab = page.locator('[data-testid="local-login-tab"]');
  84  |     await localTab.click();
  85  | 
  86  |     // Login with valid credentials
  87  |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  88  | 
  89  |     // Verify authenticated
  90  |     await assertions.assertUserAuthenticated(page, BASE_URL);
  91  |   });
  92  | 
  93  |   test('should show user identity after successful login', async ({ page }) => {
  94  |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  95  | 
  96  |     // Check that user info is displayed
  97  |     const userDisplay = page.locator('[data-testid="user-display"]');
  98  |     await expect(userDisplay).toBeVisible();
  99  | 
  100 |     // Verify username is shown
  101 |     const username = await userDisplay.textContent();
  102 |     expect(username).toContain(LOCAL_USERS.admin.username);
  103 |   });
  104 | 
  105 |   test('should maintain session across page reloads', async ({ page }) => {
  106 |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  107 |     await assertions.assertUserAuthenticated(page, BASE_URL);
  108 | 
  109 |     // Reload page
  110 |     await page.reload();
  111 | 
  112 |     // Should still be authenticated
  113 |     const token = await auth.getAuthToken(page);
  114 |     expect(token).toBeTruthy();
  115 | 
  116 |     // Should not be on login page
  117 |     await expect(page).not.toHaveURL(BASE_URL);
  118 |   });
  119 | 
  120 |   test('should support logout functionality', async ({ page }) => {
  121 |     // Login first
  122 |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  123 |     await assertions.assertUserAuthenticated(page, BASE_URL);
  124 | 
  125 |     // Logout
  126 |     await auth.logout(page, BASE_URL);
  127 | 
  128 |     // Should be back on login page
  129 |     const identityOverlay = page.locator('[data-testid="identity-check-overlay"]');
  130 |     await expect(identityOverlay).toBeVisible({ timeout: 5000 });
  131 | 
  132 |     // Token should be cleared
  133 |     const token = await auth.getAuthToken(page);
  134 |     expect(token).toBeFalsy();
  135 |   });
  136 | 
  137 |   test('should show admin button for admin users', async ({ page }) => {
  138 |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  139 |     await assertions.assertUserAuthenticated(page, BASE_URL);
  140 | 
  141 |     // Admin button should be visible
  142 |     const adminButton = page.locator('[data-testid="admin-button"]');
  143 |     await expect(adminButton).toBeVisible();
  144 |   });
  145 | 
  146 |   test('should allow switching between LDAP and local login tabs', async ({ page }) => {
  147 |     const ldapTab = page.locator('[data-testid="ldap-login-tab"]');
  148 |     const localTab = page.locator('[data-testid="local-login-tab"]');
  149 | 
  150 |     // Start on LDAP tab
  151 |     let ldapForm = page.locator('[data-testid="ldap-login-form"]');
> 152 |     await expect(ldapForm).toBeVisible();
      |                            ^ Error: expect(locator).toBeVisible() failed
  153 | 
  154 |     // Switch to local
  155 |     await localTab.click();
  156 |     ldapForm = page.locator('[data-testid="ldap-login-form"]');
  157 |     await expect(ldapForm).not.toBeVisible();
  158 | 
  159 |     // Switch back to LDAP
  160 |     await ldapTab.click();
  161 |     ldapForm = page.locator('[data-testid="ldap-login-form"]');
  162 |     await expect(ldapForm).toBeVisible();
  163 |   });
  164 | 
  165 |   test('should remember login preference on revisit', async ({ page, context }) => {
  166 |     // Login with local user
  167 |     await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL);
  168 | 
  169 |     // Close and reopen browser
  170 |     await page.close();
  171 |     const newPage = await context.newPage();
  172 |     await newPage.goto(BASE_URL);
  173 | 
  174 |     // Should still be authenticated
  175 |     const authenticated = await auth.isAuthenticated(newPage);
  176 |     expect(authenticated).toBe(true);
  177 | 
  178 |     await newPage.close();
  179 |   });
  180 | 
  181 |   test('should handle network errors gracefully', async ({ page }) => {
  182 |     // Enable offline mode
  183 |     await page.context().setOffline(true);
  184 | 
  185 |     // Try to login
  186 |     const usernameInput = page.locator('[data-testid="username-input"]');
  187 |     const passwordInput = page.locator('[data-testid="password-input"]');
  188 |     const submitButton = page.locator('[data-testid="login-submit"]');
  189 | 
  190 |     await usernameInput.fill(LOCAL_USERS.admin.username);
  191 |     await passwordInput.fill(LOCAL_USERS.admin.password);
  192 |     await submitButton.click();
  193 | 
  194 |     // Should show network error
  195 |     const errorToast = page.locator('[data-testid="toast-error"]');
  196 |     await expect(errorToast).toBeVisible({ timeout: 5000 });
  197 | 
  198 |     // Re-enable network
  199 |     await page.context().setOffline(false);
  200 |   });
  201 | 
  202 |   test('should display user list in local login tab', async ({ page }) => {
  203 |     const localTab = page.locator('[data-testid="local-login-tab"]');
  204 |     await localTab.click();
  205 | 
  206 |     // User list should be visible
  207 |     const userList = page.locator('[data-testid="user-list"]');
  208 |     await expect(userList).toBeVisible();
  209 | 
  210 |     // Should have at least one user
  211 |     const userItems = page.locator('[data-testid="user-list-item"]');
  212 |     expect(await userItems.count()).toBeGreaterThan(0);
  213 |   });
  214 | 
  215 |   test('should auto-login when clicking user from list', async ({ page }) => {
  216 |     const localTab = page.locator('[data-testid="local-login-tab"]');
  217 |     await localTab.click();
  218 | 
  219 |     // Click first user in list
  220 |     const firstUser = page.locator('[data-testid="user-list-item"]').first();
  221 |     await firstUser.click();
  222 | 
  223 |     // Password input should be focused
  224 |     const passwordInput = page.locator('[data-testid="local-password-input"]');
  225 |     await expect(passwordInput).toBeFocused();
  226 |   });
  227 | });
  228 |