vitest-browser-qwik 0.3.0 → 0.3.4

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as renderServerHTML, n as render, r as renderHook, t as cleanup } from "./pure-B8VHRLBL.js";
1
+ import { i as renderServerHTML, n as render, r as renderHook, t as cleanup } from "./pure-BlLa_nxU.js";
2
2
  import { beforeEach } from "vitest";
3
3
  import { page } from "vitest/browser";
4
4
 
@@ -50,7 +50,7 @@ function setHTMLWithScripts(container, html) {
50
50
  container.innerHTML = html;
51
51
  container.querySelectorAll("script").forEach((oldScript) => {
52
52
  const newScript = document.createElement("script");
53
- for (const attr of oldScript.attributes) newScript.setAttribute(attr.name, attr.value);
53
+ for (const attr of Array.from(oldScript.attributes)) newScript.setAttribute(attr.name, attr.value);
54
54
  newScript.text = oldScript.textContent ?? "";
55
55
  oldScript.parentNode?.replaceChild(newScript, oldScript);
56
56
  });
package/dist/pure.js CHANGED
@@ -1,3 +1,3 @@
1
- import { i as renderServerHTML, n as render, r as renderHook, t as cleanup } from "./pure-B8VHRLBL.js";
1
+ import { i as renderServerHTML, n as render, r as renderHook, t as cleanup } from "./pure-BlLa_nxU.js";
2
2
 
3
3
  export { cleanup, render, renderHook, renderServerHTML };
@@ -214,10 +214,9 @@ function hasCommandsImport(node) {
214
214
  const getClientModule = async (viteServer, moduleId) => {
215
215
  const clientEnv = viteServer.environments.client;
216
216
  await clientEnv.fetchModule(moduleId);
217
- const resolved = await clientEnv.moduleGraph.resolveUrl(moduleId);
218
- if (!resolved) throw new Error(`Could not resolve module "${moduleId}" in client environment`);
219
- const module = clientEnv.moduleGraph.getModuleById(resolved[1]);
220
- console.log("Resolved client module", moduleId, resolved, module);
217
+ const resolvedId = (await clientEnv.moduleGraph.resolveUrl(moduleId))?.[1];
218
+ if (!resolvedId) throw new Error(`Could not resolve module "${moduleId}" in client environment`);
219
+ const module = clientEnv.moduleGraph.getModuleById(resolvedId);
221
220
  if (!module) throw new Error(`Module "${moduleId}" not found in client module graph.`);
222
221
  return module;
223
222
  };
@@ -225,53 +224,64 @@ async function renderComponentToSSR(ctx, Component, props = {}) {
225
224
  const viteServer = ctx.project.vite;
226
225
  const { jsx } = await viteServer.ssrLoadModule("@qwik.dev/core");
227
226
  const jsxElement = jsx(Component, props);
228
- const { renderToStream } = await viteServer.ssrLoadModule("@qwik.dev/core/server");
227
+ const serverModule = await viteServer.ssrLoadModule("@qwik.dev/core/server");
228
+ const { renderToStream } = serverModule;
229
229
  const mapping = {};
230
+ if (!ctx.testPath) throw new Error("ctx.testPath is required for SSR rendering");
230
231
  const module = await getClientModule(viteServer, ctx.testPath);
231
232
  for (const importedModule of module?.importedModules || []) {
232
233
  const meta = importedModule.info?.meta;
233
234
  if (meta?.segment) {
234
235
  const symbol = meta.segment.hash;
235
- if (symbol) mapping[symbol] = `/@fs${importedModule.id}`;
236
+ if (symbol && importedModule.id) mapping[symbol] = importedModule.url;
236
237
  }
237
238
  }
238
- const handlersId = (await getClientModule(viteServer, "@qwik.dev/core/handlers.mjs")).id;
239
- const handlersExports = await viteServer.ssrLoadModule("@qwik.dev/core/handlers.mjs");
240
- for (const key of Object.keys(handlersExports)) if (key.startsWith("_")) mapping[key] = handlersId;
239
+ const handlersUrl = (await getClientModule(viteServer, "@qwik.dev/core/handlers.mjs")).url;
240
+ if (!handlersUrl) throw new Error("Handlers module URL could not be resolved");
241
+ const handlerNames = Object.keys(serverModule).filter((key) => /^_[a-z]+$/.test(key));
242
+ for (const key of handlerNames) mapping[key] = handlersUrl;
241
243
  const qwikManifest = {
242
244
  manifestHash: "dev",
243
245
  mapping
244
246
  };
245
- console.log(mapping);
246
- let html = "<script>var _import=(s)=>{console.log('importing', s);return import(s)}<\/script>";
247
+ let html = "";
247
248
  await renderToStream(jsxElement, {
248
249
  manifest: qwikManifest,
249
250
  containerTagName: "div",
250
251
  base: "/",
251
252
  stream: { write(chunk) {
252
- html += chunk.replace(/=import\(/g, "=_import(");
253
+ html += chunk;
253
254
  } }
254
255
  });
255
- console.log("FINAL HTML", html);
256
256
  return { html };
257
257
  }
258
258
 
259
259
  //#endregion
260
260
  //#region src/ssr-plugin.ts
261
261
  const isJSorTS = createRegExp(exactly(".").and(anyOf("j", "t")).and("s").and(maybe("x")).at.lineEnd());
262
+ function isBrowserOnlySource(source) {
263
+ if (!source) return false;
264
+ return source === "vitest" || source.startsWith("vitest/") || source === "vitest-browser-qwik" || source.startsWith("vitest-browser-qwik/") || source.includes("@vitest/");
265
+ }
266
+ function referencesStrippedId(node, strippedIds) {
267
+ if (!node || typeof node !== "object") return false;
268
+ if (node.type === "Identifier") return strippedIds.has(node.name);
269
+ if (node.type === "MemberExpression") return referencesStrippedId(node.object, strippedIds);
270
+ if (isCallExpression(node)) return referencesStrippedId(node.callee, strippedIds);
271
+ return false;
272
+ }
273
+ function isVariableDeclaration(node) {
274
+ return node.type === "VariableDeclaration";
275
+ }
276
+ let userDefines = {};
262
277
  const renderSSRCommand = async (ctx, componentPath, componentName, props = {}) => {
263
278
  const absoluteComponentPath = resolve(process.cwd(), componentPath);
264
- const viteServer = ctx.project.vite;
265
- if (!viteServer.config.define) return;
266
- for (const [key, value] of Object.entries(viteServer.config.env)) viteServer.config.define[`__vite_ssr_import_meta__.env.${key}`] = JSON.stringify(value);
267
- const Component = (await viteServer.ssrLoadModule(absoluteComponentPath))[componentName];
279
+ const Component = (await ctx.project.vite.ssrLoadModule(absoluteComponentPath))[componentName];
268
280
  if (!Component) throw new Error(`Component "${componentName}" not found in ${absoluteComponentPath}`);
269
281
  return await renderComponentToSSR(ctx, Component, props);
270
282
  };
271
283
  const renderSSRLocalCommand = async (ctx, testFilePath, componentName, allLocalComponents, props = {}) => {
272
284
  const viteServer = ctx.project.vite;
273
- if (!viteServer.config.define) return;
274
- for (const [key, value] of Object.entries(viteServer.config.env)) viteServer.config.define[`__vite_ssr_import_meta__.env.${key}`] = JSON.stringify(value);
275
285
  const { readFileSync, writeFileSync, unlinkSync } = await import("node:fs");
276
286
  const { dirname: dirname$1, join } = await import("node:path");
277
287
  const tempFileName = `ssr-test-${Date.now()}-${Math.random().toString(36).slice(2, 11)}.tsx`;
@@ -280,16 +290,28 @@ const renderSSRLocalCommand = async (ctx, testFilePath, componentName, allLocalC
280
290
  const originalContent = readFileSync(testFilePath, "utf8");
281
291
  const ast = parseSync(testFilePath, originalContent);
282
292
  const s = new MagicString(originalContent);
293
+ const strippedIds = /* @__PURE__ */ new Set();
283
294
  function cleanTestFile(node) {
284
- if (isImportDeclaration(node)) {
285
- const source = node.source?.value;
286
- if (source === "vitest" || source?.includes("@vitest/")) s.remove(node.start, node.end);
295
+ if (isImportDeclaration(node) && isBrowserOnlySource(node.source?.value)) {
296
+ for (const spec of node.specifiers || []) if (spec.local?.name) strippedIds.add(spec.local.name);
297
+ s.remove(node.start, node.end);
298
+ return;
287
299
  }
288
300
  if (isExpressionStatement(node) && node.expression?.type === "CallExpression") {
289
301
  const callExpr = node.expression;
290
302
  if (callExpr.callee.type === "Identifier") {
291
303
  const calleeName = callExpr.callee.name;
292
- if (calleeName === "test" || calleeName === "describe" || calleeName === "it") s.remove(node.start, node.end);
304
+ if (calleeName === "test" || calleeName === "describe" || calleeName === "it") {
305
+ s.remove(node.start, node.end);
306
+ return;
307
+ }
308
+ }
309
+ }
310
+ if (isVariableDeclaration(node)) {
311
+ if (node.declarations.every((d) => referencesStrippedId(d.init, strippedIds))) {
312
+ for (const d of node.declarations) if (d.id.type === "Identifier") strippedIds.add(d.id.name);
313
+ s.remove(node.start, node.end);
314
+ return;
293
315
  }
294
316
  }
295
317
  traverseChildren(node, cleanTestFile);
@@ -317,6 +339,12 @@ function testSSR() {
317
339
  return {
318
340
  name: "vitest:ssr-transform",
319
341
  enforce: "pre",
342
+ config(config) {
343
+ if (config.define) userDefines = {
344
+ ...userDefines,
345
+ ...config.define
346
+ };
347
+ },
320
348
  transform: {
321
349
  filter: {
322
350
  id: isJSorTS,
@@ -403,6 +431,9 @@ function testSSR() {
403
431
  }
404
432
  },
405
433
  configResolved(config) {
434
+ if (!config.define) config.define = {};
435
+ for (const [key, value] of Object.entries(userDefines)) if (config.define) config.define[key] = value;
436
+ for (const [key, value] of Object.entries(config.env)) if (config.define) config.define[`__vite_ssr_import_meta__.env.${key}`] = JSON.stringify(value);
406
437
  if (config.test?.browser?.enabled) config.test.browser.commands = {
407
438
  ...config.test.browser.commands,
408
439
  renderSSR: renderSSRCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-browser-qwik",
3
- "version": "0.3.0",
3
+ "version": "0.3.4",
4
4
  "description": "Render Qwik components using Vitest Browser Mode",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -55,9 +55,9 @@
55
55
  "@qwik.dev/core": "*",
56
56
  "@types/node": "^22.15.17",
57
57
  "@vitest/browser-playwright": "^4.0.18",
58
- "magic-regexp": "^0.10.0",
59
58
  "bumpp": "^10.1.0",
60
59
  "ignore": "^7.0.5",
60
+ "magic-regexp": "^0.10.0",
61
61
  "tsdown": "^0.15.9",
62
62
  "typescript": "^5.8.3",
63
63
  "vitest": "^4.0.18"