-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RSC: Add RSC+SSR smoke test to CI (#10477)
Co-authored-by: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com>
- Loading branch information
1 parent
d8ee4cd
commit ebb3475
Showing
8 changed files
with
207 additions
and
6 deletions.
There are no files selected for viewing
85 changes: 85 additions & 0 deletions
85
__fixtures__/test-project-rsc-external-packages-and-cells/web/src/ServerRoutes.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// In this file, all Page components from 'src/pages` are auto-imported. Nested | ||
// directories are supported, and should be uppercase. Each subdirectory will be | ||
// prepended onto the component name. | ||
// | ||
// Examples: | ||
// | ||
// 'src/pages/HomePage/HomePage.js' -> HomePage | ||
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage | ||
|
||
import { Route } from '@redwoodjs/router/dist/Route' | ||
import { Router } from '@redwoodjs/router/dist/server-router' | ||
import { Set } from '@redwoodjs/router/dist/Set' | ||
|
||
import NavigationLayout from './layouts/NavigationLayout/NavigationLayout' | ||
import ScaffoldLayout from './layouts/ScaffoldLayout/ScaffoldLayout' | ||
import AboutPage from './pages/AboutPage/AboutPage' | ||
import EmptyUserEmptyUsersPage from './pages/EmptyUser/EmptyUsersPage/EmptyUsersPage' | ||
import EmptyUserNewEmptyUserPage from './pages/EmptyUser/NewEmptyUserPage/NewEmptyUserPage' | ||
import HomePage from './pages/HomePage/HomePage' | ||
import MultiCellPage from './pages/MultiCellPage/MultiCellPage' | ||
import UserExampleNewUserExamplePage from './pages/UserExample/NewUserExamplePage/NewUserExamplePage' | ||
import UserExampleUserExamplePage from './pages/UserExample/UserExamplePage/UserExamplePage' | ||
import UserExampleUserExamplesPage from './pages/UserExample/UserExamplesPage/UserExamplesPage' | ||
|
||
const NotFoundPage = () => { | ||
return <div>Not Found</div> | ||
} | ||
|
||
const Routes = ({ location }) => { | ||
return ( | ||
<Router location={location}> | ||
<Set wrap={NavigationLayout} rnd={Math.random()}> | ||
<Route path="/" page={HomePage} name="home" /> | ||
<Route path="/about" page={AboutPage} name="about" /> | ||
<Route path="/multi-cell" page={MultiCellPage} name="multiCell" /> | ||
|
||
<Set | ||
wrap={ScaffoldLayout} | ||
title="EmptyUsers" | ||
titleTo="emptyUsers" | ||
buttonLabel="New EmptyUser" | ||
buttonTo="newEmptyUser" | ||
> | ||
<Route | ||
path="/empty-users/new" | ||
page={EmptyUserNewEmptyUserPage} | ||
name="newEmptyUser" | ||
/> | ||
<Route | ||
path="/empty-users" | ||
page={EmptyUserEmptyUsersPage} | ||
name="emptyUsers" | ||
/> | ||
</Set> | ||
|
||
<Set | ||
wrap={ScaffoldLayout} | ||
title="UserExamples" | ||
titleTo="userExamples" | ||
buttonLabel="New UserExample" | ||
buttonTo="newUserExample" | ||
> | ||
<Route | ||
path="/user-examples/new" | ||
page={UserExampleNewUserExamplePage} | ||
name="newUserExample" | ||
/> | ||
<Route | ||
path="/user-examples/{id:Int}" | ||
page={UserExampleUserExamplePage} | ||
name="userExample" | ||
/> | ||
<Route | ||
path="/user-examples" | ||
page={UserExampleUserExamplesPage} | ||
name="userExamples" | ||
/> | ||
</Set> | ||
</Set> | ||
<Route notfound page={NotFoundPage} /> | ||
</Router> | ||
) | ||
} | ||
|
||
export default Routes |
10 changes: 8 additions & 2 deletions
10
__fixtures__/test-project-rsc-external-packages-and-cells/web/src/entry.server.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,22 @@ | ||
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags' | ||
|
||
import { Document } from './Document' | ||
import ServerRoutes from './ServerRoutes' | ||
|
||
interface Props { | ||
css: string[] | ||
meta?: TagDescriptor[] | ||
location: { | ||
pathname: string | ||
hash?: string | ||
search?: string | ||
} | ||
} | ||
|
||
export const ServerEntry: React.FC<Props> = ({ css, meta }) => { | ||
export const ServerEntry: React.FC<Props> = ({ css, meta, location }) => { | ||
return ( | ||
<Document css={css} meta={meta}> | ||
<div>App</div> | ||
<ServerRoutes location={location} /> | ||
</Document> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
tasks/smoke-tests/rsc-external-packages-and-cells/tests/rsc-ssr.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { test, expect } from '@playwright/test' | ||
|
||
// UA taken from https://developers.google.com/search/docs/crawling-indexing/overview-google-crawlers | ||
const BOT_USERAGENT = | ||
'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36' | ||
|
||
test('Check that homepage has content fully rendered from the server, without JS', async ({ | ||
browser, | ||
}) => { | ||
// Rendering as a bot here, to make sure we're getting the full page and not | ||
// just some of it, with the rest streamed in later | ||
const botContext = await browser.newContext({ | ||
userAgent: BOT_USERAGENT, | ||
// Even without JS, this should be a fully rendered page | ||
javaScriptEnabled: false, | ||
}) | ||
|
||
const page = await botContext.newPage() | ||
|
||
await page.goto('/') | ||
|
||
// Appears when the navigation layout has successfully rendered | ||
await page.waitForSelector('main') | ||
|
||
// The NavigationLayout should have a random number in it | ||
const rnd = await page.locator('div#rnd').innerHTML() | ||
expect(rnd).toMatch(/\s*\d+\s*/) | ||
|
||
// expect there to only be one h1 heading element on the page | ||
await expect(page.locator('h1')).toHaveCount(1) | ||
await expect(page.locator('h1').first()).toHaveText('Hello Anonymous!!') | ||
|
||
// There should be a link to the about page | ||
await expect(page.locator('a').getByText('About')).toBeVisible() | ||
|
||
await botContext.close() | ||
}) | ||
|
||
test('Make sure navigation works even without JS', async ({ browser }) => { | ||
// Rendering as a bot here, to make sure we're getting the full page and not | ||
// just some of it, with the rest streamed in later | ||
const botContext = await browser.newContext({ | ||
userAgent: BOT_USERAGENT, | ||
// Even without JS, this should be a fully rendered page | ||
javaScriptEnabled: false, | ||
}) | ||
|
||
const page = await botContext.newPage() | ||
|
||
await page.goto('/') | ||
|
||
// There should be a link to the about page | ||
const aboutLink = page.locator('a').getByText('About') | ||
expect(aboutLink).toBeVisible() | ||
|
||
// Clicking on the about link should take us to the about page | ||
await aboutLink.click() | ||
|
||
expect(page.url()).toMatch(/\/about$/) | ||
|
||
// expect there to only be one h1 heading element on the page | ||
await expect(page.locator('h1')).toHaveCount(1) | ||
await expect(page.locator('h1').first()).toHaveText('About Redwood') | ||
|
||
await botContext.close() | ||
}) | ||
|
||
test('The page should have a form button, but it should be non-interactive', async ({ | ||
browser, | ||
}) => { | ||
// Rendering as a bot here, to make sure we're getting the full page and not | ||
// just some of it, with the rest streamed in later | ||
const botContext = await browser.newContext({ | ||
userAgent: BOT_USERAGENT, | ||
// Even without JS, this should be a fully rendered page | ||
javaScriptEnabled: false, | ||
}) | ||
|
||
const page = await botContext.newPage() | ||
|
||
await page.goto('/about') | ||
|
||
const paragraphs = page.locator('p') | ||
|
||
// Expect the count to be 0 when the page is first loaded | ||
expect(paragraphs.getByText('Count: 0')).toBeVisible() | ||
|
||
await page.getByRole('button', { name: 'Increment' }).click() | ||
|
||
// The count should stay at 0, because the page should not be interactive | ||
// (This is the SSRed version of the page, with no JS) | ||
await expect(paragraphs.getByText('Count: 0')).toBeVisible() | ||
|
||
await expect(paragraphs.getByText('RSC on client: enabled')).toBeVisible() | ||
await expect(paragraphs.getByText('RSC on server: enabled')).toBeVisible() | ||
|
||
await botContext.close() | ||
}) |