//go:build browser package gallery import ( "context" "encoding/json" "net/http" "strings" "testing" "time" "github.com/chromedp/chromedp" "amadan.net/rastrillo/fiesta" "amadan.net/rastrillo/fiesta/internal/harness" ) // The samples in the page's language, as a reader meets them: the // enhanced controls speak the page's language once their scripts have // run, and the money sample is written the page's way with no script // at all. // jaStrings is the framework's own Japanese catalog's plain strings. func jaStrings(t *testing.T) map[string]string { t.Helper() b, ok := fiesta.Strings("ja") if !ok { t.Fatal("the framework has no ja catalog") } var raw map[string]json.RawMessage if err := json.Unmarshal(b, &raw); err != nil { t.Fatal(err) } out := map[string]string{} for k, v := range raw { var s string if json.Unmarshal(v, &s) == nil { out[k] = s } } return out } // TestTheEnhancedControlsSpeakThePagesLanguage: in day/ja, the // filterable select, opened, offers its filter in Japanese, and the // date field's calendar button is named in Japanese and opens a // calendar named in Japanese. The frames load no script table, so the // words can only have come from the attributes the gallery wrote. func TestTheEnhancedControlsSpeakThePagesLanguage(t *testing.T) { rig := harness.New(t, func(string) http.Handler { return treeHandler(t) }) ctx, cancel := context.WithTimeout(rig.Context(), 2*time.Minute) defer cancel() ja := jaStrings(t) sel := mustEntry(t, "field-select") date := mustEntry(t, "field-date") selState, dateState := "", "" for _, st := range sel.States { if strings.Contains(st.ID, "filterable") { selState = st.ID } } for _, st := range date.States { if strings.HasPrefix(st.ID, "enhanced") { dateState = st.ID } } if selState == "" || dateState == "" { t.Fatalf("no filterable select (%q) or enhanced date field (%q) to open", selState, dateState) } mustRun(t, ctx, chromedp.EmulateViewport(900, 900), chromedp.Navigate(rig.Origin+href("day/ja/frames/field-select/"+selState+".html"))) until(t, ctx, "the select is enhanced", `!!document.querySelector("[rst-combo] input[role=combobox]")`) mustRun(t, ctx, chromedp.Click(`[rst-combo] input[role=combobox]`, chromedp.ByQuery)) until(t, ctx, "the select opens", `document.querySelector("[rst-combo] input[role=combobox]").getAttribute("aria-expanded") === "true"`) var placeholder string at(t, ctx, `JSON.stringify(document.querySelector("[rst-combo] input[role=combobox]").placeholder)`, &placeholder) if placeholder != ja["select-filter"] { t.Errorf("day/ja's filterable select, opened, offers its filter as %q, want %q", placeholder, ja["select-filter"]) } mustRun(t, ctx, chromedp.Navigate(rig.Origin+href("day/ja/frames/field-date/"+dateState+".html"))) until(t, ctx, "the date field is enhanced", `!!document.querySelector("[rst-dtp] [rst-dtp-pick]")`) var pick string at(t, ctx, `JSON.stringify(document.querySelector("[rst-dtp] [rst-dtp-pick]").getAttribute("aria-label"))`, &pick) if pick != ja["date-pick"] { t.Errorf("day/ja's date field names its calendar button %q, want %q", pick, ja["date-pick"]) } mustRun(t, ctx, chromedp.Click(`[rst-dtp] [rst-dtp-pick]`, chromedp.ByQuery)) until(t, ctx, "the calendar opens", `(() => { const c = document.querySelector("[rst-cal]"); return !!c && !c.hidden; })()`) var cal string at(t, ctx, `JSON.stringify(document.querySelector("[rst-cal]").getAttribute("aria-label"))`, &cal) if cal != ja["date-calendar"] { t.Errorf("day/ja's calendar, opened, is named %q, want %q", cal, ja["date-calendar"]) } } // TestMoneySamplesWithNoScript: the Money sample is server-rendered // text, so with no JavaScript the Spanish frame still shows the amounts // written the Spanish way; and the money field is a plain input with // its decimal keyboard and its hidden currency, as Rastrillo holds it. // Each frame is driven at its own URL, as Rastrillo's drive does. func TestMoneySamplesWithNoScript(t *testing.T) { rig := harness.New(t, func(string) http.Handler { return treeHandler(t) }) ctx, cancel := context.WithTimeout(rig.Context(), 60*time.Second) defer cancel() off := noScripts(t, ctx) money := mustEntry(t, moneyExample) var formats string if err := chromedp.Run(off, chromedp.Navigate(rig.Origin+href("day/es/frames/"+moneyExample+"/"+money.Default+".html")), chromedp.Text("dl", &formats, chromedp.ByQuery)); err != nil { t.Fatalf("es money sample, scripts off: %v", err) } requireScriptsOff(t, off, "es money sample, scripts off") if !strings.Contains(formats, "1284,50 €") { t.Errorf("Spanish money sample with no script: %q", formats) } field := mustEntry(t, "field-money") var form string if err := chromedp.Run(off, chromedp.Navigate(rig.Origin+href("day/es/frames/field-money/"+field.Default+".html")), chromedp.OuterHTML("input[inputmode]", &form, chromedp.ByQuery)); err != nil { t.Fatalf("es field-money sample, scripts off: %v", err) } requireScriptsOff(t, off, "es field-money sample, scripts off") if !strings.Contains(form, `inputmode="decimal"`) { t.Errorf("field-money with no script: %s", form) } }