Skip to content

Commit

Permalink
Debounce page refreshes triggered via Turbo streams
Browse files Browse the repository at this point in the history
Fix Turbo 8 refresh debounce in frontend #1093
  • Loading branch information
brunoprietog committed Dec 4, 2023
1 parent 5c48398 commit e237023
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/core/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ScrollObserver } from "../observers/scroll_observer"
import { StreamMessage } from "./streams/stream_message"
import { StreamMessageRenderer } from "./streams/stream_message_renderer"
import { StreamObserver } from "../observers/stream_observer"
import { clearBusyState, dispatch, findClosestRecursively, getVisitAction, markAsBusy } from "../util"
import { clearBusyState, dispatch, findClosestRecursively, getVisitAction, markAsBusy, debounce } from "../util"
import { PageView } from "./drive/page_view"
import { FrameElement } from "../elements/frame_element"
import { Preloader } from "./drive/preloader"
Expand Down Expand Up @@ -44,6 +44,7 @@ export class Session {

constructor(recentRequests) {
this.recentRequests = recentRequests
this.refresh = debounce(this.refresh.bind(this), 150)
}

start() {
Expand Down
24 changes: 17 additions & 7 deletions src/tests/functional/page_refresh_stream_action_tests.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test } from "@playwright/test"
import { assert } from "chai"
import { nextBeat } from "../helpers/page"
import { readEventLogs, sleep } from "../helpers/page"

test.beforeEach(async ({ page }) => {
await page.goto("/src/tests/fixtures/page_refresh_stream_action.html")
Expand All @@ -9,24 +9,24 @@ test.beforeEach(async ({ page }) => {
test("test refreshing the page", async ({ page }) => {
assert.match(await textContent(page), /Hello/)

await page.locator("#content").evaluate((content)=>content.innerHTML = "")
await page.locator("#content").evaluate((content) => content.innerHTML = "")
assert.notMatch(await textContent(page), /Hello/)

await page.click("#refresh button")
await nextBeat()
await sleep(250)

assert.match(await textContent(page), /Hello/)
})

test("don't refresh the page on self-originated request ids", async ({ page }) => {
assert.match(await textContent(page), /Hello/)

await page.locator("#content").evaluate((content)=>content.innerHTML = "")
page.evaluate(()=> { window.Turbo.session.recentRequests.add("123") })
await page.locator("#content").evaluate((content) => content.innerHTML = "")
page.evaluate(() => { window.Turbo.session.recentRequests.add("123") })

await page.locator("#request-id").evaluate((input)=>input.value = "123")
await page.locator("#request-id").evaluate((input) => input.value = "123")
await page.click("#refresh button")
await nextBeat()
await sleep(250)

assert.notMatch(await textContent(page), /Hello/)
})
Expand All @@ -42,6 +42,16 @@ test("fetch injects a Turbo-Request-Id with a UID generated automatically", asyn
}
})

test("debounce stream page refreshes", async ({ page }) => {
await page.click("#refresh button")
await page.click("#refresh button")
await sleep(250)

const eventLogs = await readEventLogs(page)
const requestLogs = eventLogs.filter(([name]) => name == "turbo:visit")
assert.equal(requestLogs.length, 1)
})

async function textContent(page) {
const messages = await page.locator("#content")
return await messages.textContent()
Expand Down
6 changes: 3 additions & 3 deletions src/tests/unit/stream_element_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { StreamElement } from "../../elements"
import { nextAnimationFrame } from "../../util"
import { DOMTestCase } from "../helpers/dom_test_case"
import { assert } from "@open-wc/testing"
import { nextBeat } from "../helpers/page"
import { sleep } from "../helpers/page"
import * as Turbo from "../../index"

function createStreamElement(action, target, templateElement) {
Expand Down Expand Up @@ -177,7 +177,7 @@ test("test action=refresh", async () => {
const element = createStreamElement("refresh")
subject.append(element)

await nextBeat()
await sleep(250)

assert.notOk(document.body.hasAttribute("data-modified"))
})
Expand All @@ -192,7 +192,7 @@ test("test action=refresh discarded when matching request id", async () => {
element.setAttribute("request-id", "123")
subject.append(element)

await nextBeat()
await sleep(250)

assert.ok(document.body.hasAttribute("data-modified"))
})
10 changes: 10 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,13 @@ export async function around(callback, reader) {

return [before, after]
}

export function debounce(fn, delay) {
let timeoutId = null

return (...args) => {
const callback = () => fn.apply(this, args)
clearTimeout(timeoutId)
timeoutId = setTimeout(callback, delay)
}
}

0 comments on commit e237023

Please sign in to comment.