SpellCheckCustomDictionary — Android WebView

What is being tested. The per-document dictionary lives in the renderer (SpellCheckProvider::document_custom_words_) and filters results after they come back from the platform checker, so on Android it should behave the same as on desktop even though the misspellings themselves are found by Android, not by Hunspell. These steps check that the filtering, the per-document scoping, and the caps all survive that round trip.

1. WebView opt-in: only spellcheck="true" is checked

Tap into each field below (Android checks text through the platform checker; a field may not be checked until it is focused).

1a. Opted in. Contains wugzz.

This wugzz is misspelled.

1b. Control, no attribute. Same word, no spellcheck attribute.

This wugzz is misspelled.
  1. Tap into 1a: wugzz should get a red squiggle.
  2. Tap into 1b: it should get no squiggle. WebView sets spellcheck_enabled_by_default = false, so an app's existing content is never spell checked unless it opts in.
  3. If 1a shows no squiggle either, stop: the emulator has no working spell checker service (the setup doc, step 2) and no later test is meaningful.
2. addWords() suppresses the squiggle document-wide

Both regions contain flooble: one contenteditable, one <textarea>, since WebView apps use both.

A flooble in a contenteditable.
  1. Tap into each region and confirm flooble is squiggled in both.
  2. Tap addWords once. The squiggle should clear in both regions, without any further interaction — one call covers the whole document, not just the focused field.
3. removeWords() restores the squiggle

Field contains grimpy.

One grimpy word here
  1. Tap into the field, confirm grimpy is squiggled, then tap addWords — the squiggle clears.
  2. Tap removeWords. If the field still has focus the squiggle comes back on the spot; if focus moved away, tap back into the field. Either way it must return without typing: removal clears SpellCheckProvider's cached result and invalidates the per-document check state, and a fresh pass then runs when the editable is focused by a user gesture. Unlike desktop, the answer arrives from another app in the emulator, so give it a second or two before calling it a failure.
  3. If it still has not returned, type one character and delete it, and record whether it returns then. That distinction matters: coming back only after an edit would mean the focus-driven refresh is not reaching the platform checker on Android, even though it does on desktop. Note which of the two steps made the squiggle reappear.
4. Matching is verbatim, and independent of script

Matching is exact: the stored word must equal the checked word.

A brilligzzz and a Brilligzzz.

4b is optional and only observable if the emulator's spell checker language (the setup doc, step 2) is set to a language that flags the text below. With an English-only spell checker service, Hebrew text is never flagged and there is nothing to see; record 4b as N/A in that case.

זה שלוס לא נכון.
  1. Tap into 4a. Check whether both brilligzzz and Brilligzzz are squiggled. If the platform checker leaves the capitalised form alone (some treat a capitalised word as a proper noun), the case part of this test is not observable on this image — record it as N/A and skip to Test 5. Gboard on google_apis does flag it, so it is normally observable.
  2. Tap addWords(["brilligzzz"]). The lower-case one clears; the capitalised one stays squiggled. The filter is an exact string match on the misspelled word (SpellCheck::CreateTextCheckingResults), so it is verbatim, not case-folded.
  3. (Optional) Repeat for 4b with the RTL word.
5. The dictionary is per-document, and does not survive a load

The set is cleared in SpellCheckProvider::DidCreateNewDocument(). A WebView is typically reused for many page loads, so a word added by one page must not leak into the next.

The word snorpled again.
  1. Tap into the field, confirm snorpled is squiggled, then tap addWords — the squiggle clears.
  2. Tap Reload this page, come back to this field and tap into it. snorpled must be squiggled again: the new document starts with an empty dictionary.
  3. Reloading also resets Tests 1–4, so run this before Test 6 and redo any earlier step you still need.
6. Per-document caps (20000 words / 128 bytes per word)

Run this last. The bulk step fills the per-document set for the rest of this document's life, so every earlier addWords would be silently dropped afterwards. If you need the earlier tests again, reload first.

Field A contains zzzzzqqqqq, field B contains capwordzz.

zzzzzqqqqq is misspelled.
capwordzz is misspelled.
  1. Below the cap. Tap into field A, then tap A: addWords. Its squiggle clears — normal behaviour below the cap.
  2. Fill the cap. Tap Fill cap. WebView must not crash or ANR, the page must stay scrollable and responsive, and the DevTools console (the setup doc, step 6) should show exactly one warning: “per-document word limit reached…”. The warning is emitted once per document, so tapping Fill cap again must not add a second one.
  3. Above the cap. Tap into field B, then tap B: addWords. The squiggle on capwordzz must stay: the word is rejected because the set is full. If it clears, the cap is not being enforced.

Results