fix(#5932): harden board workspace modal proof
This commit is contained in:
1 parent
eb9298ba91
commit
ea3163e234
3 files changed
+59
-38
No files matched your search
+1
-1
@@ -1798,7 +1798,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="kanban-modal-row">
|
<div class="kanban-modal-row">
|
||||||
<label for="kanbanBoardModalDefaultWorkdir" data-i18n="kanban_board_default_workdir">Default workspace path</label>
|
<label for="kanbanBoardModalDefaultWorkdir" data-i18n="kanban_board_default_workdir">Default workspace path</label>
|
||||||
<input type="text" id="kanbanBoardModalDefaultWorkdir" list="kanbanBoardModalWorkdirs" data-i18n-placeholder="kanban_board_default_workdir_placeholder" placeholder="Workspace path (optional)" autocomplete="off">
|
<input type="text" id="kanbanBoardModalDefaultWorkdir" list="kanbanBoardModalWorkdirs" maxlength="255" data-i18n-placeholder="kanban_board_default_workdir_placeholder" placeholder="Workspace path (optional)" autocomplete="off">
|
||||||
<datalist id="kanbanBoardModalWorkdirs"></datalist>
|
<datalist id="kanbanBoardModalWorkdirs"></datalist>
|
||||||
</div>
|
</div>
|
||||||
<div class="kanban-modal-row-inline">
|
<div class="kanban-modal-row-inline">
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ def test_board_payload_validates_default_workdir_and_preserves_omission(monkeypa
|
|||||||
|
|
||||||
def test_board_modal_submit_includes_and_clears_default_workdir():
|
def test_board_modal_submit_includes_and_clears_default_workdir():
|
||||||
assert 'id="kanbanBoardModalDefaultWorkdir"' in INDEX
|
assert 'id="kanbanBoardModalDefaultWorkdir"' in INDEX
|
||||||
|
default_workdir_input = re.search(
|
||||||
|
r'<input\b[^>]*\bid="kanbanBoardModalDefaultWorkdir"[^>]*>', INDEX
|
||||||
|
)
|
||||||
|
assert default_workdir_input
|
||||||
|
assert 'maxlength="255"' in default_workdir_input.group(0)
|
||||||
assert 'id="kanbanBoardModalOriginalDefaultWorkdir"' in INDEX
|
assert 'id="kanbanBoardModalOriginalDefaultWorkdir"' in INDEX
|
||||||
assert 'list="kanbanBoardModalWorkdirs"' in INDEX
|
assert 'list="kanbanBoardModalWorkdirs"' in INDEX
|
||||||
assert "if (defaultWorkdir) payload.default_workdir = defaultWorkdir;" in PANELS
|
assert "if (defaultWorkdir) payload.default_workdir = defaultWorkdir;" in PANELS
|
||||||
|
|||||||
@@ -20,40 +20,56 @@ def test_board_modal_default_workdir_layout(locale, width, height):
|
|||||||
pw = pytest.importorskip("playwright.sync_api")
|
pw = pytest.importorskip("playwright.sync_api")
|
||||||
with pw.sync_playwright() as playwright:
|
with pw.sync_playwright() as playwright:
|
||||||
browser = playwright.chromium.launch(headless=True, args=_BROWSER_ARGS)
|
browser = playwright.chromium.launch(headless=True, args=_BROWSER_ARGS)
|
||||||
page = browser.new_page(viewport={"width": width, "height": height})
|
page = None
|
||||||
page.goto(BASE + "/", wait_until="domcontentloaded")
|
try:
|
||||||
page.wait_for_selector("#kanbanBoardModalDefaultWorkdir", state="attached", timeout=10000)
|
page = browser.new_page(viewport={"width": width, "height": height})
|
||||||
page.wait_for_function(
|
try:
|
||||||
"typeof setLocale === 'function' && typeof applyLocaleToDOM === 'function' && typeof openKanbanCreateBoard === 'function'",
|
page.goto(BASE + "/", wait_until="domcontentloaded")
|
||||||
timeout=10000,
|
page.wait_for_function(
|
||||||
)
|
"() => typeof S !== 'undefined' && S._bootReady === true",
|
||||||
page.evaluate("""([lang]) => {
|
timeout=10000,
|
||||||
setLocale(lang);
|
)
|
||||||
applyLocaleToDOM();
|
page.wait_for_function(
|
||||||
openKanbanCreateBoard();
|
"() => typeof setLocale === 'function' && typeof applyLocaleToDOM === 'function' && typeof openKanbanCreateBoard === 'function'",
|
||||||
const row = document.getElementById('kanbanBoardModalDefaultWorkdir')?.closest('.kanban-modal-row');
|
timeout=10000,
|
||||||
if (row) row.id = 'kanbanBoardModalDefaultWorkdirRow';
|
)
|
||||||
}""", [locale])
|
page.evaluate("""([lang]) => {
|
||||||
page.wait_for_function("""([expected]) => {
|
setLocale(lang);
|
||||||
const modal = document.getElementById('kanbanBoardModal');
|
openKanbanCreateBoard();
|
||||||
const label = document.querySelector("label[for='kanbanBoardModalDefaultWorkdir']");
|
const modal = document.getElementById('kanbanBoardModal');
|
||||||
const row = document.getElementById('kanbanBoardModalDefaultWorkdirRow');
|
if (!modal || modal.hidden) throw new Error('Kanban board modal did not open');
|
||||||
return !!modal && !modal.hidden && !!label && !!row && label.textContent.trim() === expected;
|
applyLocaleToDOM();
|
||||||
}""", arg=[EXPECTED_LABELS[locale]])
|
const row = document.getElementById('kanbanBoardModalDefaultWorkdir')?.closest('.kanban-modal-row');
|
||||||
modal = page.locator("#kanbanBoardModal")
|
if (row) row.id = 'kanbanBoardModalDefaultWorkdirRow';
|
||||||
row = page.locator("#kanbanBoardModalDefaultWorkdirRow")
|
}""", [locale])
|
||||||
field = page.locator("#kanbanBoardModalDefaultWorkdir")
|
page.wait_for_function("""([expected]) => {
|
||||||
assert row.is_visible()
|
const modal = document.getElementById('kanbanBoardModal');
|
||||||
assert field.is_visible()
|
const label = document.querySelector("label[for='kanbanBoardModalDefaultWorkdir']");
|
||||||
label = page.locator("label[for='kanbanBoardModalDefaultWorkdir']")
|
const row = document.getElementById('kanbanBoardModalDefaultWorkdirRow');
|
||||||
assert label.is_visible()
|
return !!modal && !modal.hidden && !!label && !!row && label.textContent.trim() === expected;
|
||||||
assert label.text_content().strip() == EXPECTED_LABELS[locale]
|
}""", arg=[EXPECTED_LABELS[locale]])
|
||||||
modal_box = modal.bounding_box()
|
modal = page.locator("#kanbanBoardModal")
|
||||||
field_box = field.bounding_box()
|
row = page.locator("#kanbanBoardModalDefaultWorkdirRow")
|
||||||
assert modal_box and field_box
|
field = page.locator("#kanbanBoardModalDefaultWorkdir")
|
||||||
assert field_box["x"] >= modal_box["x"]
|
assert row.is_visible()
|
||||||
assert field_box["x"] + field_box["width"] <= modal_box["x"] + modal_box["width"]
|
assert field.is_visible()
|
||||||
assert field_box["y"] + field_box["height"] <= modal_box["y"] + modal_box["height"]
|
label = page.locator("label[for='kanbanBoardModalDefaultWorkdir']")
|
||||||
assert_no_raw_i18n_keys(page, "#kanbanBoardModalDefaultWorkdirRow")
|
assert label.is_visible()
|
||||||
assert_layout_sane(page, "#kanbanBoardModalDefaultWorkdirRow")
|
assert label.text_content().strip() == EXPECTED_LABELS[locale]
|
||||||
browser.close()
|
modal_box = modal.bounding_box()
|
||||||
|
field_box = field.bounding_box()
|
||||||
|
assert modal_box and field_box
|
||||||
|
assert field_box["x"] >= modal_box["x"]
|
||||||
|
assert field_box["x"] + field_box["width"] <= modal_box["x"] + modal_box["width"]
|
||||||
|
assert field_box["y"] + field_box["height"] <= modal_box["y"] + modal_box["height"]
|
||||||
|
assert_no_raw_i18n_keys(page, "#kanbanBoardModalDefaultWorkdirRow")
|
||||||
|
assert_layout_sane(page, "#kanbanBoardModalDefaultWorkdirRow")
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
page.evaluate("""() => {
|
||||||
|
if (typeof closeKanbanBoardModal === 'function') closeKanbanBoardModal();
|
||||||
|
}""")
|
||||||
|
finally:
|
||||||
|
page.close()
|
||||||
|
finally:
|
||||||
|
browser.close()
|
||||||
Reference in new issue
Block a user