@weapp-vite/miniprogram-automator 1.2.7 → 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.mjs CHANGED
@@ -612,7 +612,7 @@ var Connection = class Connection extends EventEmitter {
612
612
  //#endregion
613
613
  //#region src/headless.ts
614
614
  async function launchHeadlessAutomator(options) {
615
- return await (await import("./launch-mRKloPOa.mjs")).launch({ projectPath: options.projectPath });
615
+ return await (await import("./launch-DpCZfswN.mjs")).launch({ projectPath: options.projectPath });
616
616
  }
617
617
  //#endregion
618
618
  //#region src/launcher/portLease.ts
@@ -711,7 +711,7 @@ async function acquireAutomatorPortLease(preferredPort) {
711
711
  }
712
712
  //#endregion
713
713
  //#region package.json
714
- var version = "1.2.7";
714
+ var version = "1.2.8";
715
715
  //#endregion
716
716
  //#region src/Native.ts
717
717
  /** Native 的实现。 */
@@ -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.7",
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": {