616 lines
28 KiB
HTML
616 lines
28 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Fuel Stop Form - Functionality Test</title>
|
||
<link
|
||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||
rel="stylesheet"
|
||
/>
|
||
<style>
|
||
.test-container {
|
||
max-width: 800px;
|
||
margin: 2rem auto;
|
||
padding: 2rem;
|
||
}
|
||
.test-status {
|
||
margin-bottom: 2rem;
|
||
}
|
||
.success {
|
||
color: #28a745;
|
||
font-weight: bold;
|
||
}
|
||
.error {
|
||
color: #dc3545;
|
||
font-weight: bold;
|
||
}
|
||
.test-case {
|
||
border: 1px solid #dee2e6;
|
||
border-radius: 0.25rem;
|
||
padding: 1rem;
|
||
margin-bottom: 1rem;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="test-container">
|
||
<h1>Fuel Stop Form - Functionality Test</h1>
|
||
|
||
<div class="test-status">
|
||
<h3>Test Results:</h3>
|
||
<div id="test-results"></div>
|
||
</div>
|
||
|
||
<div class="test-case">
|
||
<h4>Test Case 1: Currency Change Updates Price Display</h4>
|
||
<p>
|
||
When you change the currency dropdown, the price currency
|
||
symbols should update automatically.
|
||
</p>
|
||
|
||
<form class="card">
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4">
|
||
<label class="form-label"
|
||
>Price per Liter</label
|
||
>
|
||
<div class="input-group">
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="price_per_liter"
|
||
value="1.450"
|
||
step="0.001"
|
||
min="0"
|
||
/>
|
||
<span
|
||
class="input-group-text"
|
||
id="price-currency"
|
||
>EUR</span
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Total Cost</label>
|
||
<div class="input-group">
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="total_cost"
|
||
value="50.00"
|
||
step="0.01"
|
||
min="0"
|
||
/>
|
||
<span
|
||
class="input-group-text"
|
||
id="total-currency"
|
||
>EUR</span
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Currency</label>
|
||
<select class="form-select" name="currency">
|
||
<option value="EUR" selected>
|
||
€ EUR - Euro
|
||
</option>
|
||
<option value="USD">
|
||
$ USD - US Dollar
|
||
</option>
|
||
<option value="GBP">
|
||
£ GBP - British Pound
|
||
</option>
|
||
<option value="CHF">
|
||
₣ CHF - Swiss Franc
|
||
</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="test-case">
|
||
<h4>Test Case 2: Vehicle Selection Updates Fuel Type</h4>
|
||
<p>
|
||
When you select a vehicle, the fuel type should
|
||
automatically change to match the vehicle's fuel type.
|
||
</p>
|
||
|
||
<form class="card">
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<label class="form-label">Vehicle</label>
|
||
<select class="form-select" name="vehicle_id">
|
||
<option value="">Select vehicle...</option>
|
||
<option value="1" data-fuel-type="Super E5">
|
||
BMW 320i (ABC-123)
|
||
</option>
|
||
<option value="2" data-fuel-type="Diesel">
|
||
Volkswagen Golf TDI (DEF-456)
|
||
</option>
|
||
<option
|
||
value="3"
|
||
data-fuel-type="Super E10"
|
||
>
|
||
Honda Civic (GHI-789)
|
||
</option>
|
||
<option value="4" data-fuel-type="Electric">
|
||
Tesla Model 3 (JKL-012)
|
||
</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label">Fuel Type</label>
|
||
<select class="form-select" name="fuel_type">
|
||
<option value="">
|
||
Select fuel type...
|
||
</option>
|
||
<option value="Super E5">Super E5</option>
|
||
<option value="Super E10">Super E10</option>
|
||
<option value="Super Plus">
|
||
Super Plus
|
||
</option>
|
||
<option value="Diesel">Diesel</option>
|
||
<option value="Premium Diesel">
|
||
Premium Diesel
|
||
</option>
|
||
<option value="LPG">LPG</option>
|
||
<option value="CNG">CNG</option>
|
||
<option value="Electric">Electric</option>
|
||
<option value="Hybrid">
|
||
Hybrid (Mixed)
|
||
</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="test-case">
|
||
<h4>Test Case 3: Auto-calculation</h4>
|
||
<p>
|
||
When you change the amount or price per liter, the total
|
||
cost should be calculated automatically.
|
||
</p>
|
||
|
||
<form class="card">
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-4">
|
||
<label class="form-label"
|
||
>Amount (Liters)</label
|
||
>
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="amount"
|
||
value="35.00"
|
||
step="0.01"
|
||
min="0"
|
||
/>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label"
|
||
>Price per Liter</label
|
||
>
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="price_per_liter_calc"
|
||
value="1.450"
|
||
step="0.001"
|
||
min="0"
|
||
/>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">Total Cost</label>
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="total_cost_calc"
|
||
value="50.75"
|
||
step="0.01"
|
||
min="0"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="test-case">
|
||
<h4>Test Case 4: Fuel Station Search</h4>
|
||
<p>
|
||
Click "Find Nearby" to search for fuel stations near your
|
||
location using GPS and OpenStreetMap data.
|
||
</p>
|
||
|
||
<form class="card">
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<label class="form-label">Station Name</label>
|
||
<div class="input-group">
|
||
<input
|
||
type="text"
|
||
class="form-control"
|
||
name="station_name_search"
|
||
placeholder="Enter station name"
|
||
/>
|
||
<button
|
||
class="btn btn-outline-secondary"
|
||
type="button"
|
||
onclick="testFindNearbyStations()"
|
||
>
|
||
<svg
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
width="24"
|
||
height="24"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<circle
|
||
cx="11"
|
||
cy="11"
|
||
r="8"
|
||
></circle>
|
||
<path d="m21 21-4.35-4.35"></path>
|
||
</svg>
|
||
Find Nearby
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label">Location</label>
|
||
<input
|
||
type="text"
|
||
class="form-control"
|
||
name="location_search"
|
||
placeholder="Enter location"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
<!-- Test Modal -->
|
||
<div
|
||
class="modal fade"
|
||
id="testStationSearchModal"
|
||
tabindex="-1"
|
||
aria-labelledby="testStationSearchModalLabel"
|
||
aria-hidden="true"
|
||
>
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5
|
||
class="modal-title"
|
||
id="testStationSearchModalLabel"
|
||
>
|
||
Nearby Fuel Stations (Test)
|
||
</h5>
|
||
<button
|
||
type="button"
|
||
class="btn-close"
|
||
data-bs-dismiss="modal"
|
||
aria-label="Close"
|
||
></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div id="testStationSearchResults">
|
||
<div class="text-center">
|
||
<div
|
||
class="spinner-border"
|
||
role="status"
|
||
>
|
||
<span class="visually-hidden"
|
||
>Searching...</span
|
||
>
|
||
</div>
|
||
<p class="mt-2">
|
||
Finding nearby fuel stations...
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Test results tracking
|
||
const testResults = [];
|
||
|
||
function addTestResult(testName, passed, details) {
|
||
testResults.push({ name: testName, passed, details });
|
||
updateTestDisplay();
|
||
}
|
||
|
||
function updateTestDisplay() {
|
||
const resultsDiv = document.getElementById("test-results");
|
||
resultsDiv.innerHTML = testResults
|
||
.map(
|
||
(result) =>
|
||
`<div class="${result.passed ? "success" : "error"}">
|
||
${result.passed ? "✓" : "✗"} ${result.name}: ${result.details}
|
||
</div>`,
|
||
)
|
||
.join("");
|
||
}
|
||
|
||
// Test Case 1: Currency Change Updates Price Display
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
const currencySelect = document.querySelector(
|
||
'select[name="currency"]',
|
||
);
|
||
const priceCurrency = document.getElementById("price-currency");
|
||
const totalCurrency = document.getElementById("total-currency");
|
||
|
||
if (currencySelect && priceCurrency && totalCurrency) {
|
||
const initialCurrency = currencySelect.value;
|
||
addTestResult(
|
||
"Currency Display Setup",
|
||
priceCurrency.textContent === initialCurrency &&
|
||
totalCurrency.textContent === initialCurrency,
|
||
`Initial currency display: ${priceCurrency.textContent}, ${totalCurrency.textContent}`,
|
||
);
|
||
|
||
currencySelect.addEventListener("change", function () {
|
||
const selectedCurrency = this.value;
|
||
const oldPriceCurrency = priceCurrency.textContent;
|
||
const oldTotalCurrency = totalCurrency.textContent;
|
||
|
||
priceCurrency.textContent = selectedCurrency;
|
||
totalCurrency.textContent = selectedCurrency;
|
||
|
||
const success =
|
||
priceCurrency.textContent === selectedCurrency &&
|
||
totalCurrency.textContent === selectedCurrency;
|
||
|
||
addTestResult(
|
||
"Currency Change",
|
||
success,
|
||
`Changed from ${oldPriceCurrency} to ${selectedCurrency}`,
|
||
);
|
||
});
|
||
}
|
||
|
||
// Test Case 2: Vehicle Selection Updates Fuel Type
|
||
const vehicleSelect = document.querySelector(
|
||
'select[name="vehicle_id"]',
|
||
);
|
||
const fuelTypeSelect = document.querySelector(
|
||
'select[name="fuel_type"]',
|
||
);
|
||
|
||
if (vehicleSelect && fuelTypeSelect) {
|
||
vehicleSelect.addEventListener("change", function () {
|
||
const selectedOption = this.options[this.selectedIndex];
|
||
const expectedFuelType =
|
||
selectedOption.getAttribute("data-fuel-type");
|
||
const vehicleName = selectedOption.textContent;
|
||
|
||
if (this.value && expectedFuelType) {
|
||
fuelTypeSelect.value = expectedFuelType;
|
||
|
||
const success =
|
||
fuelTypeSelect.value === expectedFuelType;
|
||
addTestResult(
|
||
"Vehicle Fuel Type Update",
|
||
success,
|
||
`Selected ${vehicleName}, fuel type set to ${expectedFuelType}`,
|
||
);
|
||
} else if (!this.value) {
|
||
fuelTypeSelect.value = "";
|
||
addTestResult(
|
||
"Vehicle Deselection",
|
||
fuelTypeSelect.value === "",
|
||
"Vehicle deselected, fuel type cleared",
|
||
);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Test Case 3: Auto-calculation
|
||
const amountInput = document.querySelector(
|
||
'input[name="amount"]',
|
||
);
|
||
const priceInputCalc = document.querySelector(
|
||
'input[name="price_per_liter_calc"]',
|
||
);
|
||
const totalInputCalc = document.querySelector(
|
||
'input[name="total_cost_calc"]',
|
||
);
|
||
|
||
function calculateTotal() {
|
||
if (amountInput && priceInputCalc && totalInputCalc) {
|
||
const amount = parseFloat(amountInput.value) || 0;
|
||
const price = parseFloat(priceInputCalc.value) || 0;
|
||
const expectedTotal = amount * price;
|
||
const oldTotal = totalInputCalc.value;
|
||
|
||
totalInputCalc.value = expectedTotal.toFixed(2);
|
||
|
||
addTestResult(
|
||
"Auto-calculation",
|
||
Math.abs(
|
||
parseFloat(totalInputCalc.value) -
|
||
expectedTotal,
|
||
) < 0.01,
|
||
`${amount}L × ${price} = ${expectedTotal.toFixed(2)} (was ${oldTotal})`,
|
||
);
|
||
}
|
||
}
|
||
|
||
if (amountInput && priceInputCalc) {
|
||
amountInput.addEventListener("input", calculateTotal);
|
||
priceInputCalc.addEventListener("input", calculateTotal);
|
||
}
|
||
|
||
// Reverse calculation test
|
||
if (totalInputCalc && amountInput && priceInputCalc) {
|
||
totalInputCalc.addEventListener("input", function () {
|
||
const total = parseFloat(this.value) || 0;
|
||
const amount = parseFloat(amountInput.value) || 0;
|
||
if (amount > 0) {
|
||
const calculatedPrice = total / amount;
|
||
const oldPrice = priceInputCalc.value;
|
||
priceInputCalc.value = calculatedPrice.toFixed(3);
|
||
|
||
addTestResult(
|
||
"Reverse Calculation",
|
||
Math.abs(
|
||
parseFloat(priceInputCalc.value) -
|
||
calculatedPrice,
|
||
) < 0.001,
|
||
`${total} ÷ ${amount}L = ${calculatedPrice.toFixed(3)} (was ${oldPrice})`,
|
||
);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Initial test setup
|
||
addTestResult(
|
||
"Page Load",
|
||
true,
|
||
"All elements loaded successfully",
|
||
);
|
||
|
||
// Test Case 4: Fuel Station Search
|
||
window.testFindNearbyStations = function () {
|
||
addTestResult(
|
||
"Station Search Initiated",
|
||
true,
|
||
"Find Nearby button clicked",
|
||
);
|
||
|
||
if (typeof bootstrap !== "undefined") {
|
||
const modal = new bootstrap.Modal(
|
||
document.getElementById("testStationSearchModal"),
|
||
);
|
||
modal.show();
|
||
|
||
addTestResult(
|
||
"Modal Display",
|
||
true,
|
||
"Search modal opened successfully",
|
||
);
|
||
|
||
// Test geolocation availability
|
||
if (navigator.geolocation) {
|
||
addTestResult(
|
||
"Geolocation Support",
|
||
true,
|
||
"Browser supports geolocation",
|
||
);
|
||
|
||
// Simulate location request
|
||
document.getElementById(
|
||
"testStationSearchResults",
|
||
).innerHTML = `
|
||
<div class="alert alert-info">
|
||
<h6>Geolocation Test</h6>
|
||
<p>This would normally request your location and search for nearby fuel stations using:</p>
|
||
<ul>
|
||
<li>Browser geolocation API</li>
|
||
<li>OpenStreetMap Overpass API</li>
|
||
<li>5km search radius</li>
|
||
</ul>
|
||
<p><strong>Note:</strong> In a real application, this would show actual fuel stations near your location.</p>
|
||
</div>
|
||
<div class="card mb-2" style="cursor: pointer;" onclick="testSelectStation('Shell', 'Hauptstraße 123, 12345 Berlin')">
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-between align-items-start">
|
||
<div>
|
||
<h6 class="card-title mb-1">Shell</h6>
|
||
<p class="card-text text-muted mb-0">Hauptstraße 123, 12345 Berlin</p>
|
||
</div>
|
||
<div class="text-end">
|
||
<span class="badge bg-primary">0.8 km</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card mb-2" style="cursor: pointer;" onclick="testSelectStation('TOTAL', 'Bahnhofstraße 45, 12345 Berlin')">
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-between align-items-start">
|
||
<div>
|
||
<h6 class="card-title mb-1">TOTAL</h6>
|
||
<p class="card-text text-muted mb-0">Bahnhofstraße 45, 12345 Berlin</p>
|
||
</div>
|
||
<div class="text-end">
|
||
<span class="badge bg-primary">1.2 km</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addTestResult(
|
||
"Station Results",
|
||
true,
|
||
"Mock station results displayed",
|
||
);
|
||
} else {
|
||
addTestResult(
|
||
"Geolocation Support",
|
||
false,
|
||
"Browser does not support geolocation",
|
||
);
|
||
document.getElementById(
|
||
"testStationSearchResults",
|
||
).innerHTML = `
|
||
<div class="alert alert-warning">
|
||
Geolocation is not supported by this browser.
|
||
</div>
|
||
`;
|
||
}
|
||
} else {
|
||
addTestResult(
|
||
"Modal Display",
|
||
false,
|
||
"Bootstrap not available for modal",
|
||
);
|
||
}
|
||
};
|
||
|
||
window.testSelectStation = function (name, address) {
|
||
// Fill form fields
|
||
document.querySelector(
|
||
'input[name="station_name_search"]',
|
||
).value = name;
|
||
document.querySelector(
|
||
'input[name="location_search"]',
|
||
).value = address;
|
||
|
||
addTestResult(
|
||
"Station Selection",
|
||
true,
|
||
`Selected: ${name} at ${address}`,
|
||
);
|
||
|
||
// Close modal
|
||
const modal = bootstrap.Modal.getInstance(
|
||
document.getElementById("testStationSearchModal"),
|
||
);
|
||
if (modal) {
|
||
modal.hide();
|
||
}
|
||
};
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|