Fix device issues and document current LAN deployment

This commit is contained in:
2026-10-13 10:54:20 +02:00
parent 35f88746ff
commit 048cec333e
23 changed files with 707 additions and 36 deletions

View File

@@ -76,7 +76,7 @@ def run():
django.setup()
from django.contrib.auth.models import User
from openpyxl import Workbook
from inventory.models import ChoiceValue, Device, Employee, UserProfile
from inventory.models import ChoiceValue, Device, Employee, FieldDefinition, UserProfile
call_command("migrate", interactive=False, verbosity=0)
call_command("seed_initial_data", verbosity=0)
@@ -93,6 +93,11 @@ def run():
for device_type, model in ((laptop, "Fixture Laptop"), (printer, "Fixture Printer"), (monitor, "Fixture Monitor")):
Device.objects.create(status=status, device_type=device_type, model=model, employee=employee)
FieldDefinition.objects.create(name="Geprüft", key="checked", field_type="boolean", show_in_list=True)
first = Device.objects.get(number=1)
first.custom_values = {"checked": False}
first.save()
port = available_port()
base_url = f"http://127.0.0.1:{port}"
with (Path(temporary) / "server.log").open("w", encoding="utf-8") as log_file:
@@ -111,6 +116,24 @@ def run():
login(page, base_url, "browser_admin")
print("PASS login and protected routes", flush=True)
# Reproduce an existing user's preferences before adding a custom column.
page.evaluate("""() => {
const id = document.body.dataset.userId;
localStorage.setItem(`csr-visible-columns-${id}`, '["number","model"]');
localStorage.setItem(`csr-complete-list-columns-${id}`, '1');
localStorage.removeItem(`csr-known-columns-${id}`);
}""")
page.reload()
custom_cell = page.locator('tr[data-device-id="1"] td[data-column="custom_checked"]')
expect(custom_cell).to_be_visible()
expect(custom_cell).to_have_text("NEIN")
page.goto(f"{base_url}/devices/1/")
expect(page.locator('[name="custom_checked"]')).to_have_value("false")
page.locator('.detail-form [name="model"]').fill("Fixture Laptop Edited")
page.locator('.detail-form button[type="submit"], .detail-form button.primary').click()
expect(page.locator('[name="custom_checked"]')).to_have_value("false")
print("PASS custom column defaults and saved boolean editing", flush=True)
for route in ("/", "/uebersicht/", "/ablauf/", "/aufgaben/", "/devices/new/",
"/devices/1/", "/configuration/", "/users/", "/import/", "/archive/", "/history/"):
response = page.goto(f"{base_url}{route}")
@@ -257,6 +280,17 @@ def run():
expect(mobile_page.locator('.mobile-header')).to_be_visible()
mobile_page.locator('[data-sidebar-toggle]').click()
expect(mobile_page.locator('#sidebar')).to_have_class('sidebar open')
for width, height in ((390, 400), (844, 390)):
mobile_page.set_viewport_size({"width": width, "height": height})
mobile_page.goto(f"{base_url}/?page_size=100")
shell = mobile_page.locator(".table-shell")
shell.scroll_into_view_if_needed()
assert shell.evaluate("el => el.clientHeight") >= 100
mobile_page.locator('.pagination').scroll_into_view_if_needed()
assert mobile_page.locator('.pagination').evaluate("el => el.getBoundingClientRect().bottom <= innerHeight + 1")
if shell.evaluate("el => el.scrollWidth > el.clientWidth"):
shell.evaluate("el => el.scrollLeft = el.scrollWidth")
assert shell.evaluate("el => el.scrollLeft") > 0
mobile.close()
print("PASS dark mode persistence and mobile navigation", flush=True)

View File

@@ -55,4 +55,29 @@ async function run() {
console.log("Frontend regression checks passed: safe confirmation text, preserved selection, no-op blur, revision save.");
} finally { dom.window.close(); }
}
run().catch(error => { console.error(error); process.exitCode = 1; });
async function testCustomColumns() {
const dom = new JSDOM(`<!doctype html><body data-user-id="42">
<button data-columns-toggle></button><div data-columns-panel></div>
<div id="device-table-container"><table data-device-table>
<thead><tr><th data-column="number">Nr.</th><th data-column="custom_checked">Checked</th></tr></thead>
<tbody><tr><td data-column="number">1</td><td data-column="custom_checked">JA</td></tr></tbody>
</table></div></body>`, {url: "https://inventory.test/", runScripts: "outside-only"});
try {
const {window} = dom;
window.fetch = async () => ({ok: true, json: async () => ({})});
window.localStorage.setItem("csr-visible-columns-42", '["number"]');
window.localStorage.setItem("csr-column-order-42", '["number","custom_checked"]');
window.localStorage.setItem("csr-complete-list-columns-42", "1");
window.eval(source);
const cell = window.document.querySelector('td[data-column="custom_checked"]');
assert.equal(cell.style.display, "", "New custom columns must appear with old preferences");
const check = window.document.querySelector('[data-columns-panel] [data-column="custom_checked"] input');
check.checked = false;
check.dispatchEvent(new window.Event("change"));
assert.equal(cell.style.display, "none");
window.eval(source);
assert.equal(cell.style.display, "none", "Explicitly hidden custom columns must stay hidden on rebinding");
console.log("Frontend regression checks passed: custom-column defaults and saved visibility.");
} finally { dom.window.close(); }
}
run().then(testCustomColumns).catch(error => { console.error(error); process.exitCode = 1; });