@stubber/virtual-worker 1.1.0 → 1.2.0

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.
@@ -1,9 +1,8 @@
1
1
  import { create_error_conceptual } from "#app/functions/create_error_conceptual.js";
2
- import { create_error_technical } from "#app/functions/create_error_technical.js";
3
2
  import { create_success } from "#app/functions/create_success.js";
4
- import { get_chromium_page } from "../../helpers/get_chromium_page.js";
5
3
  import fs from "fs";
6
4
  import { v4 } from "uuid";
5
+ import { get_chromium_page } from "../../helpers/get_chromium_page.js";
7
6
 
8
7
  /**
9
8
  *
@@ -16,7 +15,7 @@ export const browser_click = async (params, stubber_context) => {
16
15
  const { entries } = params || {};
17
16
 
18
17
  // use playwright to move the mouse and perform a left click
19
- const page_result = await get_chromium_page(stubber_context.stubref);
18
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
20
19
 
21
20
  if (!page_result.success) {
22
21
  return page_result;
@@ -9,7 +9,7 @@ export const browser_extract_data = async (params, stubber_context) => {
9
9
  }
10
10
 
11
11
  // Get the Chromium page
12
- const page_result = await get_chromium_page(stubber_context.stubref);
12
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
13
13
  if (!page_result.success) {
14
14
  return page_result;
15
15
  }
@@ -10,7 +10,7 @@ import { get_chromium_page } from "../../helpers/get_chromium_page.js";
10
10
  */
11
11
  export const browser_extract_html = async (params, stubber_context) => {
12
12
  // Get the Chromium page
13
- const page_result = await get_chromium_page(stubber_context.stubref);
13
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
14
14
  if (!page_result.success) {
15
15
  return page_result;
16
16
  }
@@ -0,0 +1,39 @@
1
+ import { create_error_conceptual } from "#app/functions/create_error_conceptual.js";
2
+ import { create_error_technical } from "#app/functions/create_error_technical.js";
3
+ import { create_success } from "#app/functions/create_success.js";
4
+ import { get_chromium_page } from "../../helpers/get_chromium_page.js";
5
+
6
+ /**
7
+ * Reads text from the system clipboard for the page's origin.
8
+ * Playwright sometimes requires permissions to use the Clipboard API; this tries to
9
+ * request clipboard-read permission for the page's origin before reading.
10
+ *
11
+ * @param {Object} params
12
+ * @param {string} [params.session_id] - optional session id for get_chromium_page
13
+ * @returns
14
+ */
15
+ export const browser_get_clipboard_text = async (params, stubber_context) => {
16
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
17
+
18
+ if (!page_result.success) {
19
+ return page_result;
20
+ }
21
+
22
+ const page = page_result.payload;
23
+
24
+ const page_url = page.url();
25
+
26
+ if (!page_url || page_url === "about:blank") {
27
+ return create_error_conceptual({ message: "No page loaded", details: { url: page_url } });
28
+ }
29
+
30
+ // This will attempt to read the clipboard using the browser API.
31
+ // Some environments require user gesture or extra permissions; handle failures.
32
+ const text = await page.evaluate(async () => {
33
+ /* global navigator */
34
+ // navigator.clipboard.readText might throw if permission is denied
35
+ return await navigator.clipboard.readText();
36
+ });
37
+
38
+ return create_success({ message: "Clipboard text retrieved successfully", payload: { text } });
39
+ };
@@ -1,10 +1,9 @@
1
1
  import { create_error_conceptual } from "#app/functions/create_error_conceptual.js";
2
- import { create_error_technical } from "#app/functions/create_error_technical.js";
3
2
  import { create_success } from "#app/functions/create_success.js";
4
3
  import { get_chromium_page } from "../../helpers/get_chromium_page.js";
5
4
 
6
- export const browser_get_localstorage = async (param, stubber_context) => {
7
- const page_result = await get_chromium_page(stubber_context.stubref);
5
+ export const browser_get_localstorage = async (params, stubber_context) => {
6
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
8
7
 
9
8
  if (!page_result.success) {
10
9
  return page_result;
@@ -3,16 +3,16 @@ import { create_success } from "#app/functions/create_success.js";
3
3
  import { get_chromium_page } from "../../helpers/get_chromium_page.js";
4
4
 
5
5
  export const browser_navigate = async (params, stubber_context) => {
6
- const result = await get_chromium_page(stubber_context.stubref);
6
+ const result = await get_chromium_page(params?.session_id || stubber_context.stubref);
7
7
  if (!result.success) {
8
8
  return result;
9
9
  }
10
10
 
11
- const { url } = params || {};
11
+ const { url, options } = params || {};
12
12
 
13
13
  const page = result.payload;
14
14
 
15
- if (url) await page.goto(url);
15
+ if (url) await page.goto(url, options);
16
16
 
17
17
  return create_success({ message: "Navigated to new page", payload: {} });
18
18
  };
@@ -9,8 +9,9 @@ import { get_chromium_page } from "#app/helpers/get_chromium_page.js";
9
9
  * @param {Array<{locator?: string, frame?:string, key?: string, keys?: string}>} params.entries - Array of locator and key pairs.
10
10
  * @returns
11
11
  */
12
- export const browser_press_key = async ({ entries }, stubber_context) => {
13
- const page_result = await get_chromium_page(stubber_context.stubref);
12
+ export const browser_press_key = async (params, stubber_context) => {
13
+ const { entries } = params || {};
14
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
14
15
  if (!page_result.success) {
15
16
  return page_result;
16
17
  }
@@ -11,8 +11,10 @@ import { create_error_technical } from "#app/functions/create_error_technical.js
11
11
  * @param {string} [params.locator] - Optional locator to screenshot a specific element
12
12
  * @returns
13
13
  */
14
- export const browser_screenshot = async ({ screenshot_options, locator }, stubber_context) => {
15
- const page_result = await get_chromium_page(stubber_context.stubref);
14
+ export const browser_screenshot = async (params, stubber_context) => {
15
+ let { screenshot_options, locator } = params || {};
16
+
17
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
16
18
  if (!page_result.success) {
17
19
  return page_result;
18
20
  }
@@ -9,8 +9,9 @@ import { get_chromium_page } from "../../helpers/get_chromium_page.js";
9
9
  * @param {Array<{locator: string, frame?:string, text: string}>} params.entries - Array of locator and text pairs.
10
10
  * @returns
11
11
  */
12
- export const browser_write_text = async ({ entries }, stubber_context) => {
13
- const page_result = await get_chromium_page(stubber_context.stubref);
12
+ export const browser_write_text = async (params, stubber_context) => {
13
+ const { entries } = params || {};
14
+ const page_result = await get_chromium_page(params?.session_id || stubber_context.stubref);
14
15
  if (!page_result.success) {
15
16
  return page_result;
16
17
  }
@@ -6,6 +6,7 @@ import { browser_write_text } from "./browser/browser_write_text.js";
6
6
  import { browser_press_key } from "./browser/browser_press_key.js";
7
7
  import { browser_extract_html } from "./browser/browser_extract_html.js";
8
8
  import { browser_screenshot } from "./browser/browser_screenshot.js";
9
+ import { browser_get_clipboard_text } from "./browser/browser_get_clipboard_text.js";
9
10
  import { cli_run } from "./cli/cli_run.js";
10
11
 
11
12
  import { upload_files } from "./file-server/upload_files.js";
@@ -20,6 +21,7 @@ const all_commands = {
20
21
  browser_press_key,
21
22
  browser_extract_html,
22
23
  browser_screenshot,
24
+ browser_get_clipboard_text,
23
25
 
24
26
  cli_run,
25
27
 
@@ -13,12 +13,12 @@ let browser;
13
13
  const contexts = {};
14
14
 
15
15
  /**
16
- * @param {string} stubref
16
+ * @param {string} session_id
17
17
  * @returns {Promise<{ success: boolean, payload?: import("playwright").Page }>}
18
18
  */
19
- export const get_chromium_page = async (stubref) => {
20
- if (!stubref) {
21
- return create_error_conceptual({ message: "stubref is required to get a Chromium page." });
19
+ export const get_chromium_page = async (session_id) => {
20
+ if (!session_id) {
21
+ return create_error_conceptual({ message: "session_id is required to get a Chromium page." });
22
22
  }
23
23
 
24
24
  // Launch the browser once and reuse it
@@ -26,22 +26,23 @@ export const get_chromium_page = async (stubref) => {
26
26
  browser = await chromium.launch({
27
27
  headless: false,
28
28
  // eslint-disable-next-line id-match
29
- slowMo: 1500,
29
+ slowMo: 500,
30
30
  });
31
31
  }
32
32
 
33
33
  // Create a new context per stubref if not already created
34
- if (!contexts[stubref]) {
34
+ if (!contexts[session_id]) {
35
35
  const context = await browser.newContext({
36
36
  // eslint-disable-next-line id-match
37
37
  ignoreHTTPSErrors: true,
38
+ permissions: ["clipboard-read", "clipboard-write"],
38
39
  });
39
- contexts[stubref] = {
40
+ contexts[session_id] = {
40
41
  context,
41
42
  };
42
43
  }
43
44
 
44
- const context = contexts[stubref].context;
45
+ const context = contexts[session_id].context;
45
46
 
46
47
  // Try to find an open page in the context
47
48
  let page = context.pages().find((p) => !p.isClosed());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stubber/virtual-worker",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Template to easily create a node app and keep development standards",
5
5
  "main": "app.js",
6
6
  "directories": {