# 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: 2-scan-adjust.spec.ts >> Scan and Adjust Workflow >> should display scanner interface with camera view - Location: e2e/workflows/2-scan-adjust.spec.ts:21:7 # Error details ``` Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:3000/ Call log: - navigating to "http://localhost:3000/", waiting until "load" ``` # Test source ```ts 1 | import { test, expect } from '@playwright/test'; 2 | import * as auth from '../fixtures/auth'; 3 | import * as assertions from '../utils/assertions'; 4 | import * as helpers from '../utils/helpers'; 5 | import { LOCAL_USERS, TEST_ITEMS } from '../fixtures/test-data'; 6 | 7 | test.describe('Scan and Adjust Workflow', () => { 8 | const BASE_URL = process.env.BASE_URL || 'http://localhost:3000'; 9 | 10 | test.beforeEach(async ({ page }) => { 11 | // Navigate to app and login > 12 | await page.goto(BASE_URL); | ^ Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:3000/ 13 | await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL); 14 | await assertions.assertUserAuthenticated(page, BASE_URL); 15 | 16 | // Navigate to scanner page 17 | await page.goto(`${BASE_URL}/scanner`); 18 | await assertions.assertScannerReady(page); 19 | }); 20 | 21 | test('should display scanner interface with camera view', async ({ page }) => { 22 | await assertions.assertScannerReady(page); 23 | 24 | // Verify camera controls 25 | const zoomButton = page.locator('[data-testid="zoom-control"]'); 26 | const cameraIndicator = page.locator('[data-testid="camera-indicator"]'); 27 | 28 | await expect(zoomButton).toBeVisible(); 29 | await expect(cameraIndicator).toBeVisible(); 30 | }); 31 | 32 | test('should display scan input field', async ({ page }) => { 33 | const scanInput = page.locator('[data-testid="scan-input"]'); 34 | await expect(scanInput).toBeVisible(); 35 | await expect(scanInput).toBeFocused(); 36 | }); 37 | 38 | test('should handle barcode scan and match to inventory item', async ({ page }) => { 39 | // Simulate barcode scan by entering barcode in input 40 | const scanInput = page.locator('[data-testid="scan-input"]'); 41 | 42 | // Enter first test item's barcode 43 | await scanInput.fill(TEST_ITEMS[0].barcode); 44 | await scanInput.press('Enter'); 45 | 46 | // Should show stock adjustment form 47 | await assertions.assertStockAdjustmentVisible(page, TEST_ITEMS[0].name); 48 | 49 | // Verify item details are shown 50 | const itemName = page.locator('[data-testid="adjustment-item-name"]'); 51 | await expect(itemName).toContainText(TEST_ITEMS[0].name); 52 | }); 53 | 54 | test('should default to check-in operation', async ({ page }) => { 55 | const scanInput = page.locator('[data-testid="scan-input"]'); 56 | await scanInput.fill(TEST_ITEMS[0].barcode); 57 | await scanInput.press('Enter'); 58 | 59 | // Check-in radio should be selected 60 | const checkInRadio = page.locator('[data-testid="operation-checkin"]'); 61 | await expect(checkInRadio).toBeChecked(); 62 | }); 63 | 64 | test('should allow switching between check-in and check-out', async ({ page }) => { 65 | const scanInput = page.locator('[data-testid="scan-input"]'); 66 | await scanInput.fill(TEST_ITEMS[0].barcode); 67 | await scanInput.press('Enter'); 68 | 69 | // Switch to check-out 70 | const checkOutRadio = page.locator('[data-testid="operation-checkout"]'); 71 | await checkOutRadio.click(); 72 | await expect(checkOutRadio).toBeChecked(); 73 | 74 | // Switch back to check-in 75 | const checkInRadio = page.locator('[data-testid="operation-checkin"]'); 76 | await checkInRadio.click(); 77 | await expect(checkInRadio).toBeChecked(); 78 | }); 79 | 80 | test('should allow quantity adjustment', async ({ page }) => { 81 | const scanInput = page.locator('[data-testid="scan-input"]'); 82 | await scanInput.fill(TEST_ITEMS[0].barcode); 83 | await scanInput.press('Enter'); 84 | 85 | // Change quantity 86 | const quantityInput = page.locator('[data-testid="adjustment-quantity-input"]'); 87 | await quantityInput.fill('10'); 88 | 89 | // Verify value changed 90 | const value = await helpers.getInputValue(page, '[data-testid="adjustment-quantity-input"]'); 91 | expect(value).toBe('10'); 92 | }); 93 | 94 | test('should reject invalid quantities', async ({ page }) => { 95 | const scanInput = page.locator('[data-testid="scan-input"]'); 96 | await scanInput.fill(TEST_ITEMS[0].barcode); 97 | await scanInput.press('Enter'); 98 | 99 | // Try invalid quantity 100 | const quantityInput = page.locator('[data-testid="adjustment-quantity-input"]'); 101 | await quantityInput.fill('-5'); 102 | 103 | // Submit should be disabled or show error 104 | const submitButton = page.locator('[data-testid="adjustment-submit"]'); 105 | if (await submitButton.isEnabled()) { 106 | await submitButton.click(); 107 | const errorToast = page.locator('[data-testid="toast-error"]'); 108 | await expect(errorToast).toBeVisible({ timeout: 3000 }); 109 | } 110 | }); 111 | 112 | test('should submit stock adjustment successfully', async ({ page }) => { ```