Code Lab

Ошибки валидации формы

ЛёгкаяЛокаторы7 мин

Перед тобой страница /items сайта lab.becomeqa.com с открытым окном Add Travel Item. Пользователь нажал Submit с пустыми полями, и форма показала красные ошибки валидации под полями Name и Cost.

Напиши локатор (CSS-селектор или XPath) для всех сообщений об ошибках на странице. Он должен работать и на других формах сайта, например в окне входа.

Источник

Локатор

Страница add-item-errors

<div id="root">
<div class="app" id="app">
<div class="min-h-screen bg-gray-100">
<header class="bg-blue-600 text-white p-4" id="main-header">
<nav class="container mx-auto flex justify-between items-center">
<div class="logo" data-test-id="logo">
<h1 class="text-2xl font-bold">QA Test Site</h1>
</div>
<div class="nav-links flex items-center space-x-4">
<a class="hover:underline nav-link" id="home-link" data-discover="true">Home</a>
<a class="hover:underline active-link" id="items-link" data-discover="true">Track your Travel</a>
<button class="bg-blue-500 hover:bg-blue-400 px-4 py-2 rounded transition-colors duration-200 login-button" id="login-btn" data-test-id="login-button">Login</button>
</div>
</nav>
</header>
<main class="container mx-auto p-6">
<div class="page-header" id="items-page-header" data-test-id="page-header">
<div class="header-content flex justify-end items-center mb-6">
<div class="action-buttons" data-test-id="action-buttons">
<button class="bg-green-500 text-white px-4 py-2 rounded mr-2 hover:bg-green-600 btn-create" id="create-item-btn">Add Travel Item</button>
<button class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 btn-download" id="download-btn" data-test-id="download-button">Export Data</button>
</div>
</div>
</div>
<div class="table-section bg-white rounded-lg shadow-lg p-6 mb-8 border-l-4 border-blue-500" id="countries-table-section">
<div class="flex justify-between items-center mb-6">
<h3 class="text-2xl font-bold text-gray-800">Travel Destinations</h3>
<div class="total-cost bg-green-100 px-4 py-2 rounded-lg border-2 border-green-300">
<span class="text-sm font-medium text-green-700">Total Cost: </span>
<span class="text-xl font-bold text-green-800" id="total-cost" data-test-id="total-cost">$0</span>
</div>
</div>
<div class="table-wrapper bg-white rounded-lg shadow">
<table class="w-full table" id="countries-table" data-test-id="countries-table">
<thead class="bg-blue-50 table-header">
<tr class="header-row">
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-blue-100 sortable-header select-none unsorted" id="header-destination" data-test-id="header-destination">
<div class="flex items-center">Destination</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-blue-100 sortable-header select-none unsorted" id="header-travel-type">
<div class="flex items-center">Travel Type</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-blue-100 sortable-header select-none unsorted" id="header-cost" data-test-id="header-cost">
<div class="flex items-center">Cost ($)</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-blue-100 sortable-header select-none unsorted" id="header-status" data-test-id="header-status">
<div class="flex items-center">Status</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-blue-100 sortable-header select-none unsorted" id="header-favorite">
<div class="flex items-center">Favorite</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider unsorted" id="header-actions">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200 table-body">
<tr>
<td colspan="6" class="px-6 py-8 text-center text-gray-500">No travel destinations added yet. Click "Add Travel Item" to get started!</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="separator-container my-8">
<div class="flex items-center">
<div class="flex-grow h-px bg-gradient-to-r from-transparent via-green-300 to-transparent"></div>
<div class="px-4 text-sm text-gray-500 font-medium bg-gray-100 rounded-full"></div>
<div class="flex-grow h-px bg-gradient-to-r from-transparent via-green-300 to-transparent"></div>
</div>
</div>
<div class="file-upload-section mb-8" id="file-upload-section" data-test-id="file-upload-section">
<div class="bg-gradient-to-r from-green-50 to-emerald-50 rounded-lg shadow-lg p-6 border-l-4 border-green-500">
<h3 class="text-2xl font-bold mb-4 text-center text-green-800">Upload Your Next Planned Trip</h3>
<p class="text-gray-700 text-center mb-6 text-sm font-medium">Upload a JSON file with your travel destinations to populate the table</p>
<div class="border-2 border-dashed rounded-lg p-8 text-center transition-all duration-300 border-green-300 hover:border-green-400 bg-white ">
<div class="mb-4">
<svg class="mx-auto h-16 w-16 text-green-400" stroke="currentColor" fill="none" viewBox="0 0 48 48">
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</div>
<div class="mb-4">
<p class="text-lg font-semibold text-gray-900 mb-2">Drop your JSON file here</p>
<p class="text-sm text-gray-600">or click to browse files</p>
</div>
<input id="file-upload" class="hidden" accept=".json" data-test-id="file-upload-input" type="file">
<label for="file-upload" class="inline-flex items-center px-6 py-3 border-2 border-green-500 text-base font-semibold rounded-lg text-green-700 bg-green-50 hover:bg-green-100 cursor-pointer transition-all duration-200 hover:shadow-md transform hover:scale-105">Choose File</label>
</div>
<div class="mt-4 text-center">
<p class="text-xs text-gray-600 font-medium">Accepted: JSON files (.json)</p>
<p class="text-xs text-gray-500 mt-1">Format: Array with destination, travelType, status, and isFavorite fields</p>
</div>
</div>
</div>
<div class="separator-container my-8">
<div class="flex items-center">
<div class="flex-grow h-px bg-gradient-to-r from-transparent via-purple-300 to-transparent"></div>
<div class="px-4 text-sm text-gray-500 font-medium bg-gray-100 rounded-full"></div>
<div class="flex-grow h-px bg-gradient-to-r from-transparent via-purple-300 to-transparent"></div>
</div>
</div>
<div class="payment-section-wrapper mb-8 flex justify-center" id="payment-section" data-test-id="payment-section">
<div class="bg-gradient-to-r from-purple-50 to-indigo-50 rounded-lg shadow-lg p-6 w-full max-w-2xl border-l-4 border-purple-500">
<h3 class="text-2xl font-bold mb-4 text-center text-purple-800">Next Trip Reservation</h3>
<p class="text-gray-700 text-center mb-6 text-sm font-medium">Book and pay for your next adventure with secure payment processing</p>
<div class="payment-iframe-container bg-white rounded-lg p-4 shadow-inner border border-purple-100"></div>
</div>
</div>
</main>
</div>
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 modal-overlay" id="modal-overlay">
<div class="bg-white rounded-lg p-6 w-96 max-w-lg modal-content" id="modal-content" data-test-id="modal-content">
<div class="modal-header mb-4">
<h3 class="text-xl font-bold modal-title" id="modal-title" data-test-id="modal-title">Add Travel Item</h3>
</div>
<div class="modal-body" data-test-id="modal-body">
<form class="space-y-4" id="item-form">
<div class="form-group">
<label class="block text-sm font-medium text-gray-700" for="item-name" data-test-id="name-label">Name <span class="text-red-500">*</span></label>
<input id="item-name" class="mt-1 block w-full border rounded-md px-3 py-2 border-red-500" placeholder="Enter destination name" type="text" value="">
<p id="name-error" data-test-id="name-error" class="mt-1 text-sm text-red-500 validation-error">Name is required</p>
</div>
<div class="form-group" data-test-id="category-group">
<label class="block text-sm font-medium text-gray-700" for="item-category">Category <span class="text-red-500">*</span></label>
<select id="item-category" class="mt-1 block w-full border rounded-md px-3 py-2 border-gray-300" data-test-id="category-dropdown">
<option value="Business" selected="">Business</option>
<option value="Leisure">Leisure</option>
<option value="Adventure">Adventure</option>
<option value="Cultural">Cultural</option>
</select>
</div>
<div class="form-group">
<label class="block text-sm font-medium text-gray-700" for="item-cost" data-test-id="cost-label">Cost ($) <span class="text-red-500">*</span></label>
<input id="item-cost" class="mt-1 block w-full border rounded-md px-3 py-2 border-red-500" placeholder="Enter cost" data-test-id="cost-input" type="number" value="">
<p id="cost-error" data-test-id="cost-error" class="mt-1 text-sm text-red-500 validation-error">Cost is required</p>
</div>
<div class="form-group">
<label class="block text-sm font-medium text-gray-700" for="item-status" data-test-id="status-label">Status</label>
<select id="item-status" class="mt-1 block w-full border rounded-md px-3 py-2 border-gray-300">
<option value="Planned" selected="">Planned</option>
<option value="Completed">Completed</option>
<option value="Cancelled">Cancelled</option>
</select>
</div>
<div class="form-group flex items-center" data-test-id="checkbox-group">
<input id="item-checked" class="h-4 w-4 mr-2" type="checkbox">
<label class="text-sm text-gray-700" for="item-checked">Favorite</label>
</div>
</form>
</div>
<div class="modal-footer flex justify-end space-x-2 mt-6">
<button type="button" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400" id="cancel-btn" data-test-id="cancel-button">Cancel</button>
<button type="submit" form="item-form" class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded" id="submit-btn">Submit</button>
</div>
</div>
</div>
</div>
</div>

Скрытые тесты запускаются по Submit.