tauri-test-cli 0.7.0 → 0.7.2

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.
Files changed (2) hide show
  1. package/dist/cli.js +216 -24
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -120707,7 +120707,9 @@ async function connect(options) {
120707
120707
  }
120708
120708
  async function disconnect() {
120709
120709
  if (browser) {
120710
- await browser.deleteSession();
120710
+ try {
120711
+ await browser.deleteSession();
120712
+ } catch {}
120711
120713
  browser = null;
120712
120714
  }
120713
120715
  stopDriver();
@@ -120905,6 +120907,17 @@ async function waitForInteractive(selector, timeout = 5000) {
120905
120907
  await element.waitForClickable({ timeout });
120906
120908
  }
120907
120909
 
120910
+ // src/commands/utils.ts
120911
+ var xvfbDisplay = null;
120912
+ function getXvfbDisplay() {
120913
+ const envVal = process.env.TAURI_TEST_XVFB_DISPLAY;
120914
+ if (envVal !== undefined) {
120915
+ const n = Number(envVal);
120916
+ return Number.isFinite(n) ? n : null;
120917
+ }
120918
+ return xvfbDisplay;
120919
+ }
120920
+
120908
120921
  // src/commands/screenshot.ts
120909
120922
  var HTML2CANVAS_CDN = "https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js";
120910
120923
  async function screenshot(options = {}) {
@@ -120921,12 +120934,21 @@ async function screenshot(options = {}) {
120921
120934
  data2 = await withTimeout(captureWithHtml2Canvas(browser3), timeout, "html2canvas timed out");
120922
120935
  method = "html2canvas";
120923
120936
  } catch (err) {
120924
- console.error(`html2canvas failed: ${err}, trying native...`);
120937
+ console.error(`html2canvas failed: ${err}, trying canvas fallback...`);
120925
120938
  try {
120926
- data2 = await withTimeout(browser3.takeScreenshot(), timeout, `Native screenshot timed out after ${timeout}ms`);
120927
- method = "native";
120928
- } catch (nativeErr) {
120929
- throw new Error(`All screenshot methods failed: ${err}, ${nativeErr}`);
120939
+ data2 = await withTimeout(captureWithCanvas(browser3), timeout, "Canvas screenshot timed out");
120940
+ method = "canvas";
120941
+ } catch (canvasErr) {
120942
+ if (getXvfbDisplay() !== null) {
120943
+ throw new Error(`All screenshot methods failed in Xvfb: html2canvas: ${err}, canvas: ${canvasErr}`);
120944
+ }
120945
+ console.error(`Canvas failed: ${canvasErr}, trying native...`);
120946
+ try {
120947
+ data2 = await withTimeout(browser3.takeScreenshot(), timeout, `Native screenshot timed out after ${timeout}ms`);
120948
+ method = "native";
120949
+ } catch (nativeErr) {
120950
+ throw new Error(`All screenshot methods failed: html2canvas: ${err}, canvas: ${canvasErr}, native: ${nativeErr}`);
120951
+ }
120930
120952
  }
120931
120953
  }
120932
120954
  if (options.output) {
@@ -120971,10 +120993,11 @@ async function captureWithHtml2Canvas(browser3) {
120971
120993
  throw new Error("Failed to load html2canvas from CDN");
120972
120994
  }
120973
120995
  await new Promise((r) => setTimeout(r, 50));
120974
- const base64 = await browser3.executeAsync((done) => {
120996
+ await browser3.execute(() => {
120997
+ window.__h2cResult = undefined;
120975
120998
  const h2c = window.html2canvas;
120976
120999
  if (!h2c) {
120977
- done("");
121000
+ window.__h2cResult = "";
120978
121001
  return;
120979
121002
  }
120980
121003
  h2c(document.body, {
@@ -120984,15 +121007,92 @@ async function captureWithHtml2Canvas(browser3) {
120984
121007
  backgroundColor: "#ffffff"
120985
121008
  }).then((canvas) => {
120986
121009
  const dataUrl = canvas.toDataURL("image/png");
120987
- done(dataUrl.replace(/^data:image\/png;base64,/, ""));
120988
- }).catch(() => done(""));
120989
- setTimeout(() => done(""), 4000);
121010
+ window.__h2cResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121011
+ }).catch(() => {
121012
+ window.__h2cResult = "";
121013
+ });
121014
+ setTimeout(() => {
121015
+ if (window.__h2cResult === undefined) {
121016
+ window.__h2cResult = "";
121017
+ }
121018
+ }, 4000);
120990
121019
  });
121020
+ const base64 = await pollForResult(browser3, "__h2cResult");
120991
121021
  if (!base64) {
120992
121022
  throw new Error("html2canvas capture returned empty");
120993
121023
  }
120994
121024
  return base64;
120995
121025
  }
121026
+ async function captureWithCanvas(browser3) {
121027
+ await browser3.execute(() => {
121028
+ window.__canvasResult = undefined;
121029
+ try {
121030
+ const w2 = window.innerWidth || 800;
121031
+ const h = window.innerHeight || 600;
121032
+ const canvas = document.createElement("canvas");
121033
+ canvas.width = w2;
121034
+ canvas.height = h;
121035
+ const ctx = canvas.getContext("2d");
121036
+ ctx.fillStyle = "#ffffff";
121037
+ ctx.fillRect(0, 0, w2, h);
121038
+ const serializer = new XMLSerializer;
121039
+ const cloned = document.documentElement.cloneNode(true);
121040
+ const html3 = serializer.serializeToString(cloned);
121041
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w2}" height="${h}">
121042
+ <foreignObject width="100%" height="100%">
121043
+ ${html3}
121044
+ </foreignObject>
121045
+ </svg>`;
121046
+ const blob = new Blob([svg], { type: "image/svg+xml;charset=utf-8" });
121047
+ const url2 = URL.createObjectURL(blob);
121048
+ const img = new Image;
121049
+ img.onload = () => {
121050
+ ctx.drawImage(img, 0, 0);
121051
+ URL.revokeObjectURL(url2);
121052
+ const dataUrl = canvas.toDataURL("image/png");
121053
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121054
+ };
121055
+ img.onerror = () => {
121056
+ URL.revokeObjectURL(url2);
121057
+ ctx.fillStyle = "#000000";
121058
+ ctx.font = "16px monospace";
121059
+ const text3 = document.body.innerText || "";
121060
+ const lines = text3.split(`
121061
+ `);
121062
+ for (let i = 0;i < lines.length && i < 40; i++) {
121063
+ ctx.fillText(lines[i], 10, 20 + i * 20);
121064
+ }
121065
+ const dataUrl = canvas.toDataURL("image/png");
121066
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121067
+ };
121068
+ img.src = url2;
121069
+ setTimeout(() => {
121070
+ if (window.__canvasResult === undefined) {
121071
+ const dataUrl = canvas.toDataURL("image/png");
121072
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121073
+ }
121074
+ }, 4000);
121075
+ } catch (e) {
121076
+ window.__canvasResult = "";
121077
+ }
121078
+ });
121079
+ const base64 = await pollForResult(browser3, "__canvasResult");
121080
+ if (!base64) {
121081
+ throw new Error("Canvas screenshot capture returned empty");
121082
+ }
121083
+ return base64;
121084
+ }
121085
+ async function pollForResult(browser3, key, intervalMs = 100, maxMs = 5000) {
121086
+ const start = Date.now();
121087
+ while (Date.now() - start < maxMs) {
121088
+ const val3 = await browser3.execute((k) => window[k], key);
121089
+ if (val3 !== undefined)
121090
+ return val3;
121091
+ await new Promise((r) => setTimeout(r, intervalMs));
121092
+ }
121093
+ const val2 = await browser3.execute((k) => window[k], key);
121094
+ return val2 ?? "";
121095
+ }
120996
121096
 
120997
121097
  // src/commands/snapshot.ts
120998
121098
  import { writeFile as writeFile2 } from "fs/promises";
@@ -121285,12 +121385,21 @@ async function screenshot2(options = {}) {
121285
121385
  data2 = await withTimeout2(captureWithHtml2Canvas2(browser3), timeout, "html2canvas timed out");
121286
121386
  method = "html2canvas";
121287
121387
  } catch (err) {
121288
- console.error(`html2canvas failed: ${err}, trying native...`);
121388
+ console.error(`html2canvas failed: ${err}, trying canvas fallback...`);
121289
121389
  try {
121290
- data2 = await withTimeout2(browser3.takeScreenshot(), timeout, `Native screenshot timed out after ${timeout}ms`);
121291
- method = "native";
121292
- } catch (nativeErr) {
121293
- throw new Error(`All screenshot methods failed: ${err}, ${nativeErr}`);
121390
+ data2 = await withTimeout2(captureWithCanvas2(browser3), timeout, "Canvas screenshot timed out");
121391
+ method = "canvas";
121392
+ } catch (canvasErr) {
121393
+ if (getXvfbDisplay() !== null) {
121394
+ throw new Error(`All screenshot methods failed in Xvfb: html2canvas: ${err}, canvas: ${canvasErr}`);
121395
+ }
121396
+ console.error(`Canvas failed: ${canvasErr}, trying native...`);
121397
+ try {
121398
+ data2 = await withTimeout2(browser3.takeScreenshot(), timeout, `Native screenshot timed out after ${timeout}ms`);
121399
+ method = "native";
121400
+ } catch (nativeErr) {
121401
+ throw new Error(`All screenshot methods failed: html2canvas: ${err}, canvas: ${canvasErr}, native: ${nativeErr}`);
121402
+ }
121294
121403
  }
121295
121404
  }
121296
121405
  if (options.output) {
@@ -121335,10 +121444,11 @@ async function captureWithHtml2Canvas2(browser3) {
121335
121444
  throw new Error("Failed to load html2canvas from CDN");
121336
121445
  }
121337
121446
  await new Promise((r) => setTimeout(r, 50));
121338
- const base64 = await browser3.executeAsync((done) => {
121447
+ await browser3.execute(() => {
121448
+ window.__h2cResult = undefined;
121339
121449
  const h2c = window.html2canvas;
121340
121450
  if (!h2c) {
121341
- done("");
121451
+ window.__h2cResult = "";
121342
121452
  return;
121343
121453
  }
121344
121454
  h2c(document.body, {
@@ -121348,15 +121458,92 @@ async function captureWithHtml2Canvas2(browser3) {
121348
121458
  backgroundColor: "#ffffff"
121349
121459
  }).then((canvas) => {
121350
121460
  const dataUrl = canvas.toDataURL("image/png");
121351
- done(dataUrl.replace(/^data:image\/png;base64,/, ""));
121352
- }).catch(() => done(""));
121353
- setTimeout(() => done(""), 4000);
121461
+ window.__h2cResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121462
+ }).catch(() => {
121463
+ window.__h2cResult = "";
121464
+ });
121465
+ setTimeout(() => {
121466
+ if (window.__h2cResult === undefined) {
121467
+ window.__h2cResult = "";
121468
+ }
121469
+ }, 4000);
121354
121470
  });
121471
+ const base64 = await pollForResult2(browser3, "__h2cResult");
121355
121472
  if (!base64) {
121356
121473
  throw new Error("html2canvas capture returned empty");
121357
121474
  }
121358
121475
  return base64;
121359
121476
  }
121477
+ async function captureWithCanvas2(browser3) {
121478
+ await browser3.execute(() => {
121479
+ window.__canvasResult = undefined;
121480
+ try {
121481
+ const w2 = window.innerWidth || 800;
121482
+ const h = window.innerHeight || 600;
121483
+ const canvas = document.createElement("canvas");
121484
+ canvas.width = w2;
121485
+ canvas.height = h;
121486
+ const ctx = canvas.getContext("2d");
121487
+ ctx.fillStyle = "#ffffff";
121488
+ ctx.fillRect(0, 0, w2, h);
121489
+ const serializer = new XMLSerializer;
121490
+ const cloned = document.documentElement.cloneNode(true);
121491
+ const html3 = serializer.serializeToString(cloned);
121492
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w2}" height="${h}">
121493
+ <foreignObject width="100%" height="100%">
121494
+ ${html3}
121495
+ </foreignObject>
121496
+ </svg>`;
121497
+ const blob = new Blob([svg], { type: "image/svg+xml;charset=utf-8" });
121498
+ const url2 = URL.createObjectURL(blob);
121499
+ const img = new Image;
121500
+ img.onload = () => {
121501
+ ctx.drawImage(img, 0, 0);
121502
+ URL.revokeObjectURL(url2);
121503
+ const dataUrl = canvas.toDataURL("image/png");
121504
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121505
+ };
121506
+ img.onerror = () => {
121507
+ URL.revokeObjectURL(url2);
121508
+ ctx.fillStyle = "#000000";
121509
+ ctx.font = "16px monospace";
121510
+ const text3 = document.body.innerText || "";
121511
+ const lines = text3.split(`
121512
+ `);
121513
+ for (let i = 0;i < lines.length && i < 40; i++) {
121514
+ ctx.fillText(lines[i], 10, 20 + i * 20);
121515
+ }
121516
+ const dataUrl = canvas.toDataURL("image/png");
121517
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121518
+ };
121519
+ img.src = url2;
121520
+ setTimeout(() => {
121521
+ if (window.__canvasResult === undefined) {
121522
+ const dataUrl = canvas.toDataURL("image/png");
121523
+ window.__canvasResult = dataUrl.replace(/^data:image\/png;base64,/, "");
121524
+ }
121525
+ }, 4000);
121526
+ } catch (e) {
121527
+ window.__canvasResult = "";
121528
+ }
121529
+ });
121530
+ const base64 = await pollForResult2(browser3, "__canvasResult");
121531
+ if (!base64) {
121532
+ throw new Error("Canvas screenshot capture returned empty");
121533
+ }
121534
+ return base64;
121535
+ }
121536
+ async function pollForResult2(browser3, key, intervalMs = 100, maxMs = 5000) {
121537
+ const start = Date.now();
121538
+ while (Date.now() - start < maxMs) {
121539
+ const val3 = await browser3.execute((k) => window[k], key);
121540
+ if (val3 !== undefined)
121541
+ return val3;
121542
+ await new Promise((r) => setTimeout(r, intervalMs));
121543
+ }
121544
+ const val2 = await browser3.execute((k) => window[k], key);
121545
+ return val2 ?? "";
121546
+ }
121360
121547
 
121361
121548
  // src/commands/snapshot.ts
121362
121549
  import { writeFile as writeFile4 } from "fs/promises";
@@ -121649,6 +121836,9 @@ async function executeCommand(cmd, globalAutoWait) {
121649
121836
  console.error(`[${new Date().toISOString()}] activateWindow took ${Date.now() - activateStart}ms`);
121650
121837
  const cmdStart = Date.now();
121651
121838
  let result;
121839
+ if (cmd.cmd === "screenshot" || cmd.cmd === "snapshot") {
121840
+ await injectKeepAlive();
121841
+ }
121652
121842
  switch (cmd.cmd) {
121653
121843
  case "screenshot":
121654
121844
  result = await screenshot2({
@@ -122124,7 +122314,7 @@ async function waitForDisplay(display, timeoutMs = 1e4) {
122124
122314
  return false;
122125
122315
  }
122126
122316
  var xvfbProcess = null;
122127
- var xvfbDisplay = null;
122317
+ var xvfbDisplay2 = null;
122128
122318
  async function startXvfb() {
122129
122319
  const display = findAvailableDisplay();
122130
122320
  const displayStr = `:${display}`;
@@ -122154,7 +122344,8 @@ async function startXvfb() {
122154
122344
  throw new Error(`Xvfb display ${displayStr} failed to start within timeout`);
122155
122345
  }
122156
122346
  console.error(`Xvfb ready on display ${displayStr}`);
122157
- xvfbDisplay = display;
122347
+ xvfbDisplay2 = display;
122348
+ process.env.TAURI_TEST_XVFB_DISPLAY = String(display);
122158
122349
  process.env.DISPLAY = displayStr;
122159
122350
  delete process.env.WAYLAND_DISPLAY;
122160
122351
  process.env.GDK_BACKEND = "x11";
@@ -122165,7 +122356,8 @@ function stopXvfb() {
122165
122356
  console.error("Stopping Xvfb...");
122166
122357
  xvfbProcess.kill("SIGTERM");
122167
122358
  xvfbProcess = null;
122168
- xvfbDisplay = null;
122359
+ xvfbDisplay2 = null;
122360
+ delete process.env.TAURI_TEST_XVFB_DISPLAY;
122169
122361
  }
122170
122362
  }
122171
122363
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tauri-test-cli",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "CLI for testing Tauri applications with screenshot capture, DOM inspection, and user interaction simulation",
5
5
  "type": "module",
6
6
  "bin": {