test Remove page content assertions from the web suites

A web test checks what a trainee can do and what the application stores or returns. It does not check how a page is written. The removed assertions matched headings, captions, table headers, link markup, aria attributes, input attribute strings, and the copyright notice. Each one broke on a presentation change that did not change a capability. Each suite keeps its status checks, its redirect checks, its repository state checks, and the user-visible values that doctrine produces: the rest hours, the planned date, the exercise values and their deltas. Two tests are deleted in full. The suggested-load test asserted the exact input markup of a prefilled field. The default-day test asserted an aria-label. The rules they covered still live in Handlers_kit.workout_view and Handlers_logbook.index and now have no test. The next step lifts that logic into pure modules with unit tests.

Commit
a56fa2a847685e53824a6c13900d7e5bae325ee8
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
test/web/app_feedback.ml
index 37ca75f7..0f147fcf 100644..100644
@@ -13,19 +13,6 @@
13 13 Alcotest.(check int)
14 14 "write tab served" 200
15 15 (status (get c "/app-feedback"));
16 Removed: let page = body (get c "/app-feedback") in
17 Removed: Alcotest.(check bool)
18 Removed: "page names the App Feedback affordance" true
19 Removed: (Option.is_some (index_from ~needle:"App Feedback" page 0));
20 Removed: Alcotest.(check bool)
21 Removed: "write tab link is present" true
22 Removed: (Option.is_some
23 Removed: (index_from ~needle:"href=\"/app-feedback?tab=write\"" page 0));
24 Removed: Alcotest.(check bool)
25 Removed: "submitted tab link is present" true
26 Removed: (Option.is_some
27 Removed: (index_from ~needle:"href=\"/app-feedback?tab=submitted\"" page
28 Removed: 0));
29 16 Alcotest.(check int)
30 17 "submitted tab served" 200
31 18 (status (get c "/app-feedback?tab=submitted")) );
test/web/auth.ml
index 17260093..b2cb903a 100644..100644
@@ -17,25 +17,6 @@
17 17 fun () ->
18 18 let c = client () in
19 19 Alcotest.(check int) "GET /login" 200 (status (get c "/login")) );
20 Removed: ( "the sign-in page identifies the copyright owner and version",
21 Removed: `Quick,
22 Removed: fun () ->
23 Removed: let c = client () in
24 Removed: let page = body (get c "/login") in
25 Removed: Alcotest.(check bool)
26 Removed: "copyright notice is visible" true
27 Removed: (Option.is_some
28 Removed: (index_from ~needle:"© 2026 Marius PETER. All rights reserved."
29 Removed: page 0));
30 Removed: Alcotest.(check bool)
31 Removed: "version is visible" true
32 Removed: (Option.is_some (index_from ~needle:"Version: " page 0));
33 Removed: let registration_page = body (get c "/register") in
34 Removed: Alcotest.(check bool)
35 Removed: "registration copyright notice is visible" true
36 Removed: (Option.is_some
37 Removed: (index_from ~needle:"© 2026 Marius PETER. All rights reserved."
38 Removed: registration_page 0)) );
39 20 ( "every response carries the browser hardening headers",
40 21 `Quick,
41 22 fun () ->
test/web/logbook.ml
index 878bb328..02df3d52 100644..100644
@@ -10,47 +10,18 @@
10 10 fun () ->
11 11 let c = client () in
12 12 let _ = sign_in_new c in
13 Removed: let page = body (get c "/logbook") in
14 Removed: Alcotest.(check bool)
15 Removed: "Logbook has Calendar tab" true
16 Removed: (Option.is_some
17 Removed: (index_from ~needle:"href=\"/logbook?tab=calendar\"" page 0));
18 Removed: Alcotest.(check bool)
19 Removed: "Logbook has Progress tab" true
20 Removed: (Option.is_some
21 Removed: (index_from ~needle:"href=\"/logbook?tab=progress\"" page 0));
22 Removed: let progress_page = body (get c "/logbook?tab=progress") in
23 Removed: Alcotest.(check bool)
24 Removed: "Progress tab is active" true
25 Removed: (Option.is_some
26 Removed: (index_from ~needle:"aria-current=\"page\"" progress_page 0));
27 Removed: Alcotest.(check bool)
28 Removed: "Progress tab does not show the calendar" true
29 Removed: (Option.is_none
30 Removed: (index_from ~needle:"calendar-grid" progress_page 0));
31 13 Alcotest.(check int)
14 Added: "the calendar view is served" 200
15 Added: (status (get c "/logbook"));
16 Added: Alcotest.(check int)
17 Added: "the progress view is served" 200
18 Added: (status (get c "/logbook?tab=progress"));
19 Added: Alcotest.(check int)
32 20 "the old progress endpoint is gone" 404
33 21 (status (get c "/progress"));
34 22 Alcotest.(check int)
35 23 "the feedback modal stays available" 200
36 24 (status (get c "/logbook?feedback=start")) );
37 Removed: ( "the Logbook selects today by default",
38 Removed: `Quick,
39 Removed: fun () ->
40 Removed: let c, now, _repo = clocked_client () in
41 Removed: now := day 10;
42 Removed: let _ = sign_in_new c in
43 Removed: let page = body (get c "/logbook") in
44 Removed: Alcotest.(check bool)
45 Removed: "today is the selected day" true
46 Removed: (Option.is_some
47 Removed: (index_from ~needle:"aria-label=\"11: today\"" page 0));
48 Removed: Alcotest.(check bool)
49 Removed: "today's empty panel is displayed" true
50 Removed: (Option.is_some
51 Removed: (index_from
52 Removed: ~needle:"No workout was recorded or planned on this day."
53 Removed: page 0)) );
54 25 ( "the calendar marks the next routine workout after recovery",
55 26 `Quick,
56 27 fun () ->
@@ -64,29 +35,12 @@
64 35 let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
65 36 let page = body (get c "/logbook?year=1970&month=1&day=13") in
66 37 Alcotest.(check bool)
67 Removed: "calendar explains its planned state" true
68 Removed: (Option.is_some (index_from ~needle:"Planned" page 0));
69 Removed: Alcotest.(check bool)
70 Removed: "calendar names the next workout" true
71 Removed: (Option.is_some (index_from ~needle:"13: planned Day 2" page 0));
72 Removed: Alcotest.(check bool)
73 Removed: "planned workout uses the selected date" true
38 Added: "the next workout is planned on the selected date" true
74 39 (Option.is_some
75 40 (index_from ~needle:"Planned on 13th January 1970" page 0));
76 41 Alcotest.(check bool)
77 Removed: "selected planned workout is displayed" true
78 Removed: (Option.is_some (index_from ~needle:"Day 2" page 0));
79 Removed: Alcotest.(check bool)
80 Removed: "planned workout names its routine and day in the table caption"
81 Removed: true
82 Removed: (Option.is_some
83 Removed: (index_from ~needle:"Ideal Routine, Day 2" page 0));
84 Removed: Alcotest.(check bool)
85 Removed: "planned workout omits change columns" true
86 Removed: (Option.is_none (index_from ~needle:"Δ" page 0));
87 Removed: Alcotest.(check bool)
88 Removed: "the old entry list is absent" true
89 Removed: (Option.is_none (index_from ~needle:"logbook-entry" page 0)) );
42 Added: "the planned workout is Day 2" true
43 Added: (Option.is_some (index_from ~needle:"Day 2" page 0)) );
90 44 ( "the Logbook keeps an overdue next workout tentative",
91 45 `Quick,
92 46 fun () ->
@@ -102,20 +56,15 @@
102 56 now := day 20;
103 57 let page = body (get c "/logbook") in
104 58 Alcotest.(check bool)
105 Removed: "today names the overdue next workout" true
59 Added: "the overdue workout is planned today" true
106 60 (Option.is_some
107 Removed: (index_from ~needle:"21: planned Day 2, today" page 0));
108 Removed: Alcotest.(check bool)
109 Removed: "the overdue tentative workout is displayed" true
110 Removed: (Option.is_some
111 Removed: (index_from ~needle:"Ideal Routine, Day 2" page 0));
112 Removed: Alcotest.(check bool)
113 Removed: "the tentative workout is planned today" true
114 Removed: (Option.is_some
115 61 (index_from ~needle:"Planned on 21st January 1970" page 0));
116 62 Alcotest.(check bool)
63 Added: "the overdue workout is still Day 2" true
64 Added: (Option.is_some (index_from ~needle:"Day 2" page 0));
65 Added: Alcotest.(check bool)
117 66 "the routine does not advance silently" true
118 Removed: (Option.is_none (index_from ~needle:"planned Day 3" page 0)) );
67 Added: (Option.is_none (index_from ~needle:"Day 3" page 0)) );
119 68 ( "a faster repeat of the identical workout shows a favourable \
120 69 duration delta",
121 70 `Quick,
@@ -233,13 +182,7 @@
233 182 ("history reports " ^ needle)
234 183 true
235 184 (Option.is_some (index_from ~needle page 0)))
236 Removed: [ "Laterals"; "12"; "+2"; "9"; "+1"; "Δ"; "Performed" ];
237 Removed: Alcotest.(check bool)
238 Removed: "the table labels the load unit in its header" true
239 Removed: (Option.is_some (index_from ~needle:"Load (kg)" page 0));
240 Removed: Alcotest.(check bool)
241 Removed: "the table does not repeat units in values" true
242 Removed: (Option.is_none (index_from ~needle:"12 kg" page 0)) );
185 Added: [ "Laterals"; "12"; "+2"; "9"; "+1" ] );
243 186 ( "each saved workout has an edit and confirmation-gated delete action",
244 187 `Quick,
245 188 fun () ->
test/web/overview.ml
index 40fe12eb..0d9e960d 100644..100644
@@ -43,42 +43,9 @@
43 43 chart. *)
44 44 let c, repo = client_with_repo () in
45 45 let _ = register c ~username:"lifter" ~password:"heavyduty1" in
46 Removed: let home = body (get c "/") in
47 Removed: Alcotest.(check bool)
48 Removed: "Home does not offer the Account affordance" false
49 Removed: (Option.is_some (index_from ~needle:"Account" home 0));
50 Removed: Alcotest.(check bool)
51 Removed: "Home does not offer the App Feedback affordance" false
52 Removed: (Option.is_some (index_from ~needle:"App Feedback" home 0));
53 46 let trainee = the_trainee repo ~username:"lifter" in
54 47 let token = Option.get (csrf_token (body (get c "/"))) in
55 48 let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
56 Removed: let selected_home = body (get c "/") in
57 Removed: Alcotest.(check bool)
58 Removed: "Home shows the next workout title" true
59 Removed: (Option.is_some
60 Removed: (index_from ~needle:"Next Workout" selected_home 0));
61 Removed: Alcotest.(check bool)
62 Removed: "Home omits the authentication copyright notice" false
63 Removed: (Option.is_some
64 Removed: (index_from ~needle:"© 2026 Marius PETER. All rights reserved."
65 Removed: selected_home 0));
66 Removed: Alcotest.(check bool)
67 Removed: "Home does not repeat the complete recovery notice" false
68 Removed: (Option.is_some
69 Removed: (index_from ~needle:"Recovery is complete." selected_home 0));
70 Removed: Alcotest.(check bool)
71 Removed: "Home offers the next workout action" true
72 Removed: (Option.is_some
73 Removed: (index_from ~needle:"value=\"Begin next workout\""
74 Removed: selected_home 0));
75 Removed: Alcotest.(check bool)
76 Removed: "Selected Home does not offer the Account affordance" false
77 Removed: (Option.is_some (index_from ~needle:"Account" selected_home 0));
78 Removed: Alcotest.(check bool)
79 Removed: "Selected Home does not offer the App Feedback affordance" false
80 Removed: (Option.is_some
81 Removed: (index_from ~needle:"App Feedback" selected_home 0));
82 49 let header =
83 50 "title,start_time,end_time,description,exercise_title,superset_id,exercise_notes,set_index,set_type,weight_kg,reps,distance_km,duration_seconds,rpe\r\n"
84 51 in
@@ -130,15 +97,8 @@
130 97 "the Day 1 preview lists Laterals" true
131 98 (Option.is_some (index_from ~needle:"Laterals" page 0));
132 99 Alcotest.(check bool)
133 Removed: "Laterals names the routine and planned workout in the table \
134 Removed: caption"
135 Removed: true
136 Removed: (Option.is_some
137 Removed: (index_from ~needle:"Ideal Routine, Day 1" page 0));
138 Removed: Alcotest.(check bool)
139 100 "Laterals shows its best load and reps" true
140 Removed: (Option.is_some (index_from ~needle:"Load (kg)" page 0)
141 Removed: && Option.is_some (index_from ~needle:">14<" page 0)
101 Added: (Option.is_some (index_from ~needle:">14<" page 0)
142 102 && Option.is_some (index_from ~needle:">10<" page 0)) );
143 103 ( "the routine page is served once a routine is selected",
144 104 `Quick,
@@ -156,7 +116,7 @@
156 116 Alcotest.(check int)
157 117 "routine browser is available" 200
158 118 (status (get c "/routines")) );
159 Removed: ( "the routine page shows the rest between workouts and the next one",
119 Added: ( "the routine page states the rest between workouts",
160 120 `Quick,
161 121 fun () ->
162 122 let c = client () in
@@ -169,12 +129,7 @@
169 129 "rest between workouts is stated" true (has "Rest 48 hours");
170 130 Alcotest.(check bool)
171 131 "the last rest leads back to the first workout" true
172 Removed: (has "Rest 72 hours, then Day 1");
173 Removed: Alcotest.(check bool)
174 Removed: "the next workout is marked" true (has ">Next<");
175 Removed: Alcotest.(check bool)
176 Removed: "the trainee can reach the routine browser" true
177 Removed: (has "href=\"/routines\"") );
132 Added: (has "Rest 72 hours, then Day 1") );
178 133 ( "selecting an unknown routine is not found and selects nothing",
179 134 `Quick,
180 135 fun () ->
test/web/workout.ml
index 4907d373..d859cfef 100644..100644
@@ -618,84 +618,5 @@
618 618 (List.length
619 619 (Lwt_main.run (Test_repo.history repo trainee.Trainee.id))
620 620 >= 1) );
621 Removed: ( "an in-range previous effort suggests its load",
622 Removed: `Quick,
623 Removed: fun () ->
624 Removed: let c, now, _repo = clocked_client () in
625 Removed: now := day 10;
626 Removed: let _ = sign_in_new c in
627 Removed: let _ = start_day_one c in
628 Removed: let record slot fields =
629 Removed: let token =
630 Removed: Option.get (csrf_token (body (get c ("/workout?slot=" ^ slot))))
631 Removed: in
632 Removed: let _ =
633 Removed: post c ("/workout/slots/" ^ slot)
634 Removed: (("dream.csrf", token) :: fields)
635 Removed: in
636 Removed: ()
637 Removed: in
638 Removed: record "0"
639 Removed: [
640 Removed: ("iso_load", "20");
641 Removed: ("iso_reps", "9");
642 Removed: ("comp_load", "60");
643 Removed: ("comp_reps", "7");
644 Removed: ("extension", "");
645 Removed: ];
646 Removed: (* Laterals failed above the 6-10 guideline. Its prior load remains
647 Removed: visible but is not suggested. Rear deltoid laterals failed inside
648 Removed: the range, so its prior load is suggested on the next Day 1. *)
649 Removed: record "1" [ ("load", "12"); ("reps", "11"); ("extension", "") ];
650 Removed: record "2" [ ("load", "10"); ("reps", "8"); ("extension", "") ];
651 Removed: record "3"
652 Removed: [
653 Removed: ("iso_load", "20");
654 Removed: ("iso_reps", "9");
655 Removed: ("comp_load", "0");
656 Removed: ("comp_reps", "7");
657 Removed: ("extension", "");
658 Removed: ];
659 Removed: let finish () =
660 Removed: let token = Option.get (csrf_token (body (get c "/workout"))) in
661 Removed: let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
662 Removed: ()
663 Removed: in
664 Removed: finish ();
665 Removed: let rec reach_day_one attempts d =
666 Removed: if attempts = 0 then Alcotest.failf "Day 1 did not recur"
667 Removed: else begin
668 Removed: now := day d;
669 Removed: let token = Option.get (csrf_token (body (get c "/"))) in
670 Removed: let _ =
671 Removed: post c "/workout"
672 Removed: [ ("dream.csrf", token); ("override", "false") ]
673 Removed: in
674 Removed: let page = body (get c "/workout") in
675 Removed: if Option.is_some (index_from ~needle:"Day 1" page 0) then page
676 Removed: else begin
677 Removed: record_all_day_one_slots c;
678 Removed: finish ();
679 Removed: reach_day_one (attempts - 1) (d + 3)
680 Removed: end
681 Removed: end
682 Removed: in
683 Removed: let page = reach_day_one 6 13 in
684 Removed: Alcotest.(check bool)
685 Removed: "an in-range prior load is pre-filled" true
686 Removed: (Option.is_some
687 Removed: (index_from
688 Removed: ~needle:
689 Removed: "name=\"load\" id=\"slot-2-load\" step=\"0.5\" required \
690 Removed: value=\"10\""
691 Removed: page 0));
692 Removed: Alcotest.(check bool)
693 Removed: "an out-of-range prior load is not pre-filled" true
694 Removed: (Option.is_none
695 Removed: (index_from
696 Removed: ~needle:
697 Removed: "name=\"load\" id=\"slot-1-load\" step=\"0.5\" required \
698 Removed: value=\"12\""
699 Removed: page 0)) );
700 621 ] );
701 622 ]