Swipes and a reader that will not scroll are reported (#384)

A swipe that only bounces sends no request and throws nothing, so
#383's stop at the 50th item left nothing in the log or the traces, and
the reader that would not scroll in the same report was never found.

The page now reports each swipe in the reader (next, prev, list, end,
short; a tap is not one) with where the reader stood, under the tap's
trace, and scroll_stuck when a drag up or down with room to move the
reader left it where it was. That one is watched by where the finger
was, not by what it landed on, so a layer lying over the reader is
caught, and its state names what is under the finger, what is inert,
the dialog, the reader's transform, a #dpeek left behind, and how long
since the app came back. ipx logs swipe as info and scroll_stuck as a
warning, in a new free-text state field, and the dashboard counts both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 20:46:31 +00:00
parent 385589ff77
commit 5c1970e8ee
7 changed files with 94 additions and 7 deletions

View File

@@ -1731,6 +1731,9 @@ test.describe('touch gestures on a phone', () => {
}
test('a swipe moves between items, and right from the first goes back to the list', async ({ page }) => {
// Each swipe says what came of it, and ipx takes it (#384); a scroll is not one.
const swipes = [];
page.on('request', r => { if (r.url().endsWith('/api/client') && r.postDataJSON()?.ev === 'swipe') swipes.push(r); });
await page.locator('#burger').click();
await page.locator('.feed', { hasText: 'Test Show' }).click();
await page.locator('.tabs button', { hasText: 'All' }).first().click();
@@ -1761,6 +1764,9 @@ test.describe('touch gestures on a phone', () => {
await expect(shown).toHaveText(titles[0]);
await drag(page, { x: 80, y: 400 }, { x: 300, y: 410 }); // right on the first: the list
await expect(page.locator('body')).not.toHaveClass(/reading/);
await expect.poll(() => swipes.length).toBe(6);
expect(swipes.map(r => r.postDataJSON().msg)).toEqual(['short', 'short', 'next', 'end', 'prev', 'list']);
for (const r of swipes) expect((await r.response())?.status()).toBe(204);
});
test('on the Unread tab, a swipe back goes to the item just read', async ({ page }) => {