@letsscrapedata/controller 0.0.39 → 0.0.41

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.cjs CHANGED
@@ -76,7 +76,6 @@ var PlaywrightElement = class _PlaywrightElement {
76
76
  return names;
77
77
  }
78
78
  /*
79
- // 如果不存在指定的子iframe,则返回null
80
79
  async #getChildFrame(parentFrame: Frame, iframeOption: IframeOption): Promise<Frame | null> {
81
80
  if (!parentFrame) {
82
81
  throw new Error("Invalid parent frame");
@@ -268,6 +267,13 @@ var PlaywrightElement = class _PlaywrightElement {
268
267
  await this.#locator.press(key, options);
269
268
  return true;
270
269
  }
270
+ async screenshot(options) {
271
+ return await this.#locator.screenshot(options);
272
+ }
273
+ async scrollIntoView() {
274
+ await this.#locator.scrollIntoViewIfNeeded();
275
+ return true;
276
+ }
271
277
  async select(options) {
272
278
  const { type, values = [], labels = [], indexes = [] } = options;
273
279
  switch (type) {
@@ -307,13 +313,15 @@ var PlaywrightElement = class _PlaywrightElement {
307
313
  }
308
314
  return true;
309
315
  }
310
- async screenshot(options) {
311
- return await this.#locator.screenshot(options);
312
- }
313
- async scrollIntoView() {
314
- await this.#locator.scrollIntoViewIfNeeded();
316
+ async setAttribute(attributeName, newValue) {
317
+ await this.#locator.evaluate((node, argvs) => {
318
+ node.setAttribute(argvs[0], argvs[1]);
319
+ }, [attributeName, newValue]);
315
320
  return true;
316
321
  }
322
+ _origElement() {
323
+ return this.#locator;
324
+ }
317
325
  };
318
326
 
319
327
  // src/playwright/page.ts
@@ -420,7 +428,6 @@ var PlaywrightPage = class extends import_node_events.default {
420
428
  return true;
421
429
  }
422
430
  /*
423
- // 如果不存在指定的子iframe,则返回null
424
431
  async #getChildFrame(parentFrame: Frame, iframeOption: IframeOption): Promise<Frame | null> {
425
432
  if (!parentFrame) {
426
433
  throw new Error("Invalid parent frame");
@@ -1498,7 +1505,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1498
1505
  #maxPageFreeSeconds() {
1499
1506
  return this.#options.maxPageFreeSeconds ? this.#options.maxPageFreeSeconds : 900;
1500
1507
  }
1501
- // 构造函数:缺省只能由LsdBrowserController.launch/connect调用创建实例!!!
1508
+ // constructor: called only by LsdBrowserController.launch/connect
1502
1509
  constructor(browser, browerType, browserCreateMethod, options, browserIdx = 0, pid = 0) {
1503
1510
  if (!browser || typeof browser.contexts !== "function") {
1504
1511
  throw new Error(`Invalid playwright browser parameter`);
@@ -1564,7 +1571,6 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1564
1571
  await lsdBrowserContext.closeFreePages();
1565
1572
  }
1566
1573
  }
1567
- // 常用方法(按常见调用顺序排序)
1568
1574
  async newBrowserContext(options) {
1569
1575
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
1570
1576
  (0, import_utils4.logwarn)(`##browser ${this.id()} can not create more new browserContext`);
@@ -1599,7 +1605,6 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1599
1605
  await this.#browser.close();
1600
1606
  return true;
1601
1607
  }
1602
- // 其它方法(按字母顺序排序)
1603
1608
  browserContexts() {
1604
1609
  return this.#lsdBrowserContexts;
1605
1610
  }
@@ -1614,7 +1619,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1614
1619
  }
1615
1620
  doesMeetBrowserContextRequirements(browserContextRequirements) {
1616
1621
  const { browserControllerTypes, browserTypes, headlesses } = browserContextRequirements;
1617
- return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 && browserTypes.includes(this.#browserType)) && (headlesses.length === 0 && headlesses.includes(this.#headless));
1622
+ return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 || browserTypes.includes(this.#browserType)) && (headlesses.length === 0 || headlesses.includes(this.#headless));
1618
1623
  }
1619
1624
  executablePath() {
1620
1625
  return this.#executablePath;
@@ -1680,7 +1685,6 @@ var PuppeteerElement = class _PuppeteerElement {
1680
1685
  const names = await this.#frame.evaluate((ele) => ele.getAttributeNames(), this.#$ele);
1681
1686
  return names;
1682
1687
  }
1683
- // 如果不存在指定的子iframe,则返回null
1684
1688
  async #getChildFrame(parentFrame, iframeOption) {
1685
1689
  if (!parentFrame) {
1686
1690
  throw new Error("Invalid parent frame");
@@ -1858,6 +1862,15 @@ var PuppeteerElement = class _PuppeteerElement {
1858
1862
  await this.#$ele.press(key, options);
1859
1863
  return true;
1860
1864
  }
1865
+ async screenshot(options) {
1866
+ return await this.#$ele.screenshot(options);
1867
+ }
1868
+ async scrollIntoView() {
1869
+ await this.#frame.evaluate((ele) => {
1870
+ ele.scrollIntoView();
1871
+ }, this.#$ele);
1872
+ return true;
1873
+ }
1861
1874
  async select(options) {
1862
1875
  const { type, values = [], labels = [], indexes = [] } = options;
1863
1876
  switch (type) {
@@ -1912,15 +1925,15 @@ var PuppeteerElement = class _PuppeteerElement {
1912
1925
  }
1913
1926
  return true;
1914
1927
  }
1915
- async screenshot(options) {
1916
- return await this.#$ele.screenshot(options);
1917
- }
1918
- async scrollIntoView() {
1919
- await this.#frame.evaluate((ele) => {
1920
- ele.scrollIntoView();
1921
- }, this.#$ele);
1928
+ async setAttribute(attributeName, newValue) {
1929
+ await this.#frame.evaluate((ele, name, value) => {
1930
+ ele.setAttribute(name, value);
1931
+ }, this.#$ele, attributeName, newValue);
1922
1932
  return true;
1923
1933
  }
1934
+ _origElement() {
1935
+ return this.#$ele;
1936
+ }
1924
1937
  };
1925
1938
 
1926
1939
  // src/puppeteer/page.ts
@@ -2004,7 +2017,6 @@ var PuppeteerPage = class extends import_node_events4.default {
2004
2017
  });
2005
2018
  return true;
2006
2019
  }
2007
- // 如果不存在指定的子iframe,则返回null
2008
2020
  async #getChildFrame(parentFrame, iframeOption) {
2009
2021
  if (!parentFrame) {
2010
2022
  throw new Error("Invalid parent frame");
@@ -3035,7 +3047,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
3035
3047
  #userAgent() {
3036
3048
  return this.#options.userAgent ? this.#options.userAgent : "";
3037
3049
  }
3038
- // 构造函数:缺省只能由LsdBrowserController.launch/connect调用创建实例!!!
3050
+ // constructor: called only by LsdBrowserController.launch/connect
3039
3051
  constructor(browser, browerType, browserCreateMethod, options, browserIdx = 0, pid = 0) {
3040
3052
  if (!browser || typeof browser.browserContexts !== "function") {
3041
3053
  throw new Error(`Invalid puppeteer browser parameter`);
@@ -3098,7 +3110,6 @@ var PuppeteerBrowser = class extends import_node_events6.default {
3098
3110
  await lsdBrowserContext.closeFreePages();
3099
3111
  }
3100
3112
  }
3101
- // 常用方法(按常见调用顺序排序)
3102
3113
  async newBrowserContext(options) {
3103
3114
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
3104
3115
  (0, import_utils8.logwarn)(`##browser ${this.id()} can not create more new browserContext`);
@@ -3129,7 +3140,6 @@ var PuppeteerBrowser = class extends import_node_events6.default {
3129
3140
  await this.#browser.close();
3130
3141
  return true;
3131
3142
  }
3132
- // 其它方法(按字母顺序排序)
3133
3143
  browserContexts() {
3134
3144
  return this.#lsdBrowserContexts;
3135
3145
  }
@@ -3144,7 +3154,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
3144
3154
  }
3145
3155
  doesMeetBrowserContextRequirements(browserContextRequirements) {
3146
3156
  const { browserControllerTypes, browserTypes, headlesses } = browserContextRequirements;
3147
- return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 && browserTypes.includes(this.#browserType)) && (headlesses.length === 0 && headlesses.includes(this.#headless));
3157
+ return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 || browserTypes.includes(this.#browserType)) && (headlesses.length === 0 || headlesses.includes(this.#headless));
3148
3158
  }
3149
3159
  executablePath() {
3150
3160
  return this.#executablePath;
@@ -3287,13 +3297,19 @@ var CheerioElement = class _CheerioElement {
3287
3297
  async press() {
3288
3298
  throw new Error("Not supported in CheerioElement.");
3289
3299
  }
3300
+ async screenshot() {
3301
+ throw new Error("Not supported in CheerioElement.");
3302
+ }
3303
+ async scrollIntoView() {
3304
+ throw new Error("Not supported in CheerioElement.");
3305
+ }
3290
3306
  async select() {
3291
3307
  throw new Error("Not supported in CheerioElement.");
3292
3308
  }
3293
- async screenshot() {
3309
+ async setAttribute() {
3294
3310
  throw new Error("Not supported in CheerioElement.");
3295
3311
  }
3296
- async scrollIntoView() {
3312
+ _origElement() {
3297
3313
  throw new Error("Not supported in CheerioElement.");
3298
3314
  }
3299
3315
  };
package/dist/index.d.cts CHANGED
@@ -1,17 +1,12 @@
1
1
  import EventEmitter from 'node:events';
2
- import { Browser as Browser$1, BrowserContext as BrowserContext$1, Frame as Frame$1, Page as Page$1, HTTPResponse, PuppeteerNode, ElementHandle } from 'puppeteer';
3
- import { Browser, BrowserContext, Frame, Page, Response, APIRequestContext, BrowserType, Locator, FrameLocator } from 'playwright';
4
-
5
- /**
6
- * 命名规则:为了与playwright/puppeteer中的同名区别
7
- * 1. name of type:AllXxxYyy,如AllBrowserContext
8
- * 2. 接口的实现类class的名称: LsdXxxYyy,如LsdBrowserContext
9
- */
2
+ import { Browser as Browser$1, BrowserContext as BrowserContext$1, Frame as Frame$1, Page as Page$1, ElementHandle, HTTPResponse, PuppeteerNode } from 'puppeteer';
3
+ import { Browser, BrowserContext, Frame, Page, Locator, Response, APIRequestContext, BrowserType, FrameLocator } from 'playwright';
10
4
 
11
5
  type AllBrowser = Browser | Browser$1;
12
6
  type AllBrowserContext = BrowserContext | BrowserContext$1;
13
7
  type AllFrame = Frame | Frame$1;
14
8
  type AllPage = Page | Page$1;
9
+ type AllElement = Locator | ElementHandle;
15
10
  type AllResponse = Response | HTTPResponse;
16
11
  type AllApiRequestContext = APIRequestContext;
17
12
  type CheerioNode = cheerio.Cheerio;
@@ -214,7 +209,7 @@ type LsdBrowserContextOptions = {
214
209
  type PageStatus = "free" | "busy" | "closed";
215
210
  /**
216
211
  * newpage: open by browserContext.newPage()
217
- * popup: open by clicking etc, 主要关注此类
212
+ * popup: open by clicking etc, important
218
213
  * manual: open by manual operation
219
214
  * launch: open by puppeteer.launch
220
215
  * connect: opened pages before connecting to browser
@@ -251,17 +246,16 @@ interface PageInfo {
251
246
  */
252
247
  openType: PageOpenType;
253
248
  /**
254
- * page添加时间:针对非connect场景,也是page打开时间
255
249
  * @default current unix time
256
250
  */
257
251
  openTime: number;
258
252
  /**
259
- * 上次status变化时间:如果status为free,表示空闲开始时间;如果status为busy,表示TE开始数据
253
+ * page's status: free or busy
260
254
  * @default current unix time
261
255
  */
262
256
  lastStatusUpdateTime: number;
263
257
  /**
264
- * 正在执行的task的ID,参见enumSpecialTaskId
258
+ * taskId that are using this page
265
259
  * @default 0
266
260
  */
267
261
  taskId: number;
@@ -276,12 +270,12 @@ interface PageInfo {
276
270
  }
277
271
  interface UpdatablePageInfo {
278
272
  /**
279
- * 上次status变化时间:如果status为free,表示空闲开始时间;如果status为busy,表示TE开始数据
273
+ * page's status: free or busy
280
274
  * @default current unix time
281
275
  */
282
276
  lastStatusUpdateTime?: number;
283
277
  /**
284
- * 正在执行的task的ID,参见enumSpecialTaskId
278
+ * taskId that are using this page
285
279
  * @default 0
286
280
  */
287
281
  taskId?: number;
@@ -461,9 +455,11 @@ interface LsdElement {
461
455
  */
462
456
  input(value: string, options?: InputOptions): Promise<boolean>;
463
457
  press(key: KeyInput, options: KeyPressOptions): Promise<boolean>;
464
- select(options: SelectOptions): Promise<boolean>;
465
458
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
466
459
  scrollIntoView(): Promise<boolean>;
460
+ select(options: SelectOptions): Promise<boolean>;
461
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
462
+ _origElement(): AllElement;
467
463
  }
468
464
  interface ViewportSize {
469
465
  height: number;
@@ -955,7 +951,7 @@ interface LsdPage extends EventEmitter {
955
951
  title(): Promise<string>;
956
952
  url(): string;
957
953
  /**
958
- * 开始使用该page(当前状态必须为free)
954
+ * start to use this free page
959
955
  */
960
956
  use(): boolean;
961
957
  /**
@@ -1090,33 +1086,6 @@ interface LsdBrowserController$1 {
1090
1086
  */
1091
1087
  newApiContext(options?: LsdApiContextOptions): Promise<LsdApiContext>;
1092
1088
  }
1093
- /**
1094
- * globObj.cfg.XXX:
1095
- * 1. 最大browser数:
1096
- * 2. 最大browserContext数/browser:
1097
- * 3. 最大page数/browserContext:
1098
- *
1099
- * 影响一个browserContext是否满足执行某TE(taskCfg)要求的因素包括:
1100
- * 1. domainCfg/taskCfg对代理的要求:proxyTypes:
1101
- * 2. domainCfg/taskCfg对浏览器的要求:
1102
- * * browserControllerTypes: playwright | puppeteer
1103
- * * browserTypes: chromium | firefox | webkit
1104
- * * browserModes: normal | incognito
1105
- * * browserHeads: headless | headful
1106
- * * APP支持的浏览器因素:globObj.cfg.supportedBrowserControllerTypes/supportedBrowserTypes(尝试启动新浏览器时判断)
1107
- * 3. 能力账号:capName
1108
- *
1109
- * 连接已有浏览器:
1110
- * * endpoint:
1111
- * * browserControllerTypes: playwright | puppeteer
1112
- * * browserType: chromium | firefox | webkit
1113
- * * browserMode: normal
1114
- * * browserHead: headful
1115
- * * proxyTypes:
1116
- */
1117
- interface BrowserManager {
1118
- getPage(): any;
1119
- }
1120
1089
 
1121
1090
  declare class PlaywrightBrowser extends EventEmitter implements LsdBrowser {
1122
1091
  #private;
@@ -1232,9 +1201,11 @@ declare class PlaywrightElement implements LsdElement {
1232
1201
  hover(): Promise<boolean>;
1233
1202
  input(value: string, options?: InputOptions): Promise<boolean>;
1234
1203
  press(key: KeyInput, options?: KeyPressOptions): Promise<boolean>;
1235
- select(options: SelectOptions): Promise<boolean>;
1236
1204
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
1237
1205
  scrollIntoView(): Promise<boolean>;
1206
+ select(options: SelectOptions): Promise<boolean>;
1207
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
1208
+ _origElement(): AllElement;
1238
1209
  }
1239
1210
 
1240
1211
  declare class PuppeteerBrowser extends EventEmitter implements LsdBrowser {
@@ -1351,9 +1322,11 @@ declare class PuppeteerElement implements LsdElement {
1351
1322
  hover(): Promise<boolean>;
1352
1323
  input(value: string, options?: InputOptions): Promise<boolean>;
1353
1324
  press(key: KeyInput, options?: KeyPressOptions): Promise<boolean>;
1354
- select(options: SelectOptions): Promise<boolean>;
1355
1325
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
1356
1326
  scrollIntoView(): Promise<boolean>;
1327
+ select(options: SelectOptions): Promise<boolean>;
1328
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
1329
+ _origElement(): AllElement;
1357
1330
  }
1358
1331
 
1359
1332
  declare class CheerioPage extends EventEmitter implements LsdPage {
@@ -1431,9 +1404,11 @@ declare class CheerioElement implements LsdElement {
1431
1404
  hover(): Promise<boolean>;
1432
1405
  input(): Promise<boolean>;
1433
1406
  press(): Promise<boolean>;
1434
- select(): Promise<boolean>;
1435
1407
  screenshot(): Promise<Buffer>;
1436
1408
  scrollIntoView(): Promise<boolean>;
1409
+ select(): Promise<boolean>;
1410
+ setAttribute(): Promise<boolean>;
1411
+ _origElement(): AllElement;
1437
1412
  }
1438
1413
 
1439
1414
  declare class LsdBrowserController implements LsdBrowserController$1 {
@@ -1447,4 +1422,4 @@ declare class LsdBrowserController implements LsdBrowserController$1 {
1447
1422
  }
1448
1423
  declare const controller: LsdBrowserController;
1449
1424
 
1450
- export { type AllApiRequestContext, type AllBrowser, type AllBrowserContext, type AllFrame, type AllPage, type AllResponse, type BrowserContextRequirements, type BrowserControllerType, type BrowserCreationMethod, type BrowserLaunchMethod, type BrowserManager, type BrowserStateData, CheerioElement, type CheerioNode, CheerioPage, type ClientCertificate, type CookieItem, type GotoOptions, type IframeOption, type InputOptions, type KeyInput, type KeyPressOptions, type LocalStorageItem, type LocalStorageOrigin, type LowerCasePaperFormat, type LsdApiContext, type LsdApiContextOptions, type LsdApiResponse, type LsdBrowser, type LsdBrowserContext, type LsdBrowserContextOptions, type LsdBrowserController$1 as LsdBrowserController, type LsdBrowserType, type LsdConnectOptions, type LsdElement, type LsdFetchOptions, type LsdLaunchOptions, type LsdPage, type MouseClickOptions, type MouseClickType, type NavigationWaitUntil, type PDFMargin, type PDFOptions, type PageEvent, type PageExtInPlaywright, type PageExtInPuppeteer, type PageInfo, type PageOpenType, type PageStatus, type PaperFormat, PlaywrightBrowser, PlaywrightBrowserContext, type PlaywrightBrowserTypes, PlaywrightElement, PlaywrightPage, type ProxyInController, PuppeteerBrowser, PuppeteerBrowserContext, PuppeteerElement, PuppeteerPage, type RequestInterceptionAction, type RequestInterceptionOption, type RequestMatch, type RequestMethod, type RequestResourceType, type ResponseHandler, type ResponseHandlerOptions, type ResponseInterceptionItem, type ResponseInterceptionOption, type ResponseMatch, type ResponsePageData, type ScreenshotOptions, type SelectOptions, type UpdatablePageInfo, type ViewportSize, type WaitElementOptions, type WaitElementState, type WaitNavigationOptions, controller };
1425
+ export { type AllApiRequestContext, type AllBrowser, type AllBrowserContext, type AllElement, type AllFrame, type AllPage, type AllResponse, type BrowserContextRequirements, type BrowserControllerType, type BrowserCreationMethod, type BrowserLaunchMethod, type BrowserStateData, CheerioElement, type CheerioNode, CheerioPage, type ClientCertificate, type CookieItem, type GotoOptions, type IframeOption, type InputOptions, type KeyInput, type KeyPressOptions, type LocalStorageItem, type LocalStorageOrigin, type LowerCasePaperFormat, type LsdApiContext, type LsdApiContextOptions, type LsdApiResponse, type LsdBrowser, type LsdBrowserContext, type LsdBrowserContextOptions, type LsdBrowserController$1 as LsdBrowserController, type LsdBrowserType, type LsdConnectOptions, type LsdElement, type LsdFetchOptions, type LsdLaunchOptions, type LsdPage, type MouseClickOptions, type MouseClickType, type NavigationWaitUntil, type PDFMargin, type PDFOptions, type PageEvent, type PageExtInPlaywright, type PageExtInPuppeteer, type PageInfo, type PageOpenType, type PageStatus, type PaperFormat, PlaywrightBrowser, PlaywrightBrowserContext, type PlaywrightBrowserTypes, PlaywrightElement, PlaywrightPage, type ProxyInController, PuppeteerBrowser, PuppeteerBrowserContext, PuppeteerElement, PuppeteerPage, type RequestInterceptionAction, type RequestInterceptionOption, type RequestMatch, type RequestMethod, type RequestResourceType, type ResponseHandler, type ResponseHandlerOptions, type ResponseInterceptionItem, type ResponseInterceptionOption, type ResponseMatch, type ResponsePageData, type ScreenshotOptions, type SelectOptions, type UpdatablePageInfo, type ViewportSize, type WaitElementOptions, type WaitElementState, type WaitNavigationOptions, controller };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,12 @@
1
1
  import EventEmitter from 'node:events';
2
- import { Browser as Browser$1, BrowserContext as BrowserContext$1, Frame as Frame$1, Page as Page$1, HTTPResponse, PuppeteerNode, ElementHandle } from 'puppeteer';
3
- import { Browser, BrowserContext, Frame, Page, Response, APIRequestContext, BrowserType, Locator, FrameLocator } from 'playwright';
4
-
5
- /**
6
- * 命名规则:为了与playwright/puppeteer中的同名区别
7
- * 1. name of type:AllXxxYyy,如AllBrowserContext
8
- * 2. 接口的实现类class的名称: LsdXxxYyy,如LsdBrowserContext
9
- */
2
+ import { Browser as Browser$1, BrowserContext as BrowserContext$1, Frame as Frame$1, Page as Page$1, ElementHandle, HTTPResponse, PuppeteerNode } from 'puppeteer';
3
+ import { Browser, BrowserContext, Frame, Page, Locator, Response, APIRequestContext, BrowserType, FrameLocator } from 'playwright';
10
4
 
11
5
  type AllBrowser = Browser | Browser$1;
12
6
  type AllBrowserContext = BrowserContext | BrowserContext$1;
13
7
  type AllFrame = Frame | Frame$1;
14
8
  type AllPage = Page | Page$1;
9
+ type AllElement = Locator | ElementHandle;
15
10
  type AllResponse = Response | HTTPResponse;
16
11
  type AllApiRequestContext = APIRequestContext;
17
12
  type CheerioNode = cheerio.Cheerio;
@@ -214,7 +209,7 @@ type LsdBrowserContextOptions = {
214
209
  type PageStatus = "free" | "busy" | "closed";
215
210
  /**
216
211
  * newpage: open by browserContext.newPage()
217
- * popup: open by clicking etc, 主要关注此类
212
+ * popup: open by clicking etc, important
218
213
  * manual: open by manual operation
219
214
  * launch: open by puppeteer.launch
220
215
  * connect: opened pages before connecting to browser
@@ -251,17 +246,16 @@ interface PageInfo {
251
246
  */
252
247
  openType: PageOpenType;
253
248
  /**
254
- * page添加时间:针对非connect场景,也是page打开时间
255
249
  * @default current unix time
256
250
  */
257
251
  openTime: number;
258
252
  /**
259
- * 上次status变化时间:如果status为free,表示空闲开始时间;如果status为busy,表示TE开始数据
253
+ * page's status: free or busy
260
254
  * @default current unix time
261
255
  */
262
256
  lastStatusUpdateTime: number;
263
257
  /**
264
- * 正在执行的task的ID,参见enumSpecialTaskId
258
+ * taskId that are using this page
265
259
  * @default 0
266
260
  */
267
261
  taskId: number;
@@ -276,12 +270,12 @@ interface PageInfo {
276
270
  }
277
271
  interface UpdatablePageInfo {
278
272
  /**
279
- * 上次status变化时间:如果status为free,表示空闲开始时间;如果status为busy,表示TE开始数据
273
+ * page's status: free or busy
280
274
  * @default current unix time
281
275
  */
282
276
  lastStatusUpdateTime?: number;
283
277
  /**
284
- * 正在执行的task的ID,参见enumSpecialTaskId
278
+ * taskId that are using this page
285
279
  * @default 0
286
280
  */
287
281
  taskId?: number;
@@ -461,9 +455,11 @@ interface LsdElement {
461
455
  */
462
456
  input(value: string, options?: InputOptions): Promise<boolean>;
463
457
  press(key: KeyInput, options: KeyPressOptions): Promise<boolean>;
464
- select(options: SelectOptions): Promise<boolean>;
465
458
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
466
459
  scrollIntoView(): Promise<boolean>;
460
+ select(options: SelectOptions): Promise<boolean>;
461
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
462
+ _origElement(): AllElement;
467
463
  }
468
464
  interface ViewportSize {
469
465
  height: number;
@@ -955,7 +951,7 @@ interface LsdPage extends EventEmitter {
955
951
  title(): Promise<string>;
956
952
  url(): string;
957
953
  /**
958
- * 开始使用该page(当前状态必须为free)
954
+ * start to use this free page
959
955
  */
960
956
  use(): boolean;
961
957
  /**
@@ -1090,33 +1086,6 @@ interface LsdBrowserController$1 {
1090
1086
  */
1091
1087
  newApiContext(options?: LsdApiContextOptions): Promise<LsdApiContext>;
1092
1088
  }
1093
- /**
1094
- * globObj.cfg.XXX:
1095
- * 1. 最大browser数:
1096
- * 2. 最大browserContext数/browser:
1097
- * 3. 最大page数/browserContext:
1098
- *
1099
- * 影响一个browserContext是否满足执行某TE(taskCfg)要求的因素包括:
1100
- * 1. domainCfg/taskCfg对代理的要求:proxyTypes:
1101
- * 2. domainCfg/taskCfg对浏览器的要求:
1102
- * * browserControllerTypes: playwright | puppeteer
1103
- * * browserTypes: chromium | firefox | webkit
1104
- * * browserModes: normal | incognito
1105
- * * browserHeads: headless | headful
1106
- * * APP支持的浏览器因素:globObj.cfg.supportedBrowserControllerTypes/supportedBrowserTypes(尝试启动新浏览器时判断)
1107
- * 3. 能力账号:capName
1108
- *
1109
- * 连接已有浏览器:
1110
- * * endpoint:
1111
- * * browserControllerTypes: playwright | puppeteer
1112
- * * browserType: chromium | firefox | webkit
1113
- * * browserMode: normal
1114
- * * browserHead: headful
1115
- * * proxyTypes:
1116
- */
1117
- interface BrowserManager {
1118
- getPage(): any;
1119
- }
1120
1089
 
1121
1090
  declare class PlaywrightBrowser extends EventEmitter implements LsdBrowser {
1122
1091
  #private;
@@ -1232,9 +1201,11 @@ declare class PlaywrightElement implements LsdElement {
1232
1201
  hover(): Promise<boolean>;
1233
1202
  input(value: string, options?: InputOptions): Promise<boolean>;
1234
1203
  press(key: KeyInput, options?: KeyPressOptions): Promise<boolean>;
1235
- select(options: SelectOptions): Promise<boolean>;
1236
1204
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
1237
1205
  scrollIntoView(): Promise<boolean>;
1206
+ select(options: SelectOptions): Promise<boolean>;
1207
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
1208
+ _origElement(): AllElement;
1238
1209
  }
1239
1210
 
1240
1211
  declare class PuppeteerBrowser extends EventEmitter implements LsdBrowser {
@@ -1351,9 +1322,11 @@ declare class PuppeteerElement implements LsdElement {
1351
1322
  hover(): Promise<boolean>;
1352
1323
  input(value: string, options?: InputOptions): Promise<boolean>;
1353
1324
  press(key: KeyInput, options?: KeyPressOptions): Promise<boolean>;
1354
- select(options: SelectOptions): Promise<boolean>;
1355
1325
  screenshot(options?: ScreenshotOptions): Promise<Buffer>;
1356
1326
  scrollIntoView(): Promise<boolean>;
1327
+ select(options: SelectOptions): Promise<boolean>;
1328
+ setAttribute(attributeName: string, newValue: string): Promise<boolean>;
1329
+ _origElement(): AllElement;
1357
1330
  }
1358
1331
 
1359
1332
  declare class CheerioPage extends EventEmitter implements LsdPage {
@@ -1431,9 +1404,11 @@ declare class CheerioElement implements LsdElement {
1431
1404
  hover(): Promise<boolean>;
1432
1405
  input(): Promise<boolean>;
1433
1406
  press(): Promise<boolean>;
1434
- select(): Promise<boolean>;
1435
1407
  screenshot(): Promise<Buffer>;
1436
1408
  scrollIntoView(): Promise<boolean>;
1409
+ select(): Promise<boolean>;
1410
+ setAttribute(): Promise<boolean>;
1411
+ _origElement(): AllElement;
1437
1412
  }
1438
1413
 
1439
1414
  declare class LsdBrowserController implements LsdBrowserController$1 {
@@ -1447,4 +1422,4 @@ declare class LsdBrowserController implements LsdBrowserController$1 {
1447
1422
  }
1448
1423
  declare const controller: LsdBrowserController;
1449
1424
 
1450
- export { type AllApiRequestContext, type AllBrowser, type AllBrowserContext, type AllFrame, type AllPage, type AllResponse, type BrowserContextRequirements, type BrowserControllerType, type BrowserCreationMethod, type BrowserLaunchMethod, type BrowserManager, type BrowserStateData, CheerioElement, type CheerioNode, CheerioPage, type ClientCertificate, type CookieItem, type GotoOptions, type IframeOption, type InputOptions, type KeyInput, type KeyPressOptions, type LocalStorageItem, type LocalStorageOrigin, type LowerCasePaperFormat, type LsdApiContext, type LsdApiContextOptions, type LsdApiResponse, type LsdBrowser, type LsdBrowserContext, type LsdBrowserContextOptions, type LsdBrowserController$1 as LsdBrowserController, type LsdBrowserType, type LsdConnectOptions, type LsdElement, type LsdFetchOptions, type LsdLaunchOptions, type LsdPage, type MouseClickOptions, type MouseClickType, type NavigationWaitUntil, type PDFMargin, type PDFOptions, type PageEvent, type PageExtInPlaywright, type PageExtInPuppeteer, type PageInfo, type PageOpenType, type PageStatus, type PaperFormat, PlaywrightBrowser, PlaywrightBrowserContext, type PlaywrightBrowserTypes, PlaywrightElement, PlaywrightPage, type ProxyInController, PuppeteerBrowser, PuppeteerBrowserContext, PuppeteerElement, PuppeteerPage, type RequestInterceptionAction, type RequestInterceptionOption, type RequestMatch, type RequestMethod, type RequestResourceType, type ResponseHandler, type ResponseHandlerOptions, type ResponseInterceptionItem, type ResponseInterceptionOption, type ResponseMatch, type ResponsePageData, type ScreenshotOptions, type SelectOptions, type UpdatablePageInfo, type ViewportSize, type WaitElementOptions, type WaitElementState, type WaitNavigationOptions, controller };
1425
+ export { type AllApiRequestContext, type AllBrowser, type AllBrowserContext, type AllElement, type AllFrame, type AllPage, type AllResponse, type BrowserContextRequirements, type BrowserControllerType, type BrowserCreationMethod, type BrowserLaunchMethod, type BrowserStateData, CheerioElement, type CheerioNode, CheerioPage, type ClientCertificate, type CookieItem, type GotoOptions, type IframeOption, type InputOptions, type KeyInput, type KeyPressOptions, type LocalStorageItem, type LocalStorageOrigin, type LowerCasePaperFormat, type LsdApiContext, type LsdApiContextOptions, type LsdApiResponse, type LsdBrowser, type LsdBrowserContext, type LsdBrowserContextOptions, type LsdBrowserController$1 as LsdBrowserController, type LsdBrowserType, type LsdConnectOptions, type LsdElement, type LsdFetchOptions, type LsdLaunchOptions, type LsdPage, type MouseClickOptions, type MouseClickType, type NavigationWaitUntil, type PDFMargin, type PDFOptions, type PageEvent, type PageExtInPlaywright, type PageExtInPuppeteer, type PageInfo, type PageOpenType, type PageStatus, type PaperFormat, PlaywrightBrowser, PlaywrightBrowserContext, type PlaywrightBrowserTypes, PlaywrightElement, PlaywrightPage, type ProxyInController, PuppeteerBrowser, PuppeteerBrowserContext, PuppeteerElement, PuppeteerPage, type RequestInterceptionAction, type RequestInterceptionOption, type RequestMatch, type RequestMethod, type RequestResourceType, type ResponseHandler, type ResponseHandlerOptions, type ResponseInterceptionItem, type ResponseInterceptionOption, type ResponseMatch, type ResponsePageData, type ScreenshotOptions, type SelectOptions, type UpdatablePageInfo, type ViewportSize, type WaitElementOptions, type WaitElementState, type WaitNavigationOptions, controller };
package/dist/index.js CHANGED
@@ -30,7 +30,6 @@ var PlaywrightElement = class _PlaywrightElement {
30
30
  return names;
31
31
  }
32
32
  /*
33
- // 如果不存在指定的子iframe,则返回null
34
33
  async #getChildFrame(parentFrame: Frame, iframeOption: IframeOption): Promise<Frame | null> {
35
34
  if (!parentFrame) {
36
35
  throw new Error("Invalid parent frame");
@@ -222,6 +221,13 @@ var PlaywrightElement = class _PlaywrightElement {
222
221
  await this.#locator.press(key, options);
223
222
  return true;
224
223
  }
224
+ async screenshot(options) {
225
+ return await this.#locator.screenshot(options);
226
+ }
227
+ async scrollIntoView() {
228
+ await this.#locator.scrollIntoViewIfNeeded();
229
+ return true;
230
+ }
225
231
  async select(options) {
226
232
  const { type, values = [], labels = [], indexes = [] } = options;
227
233
  switch (type) {
@@ -261,13 +267,15 @@ var PlaywrightElement = class _PlaywrightElement {
261
267
  }
262
268
  return true;
263
269
  }
264
- async screenshot(options) {
265
- return await this.#locator.screenshot(options);
266
- }
267
- async scrollIntoView() {
268
- await this.#locator.scrollIntoViewIfNeeded();
270
+ async setAttribute(attributeName, newValue) {
271
+ await this.#locator.evaluate((node, argvs) => {
272
+ node.setAttribute(argvs[0], argvs[1]);
273
+ }, [attributeName, newValue]);
269
274
  return true;
270
275
  }
276
+ _origElement() {
277
+ return this.#locator;
278
+ }
271
279
  };
272
280
 
273
281
  // src/playwright/page.ts
@@ -374,7 +382,6 @@ var PlaywrightPage = class extends EventEmitter {
374
382
  return true;
375
383
  }
376
384
  /*
377
- // 如果不存在指定的子iframe,则返回null
378
385
  async #getChildFrame(parentFrame: Frame, iframeOption: IframeOption): Promise<Frame | null> {
379
386
  if (!parentFrame) {
380
387
  throw new Error("Invalid parent frame");
@@ -1452,7 +1459,7 @@ var PlaywrightBrowser = class extends EventEmitter3 {
1452
1459
  #maxPageFreeSeconds() {
1453
1460
  return this.#options.maxPageFreeSeconds ? this.#options.maxPageFreeSeconds : 900;
1454
1461
  }
1455
- // 构造函数:缺省只能由LsdBrowserController.launch/connect调用创建实例!!!
1462
+ // constructor: called only by LsdBrowserController.launch/connect
1456
1463
  constructor(browser, browerType, browserCreateMethod, options, browserIdx = 0, pid = 0) {
1457
1464
  if (!browser || typeof browser.contexts !== "function") {
1458
1465
  throw new Error(`Invalid playwright browser parameter`);
@@ -1518,7 +1525,6 @@ var PlaywrightBrowser = class extends EventEmitter3 {
1518
1525
  await lsdBrowserContext.closeFreePages();
1519
1526
  }
1520
1527
  }
1521
- // 常用方法(按常见调用顺序排序)
1522
1528
  async newBrowserContext(options) {
1523
1529
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
1524
1530
  logwarn3(`##browser ${this.id()} can not create more new browserContext`);
@@ -1553,7 +1559,6 @@ var PlaywrightBrowser = class extends EventEmitter3 {
1553
1559
  await this.#browser.close();
1554
1560
  return true;
1555
1561
  }
1556
- // 其它方法(按字母顺序排序)
1557
1562
  browserContexts() {
1558
1563
  return this.#lsdBrowserContexts;
1559
1564
  }
@@ -1568,7 +1573,7 @@ var PlaywrightBrowser = class extends EventEmitter3 {
1568
1573
  }
1569
1574
  doesMeetBrowserContextRequirements(browserContextRequirements) {
1570
1575
  const { browserControllerTypes, browserTypes, headlesses } = browserContextRequirements;
1571
- return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 && browserTypes.includes(this.#browserType)) && (headlesses.length === 0 && headlesses.includes(this.#headless));
1576
+ return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 || browserTypes.includes(this.#browserType)) && (headlesses.length === 0 || headlesses.includes(this.#headless));
1572
1577
  }
1573
1578
  executablePath() {
1574
1579
  return this.#executablePath;
@@ -1634,7 +1639,6 @@ var PuppeteerElement = class _PuppeteerElement {
1634
1639
  const names = await this.#frame.evaluate((ele) => ele.getAttributeNames(), this.#$ele);
1635
1640
  return names;
1636
1641
  }
1637
- // 如果不存在指定的子iframe,则返回null
1638
1642
  async #getChildFrame(parentFrame, iframeOption) {
1639
1643
  if (!parentFrame) {
1640
1644
  throw new Error("Invalid parent frame");
@@ -1812,6 +1816,15 @@ var PuppeteerElement = class _PuppeteerElement {
1812
1816
  await this.#$ele.press(key, options);
1813
1817
  return true;
1814
1818
  }
1819
+ async screenshot(options) {
1820
+ return await this.#$ele.screenshot(options);
1821
+ }
1822
+ async scrollIntoView() {
1823
+ await this.#frame.evaluate((ele) => {
1824
+ ele.scrollIntoView();
1825
+ }, this.#$ele);
1826
+ return true;
1827
+ }
1815
1828
  async select(options) {
1816
1829
  const { type, values = [], labels = [], indexes = [] } = options;
1817
1830
  switch (type) {
@@ -1866,15 +1879,15 @@ var PuppeteerElement = class _PuppeteerElement {
1866
1879
  }
1867
1880
  return true;
1868
1881
  }
1869
- async screenshot(options) {
1870
- return await this.#$ele.screenshot(options);
1871
- }
1872
- async scrollIntoView() {
1873
- await this.#frame.evaluate((ele) => {
1874
- ele.scrollIntoView();
1875
- }, this.#$ele);
1882
+ async setAttribute(attributeName, newValue) {
1883
+ await this.#frame.evaluate((ele, name, value) => {
1884
+ ele.setAttribute(name, value);
1885
+ }, this.#$ele, attributeName, newValue);
1876
1886
  return true;
1877
1887
  }
1888
+ _origElement() {
1889
+ return this.#$ele;
1890
+ }
1878
1891
  };
1879
1892
 
1880
1893
  // src/puppeteer/page.ts
@@ -1958,7 +1971,6 @@ var PuppeteerPage = class extends EventEmitter4 {
1958
1971
  });
1959
1972
  return true;
1960
1973
  }
1961
- // 如果不存在指定的子iframe,则返回null
1962
1974
  async #getChildFrame(parentFrame, iframeOption) {
1963
1975
  if (!parentFrame) {
1964
1976
  throw new Error("Invalid parent frame");
@@ -2989,7 +3001,7 @@ var PuppeteerBrowser = class extends EventEmitter6 {
2989
3001
  #userAgent() {
2990
3002
  return this.#options.userAgent ? this.#options.userAgent : "";
2991
3003
  }
2992
- // 构造函数:缺省只能由LsdBrowserController.launch/connect调用创建实例!!!
3004
+ // constructor: called only by LsdBrowserController.launch/connect
2993
3005
  constructor(browser, browerType, browserCreateMethod, options, browserIdx = 0, pid = 0) {
2994
3006
  if (!browser || typeof browser.browserContexts !== "function") {
2995
3007
  throw new Error(`Invalid puppeteer browser parameter`);
@@ -3052,7 +3064,6 @@ var PuppeteerBrowser = class extends EventEmitter6 {
3052
3064
  await lsdBrowserContext.closeFreePages();
3053
3065
  }
3054
3066
  }
3055
- // 常用方法(按常见调用顺序排序)
3056
3067
  async newBrowserContext(options) {
3057
3068
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
3058
3069
  logwarn5(`##browser ${this.id()} can not create more new browserContext`);
@@ -3083,7 +3094,6 @@ var PuppeteerBrowser = class extends EventEmitter6 {
3083
3094
  await this.#browser.close();
3084
3095
  return true;
3085
3096
  }
3086
- // 其它方法(按字母顺序排序)
3087
3097
  browserContexts() {
3088
3098
  return this.#lsdBrowserContexts;
3089
3099
  }
@@ -3098,7 +3108,7 @@ var PuppeteerBrowser = class extends EventEmitter6 {
3098
3108
  }
3099
3109
  doesMeetBrowserContextRequirements(browserContextRequirements) {
3100
3110
  const { browserControllerTypes, browserTypes, headlesses } = browserContextRequirements;
3101
- return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 && browserTypes.includes(this.#browserType)) && (headlesses.length === 0 && headlesses.includes(this.#headless));
3111
+ return (browserControllerTypes.length === 0 || browserControllerTypes.includes(this.#browserControllerType)) && (browserTypes.length === 0 || browserTypes.includes(this.#browserType)) && (headlesses.length === 0 || headlesses.includes(this.#headless));
3102
3112
  }
3103
3113
  executablePath() {
3104
3114
  return this.#executablePath;
@@ -3241,13 +3251,19 @@ var CheerioElement = class _CheerioElement {
3241
3251
  async press() {
3242
3252
  throw new Error("Not supported in CheerioElement.");
3243
3253
  }
3254
+ async screenshot() {
3255
+ throw new Error("Not supported in CheerioElement.");
3256
+ }
3257
+ async scrollIntoView() {
3258
+ throw new Error("Not supported in CheerioElement.");
3259
+ }
3244
3260
  async select() {
3245
3261
  throw new Error("Not supported in CheerioElement.");
3246
3262
  }
3247
- async screenshot() {
3263
+ async setAttribute() {
3248
3264
  throw new Error("Not supported in CheerioElement.");
3249
3265
  }
3250
- async scrollIntoView() {
3266
+ _origElement() {
3251
3267
  throw new Error("Not supported in CheerioElement.");
3252
3268
  }
3253
3269
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letsscrapedata/controller",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "Unified browser / HTML controller interfaces that support playwright, puppeteer and cheerio",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",