@be-link/smart-test 1.0.1-beta.22 → 1.0.1-beta.23

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.
@@ -1553,9 +1553,10 @@ class InteractiveRecorder {
1553
1553
  this.context = null;
1554
1554
  this.page = null;
1555
1555
  this.session = null;
1556
+ this.browserClosedCallback = null;
1556
1557
  this.options = {
1557
1558
  headless: false,
1558
- viewport: { width: 1280, height: 800 },
1559
+ viewport: { width: 375, height: 812 }, // iPhone 13/14 尺寸
1559
1560
  apiPathPattern: '**/api/**',
1560
1561
  ...options,
1561
1562
  };
@@ -1565,7 +1566,7 @@ class InteractiveRecorder {
1565
1566
  */
1566
1567
  async start(url) {
1567
1568
  console.log('\n🎬 启动录制模式...\n');
1568
- console.log(`📱 浏览器窗口将会打开,请在浏览器中进行操作`);
1569
+ console.log(`📱 浏览器窗口正在打开...`);
1569
1570
  console.log(`🔴 录制已开始,所有操作和 API 请求都会被记录\n`);
1570
1571
  // 初始化会话
1571
1572
  this.session = {
@@ -1575,30 +1576,61 @@ class InteractiveRecorder {
1575
1576
  apis: [],
1576
1577
  screenshots: [],
1577
1578
  };
1578
- // 启动浏览器
1579
- this.browser = await test.chromium.launch({
1580
- headless: this.options.headless,
1581
- args: ['--start-maximized'],
1582
- });
1583
- this.context = await this.browser.newContext({
1584
- viewport: this.options.viewport,
1585
- recordVideo: undefined, // 可选:录制视频
1586
- });
1587
- this.page = await this.context.newPage();
1588
- // 设置监听器
1589
- await this.setupListeners();
1590
- // 访问起始页面
1591
- console.log(`🌐 正在打开页面: ${url}\n`);
1592
- await this.page.goto(url, { waitUntil: 'networkidle' });
1593
- // 记录初始导航
1594
- this.recordAction({
1595
- type: 'navigate',
1596
- description: `打开页面 ${url}`,
1597
- url,
1598
- timestamp: Date.now(),
1599
- });
1600
- console.log(`✅ 页面已加载,请开始您的操作...\n`);
1601
- console.log(`💡 提示:完成操作后,在终端按 Ctrl+C 结束录制\n`);
1579
+ try {
1580
+ // 启动浏览器
1581
+ console.log('⏳ 正在启动浏览器...');
1582
+ this.browser = await test.chromium.launch({
1583
+ headless: this.options.headless,
1584
+ args: ['--start-maximized'],
1585
+ });
1586
+ console.log('✅ 浏览器已启动\n');
1587
+ this.context = await this.browser.newContext({
1588
+ viewport: this.options.viewport,
1589
+ recordVideo: undefined,
1590
+ });
1591
+ this.page = await this.context.newPage();
1592
+ // 监听浏览器关闭事件
1593
+ this.browser.on('disconnected', () => {
1594
+ console.log('\n🛑 检测到浏览器已关闭');
1595
+ if (this.session && !this.session.endTime) {
1596
+ // 触发停止录制
1597
+ this.handleBrowserClosed();
1598
+ }
1599
+ });
1600
+ // 设置监听器
1601
+ await this.setupListeners();
1602
+ // 访问起始页面
1603
+ console.log(`🌐 正在打开页面: ${url}`);
1604
+ await this.page.goto(url, { waitUntil: 'networkidle' });
1605
+ console.log('✅ 页面已加载\n');
1606
+ // 记录初始导航
1607
+ this.recordAction({
1608
+ type: 'navigate',
1609
+ description: `打开页面 ${url}`,
1610
+ url,
1611
+ timestamp: Date.now(),
1612
+ });
1613
+ console.log(`✅ 开始录制,请在浏览器中进行操作...\n`);
1614
+ console.log(`💡 提示:完成操作后,关闭浏览器窗口即可结束录制\n`);
1615
+ }
1616
+ catch (error) {
1617
+ console.error('\n❌ 启动浏览器失败:', error);
1618
+ throw error;
1619
+ }
1620
+ }
1621
+ /**
1622
+ * 处理浏览器关闭事件
1623
+ */
1624
+ handleBrowserClosed() {
1625
+ if (this.browserClosedCallback) {
1626
+ this.browserClosedCallback();
1627
+ }
1628
+ }
1629
+ /**
1630
+ * 设置浏览器关闭的回调
1631
+ */
1632
+ onBrowserClosed(callback) {
1633
+ this.browserClosedCallback = callback;
1602
1634
  }
1603
1635
  /**
1604
1636
  * 停止录制
@@ -2252,22 +2284,20 @@ class RecordAndGenerateWorkflow {
2252
2284
  }
2253
2285
  }
2254
2286
  /**
2255
- * 等待录制完成(监听 Ctrl+C)
2287
+ * 等待录制完成(监听浏览器关闭)
2256
2288
  */
2257
2289
  async waitForRecordingComplete(recorder) {
2258
2290
  return new Promise((resolve, reject) => {
2259
- // 监听 Ctrl+C
2260
- const handleInterrupt = async () => {
2291
+ // 监听浏览器关闭事件
2292
+ recorder.onBrowserClosed(async () => {
2261
2293
  try {
2262
- process.removeListener('SIGINT', handleInterrupt);
2263
2294
  const session = await recorder.stop();
2264
2295
  resolve(session);
2265
2296
  }
2266
2297
  catch (error) {
2267
2298
  reject(error);
2268
2299
  }
2269
- };
2270
- process.on('SIGINT', handleInterrupt);
2300
+ });
2271
2301
  });
2272
2302
  }
2273
2303
  /**
@@ -102,6 +102,15 @@ export declare class InteractiveRecorder {
102
102
  * 开始录制
103
103
  */
104
104
  start(url: string): Promise<void>;
105
+ /**
106
+ * 处理浏览器关闭事件
107
+ */
108
+ private handleBrowserClosed;
109
+ private browserClosedCallback;
110
+ /**
111
+ * 设置浏览器关闭的回调
112
+ */
113
+ onBrowserClosed(callback: () => void): void;
105
114
  /**
106
115
  * 停止录制
107
116
  */
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-recorder.d.ts","sourceRoot":"","sources":["../../src/recorders/interactive-recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IAEzD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,UAAU,EAAE,CAAC;IAEtB;;OAEG;IACH,IAAI,EAAE,SAAS,EAAE,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,KAAK,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,GAAE,eAAoB;IASzC;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CvC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAkDvC;;OAEG;YACW,cAAc;IA2H5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;OAEG;IACG,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3D;;OAEG;IACH,UAAU,IAAI,gBAAgB,GAAG,IAAI;CAGtC"}
1
+ {"version":3,"file":"interactive-recorder.d.ts","sourceRoot":"","sources":["../../src/recorders/interactive-recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IAEzD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,UAAU,EAAE,CAAC;IAEtB;;OAEG;IACH,IAAI,EAAE,SAAS,EAAE,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,KAAK,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,GAAE,eAAoB;IASzC;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+DvC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,qBAAqB,CAA6B;IAE1D;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAI3C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAkDvC;;OAEG;YACW,cAAc;IA2H5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;OAEG;IACG,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3D;;OAEG;IACH,UAAU,IAAI,gBAAgB,GAAG,IAAI;CAGtC"}
@@ -69,7 +69,7 @@ export declare class RecordAndGenerateWorkflow {
69
69
  */
70
70
  execute(options: RecordAndGenerateOptions): Promise<GenerateResult>;
71
71
  /**
72
- * 等待录制完成(监听 Ctrl+C)
72
+ * 等待录制完成(监听浏览器关闭)
73
73
  */
74
74
  private waitForRecordingComplete;
75
75
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"record-and-generate.d.ts","sourceRoot":"","sources":["../../src/workflows/record-and-generate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI/F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,yBAAyB;IACpC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC;IAwHzE;;OAEG;YACW,wBAAwB;IAiBtC;;OAEG;IACH,OAAO,CAAC,WAAW;CAUpB"}
1
+ {"version":3,"file":"record-and-generate.d.ts","sourceRoot":"","sources":["../../src/workflows/record-and-generate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI/F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,yBAAyB;IACpC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,CAAC;IAwHzE;;OAEG;YACW,wBAAwB;IActC;;OAEG;IACH,OAAO,CAAC,WAAW;CAUpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@be-link/smart-test",
3
- "version": "1.0.1-beta.22",
3
+ "version": "1.0.1-beta.23",
4
4
  "description": "AI-powered visual testing for Playwright - 基于 AI 视觉模型的 Playwright 测试工具",
5
5
  "homepage": "https://github.com/snowmountain-top/be-link",
6
6
  "author": "shian",