Files
tfm_ainventory/frontend/playwright-report/data/25c086a4cde2673fed46f9d88609959f3059fc36.md

7.4 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 reject empty login credentials
  • Location: e2e/workflows/1-login.spec.ts:32:7

Error details

Test timeout of 30000ms exceeded.
Error: locator.click: Test timeout of 30000ms exceeded.
Call log:
  - waiting for locator('[data-testid="login-submit"]')

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

  1   | import { test, expect } from '@playwright/test';
  2   | import * as auth from '../fixtures/auth';
  3   | import * as assertions from '../utils/assertions';
  4   | import { LDAP_USERS, LOCAL_USERS } from '../fixtures/test-data';
  5   | 
  6   | test.describe('Login Workflow', () => {
  7   |   const BASE_URL = process.env.BASE_URL || 'http://localhost:8917';
  8   | 
  9   |   test.beforeEach(async ({ page }) => {
  10  |     // Navigate to login page
  11  |     await page.goto(BASE_URL);
  12  |     // Wait for identity check overlay
  13  |     await page.waitForSelector('[data-testid="identity-check-overlay"]', { timeout: 10000 });
  14  |   });
  15  | 
  16  |   test('should display identity check overlay on app load', async ({ page }) => {
  17  |     const overlay = page.locator('[data-testid="identity-check-overlay"]');
  18  |     await expect(overlay).toBeVisible();
  19  | 
  20  |     // Verify tabs are available
  21  |     const ldapTab = page.locator('[data-testid="ldap-login-tab"]');
  22  |     const localTab = page.locator('[data-testid="local-login-tab"]');
  23  | 
  24  |     await expect(ldapTab).toBeVisible();
  25  |     await expect(localTab).toBeVisible();
  26  |   });
  27  | 
  28  |   test('should display login form with username and password fields', async ({ page }) => {
  29  |     await assertions.assertLoginFormVisible(page);
  30  |   });
  31  | 
  32  |   test('should reject empty login credentials', async ({ page }) => {
  33  |     const submitButton = page.locator('[data-testid="login-submit"]');
> 34  |     await submitButton.click();
      |                        ^ Error: locator.click: Test timeout of 30000ms exceeded.
  35  | 
  36  |     // Should show validation error
  37  |     const errorMessage = page.locator('[data-testid="toast-error"]');
  38  |     await expect(errorMessage).toBeVisible({ timeout: 3000 });
  39  |   });
  40  | 
  41  |   test('should reject invalid LDAP credentials', async ({ page }) => {
  42  |     await auth.loginWithLdap(page, LDAP_USERS.invalid, BASE_URL);
  43  | 
  44  |     // Should show error message
  45  |     const errorToast = page.locator('[data-testid="toast-error"]');
  46  |     await expect(errorToast).toBeVisible({ timeout: 5000 });
  47  | 
  48  |     // Should still be on login page
  49  |     await expect(page).toHaveURL(BASE_URL);
  50  |   });
  51  | 
  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();