Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test cached form action with revalidate #71591

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions test/e2e/app-dir/use-cache/app/form/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { revalidateTag, unstable_cacheTag as cacheTag } from 'next/cache'

async function refresh() {
'use server'
revalidateTag('home')
}

export default async function Page() {
'use cache'
cacheTag('home')

return (
<form action={refresh}>
<button id="refresh">Refresh</button>
<p id="t">{Date.now()}</p>
</form>
)
}
27 changes: 26 additions & 1 deletion test/e2e/app-dir/use-cache/use-cache.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { retry } from 'next-test-utils'
import { retry, waitFor } from 'next-test-utils'

const GENERIC_RSC_ERROR =
'An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.'
Expand Down Expand Up @@ -241,4 +241,29 @@ describe('use-cache', () => {
expect(await browser.elementByCss('p').text()).toBe('result')
})
})

it('should be able to revalidate a page using', async () => {
const browser = await next.browser(`/form`)
const time1 = await browser.waitForElementByCss('#t').text()

await browser.loadPage(new URL(`/form`, next.url).toString())

const time2 = await browser.waitForElementByCss('#t').text()

expect(time1).toBe(time2)

await browser.elementByCss('#refresh').click()

await waitFor(500)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may have the potential to become flaky. We could do this instead:

await retry(async () => {
  const time3 = await browser.waitForElementByCss('#t').text()
  expect(time3).not.toBe(time2)
})

Or are the 500ms related to the revalidation time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no it really should be made into something more like wait for a dom node to indicate that the action has completed but I couldn't figure out how to do it without a way to using useActionState.


const time3 = await browser.waitForElementByCss('#t').text()

expect(time3).not.toBe(time2)

// Reloading again should ideally be the same value but because the Action seeds
// the cache with real params as the argument it has a different cache key.
// await browser.loadPage(new URL(`/form?c`, next.url).toString())
// const time4 = await browser.waitForElementByCss('#t').text()
// expect(time4).toBe(time3);
})
})
Loading