Skip to content

Add regression tests for keyboard handling, expanders, and distortion updates - #53

Merged
iLevyTate merged 3 commits into
mainfrom
ccr-c0e2b8a4-fjqy96
Sep 28, 2026
Merged

iLevyTate merged 3 commits into
mainfrom
ccr-c0e2b8a4-fjqy96

Conversation

@iLevyTate

Copy link
Copy Markdown
Owner

This PR adds comprehensive regression tests and updates documentation to ensure proper handling of mobile keyboard interactions, UI element visibility, and distortion/reframe logic.

Summary

Extended the regression test suite with three new test blocks (28–30) covering critical mobile UX and clinical content updates, plus corresponding smoke test enhancements and README clarifications.

Key Changes

  • Test Block 28 (Keyboard handling): Validates that tapped input fields are lifted clear of both the Android keyboard and sticky chrome when interactive-widget=resizes-content shrinks the viewport. Ensures .kb-open class switches on correctly even when keyboard height reads as 0px.

  • Test Block 29 (Expander visibility): Confirms that <details> elements opened near the bottom of a step unfold into view rather than being hidden under the sticky Continue bar.

  • Test Block 30 (Distortion pairings & migrations):

    • Validates all distortions have pre-set questions and reframe methods
    • Verifies legacy question-type names ("Zoom out (pie chart)", "Perspective broadening", "Historical test") migrate to current names
    • Confirms "Minimization" distortion tag migrates to "Magnification and Minimization"
    • Ensures intensity cues describe felt experience rather than vocal characteristics
    • Validates that picking a distortion never auto-populates a stock reframe
    • Confirms 0 intensity rating reads as "None"
  • Smoke test updates: Added assertions for the Socratic answer field on Step 4 and enhanced evidence capture validation.

  • README clarification: Updated the Thought Record description to reference the Mind Over Mood 7-column model and Burns/Beck distortion framework explicitly, and clarified behavioral activation and worry postponement features.

Implementation Details

  • Added global variable declarations for test blocks 28–30 to access app.js reference tables (DISTORTIONS, DISTORTION_DEFAULTS, INTENSITY_BANDS, etc.) within page.evaluate() contexts
  • Mobile viewport testing uses 390×844 (standard Android) and 390×480 (keyboard-open) dimensions
  • Tests verify DOM positioning using getBoundingClientRect() to ensure fields and expanders remain visible above sticky footers
  • Legacy entry migration tested by seeding localStorage with old entry formats and validating transformation

https://claude.ai/code/session_01N8j1Ct5L5H38YPLcFi7bfn

…lt-sense intensity cues

Three problems reported from the phone.

1. Tapping a text box left it hidden; you had to scroll to find it.

   On Android, interactive-widget=resizes-content shrinks innerHeight
   along with the visual viewport, so kbHeight() (innerHeight minus
   vv.height) read ~0. .kb-open never switched on, the bottom nav and the
   capture step's sticky Back / Continue bar stayed parked above the
   keyboard, and the visibility check ignored both, so a field behind
   them counted as visible. Reproduced on a 390px viewport: the Body
   textarea sat 143px under the footer while being typed into.

   Keyboard height is now measured against the tallest height seen at
   the current width while a text field has focus. revealInView()
   measures the visible band minus the bottom nav, the sticky footer and
   the top banners, clips it to a scrolling dialog, and scrolls the
   dialog then the page. It only acts on focus the user caused (a tap on
   the field or its label, Tab, or focusForUser() for "Add another
   thought" and the starter chips), so code that restores focus with
   preventScroll still never moves the page, and hand scrolling still
   switches auto-scroll off. A <details> expander, a journal entry, and
   a new mood row opened near the bottom now unfold into view instead of
   under the footer or nav.

2. The suggested Socratic question didn't fit the distortion.

   All-or-Nothing, Mental Filter and Minimization were all handed the
   responsibility pie ("how big would my slice actually be?"). The type
   used to be "Perspective broadening" (zoom out to the week); PR 6
   swapped its question for the pie and left the mapping pointing at it.
   Added Shades of gray (0 to 100 continuum) and Full picture, renamed
   the pie to Responsibility pie and gave it Personalization and
   internal control fallacy. Added three reframe styles so every default
   fits its distortion: Balanced thought, Flexible preference (shoulds,
   fairness, change) and Behavior, not identity (labeling). Compassionate
   reattribution's starter now works for blame in either direction.
   Stored "Zoom out (pie chart)" and "Perspective broadening" migrate.

3. Intensity cues described how someone sounds, not how it feels.

   "Raised voice", "vocal frustration" and "yelling" were an observer's
   checklist on a self-report scale. The cues now describe felt
   experience, and "Inferred from speech, not directly felt" on the body
   field reads "Pieced together later, not felt at the time". The
   Socratic box is three lines so its starter question isn't cut off.

Regression blocks 28-30 cover the keyboard reveal, the expander reveal,
and the pairings / migration / cue wording; each fails against the
previous code. Full suite green: lint, check, crypto, smoke, flows,
robustness, sync, regressions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N8j1Ct5L5H38YPLcFi7bfn
…and scales against sources

A source-by-source review of every piece of clinical content, checked
against Burns (Feeling Good 1980, Handbook 1989, 2016 checklist), J. Beck
(2020, Beck Institute worksheets), Greenberger & Padesky (Mind Over Mood,
2nd ed.), Padesky (1993, 1994, 2019), Salkovskis (1999), McKay, Davis &
Fanning (1981), Wolpe's SUDS, Borkovec et al. (1983) with Dippel et al.'s
2023 meta-analysis, Beck et al. (1979), Furukawa et al. (2018), NICE NG116
and CG178, and each crisis service's own site (checked Sep 2026).

Crisis resources: the US 988 Lifeline and Canada's separate 9-8-8 Suicide
Crisis Helpline were merged under one "US / Canada" label with a US-only
chat link; they're now listed apart. The text-line keywords were wrong
outside the US (UK is SHOUT to 85258, Canada's 686868 is Kids Help Phone
with CONNECT, Ireland is Text About It on 50808). The IASP directory link
now redirects to their homepage; Find A Helpline replaces it. Emergency
numbers cover Canada and Ireland.

Distortions: plain definitions faithful to Burns and Beck. always/never
moved to Overgeneralization; Catastrophizing is the worst-case prediction;
"Minimization" is restored to Burns's two-way Magnification and
Minimization (stored tags migrate); Personalization covers assuming
others' moods are about you; Should Statements cover shoulds aimed at
others. "Common pairs" had no published support and are now labelled as
examples with a reason each. The first Blame example told users
"responsibility is usually shared", which can blame victims; it now makes
room for having had no part.

Questions and reframes: Evidence examination weighs both lists; Decata-
strophizing asks worst, best and most likely before coping; the
responsibility pie fills in your own slice last, as Salkovskis does, and
is now Blame's default too; "Historical test" (a schema life-review in the
literature) is "Track record"; Behavioral experiment is an actual test;
the Socratic explainer no longer claims Socrates never lectured.

Structure: picking a distortion no longer writes a stock reframe into the
entry. Tapping through saved sentences with a literal "[X]" as the user's
balanced thought, the "unsupported thought replacement" the Reference
warns against; the starter is now the placeholder only. Step 4 gains a
field to answer the Socratic question, carried through review, detail
view, Markdown export, search and draft autosave.

Wording and attributions: the step-order comment credited Padesky with an
order the code doesn't use (the order matches Burns and J. Beck); README no
longer calls the flow "the full Mind Over Mood walk"; "Padesky asks for
both" is Beck's outcome column. Hot thought is the most emotionally
charged one; belief is rated "at the time". The accuracy tile no longer
tests thoughts by how true they feel. The Outcome screen referred to a
prediction that is never collected. The intensity scale gets a 0 (None)
anchor and personal endpoints, and Severe starts at 80 where the grounding
note appears. The mood list drops non-emotions (hypervigilant,
blameworthy, threatened, excluded), de-duplicates "contemptuous", and adds
each family's plain word; retired words on old entries stay selectable.

Worry, activity, scope: "It's worry time" shows only inside the window;
"Most worries dissolve" and the fixed "Most worries didn't need the work"
overclaimed; Settings path fixed; a see-a-doctor line for symptom worries.
Mastery is a sense of accomplishment relative to today; the predicted-vs-
actual "gap" claim is softened per Furukawa 2018; the Patterns card no
longer claims a category is "most worth the time". The pivot chip no
longer prompts an apology. "CBT alone tends to fall short" for trauma,
psychosis and severe depression contradicted NICE; it now says a self-help
journal isn't enough on its own and names what does help.

Regression blocks 30-31 extend coverage: no stock reframe written on
seeding, Blame's default, the Track record / Magnification migrations, the
0 anchor and Severe edge, and per-country crisis lines with no dead links.
Full suite green: lint, check, crypto, smoke, flows, robustness, sync,
regressions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N8j1Ct5L5H38YPLcFi7bfn
…eelings, pivot prediction, worry loop

Decisions on the open questions from the content audit.

- Accuracy is judged after the evidence. The "facts back this thought up"
  choice from Step 3 comes back on Step 4 once both evidence lists are
  written, since distorted thoughts feel true too. No "partly accurate"
  state: the true-fact, distorted-conclusion case is the normal reframe
  path, and Step 5 now says so ("keep the true part, rewrite the
  conclusion").
- New feelings after the reframe. Mind Over Mood's last column re-rates
  the original moods "as well as any new moods". Added as words (relief,
  calm, hope), not rated rows: every mood statistic reads a falling
  number as progress, which a rising "relief" is not.
- A prediction before the pivot. Optional "What do you expect will
  happen?" on Step 6, shown again on the Outcome screen and entry, and in
  the reflection prompt, so the action becomes a small behavioral
  experiment with something to check against.
- Worry loop. Postponements are counted; after two, the worry says
  worry time is for dealing with it. "Open as thought record" becomes
  "Work it through or make a plan", since the thought record ends in one
  concrete step. No new resolution value, so stats and sync are unchanged.
- Activity types add "Work or study" and "Meaning", the behavioral
  activation life areas that had nowhere to go, with matching icons.
- "Jealousy" becomes "Jealousy & envy" (Parrott & Smith, 1993); stored
  moods migrate. Family names are now escaped wherever they render.
- Kept as is: saving an untouched belief slider's shown value. It is a
  deliberate choice (the number is on screen when you move on), and
  dropping it would silently remove belief-change data from Patterns.

New fields (newFeelings, pivotPrediction, postponeCount) go through
normalizeEntry, review, entry detail, Markdown export, search and draft
autosave. Regression block 32 covers all of it. Full suite green: lint,
check, crypto, smoke, flows, robustness, sync, regressions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N8j1Ct5L5H38YPLcFi7bfn
@iLevyTate
iLevyTate merged commit 0211221 into main Sep 28, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants