vitest-browser-qwik 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{pure-Cwz8HPNP.d.ts → pure-1MgDxC6b.d.ts} +2 -3
- package/dist/{pure-BWRD5UQA.js → pure-BRpTMupH.js} +8 -10
- package/dist/pure.d.ts +1 -1
- package/dist/pure.js +1 -1
- package/dist/ssr-plugin.js +22 -65
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as cleanup, c as renderServerHTML, i as SSRRenderOptions, o as render, r as RenderResult, s as renderHook } from "./pure-1MgDxC6b.js";
|
|
2
2
|
import { JSXOutput } from "@builder.io/qwik";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
5
|
declare function renderSSR(jsxNode: JSXOutput): Promise<RenderResult>;
|
|
6
|
-
declare module "
|
|
6
|
+
declare module "vitest/browser" {
|
|
7
7
|
interface BrowserPage {
|
|
8
8
|
render: typeof render;
|
|
9
9
|
renderServerHTML: typeof renderServerHTML;
|
|
@@ -15,4 +15,4 @@ declare module "@vitest/browser/context" {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|
|
18
|
-
export { RenderResult, SSRRenderOptions, cleanup, render, renderHook, renderSSR, renderServerHTML };
|
|
18
|
+
export { type RenderResult, type SSRRenderOptions, cleanup, render, renderHook, renderSSR, renderServerHTML };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { page } from "@vitest/browser/context";
|
|
1
|
+
import { i as renderServerHTML, n as render, r as renderHook, t as cleanup } from "./pure-BRpTMupH.js";
|
|
3
2
|
import { beforeEach } from "vitest";
|
|
3
|
+
import { page } from "vitest/browser";
|
|
4
4
|
|
|
5
5
|
//#region src/index.ts
|
|
6
6
|
function renderSSR(jsxNode) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Locator, LocatorSelectors } from "
|
|
1
|
+
import { Locator, LocatorSelectors, PrettyDOMOptions } from "vitest/browser";
|
|
2
2
|
import { JSXOutput } from "@builder.io/qwik";
|
|
3
|
-
import { PrettyDOMOptions } from "@vitest/browser/utils";
|
|
4
3
|
|
|
5
4
|
//#region src/pure.d.ts
|
|
6
5
|
interface RenderResult extends LocatorSelectors {
|
|
@@ -33,4 +32,4 @@ interface RenderHookResult<Result> {
|
|
|
33
32
|
declare function renderHook<Result>(hook: () => Result): Promise<RenderHookResult<Result>>;
|
|
34
33
|
declare function cleanup(): Promise<void>;
|
|
35
34
|
//#endregion
|
|
36
|
-
export {
|
|
35
|
+
export { cleanup as a, renderServerHTML as c, SSRRenderOptions as i, RenderOptions as n, render$1 as o, RenderResult as r, renderHook as s, RenderHookResult as t };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { utils } from "vitest/browser";
|
|
1
2
|
import { component$, render } from "@builder.io/qwik";
|
|
2
3
|
import { getQwikLoaderScript } from "@builder.io/qwik/server";
|
|
3
|
-
import { debug, getElementLocatorSelectors } from "@vitest/browser/utils";
|
|
4
4
|
import { jsx } from "@builder.io/qwik/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/pure.tsx
|
|
7
|
-
const
|
|
7
|
+
const { debug, getElementLocatorSelectors } = utils;
|
|
8
|
+
const mountedContainers = /* @__PURE__ */ new Set();
|
|
8
9
|
let qwikLoaderInjected = false;
|
|
9
10
|
function csrQwikLoader() {
|
|
10
11
|
if (qwikLoaderInjected) return;
|
|
@@ -47,8 +48,7 @@ function render$1(ui, { container, baseElement } = {}) {
|
|
|
47
48
|
}
|
|
48
49
|
function setHTMLWithScripts(container, html) {
|
|
49
50
|
container.innerHTML = html;
|
|
50
|
-
|
|
51
|
-
scripts.forEach((oldScript) => {
|
|
51
|
+
container.querySelectorAll("script").forEach((oldScript) => {
|
|
52
52
|
const newScript = document.createElement("script");
|
|
53
53
|
for (const attr of oldScript.attributes) newScript.setAttribute(attr.name, attr.value);
|
|
54
54
|
newScript.text = oldScript.textContent ?? "";
|
|
@@ -66,13 +66,11 @@ async function renderHook(hook) {
|
|
|
66
66
|
const renderPromise = new Promise((resolve) => {
|
|
67
67
|
resolveRender = resolve;
|
|
68
68
|
});
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
resultContainer.value = result;
|
|
69
|
+
const screen = render$1(/* @__PURE__ */ jsx(component$(() => {
|
|
70
|
+
resultContainer.value = hook();
|
|
72
71
|
resolveRender();
|
|
73
72
|
return /* @__PURE__ */ jsx("div", { "data-testid": "hook-result" });
|
|
74
|
-
});
|
|
75
|
-
const screen = render$1(/* @__PURE__ */ jsx(TestHookComponent, {}));
|
|
73
|
+
}), {}));
|
|
76
74
|
await renderPromise;
|
|
77
75
|
return {
|
|
78
76
|
result: resultContainer.value ?? (() => {
|
|
@@ -92,4 +90,4 @@ async function cleanup() {
|
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
//#endregion
|
|
95
|
-
export {
|
|
93
|
+
export { renderServerHTML as i, render$1 as n, renderHook as r, cleanup as t };
|
package/dist/pure.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as cleanup, c as renderServerHTML, i as SSRRenderOptions, n as RenderOptions, o as render, r as RenderResult, s as renderHook, t as RenderHookResult } from "./pure-1MgDxC6b.js";
|
|
2
2
|
export { RenderHookResult, RenderOptions, RenderResult, SSRRenderOptions, cleanup, render, renderHook, renderServerHTML };
|
package/dist/pure.js
CHANGED
package/dist/ssr-plugin.js
CHANGED
|
@@ -2,46 +2,22 @@ import { dirname, relative, resolve } from "node:path";
|
|
|
2
2
|
import { symbolMapper } from "@builder.io/qwik/optimizer";
|
|
3
3
|
import MagicString from "magic-string";
|
|
4
4
|
import { parseSync } from "oxc-parser";
|
|
5
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
5
6
|
|
|
6
|
-
//#region rolldown:runtime
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
13
|
-
key = keys[i];
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
15
|
-
get: ((k) => from[k]).bind(null, key),
|
|
16
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
return to;
|
|
20
|
-
};
|
|
21
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
//#region node_modules/.pnpm/oxc-resolver@11.2.0/node_modules/oxc-resolver/browser.js
|
|
25
|
-
var browser_exports = {};
|
|
26
|
-
import * as import___oxc_resolver_binding_wasm32_wasi from "@oxc-resolver/binding-wasm32-wasi";
|
|
27
|
-
__reExport(browser_exports, import___oxc_resolver_binding_wasm32_wasi);
|
|
28
|
-
|
|
29
|
-
//#endregion
|
|
30
7
|
//#region src/ssr-plugin-utils.ts
|
|
31
|
-
const resolver = new
|
|
8
|
+
const resolver = new ResolverFactory({ extensions: [
|
|
32
9
|
".tsx",
|
|
33
10
|
".ts",
|
|
34
11
|
".jsx",
|
|
35
12
|
".js"
|
|
36
13
|
] });
|
|
37
14
|
function isFunction(node) {
|
|
38
|
-
|
|
15
|
+
return [
|
|
39
16
|
"FunctionDeclaration",
|
|
40
17
|
"FunctionExpression",
|
|
41
18
|
"TSDeclareFunction",
|
|
42
19
|
"TSEmptyBodyFunctionExpression"
|
|
43
|
-
];
|
|
44
|
-
return functionTypes.includes(node.type);
|
|
20
|
+
].includes(node.type);
|
|
45
21
|
}
|
|
46
22
|
function isCallExpression(node) {
|
|
47
23
|
return node.type === "CallExpression";
|
|
@@ -109,8 +85,7 @@ function extractPropsFromJSX(attributes, sourceCode) {
|
|
|
109
85
|
const propName = jsxAttr.name.name;
|
|
110
86
|
if (isJSXExpressionContainer(jsxAttr.value) && jsxAttr.value.expression.type !== "JSXEmptyExpression") {
|
|
111
87
|
const exprSpan = jsxAttr.value.expression;
|
|
112
|
-
|
|
113
|
-
props[propName] = expressionCode;
|
|
88
|
+
props[propName] = sourceCode.slice(exprSpan.start, exprSpan.end);
|
|
114
89
|
} else if (jsxAttr.value.type === "Literal") {
|
|
115
90
|
const literal = jsxAttr.value;
|
|
116
91
|
props[propName] = JSON.stringify(literal.value);
|
|
@@ -123,10 +98,8 @@ function isTestFile(id) {
|
|
|
123
98
|
}
|
|
124
99
|
function fallbackResolveComponentPath(importPath, testFileId) {
|
|
125
100
|
if (!importPath.startsWith(".")) return importPath.endsWith(".tsx") || importPath.endsWith(".ts") ? importPath : `${importPath}.tsx`;
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
const projectRoot = process.cwd();
|
|
129
|
-
let componentPath = `./${relative(projectRoot, resolvedPath)}`;
|
|
101
|
+
const resolvedPath = resolve(dirname(testFileId), importPath);
|
|
102
|
+
let componentPath = `./${relative(process.cwd(), resolvedPath)}`;
|
|
130
103
|
if (!componentPath.endsWith(".tsx") && !componentPath.endsWith(".ts")) componentPath += ".tsx";
|
|
131
104
|
return componentPath;
|
|
132
105
|
}
|
|
@@ -137,21 +110,18 @@ function resolveComponentPath(importPath, testFileId) {
|
|
|
137
110
|
console.warn(`[oxc-resolver] Could not resolve "${importPath}" from "${testFileId}": ${result.error || "No path resolved"}. Using fallback resolution.`);
|
|
138
111
|
return fallbackResolveComponentPath(importPath, testFileId);
|
|
139
112
|
}
|
|
140
|
-
const
|
|
141
|
-
const relativePath = relative(projectRoot, result.path);
|
|
113
|
+
const relativePath = relative(process.cwd(), result.path);
|
|
142
114
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
143
115
|
}
|
|
144
116
|
function hasCommandsImport(node) {
|
|
145
|
-
if (!isImportDeclaration(node) || node.source?.value !== "
|
|
117
|
+
if (!isImportDeclaration(node) || node.source?.value !== "vitest/browser" || !node.specifiers) return false;
|
|
146
118
|
return node.specifiers.some((spec) => spec.type === "ImportSpecifier" && spec.imported.type === "Identifier" && spec.imported.name === "commands");
|
|
147
119
|
}
|
|
148
120
|
async function renderComponentToSSR(ctx, Component, props = {}) {
|
|
149
121
|
const viteServer = ctx.project.vite;
|
|
150
|
-
const
|
|
151
|
-
const { jsx } = qwikModule;
|
|
122
|
+
const { jsx } = await viteServer.ssrLoadModule("@builder.io/qwik");
|
|
152
123
|
const jsxElement = jsx(Component, props);
|
|
153
|
-
const
|
|
154
|
-
const { renderToStream } = serverModule;
|
|
124
|
+
const { renderToStream } = await viteServer.ssrLoadModule("@builder.io/qwik/server");
|
|
155
125
|
let html = "";
|
|
156
126
|
await renderToStream(jsxElement, {
|
|
157
127
|
containerTagName: "div",
|
|
@@ -168,13 +138,11 @@ async function renderComponentToSSR(ctx, Component, props = {}) {
|
|
|
168
138
|
//#endregion
|
|
169
139
|
//#region src/ssr-plugin.ts
|
|
170
140
|
const renderSSRCommand = async (ctx, componentPath, componentName, props = {}) => {
|
|
171
|
-
const
|
|
172
|
-
const absoluteComponentPath = resolve(projectRoot, componentPath);
|
|
141
|
+
const absoluteComponentPath = resolve(process.cwd(), componentPath);
|
|
173
142
|
const viteServer = ctx.project.vite;
|
|
174
143
|
if (!viteServer.config.define) return;
|
|
175
144
|
for (const [key, value] of Object.entries(viteServer.config.env)) viteServer.config.define[`__vite_ssr_import_meta__.env.${key}`] = JSON.stringify(value);
|
|
176
|
-
const
|
|
177
|
-
const Component = componentModule[componentName];
|
|
145
|
+
const Component = (await viteServer.ssrLoadModule(absoluteComponentPath))[componentName];
|
|
178
146
|
if (!Component) throw new Error(`Component "${componentName}" not found in ${absoluteComponentPath}`);
|
|
179
147
|
return await renderComponentToSSR(ctx, Component, props);
|
|
180
148
|
};
|
|
@@ -185,8 +153,7 @@ const renderSSRLocalCommand = async (ctx, testFilePath, componentName, allLocalC
|
|
|
185
153
|
const { readFileSync, writeFileSync, unlinkSync } = await import("node:fs");
|
|
186
154
|
const { dirname: dirname$1, join } = await import("node:path");
|
|
187
155
|
const tempFileName = `ssr-test-${Date.now()}-${Math.random().toString(36).slice(2, 11)}.tsx`;
|
|
188
|
-
const
|
|
189
|
-
const tempFilePath = join(testFileDir, tempFileName);
|
|
156
|
+
const tempFilePath = join(dirname$1(testFilePath), tempFileName);
|
|
190
157
|
try {
|
|
191
158
|
const originalContent = readFileSync(testFilePath, "utf8");
|
|
192
159
|
const ast = parseSync(testFilePath, originalContent);
|
|
@@ -204,7 +171,6 @@ const renderSSRLocalCommand = async (ctx, testFilePath, componentName, allLocalC
|
|
|
204
171
|
}
|
|
205
172
|
}
|
|
206
173
|
traverseChildren(node, cleanTestFile);
|
|
207
|
-
return void 0;
|
|
208
174
|
}
|
|
209
175
|
cleanTestFile(ast.program);
|
|
210
176
|
let cleanedContent = s.toString();
|
|
@@ -234,8 +200,8 @@ function testSSR() {
|
|
|
234
200
|
const ast = parseSync(id, code);
|
|
235
201
|
if (!hasRenderSSRCallInAST(ast.program, code)) return null;
|
|
236
202
|
const s = new MagicString(code);
|
|
237
|
-
const componentImports = new Map();
|
|
238
|
-
const localComponents = new Map();
|
|
203
|
+
const componentImports = /* @__PURE__ */ new Map();
|
|
204
|
+
const localComponents = /* @__PURE__ */ new Map();
|
|
239
205
|
const renderSSRIdentifiers = new Set(["renderSSR"]);
|
|
240
206
|
let hasExistingCommandsImport = false;
|
|
241
207
|
function walkForTransformation(node) {
|
|
@@ -266,25 +232,19 @@ function testSSR() {
|
|
|
266
232
|
const componentName = jsxArg.openingElement.name.name;
|
|
267
233
|
const props = extractPropsFromJSX(jsxArg.openingElement.attributes || [], code);
|
|
268
234
|
let propsStr = "";
|
|
269
|
-
if (Object.keys(props).length > 0) {
|
|
270
|
-
|
|
271
|
-
propsStr = `, { ${propsEntries.join(", ")} }`;
|
|
272
|
-
}
|
|
273
|
-
const localComponentCode = localComponents.get(componentName);
|
|
274
|
-
if (localComponentCode) {
|
|
235
|
+
if (Object.keys(props).length > 0) propsStr = `, { ${Object.entries(props).map(([key, value]) => `${JSON.stringify(key)}: ${value}`).join(", ")} }`;
|
|
236
|
+
if (localComponents.get(componentName)) {
|
|
275
237
|
const allLocalComponentNames = Array.from(localComponents.keys());
|
|
276
|
-
const localComponentsArray = JSON.stringify(allLocalComponentNames);
|
|
277
238
|
const replacement = `(async () => {
|
|
278
|
-
const { html } = await commands.renderSSRLocal("${id}", "${componentName}", ${
|
|
239
|
+
const { html } = await commands.renderSSRLocal("${id}", "${componentName}", ${JSON.stringify(allLocalComponentNames)}${propsStr});
|
|
279
240
|
return renderServerHTML(html);
|
|
280
241
|
})()`;
|
|
281
242
|
s.overwrite(node.start, node.end, replacement);
|
|
282
243
|
} else {
|
|
283
244
|
const componentImportPath = componentImports.get(componentName);
|
|
284
245
|
if (componentImportPath) {
|
|
285
|
-
const componentPath = resolveComponentPath(componentImportPath, id);
|
|
286
246
|
const replacement = `(async () => {
|
|
287
|
-
const { html } = await commands.renderSSR("${
|
|
247
|
+
const { html } = await commands.renderSSR("${resolveComponentPath(componentImportPath, id)}", "${componentName}"${propsStr});
|
|
288
248
|
return renderServerHTML(html);
|
|
289
249
|
})()`;
|
|
290
250
|
s.overwrite(node.start, node.end, replacement);
|
|
@@ -292,7 +252,6 @@ function testSSR() {
|
|
|
292
252
|
}
|
|
293
253
|
}
|
|
294
254
|
traverseChildren(node, walkForTransformation);
|
|
295
|
-
return void 0;
|
|
296
255
|
}
|
|
297
256
|
walkForTransformation(ast.program);
|
|
298
257
|
if (s.hasChanged()) {
|
|
@@ -301,14 +260,12 @@ function testSSR() {
|
|
|
301
260
|
function findLastImport(node) {
|
|
302
261
|
if (isImportDeclaration(node)) lastImportEnd = Math.max(lastImportEnd, node.end);
|
|
303
262
|
traverseChildren(node, findLastImport);
|
|
304
|
-
return void 0;
|
|
305
263
|
}
|
|
306
264
|
findLastImport(ast.program);
|
|
307
|
-
if (lastImportEnd > 0) s.appendLeft(lastImportEnd, "\nimport { commands } from \"
|
|
265
|
+
if (lastImportEnd > 0) s.appendLeft(lastImportEnd, "\nimport { commands } from \"vitest/browser\";\nimport { renderServerHTML } from \"vitest-browser-qwik\";");
|
|
308
266
|
}
|
|
309
267
|
if (localComponents.size > 0) {
|
|
310
|
-
const
|
|
311
|
-
const exportStatement = `\n\n// Auto-generated exports for local components\nexport { ${localComponentNames.join(", ")} };`;
|
|
268
|
+
const exportStatement = `\n\n// Auto-generated exports for local components\nexport { ${Array.from(localComponents.keys()).join(", ")} };`;
|
|
312
269
|
s.append(exportStatement);
|
|
313
270
|
}
|
|
314
271
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-browser-qwik",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Render Qwik components using Vitest Browser Mode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,28 +39,27 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"@oxc-project/types": "^0.95.0",
|
|
42
43
|
"magic-string": "^0.30.17",
|
|
43
|
-
"oxc-parser": "^0.
|
|
44
|
+
"oxc-parser": "^0.95.0",
|
|
45
|
+
"oxc-resolver": "^11.11.1"
|
|
44
46
|
},
|
|
45
47
|
"peerDependencies": {
|
|
46
48
|
"@builder.io/qwik": ">=1.14.1",
|
|
47
|
-
"@vitest/browser": "^3.2.4",
|
|
48
49
|
"vite": ">=6.3.5",
|
|
49
|
-
"vitest": "^
|
|
50
|
+
"vitest": "^4.0.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@biomejs/biome": "2.0.0",
|
|
53
|
-
"@builder.io/qwik": "^1.15",
|
|
54
|
-
"@oxc-project/types": "^0.73.2",
|
|
55
54
|
"@playwright/test": "see flake.nix",
|
|
55
|
+
"@builder.io/qwik": "^1.17",
|
|
56
56
|
"@types/node": "^22.15.17",
|
|
57
|
-
"@vitest/browser": "^
|
|
57
|
+
"@vitest/browser-playwright": "^4.0.0",
|
|
58
58
|
"bumpp": "^10.1.0",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"tsdown": "^0.11.9",
|
|
59
|
+
"ignore": "^7.0.5",
|
|
60
|
+
"tsdown": "^0.15.9",
|
|
62
61
|
"typescript": "^5.8.3",
|
|
63
|
-
"vitest": "^
|
|
62
|
+
"vitest": "^4.0.0"
|
|
64
63
|
},
|
|
65
64
|
"scripts": {
|
|
66
65
|
"check": "biome ci .",
|
|
@@ -73,6 +72,7 @@
|
|
|
73
72
|
"dev": "tsdown --watch",
|
|
74
73
|
"test": "vitest",
|
|
75
74
|
"test:ssr-plugin": "vitest --config vitest.ssr-plugin.config.ts",
|
|
75
|
+
"snapshot": "vitest -u",
|
|
76
76
|
"typecheck": "tsc --noEmit",
|
|
77
77
|
"release": "bumpp && pnpm publish"
|
|
78
78
|
}
|