host/tests: Phase 0 — relate→delete row as an SX engine test (no browser)
Port the relate-picker's relate-delete behaviour from Playwright into an SX harness test that drives the real engine (web/engine.sx + web/orchestration.sx) against the OCaml runner's in-memory mock DOM. Builds the candidate row, runs process-elements to bind the form's submit, mocks fetch-request to return the host's empty 200, fires submit, and asserts the row is deleted in place — the full fetch→swap→DOM-mutation loop in pure SX. Mock-DOM completeness (run_tests.ml): NodeList.item(i) so dom-query-all can iterate querySelectorAll results, and a DOMParser mock so the empty-body sx-swap=delete path (handle-html-response → parseFromString) works as in a browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2961,6 +2961,15 @@ let run_spec_tests env test_files =
|
||||
| "setTimeout" -> (match rest with fn :: _ -> ignore (Sx_ref.cek_call fn (List [])); Nil | _ -> Nil)
|
||||
| "clearTimeout" -> Nil
|
||||
| _ -> Nil)
|
||||
(* NodeList.item(i) — dom-query-all iterates the querySelectorAll result
|
||||
(a bare List) via this method, exactly like a browser NodeList. *)
|
||||
| (List _ | ListRef _) :: String "item" :: [idx] ->
|
||||
let items = match args with
|
||||
| List l :: _ -> l
|
||||
| ListRef { contents = l } :: _ -> l
|
||||
| _ -> [] in
|
||||
let i = match idx with Number n -> int_of_float n | Integer n -> n | _ -> -1 in
|
||||
if i >= 0 && i < List.length items then List.nth items i else Nil
|
||||
| Dict d :: String "hasOwnProperty" :: [String k] ->
|
||||
Bool (Hashtbl.mem d k)
|
||||
| Dict d :: String m :: rest ->
|
||||
@@ -3070,6 +3079,26 @@ let run_spec_tests env test_files =
|
||||
(* console.log/debug/error — no-op in tests *)
|
||||
Nil
|
||||
|
||||
else if mt = "domparser" then
|
||||
(* DOMParser.parseFromString(text, "text/html") — returns a mock
|
||||
document whose <body> is parsed from `text`. An empty string yields
|
||||
a valid empty document (truthy), matching the browser: that's what
|
||||
the engine's handle-html-response relies on for an empty-body
|
||||
sx-swap="delete" response. *)
|
||||
(match m with
|
||||
| "parseFromString" ->
|
||||
let text = match rest with String t :: _ -> t | _ -> "" in
|
||||
let bd = match make_mock_element "body" with Dict d -> d | _ -> Hashtbl.create 0 in
|
||||
Hashtbl.replace bd "tagName" (String "BODY");
|
||||
Hashtbl.replace bd "nodeName" (String "BODY");
|
||||
parse_html_into bd text;
|
||||
Hashtbl.replace bd "innerHTML" (String text);
|
||||
let doc = Hashtbl.create 4 in
|
||||
Hashtbl.replace doc "__mock_type" (String "document");
|
||||
Hashtbl.replace doc "body" (Dict bd);
|
||||
Dict doc
|
||||
| _ -> Nil)
|
||||
|
||||
else
|
||||
(* Element methods *)
|
||||
(match m with
|
||||
@@ -3483,6 +3512,10 @@ let run_spec_tests env test_files =
|
||||
Dict ev
|
||||
| [String "Object"] ->
|
||||
Dict (Hashtbl.create 4)
|
||||
| [String "DOMParser"] ->
|
||||
let d = Hashtbl.create 4 in
|
||||
Hashtbl.replace d "__mock_type" (String "domparser");
|
||||
Dict d
|
||||
| _ -> Nil);
|
||||
|
||||
reg "host-callback" (fun args ->
|
||||
|
||||
Reference in New Issue
Block a user