import assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
import { load as cheerioLoad } from 'cheerio';
import { isWindows, loadFixture } from '../../../astro/test/test-utils.js';
let fixture;
describe('React Components', () => {
before(async () => {
fixture = await loadFixture({
root: new URL('./fixtures/react-component/', import.meta.url),
});
});
describe('build', () => {
before(async () => {
await fixture.build();
});
it('Can load React', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);
// test 1: basic component renders
assert.equal($('#react-static').text(), 'Hello static!');
// test 2: no reactroot
assert.equal($('#react-static').attr('data-reactroot'), undefined);
// test 3: Can use function components
assert.equal($('#arrow-fn-component').length, 1);
// test 4: Can use spread for components
assert.equal($('#component-spread-props').length, 1);
// test 5: spread props renders
assert.equal($('#component-spread-props').text(), 'Hello world!');
// test 6: Can use TS components
assert.equal($('.ts-component').length, 1);
// test 7: Can use Pure components
assert.equal($('#pure').length, 1);
// test 8: Check number of islands
assert.equal($('astro-island[uid]').length, 9);
// test 9: Check island deduplication
const uniqueRootUIDs = new Set($('astro-island').map((_i, el) => $(el).attr('uid')));
assert.equal(uniqueRootUIDs.size, 8);
// test 10: Should properly render children passed as props
const islandsWithChildren = $('.with-children');
assert.equal(islandsWithChildren.length, 2);
assert.equal(
$(islandsWithChildren[0]).html(),
$(islandsWithChildren[1]).find('astro-slot').html(),
);
// test 11: Should generate unique React.useId per island
const islandsWithId = $('.react-use-id');
assert.equal(islandsWithId.length, 2);
assert.notEqual($(islandsWithId[0]).attr('id'), $(islandsWithId[1]).attr('id'));
});
it('Can load Vue', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);
assert.equal($('#vue-h2').text(), 'Hasta la vista, baby');
});
it('Can use a pragma comment', async () => {
const html = await fixture.readFile('/pragma-comment/index.html');
const $ = cheerioLoad(html);
// test 1: rendered the PragmaComment component
assert.equal($('.pragma-comment').length, 2);
});
// TODO: is this still a relevant test?
it.skip('Includes reactroot on hydrating components', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);
const div = $('#research');
// test 1: has the hydration attr
assert.ok(div.attr('data-reactroot'));
// test 2: renders correctly
assert.equal(div.html(), 'foo bar 1');
});
it('Can load Suspense-using components', async () => {
const html = await fixture.readFile('/suspense/index.html');
const $ = cheerioLoad(html);
assert.equal($('#client #lazy').length, 1);
assert.equal($('#server #lazy').length, 1);
});
it('Can pass through props with cloneElement', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);
assert.equal($('#cloned').text(), 'Cloned With Props');
});
it('Children are parsed as React components, can be manipulated', async () => {
const html = await fixture.readFile('/children/index.html');
const $ = cheerioLoad(html);
assert.equal($('#one .with-children-count').text(), '2');
});
it('Client children passes option to the client', async () => {
const html = await fixture.readFile('/children/index.html');
const $ = cheerioLoad(html);
assert.equal($('[data-react-children]').length, 1);
});
});
if (isWindows) return;
describe('dev', () => {
/** @type {import('../../../astro/test/test-utils.js').Fixture} */
let devServer;
before(async () => {
devServer = await fixture.startDevServer();
});
after(async () => {
await devServer.stop();
});
it('scripts proxy correctly', async () => {
const html = await fixture.fetch('/').then((res) => res.text());
const $ = cheerioLoad(html);
for (const script of $('script').toArray()) {
const { src } = script.attribs;
if (!src) continue;
assert.equal((await fixture.fetch(src)).status, 200, `404: ${src}`);
}
});
// TODO: move this to separate dev test?
it.skip('Throws helpful error message on window SSR', async () => {
const html = await fixture.fetch('/window/index.html');
assert.ok(
(await html.text()).includes(
`[/window]
The window object is not available during server-side rendering (SSR).
Try using \`import.meta.env.SSR\` to write SSR-friendly code.
https://docs.astro.build/reference/api-reference/#importmeta`,
),
);
});
// In moving over to Vite, the jsx-runtime import is now obscured. TODO: update the method of finding this.
it.skip('uses the new JSX transform', async () => {
const html = await fixture.fetch('/index.html');
// Grab the imports
const exp = /import\("(.+?)"\)/g;
let match, componentUrl;
while ((match = exp.exec(html))) {
if (match[1].includes('Research.js')) {
componentUrl = match[1];
break;
}
}
const component = await fixture.readFile(componentUrl);
const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
// test 1: react/jsx-runtime is used for the component
assert.ok(jsxRuntime);
});
it('When a nested component throws it does not crash the server', async () => {
const res = await fixture.fetch('/error-rendering');
await res.arrayBuffer();
});
});
});
t/better-data-types'>feat/better-data-types
feat/better-table-type
feat/break-out-seed-returning
feat/cache-module-graph
feat/ci-next
feat/cli
feat/codemod
feat/config-log-level
feat/container
feat/context
feat/create-astro-replace-component-selector-with-astro-add
feat/create-astro-ui
feat/csr
feat/data-improvements
feat/data-with-set
feat/db-action
feat/db-relations
feat/define-data
feat/devtools
feat/dynamic-client-directives
feat/editor
feat/experimental-jsx
feat/expose-action-api-context
feat/expose-frontmatter-to-build-done-hook
feat/fetch-cache
feat/flow-components
feat/fonts-granular-preload
feat/fonts-retrieve-data
feat/foreign-key-migrations
feat/foreign-keys
feat/html-pages
feat/image-placeholders
feat/improve-custom-element-detection
feat/incremental-build
feat/indexes
feat/integration-kit
feat/jsx-transform
feat/legacy-markdown-flag
feat/markdoc-embeds
feat/markdown-components
feat/mdx-js-injection
feat/mdx-plugin-export
feat/minify-html
feat/next-get-env
feat/og
feat/ooo-streaming
feat/pragma
feat/preview
feat/react-19
feat/react-19-actions
feat/redirect-on-html-backup
feat/references
feat/remote-flag
feat/remove-astro-image-backup
feat/remove-studio
feat/render-with-queue
feat/reroute-ssr
feat/resolve-entrypoint
feat/router
feat/router-ii
feat/seo-components
feat/skip-sync-flag
feat/spa
feat/spa-ii
feat/squoosh
feat/standard-schema
feat/storage-studio
feat/streaming-rendering
feat/style-obj
feat/test-utils
feat/xray-improvements
fetch-astro-pages-mvp
fix-408
fix-all-pages-key
fix-beta-ref
fix-create-ref
fix-netlify-edge
fix-next-basics
fix-nullish-slot-name
fix-s-island-fallback
fix-vite-asset
fix/actions-cookies
fix/actions-pending-timeout
fix/assets-types
fix/astro-config-refresh
fix/astro-html-escape-bug
fix/build-subpaths
fix/client-only-component-css
fix/client-scripts-windows
fix/config-migration-defaults
fix/container-directives
fix/dates
fix/db-integration-with-missing-config
fix/devtoolbar-data-unset
fix/empty-slots
fix/filepath-layer
fix/frontmatter-file-url
fix/head-propagation
fix/hmr-css-deps
fix/import-ts-errors
fix/main-build-failure
fix/map-file-404-logs
fix/mdx-named-slots
fix/middleware-import
fix/multi-images
fix/nested-get-collection-call
fix/preact-package-build-failure
fix/primary-key-optional
fix/regex-flags
fix/server-headers
fix/stable-renderer-order
fix/transaction-type
fix/vue-nested
fix/webapi-dev
fork/markdoc-poc-with-md-support
fork/markdoc-poc-with-parser
format-imports-run
formatting
forward-button
framework-agnostic-astro-components
fryuni/db-pluggable-backend
fryuni/test-route-setup-hook
fryuni/tracing-hooks
hippotastic/legitimate-bat
hoisted-script-ts
host-ssr-example-2
hostfornode
image-non-node
improve-base-handling
inline-hoisted-scripts-now
jn.convert-assertions-to-query-params
latest
live-loaders
main
mandar1jn/ci-repo-check
markdoc-embed-prototyping
markdown
markdown-poc
mdx-path
mk/render-slot-template-backup
move-default-md-code-component
mt/lit-DSD
mt/lit-regen
mt/parse-DSD
mt/router_refactoring
nate/new-blog-template
netlify-1
netlify-preview
new-adapter-api
next
next-render
no-more-vite-postprocess
no-more-vite-postprocess2
old-build
plt-1006/unified-and-mdx
plt-1768-trailing-slash-object
preact-shared-signals
process-env-override
progress-log
re-export-drivers
react-fast-refresh
redirects-priority2
redirects-ssg-object
refactor-how-client-directives-work
refactor/image-internals
refactor/markdoc-renderer
refactor/rendere-queue
refactor/sitemap
refactor/ssr-size
release/0.17
release/0.18
remote-cdn-link
remove-fs-abstraction
remove-start
restart-on-lock
revert-13008-renovate/all-minor-patch
revert-lockfile
route-manifest-adapter
sarah11918-image-errors
sarah11918-patch-2
sb-tests2
seroval
server-islands-children
session-docs
single-file-build-2
slash-404-hint
slot-bug-1
solid-ecosystem-pkg
spike/app-setup
spike/autonav
spike/codehike
spike/context
spike/csr
spike/default-content
spike/incremental
spike/incremental-ii
spike/markdown-wasm
spike/render
spike/streaming
spike/svg
sqlite-test
squeal
ssr-redirect
stream-buffer
streaming
telemetry-audit-1
test/new-integrations-demo
test/new-ssr-demo
top-level-exports-integrations
ts-in-hoisted-script
ts-no-err
upd-vite-vendored
upgrade-deps
v1-beta
vercel-test
vite-fork
vscode-astro-global
vt-follow-redirects
warn-exp-flag
win
windows-tests-beta
wip-assets
wip-component-api-2
wip-docs-components
wip-docs-reference-gen
wip-fetch-cache
wip-fun-flags
wip-icons
wip-logging
wip-logging-saved
wip-mdc
wip-mdx-to-astro-js
wip-preview-command-integrations
wip-setup-content
wip-smoke
wip-speed-up-markdown
wip-stage
wip/react-19-test
Unnamed repository; edit this file 'description' to name the repository.
Age Commit message (Collapse ) Author Files Lines
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kelvin Soh <kelvinsoh@pop-os.localdomain>
Co-authored-by: Fred K. Schott <fkschott@gmail.com>
as 0kB, which is accurate, but confusing (#1329)
Co-authored-by: Fred K. Schott <fkschott@gmail.com>
* Add README stub for renderers
* Add renderer READMEs
* Update build command for Netlify
* Clarify directions for Netlify deploy versions
* Create deploy.md
* Update deploy.md
* Update deploy.md
Co-authored-by: Fred K. Schott <fkschott@gmail.com>
Co-authored-by: mundry <mundry@users.noreply.github.com>
* Adds a changeset
* Add types to examples and docs
* Make changes based on review feedback
* Avoid using the variable named props
* Make path a const
* Added GH pages disclaimer
* Added changeset
* Reworded disclaimer
* Correct GH Pages casing
* Update deploy.md
Co-authored-by: Fred K. Schott <fkschott@gmail.com>
* feat: add rewrite to play.astro.build
* fix: subpath redirects
* Prevent removing nodes, becasue styles preloading was detected earlier
* Add separate deduping for preloads and cover it with tests.
* Create quiet-horses-turn.md
* Test merging preload tags
Co-authored-by: mundry <mundry@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This reverts commit 1a88cfde7d2b3854e279c1bf3e12adf5d2155801.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>