@weapp-vite/miniprogram-automator 1.2.6 → 1.2.8

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.mts CHANGED
@@ -44,13 +44,20 @@ declare class Transport extends EventEmitter {
44
44
  interface SendOptions {
45
45
  timeout?: number;
46
46
  }
47
+ interface ToolInfo {
48
+ version?: string;
49
+ }
47
50
  /** Connection 的实现。 */
48
51
  declare class Connection extends EventEmitter {
49
52
  private transport;
50
53
  private callbacks;
54
+ private useAppServicePageProtocol;
51
55
  constructor(transport: Transport);
52
56
  send(method: string, params?: Record<string, any>, options?: SendOptions): Promise<any>;
53
57
  dispose(): void;
58
+ /** 根据 DevTools 版本选择稳定的 Page 协议实现。 */
59
+ configureToolInfo(info: ToolInfo): void;
60
+ get prefersAppServicePageProtocol(): boolean;
54
61
  private onMessage;
55
62
  private onClose;
56
63
  static create(url: string, timeout?: number): Promise<Connection>;
@@ -248,7 +255,7 @@ declare class Page {
248
255
  query: any;
249
256
  private id;
250
257
  private elementMap;
251
- private preferRoutePageFallback;
258
+ private preferAppServicePageProtocol;
252
259
  constructor(connection: Connection, options: IPageOptions);
253
260
  updateFromOptions(options: IPageOptions): void;
254
261
  waitFor(condition: WaitCondition): Promise<void>;
package/dist/index.mjs CHANGED
@@ -506,10 +506,13 @@ const debugProtocol = createDebug("automator:protocol");
506
506
  const closeErrTip = "Connection closed, check if wechat web devTools is still running";
507
507
  const REQUEST_TIMEOUT = 3e4;
508
508
  const CONNECT_TIMEOUT = 3e4;
509
+ /** Page frame 定向消息失效、需要切换到 App-service Page 协议的 DevTools 版本。 */
510
+ const APP_SERVICE_PAGE_PROTOCOL_VERSIONS = /* @__PURE__ */ new Set(["2.01.2510290"]);
509
511
  /** Connection 的实现。 */
510
512
  var Connection = class Connection extends EventEmitter {
511
513
  transport;
512
514
  callbacks = /* @__PURE__ */ new Map();
515
+ useAppServicePageProtocol = false;
513
516
  constructor(transport) {
514
517
  super();
515
518
  this.transport = transport;
@@ -550,6 +553,13 @@ var Connection = class Connection extends EventEmitter {
550
553
  dispose() {
551
554
  this.transport.close();
552
555
  }
556
+ /** 根据 DevTools 版本选择稳定的 Page 协议实现。 */
557
+ configureToolInfo(info) {
558
+ this.useAppServicePageProtocol = APP_SERVICE_PAGE_PROTOCOL_VERSIONS.has(String(info.version ?? ""));
559
+ }
560
+ get prefersAppServicePageProtocol() {
561
+ return this.useAppServicePageProtocol;
562
+ }
553
563
  onMessage = (message) => {
554
564
  debugProtocol(`${dateFormat("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${message}`);
555
565
  const { id, method, error, result, params } = JSON.parse(message);
@@ -602,7 +612,7 @@ var Connection = class Connection extends EventEmitter {
602
612
  //#endregion
603
613
  //#region src/headless.ts
604
614
  async function launchHeadlessAutomator(options) {
605
- return await (await import("./launch-mRKloPOa.mjs")).launch({ projectPath: options.projectPath });
615
+ return await (await import("./launch-DpCZfswN.mjs")).launch({ projectPath: options.projectPath });
606
616
  }
607
617
  //#endregion
608
618
  //#region src/launcher/portLease.ts
@@ -701,7 +711,7 @@ async function acquireAutomatorPortLease(preferredPort) {
701
711
  }
702
712
  //#endregion
703
713
  //#region package.json
704
- var version = "1.2.6";
714
+ var version = "1.2.8";
705
715
  //#endregion
706
716
  //#region src/Native.ts
707
717
  /** Native 的实现。 */
@@ -823,12 +833,13 @@ var Page = class Page {
823
833
  query = {};
824
834
  id;
825
835
  elementMap = /* @__PURE__ */ new Map();
826
- preferRoutePageFallback = false;
836
+ preferAppServicePageProtocol = false;
827
837
  constructor(connection, options) {
828
838
  this.connection = connection;
829
839
  this.id = options.id;
830
840
  this.path = options.path;
831
841
  this.query = options.query;
842
+ this.preferAppServicePageProtocol = connection.prefersAppServicePageProtocol;
832
843
  }
833
844
  updateFromOptions(options) {
834
845
  this.path = options.path;
@@ -846,7 +857,7 @@ var Page = class Page {
846
857
  if (isStr(condition)) await waitUntil(async () => (await this.$$(condition)).length > 0);
847
858
  }
848
859
  async $(selector, options = {}) {
849
- if (options.routeOnly || this.preferRoutePageFallback) return await this.queryRouteElement(selector, options);
860
+ if (options.routeOnly || options.fallback !== false && this.preferAppServicePageProtocol) return await this.queryRouteElement(selector, options);
850
861
  try {
851
862
  const element = await this.send("Page.getElement", { selector }, { timeout: options.timeout ?? PAGE_QUERY_TIMEOUT });
852
863
  return Element.create(this.connection, {
@@ -855,14 +866,14 @@ var Page = class Page {
855
866
  }, this.elementMap);
856
867
  } catch (error) {
857
868
  if (options.fallback !== false && isRecoverablePageProtocolError(error, "Page.getElement")) {
858
- this.preferRoutePageFallback = true;
869
+ this.preferAppServicePageProtocol = true;
859
870
  return await this.queryRouteElement(selector, options);
860
871
  }
861
872
  return null;
862
873
  }
863
874
  }
864
875
  async $$(selector, options = {}) {
865
- if (options.routeOnly || this.preferRoutePageFallback) return await this.queryRouteElements(selector, options);
876
+ if (options.routeOnly || options.fallback !== false && this.preferAppServicePageProtocol) return await this.queryRouteElements(selector, options);
866
877
  try {
867
878
  const { elements } = await this.send("Page.getElements", { selector }, { timeout: options.timeout ?? PAGE_QUERY_TIMEOUT });
868
879
  return elements.map((element) => {
@@ -873,7 +884,7 @@ var Page = class Page {
873
884
  });
874
885
  } catch (error) {
875
886
  if (options.fallback === false || !isRecoverablePageProtocolError(error, "Page.getElements")) throw error;
876
- this.preferRoutePageFallback = true;
887
+ this.preferAppServicePageProtocol = true;
877
888
  return await this.queryRouteElements(selector, options);
878
889
  }
879
890
  }
@@ -1360,13 +1371,13 @@ var Page = class Page {
1360
1371
  const payload = {};
1361
1372
  if (path) payload.path = path;
1362
1373
  const timeout = options.timeout ?? PAGE_DATA_TIMEOUT;
1363
- if (options.routeOnly || this.preferRoutePageFallback) return await this.readRouteData(path, timeout);
1374
+ if (options.routeOnly || options.fallback !== false && this.preferAppServicePageProtocol) return await this.readRouteData(path, timeout);
1364
1375
  try {
1365
1376
  return (await this.send("Page.getData", payload, { timeout: Math.min(timeout, PAGE_DATA_PROTOCOL_TIMEOUT) })).data;
1366
1377
  } catch (error) {
1367
1378
  if (options.fallback === false) throw error;
1368
1379
  if (!isRecoverablePageProtocolError(error, "Page.getData")) throw error;
1369
- this.preferRoutePageFallback = true;
1380
+ this.preferAppServicePageProtocol = true;
1370
1381
  return await this.readRouteData(path, timeout);
1371
1382
  }
1372
1383
  }
@@ -1425,7 +1436,7 @@ var Page = class Page {
1425
1436
  }, { timeout })).result;
1426
1437
  }
1427
1438
  async setData(data) {
1428
- if (this.preferRoutePageFallback) {
1439
+ if (this.preferAppServicePageProtocol) {
1429
1440
  await this.setRouteData(data);
1430
1441
  return;
1431
1442
  }
@@ -1433,7 +1444,7 @@ var Page = class Page {
1433
1444
  await this.send("Page.setData", { data }, { timeout: PAGE_SET_DATA_PROTOCOL_TIMEOUT });
1434
1445
  } catch (error) {
1435
1446
  if (!isRecoverablePageProtocolError(error, "Page.setData") && !isPageStackStaleError(error)) throw error;
1436
- this.preferRoutePageFallback = true;
1447
+ this.preferAppServicePageProtocol = true;
1437
1448
  await this.setRouteData(data);
1438
1449
  }
1439
1450
  }
@@ -1448,7 +1459,7 @@ var Page = class Page {
1448
1459
  return await this.callMethodWithOptions(method, {}, ...args);
1449
1460
  }
1450
1461
  async callMethodWithOptions(method, options = {}, ...args) {
1451
- if (options.routeOnly || this.preferRoutePageFallback) return await this.callRouteMethod(method, args, options.timeout);
1462
+ if (options.routeOnly || options.fallback !== false && this.preferAppServicePageProtocol) return await this.callRouteMethod(method, args, options.timeout);
1452
1463
  try {
1453
1464
  return (await this.send("Page.callMethod", {
1454
1465
  method,
@@ -1457,7 +1468,7 @@ var Page = class Page {
1457
1468
  } catch (error) {
1458
1469
  if (options.fallback === false) throw error;
1459
1470
  if (!isRecoverablePageProtocolError(error, "Page.callMethod") && !isPageStackStaleError(error)) throw error;
1460
- this.preferRoutePageFallback = true;
1471
+ this.preferAppServicePageProtocol = true;
1461
1472
  }
1462
1473
  return await this.callRouteMethod(method, args, options.timeout);
1463
1474
  }
@@ -1943,7 +1954,9 @@ var MiniProgram = class extends EventEmitter {
1943
1954
  await this.send("App.addBinding", { name });
1944
1955
  }
1945
1956
  async checkVersion() {
1946
- const sdkVersion = (await this.send("Tool.getInfo")).SDKVersion;
1957
+ const toolInfo = await this.send("Tool.getInfo");
1958
+ this.connection.configureToolInfo(toolInfo);
1959
+ const sdkVersion = toolInfo.SDKVersion;
1947
1960
  if (sdkVersion !== "dev" && cmpVersion(sdkVersion, "2.7.3") < 0) throw new Error(`SDKVersion is currently ${sdkVersion}, while automator(${version}) requires at least version 2.7.3`);
1948
1961
  }
1949
1962
  /**
@@ -3291,6 +3291,48 @@ function renderRuntimePageTree(context, page) {
3291
3291
  function createDuplicateRegistrationError(kind, id) {
3292
3292
  return /* @__PURE__ */ new Error(`Duplicate ${kind} registration in headless runtime: ${id}`);
3293
3293
  }
3294
+ function callDefinitionMethod(instance, method, args) {
3295
+ if (typeof method === "function") return method.apply(instance, args);
3296
+ }
3297
+ function normalizeComponentPageDefinition(definition) {
3298
+ const { lifetimes = {}, methods = {}, pageLifetimes = {}, ...rest } = definition;
3299
+ const created = lifetimes.created ?? rest.created;
3300
+ const attached = lifetimes.attached ?? rest.attached;
3301
+ const ready = lifetimes.ready ?? rest.ready ?? methods.onReady ?? rest.onReady;
3302
+ const detached = lifetimes.detached ?? rest.detached ?? methods.onUnload ?? rest.onUnload;
3303
+ const load = methods.onLoad ?? rest.onLoad;
3304
+ const show = pageLifetimes.show ?? methods.onShow ?? rest.onShow;
3305
+ const hide = pageLifetimes.hide ?? methods.onHide ?? rest.onHide;
3306
+ const resize = pageLifetimes.resize ?? methods.onResize ?? rest.onResize;
3307
+ const routeDone = pageLifetimes.routeDone ?? methods.onRouteDone ?? rest.onRouteDone;
3308
+ return {
3309
+ ...rest,
3310
+ ...methods,
3311
+ onLoad(...args) {
3312
+ callDefinitionMethod(this, created, []);
3313
+ callDefinitionMethod(this, attached, []);
3314
+ return callDefinitionMethod(this, load, args);
3315
+ },
3316
+ onShow(...args) {
3317
+ return callDefinitionMethod(this, show, args);
3318
+ },
3319
+ onHide(...args) {
3320
+ return callDefinitionMethod(this, hide, args);
3321
+ },
3322
+ onReady(...args) {
3323
+ return callDefinitionMethod(this, ready, args);
3324
+ },
3325
+ onUnload(...args) {
3326
+ return callDefinitionMethod(this, detached, args);
3327
+ },
3328
+ onResize(...args) {
3329
+ return callDefinitionMethod(this, resize, args);
3330
+ },
3331
+ onRouteDone(...args) {
3332
+ return callDefinitionMethod(this, routeDone, args);
3333
+ }
3334
+ };
3335
+ }
3294
3336
  function createHostRegistries() {
3295
3337
  return {
3296
3338
  appDefinition: null,
@@ -3312,6 +3354,7 @@ function registerPageDefinition(registries, definition) {
3312
3354
  return definition;
3313
3355
  }
3314
3356
  function registerComponentDefinition(registries, definition) {
3357
+ if (registries.currentLoadContext?.kind === "page") return registerPageDefinition(registries, normalizeComponentPageDefinition(definition));
3315
3358
  const id = registries.currentLoadContext?.route ?? `anonymous:${registries.components.size}`;
3316
3359
  if (registries.components.has(id)) throw createDuplicateRegistrationError("component", id);
3317
3360
  registries.components.set(id, definition);
@@ -5181,7 +5224,8 @@ function createModuleLoader(registries, getCurrentPages, getApp, wxDriver) {
5181
5224
  const definition = registries.components.get(id);
5182
5225
  if (!definition) throw new Error(`Component() was not registered for id "${id}" while executing ${normalize(filePath)}.`);
5183
5226
  return definition;
5184
- }
5227
+ },
5228
+ wx: executionContext.wx
5185
5229
  };
5186
5230
  }
5187
5231
  //#endregion
@@ -6991,6 +7035,11 @@ var HeadlessSession = class {
6991
7035
  getCurrentPages() {
6992
7036
  return this.pages.slice();
6993
7037
  }
7038
+ callWxMethod(methodName, ...args) {
7039
+ const method = this.moduleLoader.wx[methodName];
7040
+ if (typeof method !== "function") throw new TypeError(`wx.${methodName} is not available in headless runtime.`);
7041
+ return Reflect.apply(method, this.moduleLoader.wx, args);
7042
+ }
6994
7043
  getCurrentPageNavigationBarTitle() {
6995
7044
  return this.currentPageInstance?.__navigationBarTitle__ ?? null;
6996
7045
  }
@@ -7359,6 +7408,7 @@ var HeadlessSession = class {
7359
7408
  const pageInstance = this.createFreshPage(target);
7360
7409
  this.pages.push(pageInstance);
7361
7410
  this.currentPageInstance = pageInstance;
7411
+ this.runInitialPageLifecycles(pageInstance, target.query);
7362
7412
  return pageInstance;
7363
7413
  }
7364
7414
  navigateTo(url) {
@@ -7371,6 +7421,7 @@ var HeadlessSession = class {
7371
7421
  const pageInstance = this.createFreshPage(target);
7372
7422
  this.pages.push(pageInstance);
7373
7423
  this.currentPageInstance = pageInstance;
7424
+ this.runInitialPageLifecycles(pageInstance, target.query);
7374
7425
  return pageInstance;
7375
7426
  }
7376
7427
  redirectTo(url) {
@@ -7385,6 +7436,7 @@ var HeadlessSession = class {
7385
7436
  const pageInstance = this.createFreshPage(target);
7386
7437
  this.pages.push(pageInstance);
7387
7438
  this.currentPageInstance = pageInstance;
7439
+ this.runInitialPageLifecycles(pageInstance, target.query);
7388
7440
  return pageInstance;
7389
7441
  }
7390
7442
  navigateBack(delta = 1) {
@@ -7421,17 +7473,21 @@ var HeadlessSession = class {
7421
7473
  this.unloadPage(page);
7422
7474
  }
7423
7475
  let nextPage = cachedTarget;
7476
+ let shouldRunInitialLifecycles = false;
7424
7477
  if (!nextPage) {
7425
7478
  nextPage = this.createFreshPage(target);
7426
7479
  this.tabPages.set(target.routeRecord.route, nextPage);
7427
- } else if (current !== nextPage) {
7428
- nextPage.onShow?.();
7429
- this.runPageComponentLifetime(nextPage.route, "show");
7480
+ shouldRunInitialLifecycles = true;
7430
7481
  }
7431
- nextPage.onTabItemTap?.(tabItem);
7432
7482
  this.pages.length = 0;
7433
7483
  this.pages.push(nextPage);
7434
7484
  this.currentPageInstance = nextPage;
7485
+ if (shouldRunInitialLifecycles) this.runInitialPageLifecycles(nextPage, target.query);
7486
+ else if (current !== nextPage) {
7487
+ nextPage.onShow?.();
7488
+ this.runPageComponentLifetime(nextPage.route, "show");
7489
+ }
7490
+ nextPage.onTabItemTap?.(tabItem);
7435
7491
  return nextPage;
7436
7492
  }
7437
7493
  pageScrollTo(option) {
@@ -7506,12 +7562,14 @@ var HeadlessSession = class {
7506
7562
  pageInstance.createMediaQueryObserver = () => this.createMediaQueryObserver(pageInstance);
7507
7563
  pageInstance.selectComponent = (selector) => this.selectComponent(selector);
7508
7564
  pageInstance.selectAllComponents = (selector) => this.selectAllComponents(selector);
7509
- pageInstance.onLoad?.(target.query);
7510
- pageInstance.onShow?.();
7511
- pageInstance.onReady?.();
7512
7565
  if (this.isTabBarRoute(target.routeRecord.route)) this.tabPages.set(target.routeRecord.route, pageInstance);
7513
7566
  return pageInstance;
7514
7567
  }
7568
+ runInitialPageLifecycles(pageInstance, query) {
7569
+ pageInstance.onLoad?.(query);
7570
+ pageInstance.onShow?.();
7571
+ pageInstance.onReady?.();
7572
+ }
7515
7573
  isTabBarRoute(route) {
7516
7574
  return this.tabBarRoutes.has(stripLeadingSlash(route));
7517
7575
  }
@@ -7717,9 +7775,52 @@ function createHeadlessSession(options) {
7717
7775
  return new HeadlessSession(options);
7718
7776
  }
7719
7777
  //#endregion
7720
- //#region ../../mpcore/packages/simulator/src/testing/pageHandle.ts
7778
+ //#region ../../mpcore/packages/simulator/src/testing/sessionHandle/shared.ts
7779
+ const LEADING_SLASH_RE = /^\/+/;
7721
7780
  const DEFAULT_WAIT_TIMEOUT$1 = 1e3;
7722
7781
  const DEFAULT_WAIT_INTERVAL$1 = 10;
7782
+ function normalizeRoute(route) {
7783
+ return route.replace(LEADING_SLASH_RE, "");
7784
+ }
7785
+ function resolvePageScopeId(scopeId) {
7786
+ const pagePathIndex = scopeId.indexOf("/page/");
7787
+ return pagePathIndex >= 0 ? scopeId.slice(0, pagePathIndex) : scopeId;
7788
+ }
7789
+ function normalizeNonEmptyInput(value, label) {
7790
+ const normalizedValue = value.trim();
7791
+ if (!normalizedValue) throw new Error(`${label} must be a non-empty string in headless testing runtime.`);
7792
+ return normalizedValue;
7793
+ }
7794
+ async function waitForDelay(ms = 0) {
7795
+ if (ms <= 0) return;
7796
+ await new Promise((resolve) => setTimeout(resolve, ms));
7797
+ }
7798
+ async function pollUntil(check, errorMessage, options = {}) {
7799
+ const timeout = Number.isFinite(options.timeout) ? Math.max(0, Math.trunc(options.timeout ?? DEFAULT_WAIT_TIMEOUT$1)) : DEFAULT_WAIT_TIMEOUT$1;
7800
+ const interval = Number.isFinite(options.interval) ? Math.max(1, Math.trunc(options.interval ?? DEFAULT_WAIT_INTERVAL$1)) : DEFAULT_WAIT_INTERVAL$1;
7801
+ const deadline = Date.now() + timeout;
7802
+ while (true) {
7803
+ const result = await check();
7804
+ if (result != null) return result;
7805
+ if (Date.now() >= deadline) throw new Error(errorMessage);
7806
+ await waitForDelay(interval);
7807
+ }
7808
+ }
7809
+ async function runWithTimeout(operation, timeout, message) {
7810
+ if (!Number.isFinite(timeout) || (timeout ?? 0) <= 0) return await operation();
7811
+ let timer;
7812
+ try {
7813
+ return await Promise.race([Promise.resolve().then(operation), new Promise((_resolve, reject) => {
7814
+ timer = setTimeout(() => reject(new Error(message)), Math.trunc(timeout));
7815
+ })]);
7816
+ } finally {
7817
+ if (timer) clearTimeout(timer);
7818
+ }
7819
+ }
7820
+ //#endregion
7821
+ //#region ../../mpcore/packages/simulator/src/testing/pageHandle.ts
7822
+ const DEFAULT_WAIT_TIMEOUT = 1e3;
7823
+ const DEFAULT_WAIT_INTERVAL = 10;
7723
7824
  var HeadlessTestingPageHandle = class {
7724
7825
  project;
7725
7826
  page;
@@ -7729,6 +7830,12 @@ var HeadlessTestingPageHandle = class {
7729
7830
  this.page = page;
7730
7831
  this.session = session;
7731
7832
  }
7833
+ get path() {
7834
+ return this.page.route;
7835
+ }
7836
+ get query() {
7837
+ return { ...this.page.options };
7838
+ }
7732
7839
  resolveDataByPath(path) {
7733
7840
  if (!path) return this.page.data;
7734
7841
  const segments = path.split(".").filter(Boolean);
@@ -7737,8 +7844,8 @@ var HeadlessTestingPageHandle = class {
7737
7844
  return current;
7738
7845
  }
7739
7846
  async pollUntil(check, errorMessage, options = {}) {
7740
- const timeout = Number.isFinite(options.timeout) ? Math.max(0, Math.trunc(options.timeout ?? DEFAULT_WAIT_TIMEOUT$1)) : DEFAULT_WAIT_TIMEOUT$1;
7741
- const interval = Number.isFinite(options.interval) ? Math.max(1, Math.trunc(options.interval ?? DEFAULT_WAIT_INTERVAL$1)) : DEFAULT_WAIT_INTERVAL$1;
7847
+ const timeout = Number.isFinite(options.timeout) ? Math.max(0, Math.trunc(options.timeout ?? DEFAULT_WAIT_TIMEOUT)) : DEFAULT_WAIT_TIMEOUT;
7848
+ const interval = Number.isFinite(options.interval) ? Math.max(1, Math.trunc(options.interval ?? DEFAULT_WAIT_INTERVAL)) : DEFAULT_WAIT_INTERVAL;
7742
7849
  const deadline = Date.now() + timeout;
7743
7850
  while (true) {
7744
7851
  const result = await check();
@@ -7752,9 +7859,15 @@ var HeadlessTestingPageHandle = class {
7752
7859
  return scopeId ? new HeadlessTestingScopeHandle(scopeId, this.project, this.session) : null;
7753
7860
  }
7754
7861
  async callMethod(methodName, ...args) {
7755
- const method = this.page[methodName];
7756
- if (typeof method !== "function") throw new TypeError(`Method "${methodName}" does not exist on headless page ${this.page.route}.`);
7757
- return await method.apply(this.page, args);
7862
+ return await this.callMethodWithOptions(methodName, {}, ...args);
7863
+ }
7864
+ async callMethodWithOptions(methodName, options = {}, ...args) {
7865
+ const normalizedMethodName = normalizeNonEmptyInput(methodName, "Page method name");
7866
+ return await runWithTimeout(async () => {
7867
+ const method = this.page[normalizedMethodName];
7868
+ if (typeof method !== "function") throw new TypeError(`Method "${normalizedMethodName}" does not exist on headless page ${this.page.route}.`);
7869
+ return await method.apply(this.page, args);
7870
+ }, options.timeout, `Timed out calling page method "${normalizedMethodName}" in headless testing runtime.`);
7758
7871
  }
7759
7872
  async data(path) {
7760
7873
  return this.resolveDataByPath(path);
@@ -7856,38 +7969,6 @@ var HeadlessTestingPageHandle = class {
7856
7969
  }
7857
7970
  };
7858
7971
  //#endregion
7859
- //#region ../../mpcore/packages/simulator/src/testing/sessionHandle/shared.ts
7860
- const LEADING_SLASH_RE = /^\/+/;
7861
- const DEFAULT_WAIT_TIMEOUT = 1e3;
7862
- const DEFAULT_WAIT_INTERVAL = 10;
7863
- function normalizeRoute(route) {
7864
- return route.replace(LEADING_SLASH_RE, "");
7865
- }
7866
- function resolvePageScopeId(scopeId) {
7867
- const pagePathIndex = scopeId.indexOf("/page/");
7868
- return pagePathIndex >= 0 ? scopeId.slice(0, pagePathIndex) : scopeId;
7869
- }
7870
- function normalizeNonEmptyInput(value, label) {
7871
- const normalizedValue = value.trim();
7872
- if (!normalizedValue) throw new Error(`${label} must be a non-empty string in headless testing runtime.`);
7873
- return normalizedValue;
7874
- }
7875
- async function waitForDelay(ms = 0) {
7876
- if (ms <= 0) return;
7877
- await new Promise((resolve) => setTimeout(resolve, ms));
7878
- }
7879
- async function pollUntil(check, errorMessage, options = {}) {
7880
- const timeout = Number.isFinite(options.timeout) ? Math.max(0, Math.trunc(options.timeout ?? DEFAULT_WAIT_TIMEOUT)) : DEFAULT_WAIT_TIMEOUT;
7881
- const interval = Number.isFinite(options.interval) ? Math.max(1, Math.trunc(options.interval ?? DEFAULT_WAIT_INTERVAL)) : DEFAULT_WAIT_INTERVAL;
7882
- const deadline = Date.now() + timeout;
7883
- while (true) {
7884
- const result = await check();
7885
- if (result != null) return result;
7886
- if (Date.now() >= deadline) throw new Error(errorMessage);
7887
- await waitForDelay(interval);
7888
- }
7889
- }
7890
- //#endregion
7891
7972
  //#region ../../mpcore/packages/simulator/src/testing/sessionHandle/scope.ts
7892
7973
  var HeadlessTestingScopeHandle = class HeadlessTestingScopeHandle {
7893
7974
  scopeId;
@@ -7961,6 +8042,13 @@ var HeadlessTestingSessionHandle = class {
7961
8042
  async getCurrentPages() {
7962
8043
  return this.session.getCurrentPages().map((page) => new HeadlessTestingPageHandle(this.project, page, this.session));
7963
8044
  }
8045
+ async callWxMethod(methodName, ...args) {
8046
+ return await this.callWxMethodWithOptions(methodName, {}, ...args);
8047
+ }
8048
+ async callWxMethodWithOptions(methodName, options = {}, ...args) {
8049
+ const normalizedMethodName = normalizeNonEmptyInput(methodName, "wx method name");
8050
+ return await runWithTimeout(() => this.session.callWxMethod(normalizedMethodName, ...args), options.timeout, `Timed out calling wx.${normalizedMethodName} in headless testing runtime.`);
8051
+ }
7964
8052
  async scopeSnapshot(scopeId) {
7965
8053
  const normalizedScopeId = normalizeNonEmptyInput(scopeId, "Scope id");
7966
8054
  return this.session.getScopeSnapshot(normalizedScopeId);
@@ -7988,7 +8076,9 @@ var HeadlessTestingSessionHandle = class {
7988
8076
  }, `Timed out waiting for ${normalizedCount} component(s) matching "${normalizedSelector}" in headless testing runtime.`, options);
7989
8077
  }
7990
8078
  async reLaunch(route) {
7991
- const page = this.session.reLaunch(route);
8079
+ this.session.callWxMethod("reLaunch", { url: route });
8080
+ const page = this.session.getCurrentPages().at(-1);
8081
+ if (!page) throw new Error(`Failed to reLaunch route "${route}" through the headless wx runtime.`);
7992
8082
  return new HeadlessTestingPageHandle(this.project, page, this.session);
7993
8083
  }
7994
8084
  async waitForCurrentPage(route, options = {}) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@weapp-vite/miniprogram-automator",
3
3
  "type": "module",
4
- "version": "1.2.6",
4
+ "version": "1.2.8",
5
5
  "description": "完全兼容微信 miniprogram-automator 的现代化替代实现",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -41,8 +41,8 @@
41
41
  "node": "^20.19.0 || >=22.12.0"
42
42
  },
43
43
  "dependencies": {
44
- "obug": "^2.1.3",
45
- "ws": "^8.21.0",
44
+ "obug": "^2.1.4",
45
+ "ws": "^8.21.1",
46
46
  "@weapp-vite/qr": "1.1.1"
47
47
  },
48
48
  "publishConfig": {