diff --git a/examples/preact/BUILD.bazel b/examples/preact/BUILD.bazel new file mode 100644 index 00000000..10783b36 --- /dev/null +++ b/examples/preact/BUILD.bazel @@ -0,0 +1,46 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") +load("//:index.bzl", "prerender_pages", "web_resources_devserver") +load("//tools/jasmine:defs.bzl", "jasmine_web_test_suite") +load("//tools/typescript:defs.bzl", "ts_project") + +copy_to_bin( + name = "package", + srcs = ["package.json"], +) + +prerender_pages( + name = "site", + src = "site.tsx", + tsconfig = "//:tsconfig", + source_map = True, + # Need `"type": "module"` to load `*.js` files output by `*.tsx` compilation. + data = [":package"], + lib_deps = [ + "//:node_modules/@rules_prerender/preact", + "//:node_modules/preact", + ], + deps = ["//examples/preact/component"], +) + +web_resources_devserver( + name = "devserver", + resources = ":site", +) + +ts_project( + name = "test_lib", + srcs = ["test.mts"], + data = [":devserver"], + testonly = True, + deps = [ + "//common/testing:devserver", + "//common/testing:webdriver", + "//:node_modules/@types/jasmine", + ], +) + +jasmine_web_test_suite( + name = "test", + browsers = ["//tools/browsers:chromium-local"], + deps = [":test_lib"], +) diff --git a/examples/preact/component/BUILD.bazel b/examples/preact/component/BUILD.bazel new file mode 100644 index 00000000..d21c3230 --- /dev/null +++ b/examples/preact/component/BUILD.bazel @@ -0,0 +1,26 @@ +load("//tools/typescript:defs.bzl", "ts_project") +load("//:index.bzl", "css_library", "prerender_component") + +prerender_component( + name = "component", + srcs = ["component.tsx"], + scripts = [":script"], + styles = [":style"], + tsconfig = "//:tsconfig", + source_map = True, + visibility = ["//examples/preact:__pkg__"], + lib_deps = [ + "//:node_modules/@rules_prerender/preact", + "//:node_modules/preact", + ], +) + +ts_project( + name = "script", + srcs = ["script.mts"], +) + +css_library( + name = "style", + srcs = ["style.css"], +) diff --git a/examples/preact/component/component.tsx b/examples/preact/component/component.tsx new file mode 100644 index 00000000..ede74d64 --- /dev/null +++ b/examples/preact/component/component.tsx @@ -0,0 +1,19 @@ +import { Template, includeScript, inlineStyle } from '@rules_prerender/preact'; +import { ComponentChildren, VNode } from 'preact'; + +export function Component({ text, children }: { + text: string, + children: ComponentChildren, +}): VNode { + return
+ +
This text to be replaced by page JavaScript.
+ {children} +
; +} diff --git a/examples/preact/component/script.mts b/examples/preact/component/script.mts new file mode 100644 index 00000000..024c5c61 --- /dev/null +++ b/examples/preact/component/script.mts @@ -0,0 +1 @@ +document.getElementById('replace')!.textContent = 'Hello from JavaScript!'; diff --git a/examples/preact/component/style.css b/examples/preact/component/style.css new file mode 100644 index 00000000..d7d3458a --- /dev/null +++ b/examples/preact/component/style.css @@ -0,0 +1,3 @@ +h2 { + color: red; +} diff --git a/examples/preact/package.json b/examples/preact/package.json new file mode 100644 index 00000000..3dbc1ca5 --- /dev/null +++ b/examples/preact/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/examples/preact/site.tsx b/examples/preact/site.tsx new file mode 100644 index 00000000..96b4ed63 --- /dev/null +++ b/examples/preact/site.tsx @@ -0,0 +1,18 @@ +import { PrerenderResource, renderToHtml } from '@rules_prerender/preact'; +import { Component } from './component/component.js'; + +export default function*(): Generator { + yield PrerenderResource.of('/index.html', renderToHtml( + + + Preact + + + + +

Goodbye, World!

+
+ + + )); +} diff --git a/examples/preact/test.mts b/examples/preact/test.mts new file mode 100644 index 00000000..81c49bb4 --- /dev/null +++ b/examples/preact/test.mts @@ -0,0 +1,28 @@ +import { useDevserver } from '../../common/testing/devserver.mjs'; +import { useWebDriver, getColor } from '../../common/testing/webdriver.mjs'; + +describe('preact', () => { + const devserver = useDevserver('examples/preact/devserver.sh'); + const wd = useWebDriver(devserver); + + it('renders', async () => { + const browser = wd.get(); + await browser.url('/'); + + expect(await browser.getTitle()).toBe('Preact'); + + // Test JavaScript execution. + expect(await browser.$('#replace').getText()) + .toBe('Hello from JavaScript!'); + + // Test CSS applied within declarative shadow DOM. + const hello = await browser.$('#component').shadow$('h2'); + expect(await hello.getText()).toBe('Hello, World!'); + expect(await getColor(browser, hello)).toBe('rgb(255, 0, 0)'); // Red. + + // Test CSS did *not* apply in component light DOM. + const goodbye = await browser.$('h2'); + expect(await goodbye.getText()).toBe('Goodbye, World!'); + expect(await getColor(browser, goodbye)).toBe('rgb(0, 0, 0)'); // Black. + }); +});