Add tests for window layout and responsiveness in GUI

- Verify that the window starts in a compact size with a minimum size floor.
- Ensure that the overview and sidebar adapt correctly to narrow widths.
This commit is contained in:
emirhanmamak-blueforce 2026-09-17 08:51:28 +03:00
parent 2bad7fbb7f
commit 04134c3096
3 changed files with 88885 additions and 5052 deletions

View file

@ -2715,6 +2715,8 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
self._browser_inner: dict[str, Any] = {}
self._detail_body: dict[str, Any] = {}
self._activity: list[tuple[str, str, str, str, str]] = []
self._overview_card_frames: list[Any] = []
self._overview_quick_buttons: list[Any] = []
self._elapsed = widgets.Elapsed()
self._exec_title_text = "Etkin işlem yok."
self._current_page = CATEGORIES[0]
@ -2723,13 +2725,19 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
# gecerli olmali, sonradan boyamak gri bir pencere ve titreme uretir.
self.styles = theme.apply_theme(root)
root.title(WINDOW_TITLE)
root.minsize(1040, 760)
# Tk, geometry verilmezse en buyuk istegi olan cikti/alt cubuk
# kombinasyonuna gore pencereyi ekranin tamamindan da buyuk acabiliyor.
# Saha laptoplarinda ilk bakis tek ekrana sigmali; kullanici yine
# pencereyi buyutebilir. 860x620, detayli moddaki iki kolonun
# kullanilabilir en dar guvenli tabanidir.
root.geometry("1180x720")
root.minsize(860, 620)
root.columnconfigure(0, weight=1)
# Bantlar: baslik -> uyarilar -> hedef -> govde -> cikti -> eylem.
# minsize: minimum pencerede (1040x760) islem listesi de cikti kuyusu da
# minsize: minimum pencerede (860x620) islem listesi de cikti kuyusu da
# gorunur kalir; ikisi de agirlikla buyur, hicbiri digerini yutamaz.
root.rowconfigure(3, weight=3, minsize=200)
root.rowconfigure(4, weight=2, minsize=170)
root.rowconfigure(4, weight=1, minsize=120)
self._build_header()
self._build_notices()
@ -2747,11 +2755,12 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
output_area.grid(row=4, column=0, sticky="nsew",
padx=theme.SP_4, pady=(theme.SP_3, 0))
self._build_exec_header(output_area)
self.output = OutputPane(output_area, self.styles, height=7,
self.output = OutputPane(output_area, self.styles, height=5,
log_path=ctx.console_log)
self.output.drain()
self._build_footer()
self._apply_privilege_controls()
self.root.bind("<Configure>", self._on_window_resized)
self.show_mode(full=full_mode)
self._load_inventory()
@ -3167,6 +3176,7 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
pady=(theme.SP_1, theme.SP_3))
self._bind_wrap(card, sub, theme.SP_7)
self._overview_values[key] = (value, sub)
self._overview_card_frames.append(card)
self._refresh_overview()
box = ttk.Frame(page, style=self.styles["panel"])
@ -3187,7 +3197,9 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
else self.styles["big_button"])
button = ttk.Button(inner, text=label, command=command,
style=style_name, width=18)
button.pack(fill="x", pady=theme.SP_2)
button.pack(side="left", fill="x", expand=True,
padx=(0, theme.SP_2), pady=theme.SP_2)
self._overview_quick_buttons.append(button)
if label == "Kur":
self.install_button = button
ttk.Label(
@ -3399,14 +3411,28 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
self._paint_nav()
def _on_window_resized(self, event) -> None:
"""Dar pencerede kenar cubugu katlanir (icerik nefes alir)."""
"""Dar pencerede kabugu ve Genel Bakis kartlarini toplar."""
if event.widget is not self.root:
return
if event.width < 900:
if hasattr(self, "_sidebar"):
self._sidebar.grid_remove()
else:
elif hasattr(self, "_sidebar"):
self._sidebar.grid()
cards = getattr(self, "_overview_card_frames", ())
if cards:
columns = 2 if event.width < 1120 else 4
for index, card in enumerate(cards):
card.grid_configure(
row=index // columns,
column=index % columns,
padx=(0, theme.SP_3) if index % columns < columns - 1 else (0, 0),
pady=(0, theme.SP_2) if columns == 2 and index // columns == 0 else (0, 0),
)
for column in range(4):
self._overview_cards.columnconfigure(column, weight=1 if column < columns else 0)
def _build_category_page(self, parent, category: str):
"""Kategori sayfasi: solda islem tarayici, sagda ayrinti paneli."""
page = ttk.Frame(parent, style=self.styles["frame"])

File diff suppressed because one or more lines are too long

View file

@ -1055,6 +1055,20 @@ class TestConsoleLayoutContract(StaticCase):
self.assertEqual(
re.findall(r"#[0-9a-fA-F]{3,8}\b", widgets_source), [])
def test_window_starts_compact_and_has_small_screen_floor(self) -> None:
self.assertIn('root.geometry("1180x720")', self.source)
self.assertIn('root.minsize(860, 620)', self.source)
self.assertIn('OutputPane(output_area, self.styles, height=5', self.source)
def test_overview_and_sidebar_adapt_to_narrow_widths(self) -> None:
for needle in (
'if event.width < 900:',
'columns = 2 if event.width < 1120 else 4',
'self._overview_card_frames',
):
with self.subTest(needle=needle):
self.assertIn(needle, self.source)
def test_there_is_exactly_one_exit_control(self) -> None:
"""'Cik' tek kontrol: ya basit modda ya alt cubukta, ayni anda degil."""
self.assertEqual(self.source.count('text="Çıkış"'), 1)