oficina / slides Public

Clone
git clone https://amadan.net/oficina/slides

Plain git — no account needed to clone.

Download

Download this file

1//go:build browser
2
3package slidestest
4
5import (
6 "testing"
7
8 "github.com/chromedp/chromedp"
9 "github.com/chromedp/chromedp/kb"
10)
11
12// TestBrowserDroppedBatchStaysFailed: estilo's savestatus module loads
13// and moves the editor's save line, and a batch the server refused
14// (a 422, dropped rather than retried) keeps the line on the
15// dropped-batch words even after a later save succeeds — main's
16// behaviour since the "failed" state split from "Offline, retrying".
17func TestBrowserDroppedBatchStaysFailed(t *testing.T) {
18 rig, mailer := newRig(t)
19 browserSignIn(t, rig, mailer)
20 var deck string
21 rig.Run(chromedp.Evaluate(`document.querySelector('a[href^="/d/"]').getAttribute('href')`, &deck))
22 const heading = `[slides-stage] [data-block="heading"]`
23 rig.Run(
24 chromedp.Navigate(rig.Origin+deck+"/edit"),
25 waitFor(`document.querySelector('`+heading+`')?.getAttribute('contenteditable') === 'true'`),
26 // The line moves at all: a keystroke is "saving", then "saved".
27 chromedp.Evaluate(`(() => {
28 const line = document.querySelector('[estilo-save-status]')
29 window.__states = []
30 new MutationObserver(() => window.__states.push(line.dataset.state)).observe(line, { attributes: true })
31 })()`, nil),
32 chromedp.Click(heading, chromedp.ByQuery),
33 chromedp.SendKeys(heading, string(kb.End)+" kept", chromedp.ByQuery),
34 waitFor(`window.__states.includes('saving') && document.querySelector('[estilo-save-status]').dataset.state === 'saved'`),
35 chromedp.Evaluate(`(() => {
36 const before = window.fetch
37 let refuse = true
38 window.fetch = async (...args) => {
39 if (String(args[0]).endsWith('/updates') && args[1]?.method === 'POST') {
40 if (refuse) { refuse = false; setTimeout(() => { window.__refused = true }, 0); return new Response('', { status: 422 }) }
41 const res = await before(...args)
42 if (res.ok) setTimeout(() => { window.__savedAfter = true }, 0)
43 return res
44 }
45 return before(...args)
46 }
47 })()`, nil),
48 chromedp.Click(heading, chromedp.ByQuery),
49 chromedp.SendKeys(heading, string(kb.End)+" dropped", chromedp.ByQuery),
50 waitFor(`window.__refused === true`),
51 // The resync rebuilt the tab from the server: the dropped words are gone.
52 waitFor(`!document.querySelector('`+heading+`').textContent.includes('dropped')`),
53 waitFor(`document.querySelector('`+heading+`')?.getAttribute('contenteditable') === 'true'`),
54 chromedp.Click(heading, chromedp.ByQuery),
55 chromedp.SendKeys(heading, string(kb.End)+" later", chromedp.ByQuery),
56 waitFor(`window.__savedAfter === true`),
57 chromedp.Sleep(300),
58 )
59 var state, text, want string
60 rig.Run(
61 chromedp.Evaluate(`document.querySelector('[estilo-save-status]').dataset.state`, &state),
62 chromedp.Evaluate(`document.querySelector('[estilo-save-status]').textContent`, &text),
63 chromedp.Evaluate(`document.querySelector('[estilo-save-status]').dataset.textFailed`, &want),
64 )
65 if state != "failed" || text != want || want == "" {
66 t.Fatalf("after a dropped batch and a later save the line is state=%q text=%q, want failed %q", state, text, want)
67 }
68 rig.Screen("[slides-editor]", "dropped batch stays failed")
69}
70