-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a browse test for a prerendered counter component.
Refs #36. This prerenders a `site-counter` component and then loads it in Puppeteer based the second strategy suggested in #36 (comment). This requires quite a bit of boilerplate but is relatively intuitive and mostly works out of the box. It does rely on testing helpers private to `rules_prerender` which real users would not be able to take advantage of (`useDevserver()`, `usePuppeteer()`, `resolveRunfile()`). Regardless, it tests the critical integration point of JavaScript running on prerendered HTML, verifying that the content is hydrated and used correctly. This does include the known downside of using separate files for generating test cases and actually running the tests. It requires a bit of unfortunate back and forth, but isn't too bad for a simple counter at least. Some helpers could be introduced to reduce the boilerplate, such as a `generateTestCase('Zero', () => `<site-counter>...</site-counter>`)` which could generate all the HTML scaffolding for the page with a given title and body content. `useDevserver()` and `usePuppeteer()` could be turned into public APIs (maybe less opinionated though). One unfortunate limitation of the current approach is that the page hydrates too fast for Puppeteer to inspect the browser DOM. We could drop the prerender unit test and merge it into this if it were possible teo inspect the component DOM before it hydrates. It would allow us to easily test that the component prerendered to a good state (initial value visible, buttons disabled, etc.) before testing the loaded JavaScript. Again, some more opinionated test helpers might be able to defer JS execution to make this possible.
- Loading branch information
Showing
3 changed files
with
183 additions
and
3 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import 'jasmine'; | ||
|
||
import { useDevserver } from 'rules_prerender/common/testing/devserver'; | ||
import { resolveRunfile } from 'rules_prerender/common/runfiles'; | ||
import { puppeteerTestTimeout, useBrowser, usePage } from 'rules_prerender/common/testing/puppeteer'; | ||
|
||
const devserverBinary = resolveRunfile( | ||
'rules_prerender/examples/site/components/counter/counter_test_cases_devserver'); | ||
|
||
describe('Counter', () => { | ||
const devserver = useDevserver(devserverBinary); | ||
const browser = useBrowser(); | ||
const page = usePage(browser); | ||
|
||
it('increments when the increment button is clicked', async () => { | ||
await page.get().goto( | ||
`http://${devserver.get().host}:${devserver.get().port}/zero.html`, | ||
{ waitUntil: 'load' }, | ||
); | ||
|
||
const counter = (await page.get().$('site-counter'))!; | ||
|
||
const initialLbl = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(initialLbl).toBe('The current count is: 0.'); | ||
|
||
const incrementBtn = (await counter.$('[increment]'))!; | ||
await incrementBtn.click(); | ||
|
||
const incrementedLabel = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(incrementedLabel).toBe('The current count is: 1.'); | ||
}, puppeteerTestTimeout); | ||
|
||
it('decrements when the decrement button is clicked', async () => { | ||
await page.get().goto( | ||
`http://${devserver.get().host}:${devserver.get().port}/zero.html`, | ||
{ waitUntil: 'load' }, | ||
); | ||
|
||
const counter = (await page.get().$('site-counter'))!; | ||
|
||
const initialLbl = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(initialLbl).toBe('The current count is: 0.'); | ||
|
||
const decrementBtn = (await counter.$('[decrement]'))!; | ||
await decrementBtn.click(); | ||
|
||
const decrementedLabel = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(decrementedLabel).toBe('The current count is: -1.'); | ||
}, puppeteerTestTimeout); | ||
|
||
it('hydrates from an initial positive value', async () => { | ||
await page.get().goto( | ||
`http://${devserver.get().host}:${devserver.get().port}/positive.html`, | ||
{ waitUntil: 'load' }, | ||
); | ||
|
||
const counter = (await page.get().$('site-counter'))!; | ||
|
||
const initialLbl = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(initialLbl).toBe('The current count is: 4.'); | ||
|
||
// Increment to confirm that the initialized value is actually used. | ||
const incrementBtn = (await counter.$('[increment]'))!; | ||
await incrementBtn.click(); | ||
|
||
const incrementedLabel = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(incrementedLabel).toBe('The current count is: 5.'); | ||
}, puppeteerTestTimeout); | ||
|
||
it('hydrates from an initial negative value', async () => { | ||
await page.get().goto( | ||
`http://${devserver.get().host}:${devserver.get().port}/negative.html`, | ||
{ waitUntil: 'load' }, | ||
); | ||
|
||
const counter = (await page.get().$('site-counter'))!; | ||
|
||
const initialLbl = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(initialLbl).toBe('The current count is: -7.'); | ||
|
||
// Increment to confirm that the initialized value is actually used. | ||
const incrementBtn = (await counter.$('[increment]'))!; | ||
await incrementBtn.click(); | ||
|
||
const incrementedLabel = | ||
await counter.$eval('[label]', (el) => el.textContent); | ||
expect(incrementedLabel).toBe('The current count is: -6.'); | ||
}, puppeteerTestTimeout); | ||
}); |
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,44 @@ | ||
import { PrerenderResource } from 'rules_prerender'; | ||
import { renderCounter } from 'rules_prerender/examples/site/components/counter/counter_prerender'; | ||
|
||
/** Generates prerendered test cases of the counter. */ | ||
export default function* (): Generator<PrerenderResource, void, void> { | ||
// Prerendered counter with an initial value of zero. | ||
yield PrerenderResource.of('/zero.html', ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Zero</title> | ||
</head> | ||
<body> | ||
${renderCounter(0 /* initial value */)} | ||
</body> | ||
</html> | ||
`); | ||
|
||
// Prerendered counter with a positive initial value (4). | ||
yield PrerenderResource.of('/positive.html', ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Positive</title> | ||
</head> | ||
<body> | ||
${renderCounter(4 /* initial value */)} | ||
</body> | ||
</html> | ||
`); | ||
|
||
// Prerendered counter with a negative initial value (-7). | ||
yield PrerenderResource.of('/negative.html', ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Negative</title> | ||
</head> | ||
<body> | ||
${renderCounter(-7 /* initial value */)} | ||
</body> | ||
</html> | ||
`); | ||
} |