@iflyrpa/playwright 1.0.6 → 1.0.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.cjs CHANGED
@@ -5,7 +5,6 @@ const path = require('node:path');
5
5
  const axios = require('axios');
6
6
  const fs = require('fs-extra');
7
7
  const electron = require('electron');
8
- const playwright = require('playwright');
9
8
  const spawn = require('cross-spawn');
10
9
 
11
10
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -18,7 +17,7 @@ const spawn__default = /*#__PURE__*/_interopDefaultCompat(spawn);
18
17
 
19
18
  const name = "@iflyrpa/playwright";
20
19
  const type = "module";
21
- const version$1 = "1.0.6";
20
+ const version$1 = "1.0.8";
22
21
  const description = "";
23
22
  const main = "./dist/index.cjs";
24
23
  const module$1 = "./dist/index.mjs";
@@ -103,9 +102,9 @@ const xiaohongshuPublishAction = async (props) => {
103
102
  const selectAddress = async (selector, address) => {
104
103
  const instance = typeof selector === "string" ? page.locator(selector) : selector;
105
104
  await instance.click();
106
- await instance.fill(address);
105
+ await instance.locator("input").fill(address);
107
106
  const poperInstance = page.locator(
108
- ".el-popper[aria-hidden=false] ul li[role=option]"
107
+ '.d-popover:not([style*="display: none"]) .d-options .d-grid-item'
109
108
  );
110
109
  await poperInstance.first().waitFor();
111
110
  await poperInstance.first().click();
@@ -116,8 +115,12 @@ const xiaohongshuPublishAction = async (props) => {
116
115
  await instance.fill(date);
117
116
  await instance.blur();
118
117
  };
119
- await page.waitForSelector("#CreatorPlatform", { state: "visible" });
120
- await page.locator("#content-area .menu-container .publish-video a").click();
118
+ await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
119
+ throw new Error("\u767B\u5F55\u5931\u8D25");
120
+ });
121
+ await page.locator("#content-area .menu-container .publish-video a").click().catch(() => {
122
+ throw new Error("\u672A\u627E\u5230\u53D1\u5E03\u7B14\u8BB0\u6309\u94AE");
123
+ });
121
124
  await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click();
122
125
  const images = await Promise.all(
123
126
  params.banners.map((url) => {
@@ -138,52 +141,56 @@ const xiaohongshuPublishAction = async (props) => {
138
141
  const container = page.locator(".creator-container .content .scroll-content");
139
142
  await container.focus();
140
143
  await page.mouse.wheel(0, 500);
141
- await selectAddress(
142
- ".media-extension .address-input input[placeholder=\u6DFB\u52A0\u5730\u70B9]",
143
- params.address
144
- );
145
- await page.locator(".declaration-wrapper").click();
146
- const selfDeclarationInstance = page.locator(
147
- ".el-popper[aria-hidden=false] ul li[role=menuitem]"
148
- );
149
- if (params.selfDeclaration.type === "fictional-rendition") {
150
- await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
151
- } else if (params.selfDeclaration.type === "ai-generated") {
152
- await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
153
- } else if (params.selfDeclaration.type === "source-statement") {
154
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
155
- const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
156
- await selfDeclarationSecondaryMenuInstance.first().waitFor();
157
- if (params.selfDeclaration.childType === "self-labeling") {
158
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
159
- } else if (params.selfDeclaration.childType === "self-shooting") {
160
- const { shootingDate, shootingLocation } = params.selfDeclaration;
161
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
162
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
163
- await selfShootingPopup.waitFor();
164
- const hasCustomContent = shootingDate || shootingLocation;
165
- if (shootingLocation) {
166
- await selectAddress(
167
- selfShootingPopup.locator(".address-input input"),
168
- shootingLocation
169
- );
170
- }
171
- if (shootingDate) {
172
- await selectDate(
173
- selfShootingPopup.locator(".date-picker input"),
174
- shootingDate
175
- );
176
- }
177
- await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
178
- } else if (params.selfDeclaration.childType === "transshipment") {
179
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
180
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
181
- await selfShootingPopup.waitFor();
182
- const sourceMedia = params.selfDeclaration.sourceMedia;
183
- if (sourceMedia) {
184
- await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
144
+ if (params.address) {
145
+ await selectAddress(
146
+ page.locator(".media-extension .address-input").filter({ hasText: "\u6DFB\u52A0\u5730\u70B9" }),
147
+ params.address
148
+ );
149
+ }
150
+ if (params.selfDeclaration) {
151
+ await page.locator(".declaration-wrapper").click();
152
+ const selfDeclarationInstance = page.locator(
153
+ ".el-popper[aria-hidden=false] ul li[role=menuitem]"
154
+ );
155
+ if (params.selfDeclaration.type === "fictional-rendition") {
156
+ await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
157
+ } else if (params.selfDeclaration.type === "ai-generated") {
158
+ await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
159
+ } else if (params.selfDeclaration.type === "source-statement") {
160
+ await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
161
+ const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
162
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
163
+ if (params.selfDeclaration.childType === "self-labeling") {
164
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
165
+ } else if (params.selfDeclaration.childType === "self-shooting") {
166
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
167
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
168
+ const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
169
+ await selfShootingPopup.waitFor();
170
+ const hasCustomContent = shootingDate || shootingLocation;
171
+ if (shootingLocation) {
172
+ await selectAddress(
173
+ selfShootingPopup.locator(".address-input"),
174
+ shootingLocation
175
+ );
176
+ }
177
+ if (shootingDate) {
178
+ await selectDate(
179
+ selfShootingPopup.locator(".date-picker input"),
180
+ shootingDate
181
+ );
182
+ }
183
+ await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
184
+ } else if (params.selfDeclaration.childType === "transshipment") {
185
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
186
+ const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
187
+ await selfShootingPopup.waitFor();
188
+ const sourceMedia = params.selfDeclaration.sourceMedia;
189
+ if (sourceMedia) {
190
+ await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
191
+ }
192
+ await selfShootingPopup.locator("footer button").filter({ hasText: sourceMedia ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
185
193
  }
186
- await selfShootingPopup.locator("footer button").filter({ hasText: sourceMedia ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
187
194
  }
188
195
  }
189
196
  const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
@@ -224,7 +231,8 @@ const generateFile = async (dir) => {
224
231
  }
225
232
  return filePath;
226
233
  };
227
- const createElectronApp = async (cachePath) => {
234
+ const createElectronApp = async (cachePath, playwrightPackage) => {
235
+ const playwright = await playwrightPackage;
228
236
  const mainPath = await generateFile(cachePath);
229
237
  const electronApp = await playwright._electron.launch({
230
238
  executablePath: electron.app.getPath("exe"),
@@ -241,14 +249,15 @@ var __publicField$1 = (obj, key, value) => {
241
249
  return value;
242
250
  };
243
251
  class PackageManager {
244
- // 依赖名称
245
- constructor(packageName, cacheDir) {
252
+ constructor(params) {
246
253
  __publicField$1(this, "cacheDir");
247
254
  // 依赖安装目录
248
- __publicField$1(this, "packageName");
249
- this.cacheDir = cacheDir;
250
- this.packageName = packageName;
251
- this.init();
255
+ __publicField$1(this, "forceUpdate");
256
+ // 是否强制更新
257
+ __publicField$1(this, "initPromise");
258
+ this.cacheDir = params.cacheDir;
259
+ this.forceUpdate = params.forceUpdate || true;
260
+ this.initPromise = this.init(params.packageName, params.packageVersion);
252
261
  }
253
262
  // 在子线程执行 npm 命令
254
263
  execCommand(cmd, modules, where = this.cacheDir) {
@@ -280,7 +289,7 @@ class PackageManager {
280
289
  });
281
290
  }
282
291
  // 构建 package.json 文件,有了该文件后,依赖可以安装在该目录下,避免污染全局环境
283
- async initCacheProject() {
292
+ initCacheProject() {
284
293
  const packagePath = path__default.join(this.cacheDir, "package.json");
285
294
  if (!fs__default.existsSync(packagePath)) {
286
295
  const pkg = {
@@ -288,10 +297,8 @@ class PackageManager {
288
297
  description: "rpa-plugins",
289
298
  license: "MIT"
290
299
  };
291
- await fs__default.ensureFile(packagePath);
292
- await Promise.all([
293
- fs__default.writeFile(packagePath, JSON.stringify(pkg), "utf8")
294
- ]);
300
+ fs__default.ensureFileSync(packagePath);
301
+ fs__default.writeFileSync(packagePath, JSON.stringify(pkg), "utf8");
295
302
  }
296
303
  }
297
304
  // 获取依赖信息
@@ -311,26 +318,31 @@ class PackageManager {
311
318
  return null;
312
319
  }
313
320
  }
321
+ async getPluginAfterInit(module) {
322
+ await this.initPromise;
323
+ return this.getPlugin(module);
324
+ }
314
325
  // 安装依赖
315
- install(module) {
316
- return this.execCommand("install", [module]);
326
+ install(module, version) {
327
+ const moduleName = version ? `${module}@${version}` : module;
328
+ return this.execCommand("install", [moduleName]);
317
329
  }
318
330
  // 更新依赖
319
331
  update(module) {
320
332
  return this.execCommand("update", [module]);
321
333
  }
322
- async init() {
323
- await this.initCacheProject();
324
- const plugin = this.getPlugin(path__default.join(this.packageName, "package.json"));
334
+ async init(name, version) {
335
+ this.initCacheProject();
336
+ const plugin = this.getPlugin(path__default.join(name, "package.json"));
325
337
  if (!plugin) {
326
- await this.install(this.packageName);
327
- } else {
328
- const pkInfo = await this.getPluginInfo(this.packageName);
338
+ await this.install(name, version);
339
+ } else if (this.forceUpdate) {
340
+ const pkInfo = await this.getPluginInfo(name);
329
341
  if (!pkInfo)
330
342
  throw new Error("\u4F9D\u8D56\u4FE1\u606F\u83B7\u53D6\u5931\u8D25");
331
343
  const hasNewVersion = semver__default.gt(pkInfo.version, plugin.version);
332
344
  if (hasNewVersion) {
333
- await this.install(`${this.packageName}@${pkInfo.version}`);
345
+ await this.install(name, pkInfo.version);
334
346
  }
335
347
  }
336
348
  console.log("Package manager init done!");
@@ -343,15 +355,44 @@ var __publicField = (obj, key, value) => {
343
355
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
344
356
  return value;
345
357
  };
358
+ const PLAYWRIGHT_VERSION = "1.46.1";
346
359
  class LocalAutomateTask {
347
360
  constructor(params) {
348
361
  __publicField(this, "cachePath");
349
362
  __publicField(this, "debug");
350
363
  __publicField(this, "appWhenReady");
364
+ __publicField(this, "playwrightPackage");
351
365
  this.cachePath = params.cachePath;
352
366
  this.debug = params.debug || false;
353
- this.appWhenReady = createElectronApp(params.cachePath);
367
+ this.playwrightPackage = this.installPlaywright();
368
+ this.appWhenReady = createElectronApp(
369
+ params.cachePath,
370
+ this.playwrightPackage
371
+ );
372
+ }
373
+ /**
374
+ * 安装 playwright
375
+ * @returns
376
+ */
377
+ installPlaywright() {
378
+ const playwrightPackageManager = new PackageManager({
379
+ packageName: "playwright",
380
+ packageVersion: PLAYWRIGHT_VERSION,
381
+ cacheDir: this.cachePath
382
+ });
383
+ return playwrightPackageManager.getPluginAfterInit("playwright");
384
+ }
385
+ /**
386
+ * 关闭 playwright 启动的 electron 客户端
387
+ * @returns
388
+ */
389
+ async close() {
390
+ const electronApp = await this.appWhenReady;
391
+ return electronApp.close();
354
392
  }
393
+ /**
394
+ * 小红书自动化发布
395
+ */
355
396
  async xiaohongshuPublish(params) {
356
397
  const electronApp = await this.appWhenReady;
357
398
  const commonCookies = {
@@ -403,7 +444,10 @@ class LocalAutomateTask {
403
444
  }
404
445
  }
405
446
  const RpaTask = (params) => {
406
- const packageManager = new PackageManager(packageJson.name, params.cachePath);
447
+ const packageManager = new PackageManager({
448
+ packageName: packageJson.name,
449
+ cacheDir: params.cachePath
450
+ });
407
451
  const localPackge = packageManager.getPlugin(packageJson.name);
408
452
  if (localPackge?.LocalAutomateTask && localPackge?.version && semver__default.gt(localPackge.version, packageJson.version)) {
409
453
  return new localPackge.LocalAutomateTask(params);
package/dist/index.d.cts CHANGED
@@ -32,8 +32,8 @@ interface XiaohonshuPublishParams
32
32
  banners: string[]; // 图片
33
33
  title: string; // 标题
34
34
  content: string; // 正文
35
- address: string; // 地点
36
- selfDeclaration: SelfDeclaration; // 自主声明
35
+ address?: string; // 地点
36
+ selfDeclaration?: SelfDeclaration; // 自主声明
37
37
  visibleRange: "public" | "private"; // 可见范围
38
38
  isImmediatelyPublish?: boolean; // 是否立即发布
39
39
  scheduledPublish?: string; // 定时发布时间
@@ -47,7 +47,21 @@ declare class LocalAutomateTask implements TaskParams {
47
47
  cachePath: string;
48
48
  debug: boolean;
49
49
  appWhenReady: Promise<ElectronApplication>;
50
+ playwrightPackage: Promise<unknown>;
50
51
  constructor(params: TaskParams);
52
+ /**
53
+ * 安装 playwright
54
+ * @returns
55
+ */
56
+ installPlaywright(): Promise<any>;
57
+ /**
58
+ * 关闭 playwright 启动的 electron 客户端
59
+ * @returns
60
+ */
61
+ close(): Promise<void>;
62
+ /**
63
+ * 小红书自动化发布
64
+ */
51
65
  xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
52
66
  }
53
67
  declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
package/dist/index.d.mts CHANGED
@@ -32,8 +32,8 @@ interface XiaohonshuPublishParams
32
32
  banners: string[]; // 图片
33
33
  title: string; // 标题
34
34
  content: string; // 正文
35
- address: string; // 地点
36
- selfDeclaration: SelfDeclaration; // 自主声明
35
+ address?: string; // 地点
36
+ selfDeclaration?: SelfDeclaration; // 自主声明
37
37
  visibleRange: "public" | "private"; // 可见范围
38
38
  isImmediatelyPublish?: boolean; // 是否立即发布
39
39
  scheduledPublish?: string; // 定时发布时间
@@ -47,7 +47,21 @@ declare class LocalAutomateTask implements TaskParams {
47
47
  cachePath: string;
48
48
  debug: boolean;
49
49
  appWhenReady: Promise<ElectronApplication>;
50
+ playwrightPackage: Promise<unknown>;
50
51
  constructor(params: TaskParams);
52
+ /**
53
+ * 安装 playwright
54
+ * @returns
55
+ */
56
+ installPlaywright(): Promise<any>;
57
+ /**
58
+ * 关闭 playwright 启动的 electron 客户端
59
+ * @returns
60
+ */
61
+ close(): Promise<void>;
62
+ /**
63
+ * 小红书自动化发布
64
+ */
51
65
  xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
52
66
  }
53
67
  declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
package/dist/index.d.ts CHANGED
@@ -32,8 +32,8 @@ interface XiaohonshuPublishParams
32
32
  banners: string[]; // 图片
33
33
  title: string; // 标题
34
34
  content: string; // 正文
35
- address: string; // 地点
36
- selfDeclaration: SelfDeclaration; // 自主声明
35
+ address?: string; // 地点
36
+ selfDeclaration?: SelfDeclaration; // 自主声明
37
37
  visibleRange: "public" | "private"; // 可见范围
38
38
  isImmediatelyPublish?: boolean; // 是否立即发布
39
39
  scheduledPublish?: string; // 定时发布时间
@@ -47,7 +47,21 @@ declare class LocalAutomateTask implements TaskParams {
47
47
  cachePath: string;
48
48
  debug: boolean;
49
49
  appWhenReady: Promise<ElectronApplication>;
50
+ playwrightPackage: Promise<unknown>;
50
51
  constructor(params: TaskParams);
52
+ /**
53
+ * 安装 playwright
54
+ * @returns
55
+ */
56
+ installPlaywright(): Promise<any>;
57
+ /**
58
+ * 关闭 playwright 启动的 electron 客户端
59
+ * @returns
60
+ */
61
+ close(): Promise<void>;
62
+ /**
63
+ * 小红书自动化发布
64
+ */
51
65
  xiaohongshuPublish(params: XiaohonshuPublishParams): Promise<string>;
52
66
  }
53
67
  declare const RpaTask: (params: TaskParams) => LocalAutomateTask;
package/dist/index.mjs CHANGED
@@ -3,12 +3,11 @@ import path from 'node:path';
3
3
  import axios from 'axios';
4
4
  import fs from 'fs-extra';
5
5
  import { app } from 'electron';
6
- import { _electron } from 'playwright';
7
6
  import spawn from 'cross-spawn';
8
7
 
9
8
  const name = "@iflyrpa/playwright";
10
9
  const type = "module";
11
- const version$1 = "1.0.6";
10
+ const version$1 = "1.0.8";
12
11
  const description = "";
13
12
  const main = "./dist/index.cjs";
14
13
  const module = "./dist/index.mjs";
@@ -93,9 +92,9 @@ const xiaohongshuPublishAction = async (props) => {
93
92
  const selectAddress = async (selector, address) => {
94
93
  const instance = typeof selector === "string" ? page.locator(selector) : selector;
95
94
  await instance.click();
96
- await instance.fill(address);
95
+ await instance.locator("input").fill(address);
97
96
  const poperInstance = page.locator(
98
- ".el-popper[aria-hidden=false] ul li[role=option]"
97
+ '.d-popover:not([style*="display: none"]) .d-options .d-grid-item'
99
98
  );
100
99
  await poperInstance.first().waitFor();
101
100
  await poperInstance.first().click();
@@ -106,8 +105,12 @@ const xiaohongshuPublishAction = async (props) => {
106
105
  await instance.fill(date);
107
106
  await instance.blur();
108
107
  };
109
- await page.waitForSelector("#CreatorPlatform", { state: "visible" });
110
- await page.locator("#content-area .menu-container .publish-video a").click();
108
+ await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
109
+ throw new Error("\u767B\u5F55\u5931\u8D25");
110
+ });
111
+ await page.locator("#content-area .menu-container .publish-video a").click().catch(() => {
112
+ throw new Error("\u672A\u627E\u5230\u53D1\u5E03\u7B14\u8BB0\u6309\u94AE");
113
+ });
111
114
  await page.locator(".creator-container .header .title").filter({ hasText: /^上传图文$/ }).click();
112
115
  const images = await Promise.all(
113
116
  params.banners.map((url) => {
@@ -128,52 +131,56 @@ const xiaohongshuPublishAction = async (props) => {
128
131
  const container = page.locator(".creator-container .content .scroll-content");
129
132
  await container.focus();
130
133
  await page.mouse.wheel(0, 500);
131
- await selectAddress(
132
- ".media-extension .address-input input[placeholder=\u6DFB\u52A0\u5730\u70B9]",
133
- params.address
134
- );
135
- await page.locator(".declaration-wrapper").click();
136
- const selfDeclarationInstance = page.locator(
137
- ".el-popper[aria-hidden=false] ul li[role=menuitem]"
138
- );
139
- if (params.selfDeclaration.type === "fictional-rendition") {
140
- await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
141
- } else if (params.selfDeclaration.type === "ai-generated") {
142
- await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
143
- } else if (params.selfDeclaration.type === "source-statement") {
144
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
145
- const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
146
- await selfDeclarationSecondaryMenuInstance.first().waitFor();
147
- if (params.selfDeclaration.childType === "self-labeling") {
148
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
149
- } else if (params.selfDeclaration.childType === "self-shooting") {
150
- const { shootingDate, shootingLocation } = params.selfDeclaration;
151
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
152
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
153
- await selfShootingPopup.waitFor();
154
- const hasCustomContent = shootingDate || shootingLocation;
155
- if (shootingLocation) {
156
- await selectAddress(
157
- selfShootingPopup.locator(".address-input input"),
158
- shootingLocation
159
- );
160
- }
161
- if (shootingDate) {
162
- await selectDate(
163
- selfShootingPopup.locator(".date-picker input"),
164
- shootingDate
165
- );
166
- }
167
- await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
168
- } else if (params.selfDeclaration.childType === "transshipment") {
169
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
170
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
171
- await selfShootingPopup.waitFor();
172
- const sourceMedia = params.selfDeclaration.sourceMedia;
173
- if (sourceMedia) {
174
- await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
134
+ if (params.address) {
135
+ await selectAddress(
136
+ page.locator(".media-extension .address-input").filter({ hasText: "\u6DFB\u52A0\u5730\u70B9" }),
137
+ params.address
138
+ );
139
+ }
140
+ if (params.selfDeclaration) {
141
+ await page.locator(".declaration-wrapper").click();
142
+ const selfDeclarationInstance = page.locator(
143
+ ".el-popper[aria-hidden=false] ul li[role=menuitem]"
144
+ );
145
+ if (params.selfDeclaration.type === "fictional-rendition") {
146
+ await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
147
+ } else if (params.selfDeclaration.type === "ai-generated") {
148
+ await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
149
+ } else if (params.selfDeclaration.type === "source-statement") {
150
+ await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
151
+ const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
152
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
153
+ if (params.selfDeclaration.childType === "self-labeling") {
154
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
155
+ } else if (params.selfDeclaration.childType === "self-shooting") {
156
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
157
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
158
+ const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
159
+ await selfShootingPopup.waitFor();
160
+ const hasCustomContent = shootingDate || shootingLocation;
161
+ if (shootingLocation) {
162
+ await selectAddress(
163
+ selfShootingPopup.locator(".address-input"),
164
+ shootingLocation
165
+ );
166
+ }
167
+ if (shootingDate) {
168
+ await selectDate(
169
+ selfShootingPopup.locator(".date-picker input"),
170
+ shootingDate
171
+ );
172
+ }
173
+ await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
174
+ } else if (params.selfDeclaration.childType === "transshipment") {
175
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
176
+ const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
177
+ await selfShootingPopup.waitFor();
178
+ const sourceMedia = params.selfDeclaration.sourceMedia;
179
+ if (sourceMedia) {
180
+ await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
181
+ }
182
+ await selfShootingPopup.locator("footer button").filter({ hasText: sourceMedia ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
175
183
  }
176
- await selfShootingPopup.locator("footer button").filter({ hasText: sourceMedia ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
177
184
  }
178
185
  }
179
186
  const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
@@ -214,9 +221,10 @@ const generateFile = async (dir) => {
214
221
  }
215
222
  return filePath;
216
223
  };
217
- const createElectronApp = async (cachePath) => {
224
+ const createElectronApp = async (cachePath, playwrightPackage) => {
225
+ const playwright = await playwrightPackage;
218
226
  const mainPath = await generateFile(cachePath);
219
- const electronApp = await _electron.launch({
227
+ const electronApp = await playwright._electron.launch({
220
228
  executablePath: app.getPath("exe"),
221
229
  // 获取 Electron 可执行文件的路径
222
230
  args: [mainPath]
@@ -231,14 +239,15 @@ var __publicField$1 = (obj, key, value) => {
231
239
  return value;
232
240
  };
233
241
  class PackageManager {
234
- // 依赖名称
235
- constructor(packageName, cacheDir) {
242
+ constructor(params) {
236
243
  __publicField$1(this, "cacheDir");
237
244
  // 依赖安装目录
238
- __publicField$1(this, "packageName");
239
- this.cacheDir = cacheDir;
240
- this.packageName = packageName;
241
- this.init();
245
+ __publicField$1(this, "forceUpdate");
246
+ // 是否强制更新
247
+ __publicField$1(this, "initPromise");
248
+ this.cacheDir = params.cacheDir;
249
+ this.forceUpdate = params.forceUpdate || true;
250
+ this.initPromise = this.init(params.packageName, params.packageVersion);
242
251
  }
243
252
  // 在子线程执行 npm 命令
244
253
  execCommand(cmd, modules, where = this.cacheDir) {
@@ -270,7 +279,7 @@ class PackageManager {
270
279
  });
271
280
  }
272
281
  // 构建 package.json 文件,有了该文件后,依赖可以安装在该目录下,避免污染全局环境
273
- async initCacheProject() {
282
+ initCacheProject() {
274
283
  const packagePath = path.join(this.cacheDir, "package.json");
275
284
  if (!fs.existsSync(packagePath)) {
276
285
  const pkg = {
@@ -278,10 +287,8 @@ class PackageManager {
278
287
  description: "rpa-plugins",
279
288
  license: "MIT"
280
289
  };
281
- await fs.ensureFile(packagePath);
282
- await Promise.all([
283
- fs.writeFile(packagePath, JSON.stringify(pkg), "utf8")
284
- ]);
290
+ fs.ensureFileSync(packagePath);
291
+ fs.writeFileSync(packagePath, JSON.stringify(pkg), "utf8");
285
292
  }
286
293
  }
287
294
  // 获取依赖信息
@@ -301,26 +308,31 @@ class PackageManager {
301
308
  return null;
302
309
  }
303
310
  }
311
+ async getPluginAfterInit(module) {
312
+ await this.initPromise;
313
+ return this.getPlugin(module);
314
+ }
304
315
  // 安装依赖
305
- install(module) {
306
- return this.execCommand("install", [module]);
316
+ install(module, version) {
317
+ const moduleName = version ? `${module}@${version}` : module;
318
+ return this.execCommand("install", [moduleName]);
307
319
  }
308
320
  // 更新依赖
309
321
  update(module) {
310
322
  return this.execCommand("update", [module]);
311
323
  }
312
- async init() {
313
- await this.initCacheProject();
314
- const plugin = this.getPlugin(path.join(this.packageName, "package.json"));
324
+ async init(name, version) {
325
+ this.initCacheProject();
326
+ const plugin = this.getPlugin(path.join(name, "package.json"));
315
327
  if (!plugin) {
316
- await this.install(this.packageName);
317
- } else {
318
- const pkInfo = await this.getPluginInfo(this.packageName);
328
+ await this.install(name, version);
329
+ } else if (this.forceUpdate) {
330
+ const pkInfo = await this.getPluginInfo(name);
319
331
  if (!pkInfo)
320
332
  throw new Error("\u4F9D\u8D56\u4FE1\u606F\u83B7\u53D6\u5931\u8D25");
321
333
  const hasNewVersion = semver.gt(pkInfo.version, plugin.version);
322
334
  if (hasNewVersion) {
323
- await this.install(`${this.packageName}@${pkInfo.version}`);
335
+ await this.install(name, pkInfo.version);
324
336
  }
325
337
  }
326
338
  console.log("Package manager init done!");
@@ -333,15 +345,44 @@ var __publicField = (obj, key, value) => {
333
345
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
334
346
  return value;
335
347
  };
348
+ const PLAYWRIGHT_VERSION = "1.46.1";
336
349
  class LocalAutomateTask {
337
350
  constructor(params) {
338
351
  __publicField(this, "cachePath");
339
352
  __publicField(this, "debug");
340
353
  __publicField(this, "appWhenReady");
354
+ __publicField(this, "playwrightPackage");
341
355
  this.cachePath = params.cachePath;
342
356
  this.debug = params.debug || false;
343
- this.appWhenReady = createElectronApp(params.cachePath);
357
+ this.playwrightPackage = this.installPlaywright();
358
+ this.appWhenReady = createElectronApp(
359
+ params.cachePath,
360
+ this.playwrightPackage
361
+ );
362
+ }
363
+ /**
364
+ * 安装 playwright
365
+ * @returns
366
+ */
367
+ installPlaywright() {
368
+ const playwrightPackageManager = new PackageManager({
369
+ packageName: "playwright",
370
+ packageVersion: PLAYWRIGHT_VERSION,
371
+ cacheDir: this.cachePath
372
+ });
373
+ return playwrightPackageManager.getPluginAfterInit("playwright");
374
+ }
375
+ /**
376
+ * 关闭 playwright 启动的 electron 客户端
377
+ * @returns
378
+ */
379
+ async close() {
380
+ const electronApp = await this.appWhenReady;
381
+ return electronApp.close();
344
382
  }
383
+ /**
384
+ * 小红书自动化发布
385
+ */
345
386
  async xiaohongshuPublish(params) {
346
387
  const electronApp = await this.appWhenReady;
347
388
  const commonCookies = {
@@ -393,7 +434,10 @@ class LocalAutomateTask {
393
434
  }
394
435
  }
395
436
  const RpaTask = (params) => {
396
- const packageManager = new PackageManager(packageJson.name, params.cachePath);
437
+ const packageManager = new PackageManager({
438
+ packageName: packageJson.name,
439
+ cacheDir: params.cachePath
440
+ });
397
441
  const localPackge = packageManager.getPlugin(packageJson.name);
398
442
  if (localPackge?.LocalAutomateTask && localPackge?.version && semver.gt(localPackge.version, packageJson.version)) {
399
443
  return new localPackge.LocalAutomateTask(params);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iflyrpa/playwright",
3
3
  "type": "module",
4
- "version": "1.0.6",
4
+ "version": "1.0.8",
5
5
  "description": "",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.mjs",