@intuned/browser-dev 0.1.7-dev.0 → 0.1.9-dev.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.
- package/README.md +85 -143
- package/dist/ai/export.d.ts +292 -144
- package/dist/ai/extractStructuredDataUsingAi.js +24 -1
- package/dist/ai/index.d.ts +292 -144
- package/dist/ai/tests/testExtractStructuredData.spec.js +2 -2
- package/dist/common/Logger/index.js +2 -2
- package/dist/helpers/export.d.ts +703 -577
- package/dist/helpers/gotoUrl.js +50 -51
- package/dist/helpers/index.d.ts +703 -577
- package/dist/helpers/tests/testClickUntilExhausted.spec.js +2 -1
- package/dist/helpers/withNetworkSettledWait.js +2 -7
- package/dist/optimized-extractors/export.d.ts +17 -18
- package/dist/optimized-extractors/index.d.ts +17 -18
- package/how-to-generate-docs.md +40 -28
- package/package.json +2 -3
- package/generated-docs/ai/functions/extractStructuredData.mdx +0 -255
- package/generated-docs/ai/functions/isPageLoaded.mdx +0 -89
- package/generated-docs/ai/interfaces/ArraySchema.mdx +0 -36
- package/generated-docs/ai/interfaces/BasicSchema.mdx +0 -14
- package/generated-docs/ai/interfaces/BooleanSchema.mdx +0 -28
- package/generated-docs/ai/interfaces/ImageBufferContentItem.mdx +0 -16
- package/generated-docs/ai/interfaces/ImageUrlContentItem.mdx +0 -16
- package/generated-docs/ai/interfaces/NumberSchema.mdx +0 -35
- package/generated-docs/ai/interfaces/ObjectSchema.mdx +0 -39
- package/generated-docs/ai/interfaces/StringSchema.mdx +0 -35
- package/generated-docs/ai/interfaces/TextContentItem.mdx +0 -14
- package/generated-docs/ai/type-aliases/ContentItem.mdx +0 -12
- package/generated-docs/ai/type-aliases/JsonSchema.mdx +0 -47
- package/generated-docs/ai/type-aliases/SUPPORTED_MODELS.mdx +0 -85
- package/generated-docs/helpers/functions/clickButtonAndWait.mdx +0 -63
- package/generated-docs/helpers/functions/clickUntilExhausted.mdx +0 -112
- package/generated-docs/helpers/functions/downloadFile.mdx +0 -99
- package/generated-docs/helpers/functions/extractMarkdown.mdx +0 -56
- package/generated-docs/helpers/functions/filterEmptyValues.mdx +0 -51
- package/generated-docs/helpers/functions/goToUrl.mdx +0 -124
- package/generated-docs/helpers/functions/processDate.mdx +0 -55
- package/generated-docs/helpers/functions/resolveUrl.mdx +0 -165
- package/generated-docs/helpers/functions/sanitizeHtml.mdx +0 -113
- package/generated-docs/helpers/functions/saveFileToS3.mdx +0 -127
- package/generated-docs/helpers/functions/scrollToLoadContent.mdx +0 -83
- package/generated-docs/helpers/functions/uploadFileToS3.mdx +0 -121
- package/generated-docs/helpers/functions/validateDataUsingSchema.mdx +0 -90
- package/generated-docs/helpers/functions/waitForDomSettled.mdx +0 -91
- package/generated-docs/helpers/functions/withNetworkSettledWait.mdx +0 -76
- package/generated-docs/helpers/interfaces/Attachment.mdx +0 -56
- package/generated-docs/helpers/interfaces/S3Configs.mdx +0 -52
- package/generated-docs/helpers/interfaces/SanitizeHtmlOptions.mdx +0 -22
- package/generated-docs/helpers/type-aliases/AttachmentType.mdx +0 -10
- package/generated-docs/helpers/type-aliases/FileType.mdx +0 -61
- package/generated-docs/helpers/type-aliases/Trigger.mdx +0 -62
package/dist/helpers/export.d.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import type { Locator, Page, ElementHandle } from "playwright";
|
|
4
4
|
import type { ReadStream } from "fs";
|
|
5
5
|
import { Download } from "playwright";
|
|
6
|
-
import { SUPPORTED_MODELS } from "../ai/export";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Configuration options for sanitizing HTML content.
|
|
@@ -11,11 +10,11 @@ import { SUPPORTED_MODELS } from "../ai/export";
|
|
|
11
10
|
export interface SanitizeHtmlOptions {
|
|
12
11
|
/** The HTML content to sanitize */
|
|
13
12
|
html: string;
|
|
14
|
-
/** Remove all
|
|
13
|
+
/** Remove all \<script\> elements. Defaults to true. */
|
|
15
14
|
removeScripts?: boolean;
|
|
16
|
-
/** Remove all
|
|
15
|
+
/** Remove all \<style\> elements. Defaults to true. */
|
|
17
16
|
removeStyles?: boolean;
|
|
18
|
-
/** Remove all
|
|
17
|
+
/** Remove all \<svg\> elements. Defaults to true. */
|
|
19
18
|
removeSvgs?: boolean;
|
|
20
19
|
/** Remove HTML comments. Defaults to true. */
|
|
21
20
|
removeComments?: boolean;
|
|
@@ -53,108 +52,101 @@ export interface SanitizeHtmlOptions {
|
|
|
53
52
|
*
|
|
54
53
|
* @example
|
|
55
54
|
* ```typescript Basic Sanitization
|
|
55
|
+
* import { BrowserContext, Page } from "playwright";
|
|
56
56
|
* import { sanitizeHtml } from "@intuned/browser";
|
|
57
|
-
* export default async function handler(params, page, context){
|
|
58
|
-
* const dirtyHtml = `
|
|
59
|
-
* <div>
|
|
60
|
-
* <script>alert('xss')</script>
|
|
61
|
-
* <p style="color: red;">Hello World</p>
|
|
62
|
-
* <span></span>
|
|
63
|
-
* </div>
|
|
64
|
-
* `;
|
|
65
|
-
* const sanitizedHtml = sanitizeHtml({ html: dirtyHtml });
|
|
66
|
-
* // Returns: '<div><p>Hello World</p></div>'
|
|
67
|
-
* }
|
|
68
|
-
* ```
|
|
69
57
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
|
|
88
|
-
* preserveAttributes: ["class", "src", "style"]
|
|
89
|
-
* });
|
|
90
|
-
* }
|
|
58
|
+
* interface Params {}
|
|
59
|
+
*
|
|
60
|
+
* export default async function handler(
|
|
61
|
+
* params: Params,
|
|
62
|
+
* page: Page,
|
|
63
|
+
* context: BrowserContext
|
|
64
|
+
* ) {
|
|
65
|
+
* await page.goto("https://books.toscrape.com");
|
|
66
|
+
* const firstRow = page.locator("ol.row").locator("li").first();
|
|
67
|
+
* // Get the HTML of the first row.
|
|
68
|
+
* const html = await firstRow.innerHTML();
|
|
69
|
+
* // Sanitize the HTML.
|
|
70
|
+
* const sanitizedHtml = sanitizeHtml({ html });
|
|
71
|
+
* // Log the sanitized HTML.
|
|
72
|
+
* console.log(sanitizedHtml);
|
|
73
|
+
* // Return the sanitized HTML.
|
|
74
|
+
* return sanitizedHtml;
|
|
75
|
+
}
|
|
91
76
|
* ```
|
|
92
77
|
*/
|
|
93
78
|
|
|
94
79
|
export declare function sanitizeHtml(options: SanitizeHtmlOptions): string;
|
|
95
80
|
|
|
96
81
|
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
* 3. **Custom Callback**: Execute a custom function to trigger the download programmatically
|
|
82
|
+
* Downloads a file from a web page using various trigger methods. This function provides three flexible ways to initiate file downloads:
|
|
83
|
+
*
|
|
84
|
+
* - **URL**: Creates a new page, navigates to the URL, waits for download, then automatically closes the page. Ideal for direct download links.
|
|
85
|
+
* - **Locator**: Uses the current page to click the element and capture the resulting download. Perfect for download buttons or interactive elements.
|
|
86
|
+
* - **Callback**: Executes the provided function with the page object and captures the first triggered download. Offers maximum flexibility for complex download scenarios.
|
|
103
87
|
*
|
|
104
88
|
* @param {Object} input - Configuration object for the download operation
|
|
105
89
|
* @param {Page} input.page - The Playwright Page object to use for the download
|
|
106
|
-
* @param {Trigger} input.trigger - The [Trigger](../type-
|
|
107
|
-
* @param {number} [input.timeoutInMs=5000] - Maximum time in milliseconds to wait for download
|
|
108
|
-
* @returns {Promise<Download>} Promise that resolves to a Playwright Download object
|
|
90
|
+
* @param {Trigger} input.trigger - The [Trigger](../type-references/Trigger) method to initiate the download
|
|
91
|
+
* @param {number} [input.timeoutInMs=5000] - Maximum time in milliseconds to wait for the download to trigger. Defaults to 5000.
|
|
92
|
+
* @returns {Promise<Download>} Promise that resolves to a [Playwright Download object](https://playwright.dev/docs/api/class-download)
|
|
109
93
|
*
|
|
110
94
|
* @example
|
|
111
|
-
* ```typescript URL
|
|
95
|
+
* ```typescript Download from direct URL
|
|
112
96
|
* import { downloadFile } from "@intuned/browser";
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
*
|
|
116
|
-
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
97
|
+
* import { BrowserContext, Page } from "playwright";
|
|
98
|
+
|
|
99
|
+
* interface Params {}
|
|
100
|
+
|
|
101
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
102
|
+
* // Download from a direct URL, this will open the url and automatically download the content in it.
|
|
103
|
+
* const download = await downloadFile({
|
|
104
|
+
* page,
|
|
105
|
+
* trigger: "https://intuned-docs-public-images.s3.amazonaws.com/32UP83A_ENG_US.pdf"
|
|
106
|
+
* });
|
|
107
|
+
* file_name = download.suggestedFilename();
|
|
108
|
+
* return file_name;
|
|
109
|
+
*
|
|
120
110
|
* }
|
|
121
111
|
* ```
|
|
122
112
|
*
|
|
123
113
|
* @example
|
|
124
|
-
* ```typescript Locator
|
|
114
|
+
* ```typescript Locator Trigger
|
|
125
115
|
* import { downloadFile } from "@intuned/browser";
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
116
|
+
* import { BrowserContext, Page } from "playwright";
|
|
117
|
+
*
|
|
118
|
+
* interface Params {}
|
|
119
|
+
|
|
120
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
121
|
+
* await page.goto("https://sandbox.intuned.dev/pdfs");
|
|
122
|
+
* const download = await downloadFile({
|
|
123
|
+
* page,
|
|
124
|
+
* trigger: page.locator("xpath=//tbody/tr[1]//*[name()='svg']")
|
|
125
|
+
* });
|
|
126
|
+
* file_name = download.suggestedFilename();
|
|
127
|
+
* return file_name;
|
|
134
128
|
* }
|
|
135
129
|
* ```
|
|
136
130
|
*
|
|
137
131
|
* @example
|
|
138
|
-
* ```typescript Callback
|
|
132
|
+
* ```typescript Callback Trigger
|
|
139
133
|
* import { downloadFile } from "@intuned/browser";
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
134
|
+
* import { BrowserContext, Page } from "playwright";
|
|
135
|
+
*
|
|
136
|
+
* interface Params {}
|
|
137
|
+
*
|
|
138
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
139
|
+
* await page.goto("https://sandbox.intuned.dev/pdfs");
|
|
140
|
+
* const download = await downloadFile({
|
|
141
|
+
* page,
|
|
142
|
+
* trigger: async (page) => {
|
|
143
|
+
* await page.locator("xpath=//tbody/tr[1]//*[name()='svg']").click();
|
|
144
|
+
* }
|
|
145
|
+
* });
|
|
146
|
+
* file_name = download.suggestedFilename();
|
|
147
|
+
* return file_name;
|
|
150
148
|
* }
|
|
151
149
|
* ```
|
|
152
|
-
*
|
|
153
|
-
* @note
|
|
154
|
-
* **Trigger Behavior:**
|
|
155
|
-
* - **URL**: Creates a new page, navigates to the URL, waits for download, then closes the page
|
|
156
|
-
* - **Locator**: Uses the current page to click the element and capture the resulting download
|
|
157
|
-
* - **Callback**: Executes the provided function with the page object and captures the first triggered downloads
|
|
158
150
|
*/
|
|
159
151
|
export declare function downloadFile(input: {
|
|
160
152
|
page: Page;
|
|
@@ -179,10 +171,26 @@ export declare function downloadFile(input: {
|
|
|
179
171
|
* @example
|
|
180
172
|
* ```typescript Basic Usage
|
|
181
173
|
* import { filterEmptyValues } from "@intuned/browser";
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
174
|
+
* import { BrowserContext, Page } from "playwright";
|
|
175
|
+
*
|
|
176
|
+
* interface Params {}
|
|
177
|
+
*
|
|
178
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
179
|
+
* // Filter empty values from dictionary
|
|
180
|
+
* const result1 = filterEmptyValues({ data: { a: "", b: "hello", c: null } });
|
|
181
|
+
* // Output: { b: "hello" }
|
|
182
|
+
* console.log(result1);
|
|
183
|
+
*
|
|
184
|
+
* // Filter empty values from list
|
|
185
|
+
* const result2 = filterEmptyValues({ data: [1, "", null, [2, ""]] });
|
|
186
|
+
* // Output: [1, [2]]
|
|
187
|
+
* console.log(result2);
|
|
188
|
+
*
|
|
189
|
+
* // Filter nested structures
|
|
190
|
+
* const result3 = filterEmptyValues({ data: { users: [{ name: "" }, { name: "John" }] } });
|
|
191
|
+
* // Output: { users: [{ name: "John" }] }
|
|
192
|
+
* console.log(result3);
|
|
193
|
+
* return "All data filtered successfully";
|
|
186
194
|
* }
|
|
187
195
|
* ```
|
|
188
196
|
*/
|
|
@@ -190,66 +198,78 @@ export declare function filterEmptyValues<T>(input: { data: T }): T;
|
|
|
190
198
|
|
|
191
199
|
/**
|
|
192
200
|
* Navigates to a specified URL with enhanced reliability features including automatic retries with exponential backoff,
|
|
193
|
-
* intelligent timeout
|
|
194
|
-
*
|
|
195
|
-
* This function handles common navigation challenges by automatically retrying failed requests, detecting navigation hangs, and ensuring the page reaches a truly idle state.
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* @param {Object} input - The input object containing the page and url
|
|
200
|
-
* @param {Page} input.page - The Playwright page object to navigate
|
|
201
|
-
* @param {string} input.url - The URL to navigate to
|
|
202
|
-
* @param {number} [input.
|
|
203
|
-
* @param {number} [input.
|
|
204
|
-
* @param {
|
|
205
|
-
* @param {boolean} [input.throwOnTimeout=
|
|
206
|
-
* @param {boolean} [input.waitForLoadingStateUsingAi=false] - When true, uses AI vision to verify the page is fully loaded by checking for loading spinners, blank content, or incomplete states. Retries up to
|
|
207
|
-
*
|
|
208
|
-
* @param {string} [input.
|
|
209
|
-
* @
|
|
201
|
+
* intelligent timeout handling, and optional AI-powered loading verification.
|
|
202
|
+
*
|
|
203
|
+
* This function handles common navigation challenges by automatically retrying failed requests, detecting navigation hangs, and ensuring the page reaches a truly idle state.
|
|
204
|
+
*
|
|
205
|
+
* This method can also use AI vision to verify the page is fully loaded by checking for loading spinners, blank content, or incomplete states.
|
|
206
|
+
*
|
|
207
|
+
* @param {Object} input - The input object containing the page and url.
|
|
208
|
+
* @param {Page} input.page - The Playwright page object to navigate.
|
|
209
|
+
* @param {string} input.url - The URL to navigate to.
|
|
210
|
+
* @param {number} [input.timeoutInMs=30000] - Maximum time in milliseconds to wait for navigation. Defaults to 30000.
|
|
211
|
+
* @param {number} [input.retries=3] - Number of retry attempts with exponential backoff (factor: 2). Defaults to 3.
|
|
212
|
+
* @param {("load"|"domcontentloaded"|"networkidle"|"commit")} [input.waitForLoadState="load"] - When to consider navigation succeeded. Defaults to `"load"`
|
|
213
|
+
* @param {boolean} [input.throwOnTimeout=false] - Whether to throw an error if navigation times out. When true, the function throws an error on navigation timeout. Defaults to false.
|
|
214
|
+
* @param {boolean} [input.waitForLoadingStateUsingAi=false] - When true, uses AI vision to verify the page is fully loaded by checking for loading spinners, blank content, or incomplete states. Retries up to 3 times with 5-second delays. Defaults to false
|
|
215
|
+
* Check [isPageLoaded](../../ai/functions/isPageLoaded) for more details on the AI loading verification.
|
|
216
|
+
* @param {string} [input.model="gpt-5-mini-2025-08-07"] - AI model to use for loading verification. Defaults to `"gpt-5-mini-2025-08-07"`
|
|
217
|
+
* @param {string} [input.apiKey] - Optional API key for the AI check.
|
|
218
|
+
* @returns {Promise<void>} Promise that resolves when navigation completes. If the operation fails and `throwOnTimeout` is false, resolves without error
|
|
210
219
|
*
|
|
211
220
|
* @example
|
|
212
|
-
* ```typescript
|
|
221
|
+
* ```typescript Without options
|
|
213
222
|
* import { goToUrl } from "@intuned/browser";
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
223
|
+
* import { BrowserContext, Page } from "playwright";
|
|
224
|
+
*
|
|
225
|
+
* interface Params {}
|
|
226
|
+
*
|
|
227
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
228
|
+
* await goToUrl({
|
|
229
|
+
* page,
|
|
230
|
+
* url: 'https://sandbox.intuned.dev/'
|
|
231
|
+
* });
|
|
232
|
+
* // At this point, goToUrl has waited for the page to be loaded and the network requests to be settled.
|
|
221
233
|
* }
|
|
222
234
|
* ```
|
|
223
235
|
*
|
|
224
236
|
* @example
|
|
225
|
-
* ```typescript
|
|
237
|
+
* ```typescript With options
|
|
226
238
|
* import { goToUrl } from "@intuned/browser";
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
239
|
+
* import { BrowserContext, Page } from "playwright";
|
|
240
|
+
*
|
|
241
|
+
* interface Params {}
|
|
242
|
+
*
|
|
243
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
244
|
+
* await goToUrl({
|
|
245
|
+
* page,
|
|
246
|
+
* url: 'https://intunedhq.com',
|
|
247
|
+
* waitForLoadState: "domcontentloaded", // Faster than "load" state. The function automatically waits for the page to settle.
|
|
248
|
+
* throwOnTimeout: true,
|
|
249
|
+
* timeoutInMs: 10000,
|
|
250
|
+
* retries: 3
|
|
251
|
+
* });
|
|
252
|
+
* // At this point, DOM content is loaded and goToUrl has waited for network requests to settle.
|
|
237
253
|
* }
|
|
238
254
|
* ```
|
|
239
255
|
*
|
|
240
256
|
* @example
|
|
241
|
-
* ```typescript AI
|
|
257
|
+
* ```typescript With AI Loading Detection
|
|
242
258
|
* import { goToUrl } from "@intuned/browser";
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
259
|
+
* import { BrowserContext, Page } from "playwright";
|
|
260
|
+
*
|
|
261
|
+
* interface Params {}
|
|
262
|
+
*
|
|
263
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
264
|
+
* await goToUrl({
|
|
265
|
+
* page,
|
|
266
|
+
* url: 'https://intunedhq.com',
|
|
267
|
+
* waitForLoadingStateUsingAi: true,
|
|
268
|
+
* model: "gpt-4o"
|
|
269
|
+
* });
|
|
270
|
+
* // The page is loaded and ready to use.
|
|
271
|
+
* // If the AI check fails, the method won't throw even if throwOnTimeout is true.
|
|
272
|
+
* // It only throws if the page times out reaching the default load state and throwOnTimeout is true.
|
|
253
273
|
* }
|
|
254
274
|
* ```
|
|
255
275
|
*/
|
|
@@ -259,9 +279,9 @@ export declare function goToUrl(input: {
|
|
|
259
279
|
timeoutInMs?: number;
|
|
260
280
|
retries?: number;
|
|
261
281
|
throwOnTimeout?: boolean;
|
|
262
|
-
waitForLoadState?: "load" | "domcontentloaded" | "networkidle";
|
|
282
|
+
waitForLoadState?: "load" | "domcontentloaded" | "networkidle" | "commit";
|
|
263
283
|
waitForLoadingStateUsingAi?: boolean;
|
|
264
|
-
model?:
|
|
284
|
+
model?: string;
|
|
265
285
|
apiKey?: string;
|
|
266
286
|
}): Promise<void>;
|
|
267
287
|
|
|
@@ -269,38 +289,49 @@ export declare function goToUrl(input: {
|
|
|
269
289
|
* Automatically scrolls through infinite scroll content by repeatedly scrolling to the bottom
|
|
270
290
|
* until no new content loads or maximum scroll limit is reached.
|
|
271
291
|
*
|
|
272
|
-
* @param {Object} input - The input object containing the data to scroll to load content
|
|
273
|
-
* @param {Page | Locator} input.source - The Playwright Page or Locator to scroll
|
|
274
|
-
* @param {Function} [input.onScrollProgress] - Optional callback function to call during each scroll iteration
|
|
275
|
-
* @param {number} [input.maxScrolls=50] - Maximum number of scroll attempts before stopping. Defaults to 50
|
|
276
|
-
* @param {number} [input.delayInMs=100] - Delay in milliseconds between scroll attempts. Defaults to 100
|
|
277
|
-
* @param {number} [input.minHeightChange=100] - Minimum height change in pixels required to continue scrolling. Defaults to 100
|
|
278
|
-
*
|
|
292
|
+
* @param {Object} input - The input object containing the data to scroll to load content.
|
|
293
|
+
* @param {Page | Locator} input.source - The Playwright Page or Locator to scroll.
|
|
294
|
+
* @param {Function} [input.onScrollProgress] - Optional callback function to call during each scroll iteration.
|
|
295
|
+
* @param {number} [input.maxScrolls=50] - Maximum number of scroll attempts before stopping. Defaults to 50.
|
|
296
|
+
* @param {number} [input.delayInMs=100] - Delay in milliseconds between scroll attempts. Defaults to 100.
|
|
297
|
+
* @param {number} [input.minHeightChange=100] - Minimum height change in pixels required to continue scrolling. Defaults to 100.
|
|
298
|
+
* If the page has loaded all content and we still haven't reached the maxScrolls, the minHeightChange will detect that no new content is loaded and stop the scrolling.
|
|
299
|
+
* @returns {Promise<void>} Promise that resolves when scrolling is complete.
|
|
279
300
|
*
|
|
280
301
|
* @example
|
|
281
|
-
* ```typescript Basic Infinite Scroll
|
|
302
|
+
* ```typescript Basic Infinite Scroll handling
|
|
282
303
|
* import { scrollToLoadContent } from "@intuned/browser";
|
|
283
|
-
*
|
|
304
|
+
* import { BrowserContext, Page } from "playwright";
|
|
305
|
+
*
|
|
306
|
+
* interface Params {}
|
|
307
|
+
*
|
|
308
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
284
309
|
* // Scroll through entire page content
|
|
285
|
-
* await page.goto("https://
|
|
310
|
+
* await page.goto("https://sandbox.intuned.dev/infinite-scroll")
|
|
286
311
|
* await scrollToLoadContent({
|
|
287
312
|
* source: page,
|
|
288
313
|
* });
|
|
289
|
-
* //
|
|
314
|
+
* // Will keep scrolling until the page has loaded all content or the maxScrolls is reached.
|
|
290
315
|
* }
|
|
291
316
|
* ```
|
|
292
317
|
*
|
|
293
318
|
* @example
|
|
294
319
|
* ```typescript Scroll Specific Container
|
|
295
320
|
* import { scrollToLoadContent } from "@intuned/browser";
|
|
296
|
-
*
|
|
321
|
+
* import { BrowserContext, Page } from "playwright";
|
|
322
|
+
*
|
|
323
|
+
* interface Params {}
|
|
324
|
+
*
|
|
325
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
297
326
|
* // Scroll through a specific scrollable div
|
|
298
|
-
* await page.goto("https://docs.intunedhq.com/docs-
|
|
327
|
+
* await page.goto("https://docs.intunedhq.com/docs/00-getting-started/introduction")
|
|
328
|
+
* // This will scroll the sidebar content only and watch its height to change.
|
|
299
329
|
* const container = page.locator("xpath=//div[@id='sidebar-content']");
|
|
300
330
|
* await scrollToLoadContent({
|
|
301
331
|
* source: container,
|
|
302
332
|
* maxScrolls: 20
|
|
303
333
|
* });
|
|
334
|
+
* // Will keep scrolling until the sidebar content has loaded all content or the maxScrolls is reached.
|
|
304
335
|
* }
|
|
305
336
|
* ```
|
|
306
337
|
*/
|
|
@@ -313,32 +344,6 @@ export declare function scrollToLoadContent(input: {
|
|
|
313
344
|
minHeightChange?: number;
|
|
314
345
|
}): Promise<void>;
|
|
315
346
|
|
|
316
|
-
/**
|
|
317
|
-
* Click a button and wait briefly for content to load.
|
|
318
|
-
*
|
|
319
|
-
* This function clicks a button element and waits for a specified delay, allowing time for
|
|
320
|
-
* any triggered content to load. It automatically waits for network activity to settle.
|
|
321
|
-
*
|
|
322
|
-
* @param {Object} input - Configuration options
|
|
323
|
-
* @param {Page} input.page - Playwright Page object
|
|
324
|
-
* @param {Locator} input.buttonLocator - Locator for the button element to click
|
|
325
|
-
* @param {number} [input.clickDelay=0.5] - Delay after clicking the button (in seconds)
|
|
326
|
-
* @returns {Promise<void>} Promise that resolves when the click and wait is complete
|
|
327
|
-
*
|
|
328
|
-
* @example
|
|
329
|
-
* ```typescript Basic Button Click
|
|
330
|
-
* import { clickButtonAndWait } from "@intuned/browser";
|
|
331
|
-
* export default async function handler(params, page, context){
|
|
332
|
-
* await page.goto("https://example.com/products");
|
|
333
|
-
* const loadMoreButton = page.locator("#load-more-button");
|
|
334
|
-
* await clickButtonAndWait({
|
|
335
|
-
* page,
|
|
336
|
-
* buttonLocator: loadMoreButton,
|
|
337
|
-
* clickDelay: 1.0
|
|
338
|
-
* });
|
|
339
|
-
* }
|
|
340
|
-
* ```
|
|
341
|
-
*/
|
|
342
347
|
export declare function clickButtonAndWait(input: {
|
|
343
348
|
page: Page;
|
|
344
349
|
buttonLocator: Locator;
|
|
@@ -350,8 +355,7 @@ export declare function clickButtonAndWait(input: {
|
|
|
350
355
|
*
|
|
351
356
|
* This function is useful for "Load More" buttons or paginated content where you need to
|
|
352
357
|
* keep clicking until all content is loaded. It provides several stopping conditions:
|
|
353
|
-
* - Button becomes invisible
|
|
354
|
-
* - Button becomes disabled
|
|
358
|
+
* - Button becomes invisible/disabled
|
|
355
359
|
* - Maximum number of clicks reached
|
|
356
360
|
* - No change detected in container content (when containerLocator is provided)
|
|
357
361
|
*
|
|
@@ -360,17 +364,21 @@ export declare function clickButtonAndWait(input: {
|
|
|
360
364
|
* @param {Locator} input.buttonLocator - Locator for the button to click repeatedly
|
|
361
365
|
* @param {CallableFunction} [input.heartbeat] - Optional callback invoked after each click
|
|
362
366
|
* @param {Locator} [input.containerLocator] - Optional content container to detect changes
|
|
363
|
-
* @param {number} [input.maxClicks=50] - Maximum number of times to click the button
|
|
364
|
-
* @param {number} [input.clickDelay=0.5] - Delay after each click (in seconds)
|
|
365
|
-
* @param {number} [input.noChangeThreshold=0] - Minimum change in content size to continue clicking
|
|
367
|
+
* @param {number} [input.maxClicks=50] - Maximum number of times to click the button. Defaults to 50.
|
|
368
|
+
* @param {number} [input.clickDelay=0.5] - Delay after each click (in seconds). Defaults to 0.5.
|
|
369
|
+
* @param {number} [input.noChangeThreshold=0] - Minimum change in content size to continue clicking. Defaults to 0.
|
|
366
370
|
* @returns {Promise<void>} Promise that resolves when clicking is exhausted
|
|
367
371
|
*
|
|
368
372
|
* @example
|
|
369
373
|
* ```typescript Load All Items
|
|
370
374
|
* import { clickUntilExhausted } from "@intuned/browser";
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
375
|
+
* import { BrowserContext, Page } from "playwright";
|
|
376
|
+
*
|
|
377
|
+
* interface Params {}
|
|
378
|
+
*
|
|
379
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
380
|
+
* await page.goto("https://sandbox.intuned.dev/load-more");
|
|
381
|
+
* const loadMoreButton = page.locator("main main button"); // Select the main button in the main content area.
|
|
374
382
|
*
|
|
375
383
|
* // Click until button disappears or is disabled
|
|
376
384
|
* await clickUntilExhausted({
|
|
@@ -378,22 +386,27 @@ export declare function clickButtonAndWait(input: {
|
|
|
378
386
|
* buttonLocator: loadMoreButton,
|
|
379
387
|
* maxClicks: 20
|
|
380
388
|
* });
|
|
389
|
+
* // Will keep clicking the button until the button disappears or is disabled or the maxClicks is reached.
|
|
381
390
|
* }
|
|
382
391
|
* ```
|
|
383
392
|
*
|
|
384
393
|
* @example
|
|
385
394
|
* ```typescript Track Container Changes
|
|
386
395
|
* import { clickUntilExhausted } from "@intuned/browser";
|
|
387
|
-
*
|
|
388
|
-
* await page.goto("https://example.com/products");
|
|
389
|
-
* const loadMoreButton = page.locator("#load-more");
|
|
390
|
-
* const productsContainer = page.locator("#products-list");
|
|
396
|
+
* import { BrowserContext, Page } from "playwright";
|
|
391
397
|
*
|
|
398
|
+
* interface Params {}
|
|
399
|
+
*
|
|
400
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
401
|
+
* await page.goto("https://sandbox.intuned.dev/load-more");
|
|
402
|
+
* const loadMoreButton = page.locator("aside button"); // Select the button in the sidebar.
|
|
403
|
+
* const container = page.locator('xpath=//*[@id="root"]/div[1]/main/slot/div/aside/div/div/slot/slot'); // Watch the sidebar container to detect changes.
|
|
404
|
+
* // This will count the elements under the container given before each click and after, if the count is the same, the function will stop.
|
|
392
405
|
* let clickCount = 0;
|
|
393
406
|
* await clickUntilExhausted({
|
|
394
407
|
* page,
|
|
395
408
|
* buttonLocator: loadMoreButton,
|
|
396
|
-
* containerLocator:
|
|
409
|
+
* containerLocator: container,
|
|
397
410
|
* heartbeat: () => {
|
|
398
411
|
* clickCount++;
|
|
399
412
|
* console.log(`Clicked ${clickCount} times`);
|
|
@@ -402,6 +415,7 @@ export declare function clickButtonAndWait(input: {
|
|
|
402
415
|
* clickDelay: 0.5,
|
|
403
416
|
* noChangeThreshold: 0
|
|
404
417
|
* });
|
|
418
|
+
* // Will keep clicking the button until the button disappears or is disabled or the maxClicks is reached or no more content is loaded.
|
|
405
419
|
* }
|
|
406
420
|
* ```
|
|
407
421
|
*/
|
|
@@ -416,30 +430,76 @@ export declare function clickUntilExhausted(input: {
|
|
|
416
430
|
}): Promise<void>;
|
|
417
431
|
|
|
418
432
|
/**
|
|
419
|
-
* Parses various date string formats into Date objects.
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* -
|
|
425
|
-
* -
|
|
426
|
-
* -
|
|
427
|
-
* -
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
433
|
+
* Parses various date string formats into Date objects, returning only the date part with time set to midnight.
|
|
434
|
+
* This utility function provides robust date parsing capabilities for a wide range of common formats.
|
|
435
|
+
*
|
|
436
|
+
* ## Key features
|
|
437
|
+
*
|
|
438
|
+
* - Returns only the date part (year, month, day)
|
|
439
|
+
* - Time is always set to 00:00:00
|
|
440
|
+
* - Supports multiple international formats
|
|
441
|
+
* - Handles timezones and AM/PM formats
|
|
442
|
+
*
|
|
443
|
+
* ## Supported formats
|
|
444
|
+
*
|
|
445
|
+
* The function handles these date format categories:
|
|
446
|
+
*
|
|
447
|
+
* ### Standard date formats
|
|
448
|
+
* - `DD/MM/YYYY`: "22/11/2024", "13/12/2024"
|
|
449
|
+
* - `MM/DD/YYYY`: "01/17/2025", "10/25/2024"
|
|
450
|
+
* - Single-digit variants: "8/16/2019", "9/28/2024"
|
|
451
|
+
*
|
|
452
|
+
* ### Date-time combinations
|
|
453
|
+
* - With 24-hour time: "22/11/2024 21:19:05"
|
|
454
|
+
* - With AM/PM: "12/09/2024 9:00 AM"
|
|
455
|
+
* - With dash separator: "12/19/2024 - 2:00 PM"
|
|
456
|
+
*
|
|
457
|
+
* ### Timezone support
|
|
458
|
+
* - With timezone abbreviations: "10/23/2024 12:06 PM CST"
|
|
459
|
+
* - With timezone offset: "01/17/2025 3:00:00 PM CT"
|
|
460
|
+
*
|
|
461
|
+
* ### Text month formats
|
|
462
|
+
* - Short month: "5 Dec 2024", "11 Sep 2024"
|
|
463
|
+
* - With time: "5 Dec 2024 8:00 AM PST"
|
|
464
|
+
* - Full month: "November 14, 2024", "January 31, 2025, 5:00 pm"
|
|
432
465
|
*
|
|
433
466
|
* @param {Object} input - The input object containing the date to process
|
|
434
467
|
* @param {string} input.date - A string containing a date in various possible formats
|
|
435
|
-
* @returns {Date | null} Date object with only date components (time set to 00:00:00
|
|
468
|
+
* @returns {Date | null} Returns a `Date` object with only date components preserved (year, month, day), time always set to 00:00:00, or `null` if parsing fails
|
|
436
469
|
*
|
|
437
470
|
* @example
|
|
438
|
-
* ```typescript Basic
|
|
471
|
+
* ```typescript Basic Usage
|
|
439
472
|
* import { processDate } from "@intuned/browser";
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
473
|
+
* import { BrowserContext, Page } from "playwright";
|
|
474
|
+
*
|
|
475
|
+
* interface Params {}
|
|
476
|
+
*
|
|
477
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
478
|
+
* // Basic date string
|
|
479
|
+
* const date1 = processDate({ date: "22/11/2024" });
|
|
480
|
+
* console.log(date1); // 2024-11-22 00:00:00
|
|
481
|
+
*
|
|
482
|
+
* // Date with time (time is ignored)
|
|
483
|
+
* const date2 = processDate({ date: "5 Dec 2024 8:00 AM PST" });
|
|
484
|
+
* console.log(date2); // 2024-12-05 00:00:00
|
|
485
|
+
* }
|
|
486
|
+
* ```
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript Invalid Date
|
|
490
|
+
* import { processDate } from "@intuned/browser";
|
|
491
|
+
* import { BrowserContext, Page } from "playwright";
|
|
492
|
+
*
|
|
493
|
+
* interface Params {}
|
|
494
|
+
*
|
|
495
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
496
|
+
* // Invalid date returns null
|
|
497
|
+
* const invalidDate = processDate({ date: "invalid date" });
|
|
498
|
+
* console.log(invalidDate); // will return null.
|
|
499
|
+
* if (invalidDate === null) {
|
|
500
|
+
* throw new Error("Invalid date");
|
|
501
|
+
* }
|
|
502
|
+
* return "should not reach here";
|
|
443
503
|
* }
|
|
444
504
|
* ```
|
|
445
505
|
*/
|
|
@@ -449,81 +509,83 @@ export declare function processDate(input: { date: string }): Date | null;
|
|
|
449
509
|
* Uploads files to AWS S3 storage with flexible configuration options.
|
|
450
510
|
*
|
|
451
511
|
* This function accepts various file types including Playwright Download objects, binary data,
|
|
452
|
-
*
|
|
512
|
+
* making it versatile for different upload scenarios. It automatically
|
|
453
513
|
* handles file metadata and provides comprehensive S3 configuration options.
|
|
454
514
|
*
|
|
515
|
+
* ## S3 configuration fallback
|
|
516
|
+
*
|
|
517
|
+
* The function uses a fallback system to determine S3 settings:
|
|
518
|
+
*
|
|
519
|
+
* 1. **S3Configs Parameter** - If provided, uses the explicit `configs` object with your custom settings.
|
|
520
|
+
* 2. **Environment Variables** - If no configs provided, automatically reads from environment variables:
|
|
521
|
+
* - `AWS_ACCESS_KEY_ID` - Your AWS access key
|
|
522
|
+
* - `AWS_SECRET_ACCESS_KEY` - Your AWS secret key
|
|
523
|
+
* - `AWS_REGION` - AWS region (e.g., "us-west-1")
|
|
524
|
+
* - `AWS_BUCKET` - S3 bucket name
|
|
525
|
+
* - `AWS_ENDPOINT_URL` - Optional custom S3 endpoint
|
|
526
|
+
* - Check [Environment Variables & Secrets](https://docs.intunedhq.com/docs/02-features/environment-variables-secrets) to learn more about setting environment variables.
|
|
527
|
+
* 3. **Intuned Defaults** - If environment variables aren't set, falls back to Intuned's managed S3 storage. See [S3 Attachment Storage](https://docs.intunedhq.com/docs/04-integrations/s3/s3-attachment-storage) for more details.
|
|
528
|
+
*
|
|
455
529
|
* @param {Object} input - Configuration object for the upload operation
|
|
456
|
-
* @param {FileType} input.file - The file to upload. Accepts [FileType](../type-
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
* - ReadStream (file streams)
|
|
460
|
-
* @param {S3Configs} [input.configs] - Optional [S3Configs](../interfaces/S3Configs) for customizing the S3 upload. If not provided, uses environment variables or default configuration
|
|
461
|
-
* @param {string} [input.fileNameOverride] - Optional custom filename for the uploaded file. If not provided, uses the original filename
|
|
530
|
+
* @param {FileType} input.file - The file to upload. Accepts [FileType](../type-references/FileType) types including Playwright Download objects, Uint8Array, Buffer, or ReadStream
|
|
531
|
+
* @param {S3Configs} [input.configs] - Optional [S3Configs](../type-references/S3Configs) for customizing the S3 upload. If not provided, uses environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, `AWS_ENDPOINT_URL`, `AWS_BUCKET`). If environment variables aren't set, uses default Intuned S3 settings.
|
|
532
|
+
* @param {string} [input.fileNameOverride] - Optional custom filename for the uploaded file. If not provided, uses the original filename or generates a unique name.
|
|
462
533
|
* @param {string} [input.contentType] - Optional MIME type for the uploaded file (e.g., "application/pdf", "image/png")
|
|
463
|
-
* @returns {Promise<Attachment>} Promise that resolves to an [Attachment](../
|
|
534
|
+
* @returns {Promise<Attachment>} Promise that resolves to an [Attachment](../type-references/Attachment) object with file metadata and utility methods
|
|
464
535
|
*
|
|
465
536
|
* @example
|
|
466
537
|
* ```typescript Upload Downloaded File
|
|
467
538
|
* import { downloadFile, uploadFileToS3 } from "@intuned/browser";
|
|
468
|
-
*
|
|
469
|
-
* // Download and upload a file with custom S3 configuration
|
|
470
|
-
* await page.goto("https://sandbox.intuned.dev/pdfs")
|
|
471
|
-
* const download = await downloadFile({
|
|
472
|
-
* page,
|
|
473
|
-
* trigger: page.locator("xpath=//tbody/tr[1]//*[name()='svg']")
|
|
474
|
-
* });
|
|
539
|
+
* import { BrowserContext, Page } from "playwright";
|
|
475
540
|
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
541
|
+
* interface Params {}
|
|
542
|
+
*
|
|
543
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
544
|
+
* await page.goto("https://sandbox.intuned.dev/pdfs");
|
|
545
|
+
* const download = await downloadFile({
|
|
546
|
+
* page,
|
|
547
|
+
* trigger: page.locator("xpath=//tbody/tr[1]//*[name()='svg']")
|
|
548
|
+
* });
|
|
549
|
+
* // Set your environment variables for the AWS credentials.
|
|
550
|
+
* // Check https://docs.intunedhq.com/docs/02-features/environment-variables-secrets to learn more about setting environment variables.
|
|
551
|
+
* const uploadedFile = await uploadFileToS3({
|
|
552
|
+
* file: download,
|
|
553
|
+
* configs: {
|
|
554
|
+
* bucket: process.env.AWS_BUCKET,
|
|
555
|
+
* region: process.env.AWS_REGION,
|
|
556
|
+
* accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
557
|
+
* secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
483
558
|
* },
|
|
484
559
|
* fileNameOverride: 'reports/monthly-report.pdf'
|
|
485
|
-
* }
|
|
486
|
-
* });
|
|
560
|
+
* });
|
|
487
561
|
*
|
|
488
|
-
*
|
|
489
|
-
* console.log(`S3 URL: ${uploadedFile.getS3Key()}`);
|
|
562
|
+
* console.log(`File uploaded: ${uploadedFile.suggestedFileName}`);
|
|
490
563
|
* }
|
|
491
564
|
* ```
|
|
492
565
|
*
|
|
493
566
|
* @example
|
|
494
567
|
* ```typescript Upload Binary Data
|
|
495
568
|
* import { uploadFileToS3 } from "@intuned/browser";
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* }
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
* });
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
569
|
+
* import { BrowserContext, Page } from "playwright";
|
|
570
|
+
*
|
|
571
|
+
* interface Params {}
|
|
572
|
+
*
|
|
573
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
574
|
+
* const fileBuffer = Buffer.from('Hello World', 'utf8');
|
|
575
|
+
* const uploadedFile = await uploadFileToS3({
|
|
576
|
+
* file: fileBuffer,
|
|
577
|
+
* fileNameOverride: 'data/text-file.txt',
|
|
578
|
+
* contentType: 'text/plain'
|
|
579
|
+
* });
|
|
580
|
+
*
|
|
581
|
+
* // Generate a temporary download URL
|
|
582
|
+
* const downloadUrl = await uploadedFile.getSignedUrl();
|
|
583
|
+
* console.log(`Download URL: ${downloadUrl}`);
|
|
584
|
+
* return {
|
|
585
|
+
* downloadUrl: downloadUrl
|
|
586
|
+
* };
|
|
514
587
|
* }
|
|
515
588
|
* ```
|
|
516
|
-
*
|
|
517
|
-
* @note
|
|
518
|
-
* **S3 Configuration Priority:**
|
|
519
|
-
* 1. **Explicit configs**: Values provided in `input.configs.s3Configs`
|
|
520
|
-
* 2. **Environment variables**: Standard AWS environment variables:
|
|
521
|
-
* - `AWS_BUCKET`
|
|
522
|
-
* - `AWS_REGION`
|
|
523
|
-
* - `AWS_ACCESS_KEY_ID`
|
|
524
|
-
* - `AWS_SECRET_ACCESS_KEY`
|
|
525
|
-
* - `AWS_ENDPOINT_URL`
|
|
526
|
-
* 3. **Default fallback**: Intuned's default S3 configuration
|
|
527
589
|
*/
|
|
528
590
|
|
|
529
591
|
export declare function uploadFileToS3(input: {
|
|
@@ -535,41 +597,58 @@ export declare function uploadFileToS3(input: {
|
|
|
535
597
|
|
|
536
598
|
/**
|
|
537
599
|
* Validates data against a JSON schema using the AJV validator.
|
|
538
|
-
* This function can validate any given data against a given schema. It supports validating custom data types such as the [Attachment](../
|
|
600
|
+
* This function can validate any given data against a given schema. It supports validating custom data types such as the [Attachment](../type-references/Attachment) type.
|
|
539
601
|
*
|
|
540
602
|
* @param {Object} input - The input object containing data and schema
|
|
541
603
|
* @param {Record<string, any> | Record<string, any>[]} input.data - The data to validate. Can be a single data object or an array of data objects
|
|
542
604
|
* @param {Record<string, any>} input.schema - JSON schema object defining validation rules
|
|
543
605
|
* @returns {void} Returns nothing if validation passes, throws ValidationError if it fails
|
|
606
|
+
* @throws {ValidationError} If validation fails
|
|
544
607
|
*
|
|
545
608
|
* @example
|
|
546
|
-
* ```typescript Basic
|
|
609
|
+
* ```typescript Basic Validation
|
|
547
610
|
* import { validateDataUsingSchema } from "@intuned/browser";
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
611
|
+
* import { BrowserContext, Page } from "playwright";
|
|
612
|
+
*
|
|
613
|
+
* interface Params {}
|
|
614
|
+
*
|
|
615
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
616
|
+
* const uploadData = {
|
|
617
|
+
* file: {
|
|
618
|
+
* fileName: "documents/report.pdf",
|
|
619
|
+
* bucket: "my-bucket",
|
|
620
|
+
* region: "us-east-1",
|
|
621
|
+
* key: "documents/report.pdf",
|
|
622
|
+
* endpoint: null,
|
|
623
|
+
* suggestedFileName: "Monthly Report.pdf",
|
|
624
|
+
* fileType: "document"
|
|
625
|
+
* },
|
|
626
|
+
* name: "Test File Upload"
|
|
553
627
|
* };
|
|
554
628
|
*
|
|
555
|
-
* const
|
|
629
|
+
* const uploadSchema = {
|
|
556
630
|
* type: "object",
|
|
557
|
-
* required: ["
|
|
631
|
+
* required: ["file", "name"],
|
|
558
632
|
* properties: {
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
* age: { type: "number", minimum: 0 }
|
|
633
|
+
* file: { type: "attachment" },
|
|
634
|
+
* name: { type: "string" }
|
|
562
635
|
* }
|
|
563
636
|
* };
|
|
564
637
|
*
|
|
565
|
-
* validateDataUsingSchema({ data:
|
|
566
|
-
* // Validation passes
|
|
638
|
+
* validateDataUsingSchema({ data: uploadData, schema: uploadSchema });
|
|
639
|
+
* // Validation passes with Attachment type
|
|
640
|
+
* console.log("Validation passed");
|
|
641
|
+
* return "Validation passed";
|
|
567
642
|
* }
|
|
568
643
|
* ```
|
|
569
644
|
* @example
|
|
570
645
|
* ```typescript Invalid Data Validation
|
|
571
646
|
* import { validateDataUsingSchema } from "@intuned/browser";
|
|
572
|
-
*
|
|
647
|
+
* import { BrowserContext, Page } from "playwright";
|
|
648
|
+
*
|
|
649
|
+
* interface Params {}
|
|
650
|
+
*
|
|
651
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
573
652
|
* const userData = {
|
|
574
653
|
* name: "John Doe",
|
|
575
654
|
* email: "john@example.com",
|
|
@@ -585,8 +664,10 @@ export declare function uploadFileToS3(input: {
|
|
|
585
664
|
* }
|
|
586
665
|
* };
|
|
587
666
|
*
|
|
588
|
-
* validateDataUsingSchema({ data: userData, schema: userSchema });
|
|
667
|
+
* validateDataUsingSchema({ data: userData, schema: userSchema }); // this will throw
|
|
589
668
|
* // Validation fails, throws ValidationError
|
|
669
|
+
* console.log("Never reached");
|
|
670
|
+
* return "Never reached";
|
|
590
671
|
* }
|
|
591
672
|
* ```
|
|
592
673
|
*/
|
|
@@ -596,11 +677,11 @@ export declare function validateDataUsingSchema(input: {
|
|
|
596
677
|
}): void;
|
|
597
678
|
|
|
598
679
|
/**
|
|
599
|
-
* Executes a callback function and waits for network
|
|
680
|
+
* Executes a callback function and waits for network activity to settle before returning.
|
|
600
681
|
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
682
|
+
* ## `withNetworkSettledWait` vs `waitForDomSettled`
|
|
683
|
+
* - Use `withNetworkSettledWait` when watching **network requests** (API calls, form submissions, resource loading)
|
|
684
|
+
* - Use [waitForDomSettled](../functions/waitForDomSettled) when watching **DOM mutations** (elements added/removed/modified, loading spinners, dynamic content injection)
|
|
604
685
|
*
|
|
605
686
|
* @param {Function} callback - The callback function to execute. Receives the page object as parameter
|
|
606
687
|
* @param {Object} [options] - Configuration options for network monitoring
|
|
@@ -609,21 +690,59 @@ export declare function validateDataUsingSchema(input: {
|
|
|
609
690
|
* @param {number} [options.maxInflightRequests=0] - Maximum number of pending requests to consider as "settled". Defaults to 0 (waits for all requests to complete)
|
|
610
691
|
* @returns {Promise<T>} Promise that resolves to the callback's return value after network settles
|
|
611
692
|
* @example
|
|
612
|
-
* ```typescript
|
|
693
|
+
* ```typescript Wrapper with Inline Function
|
|
613
694
|
* import { withNetworkSettledWait } from "@intuned/browser";
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
626
|
-
* );
|
|
695
|
+
* import { BrowserContext, Page } from "playwright";
|
|
696
|
+
*
|
|
697
|
+
* interface Params {}
|
|
698
|
+
*
|
|
699
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
700
|
+
* await page.goto('https://sandbox.intuned.dev/infinite-scroll');
|
|
701
|
+
*
|
|
702
|
+
* // Execute action and wait for network to settle
|
|
703
|
+
* const result = await withNetworkSettledWait(
|
|
704
|
+
* async (page) => {
|
|
705
|
+
* // scroll to load more content
|
|
706
|
+
* await page.evaluate(() => {
|
|
707
|
+
* window.scrollTo(0, document.body.scrollHeight);
|
|
708
|
+
* });
|
|
709
|
+
* return "scrolled";
|
|
710
|
+
* },
|
|
711
|
+
* {
|
|
712
|
+
* page,
|
|
713
|
+
* timeoutInMs: 15000,
|
|
714
|
+
* maxInflightRequests: 0
|
|
715
|
+
* }
|
|
716
|
+
* );
|
|
717
|
+
* console.log(result); // "scrolled"
|
|
718
|
+
* return result;
|
|
719
|
+
* }
|
|
720
|
+
* ```
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* ```typescript Click Link with Network Wait
|
|
724
|
+
* import { withNetworkSettledWait } from "@intuned/browser";
|
|
725
|
+
* import { BrowserContext, Page } from "playwright";
|
|
726
|
+
*
|
|
727
|
+
* interface Params {}
|
|
728
|
+
*
|
|
729
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
730
|
+
* await page.goto('https://sandbox.intuned.dev/');
|
|
731
|
+
*
|
|
732
|
+
* // Click Object Extractors link and wait for page to load
|
|
733
|
+
* await withNetworkSettledWait(
|
|
734
|
+
* async (page) => {
|
|
735
|
+
* await page.getByText('Object Extractors').click();
|
|
736
|
+
* },
|
|
737
|
+
* {
|
|
738
|
+
* page,
|
|
739
|
+
* timeoutInMs: 10000,
|
|
740
|
+
* maxInflightRequests: 0
|
|
741
|
+
* }
|
|
742
|
+
* );
|
|
743
|
+
* // Object Extractors page loaded
|
|
744
|
+
* const title = await page.locator('div h2').innerText();
|
|
745
|
+
* return title;
|
|
627
746
|
* }
|
|
628
747
|
* ```
|
|
629
748
|
*/
|
|
@@ -637,57 +756,70 @@ export declare function withNetworkSettledWait<T>(
|
|
|
637
756
|
): Promise<T>;
|
|
638
757
|
|
|
639
758
|
/**
|
|
640
|
-
* Waits for
|
|
641
|
-
* that loads progressively or elements that appear/update after initial page load.
|
|
759
|
+
* Waits for DOM mutations to settle without executing any function first. This helper uses a MutationObserver to monitor DOM changes and waits until the DOM has been stable (no mutations) for the specified settle duration.
|
|
642
760
|
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
761
|
+
* ## `waitForDomSettled` vs `withNetworkSettledWait`
|
|
762
|
+
*
|
|
763
|
+
* - Use `waitForDomSettled` when watching **DOM mutations** (elements added/removed/modified, loading spinners, dynamic content injection)
|
|
764
|
+
* - Use [withNetworkSettledWait](../functions/withNetworkSettledWait) when watching **network requests** (API calls, form submissions, resource loading)
|
|
646
765
|
*
|
|
647
766
|
* @param {Object} options - Configuration object for DOM settlement monitoring
|
|
648
|
-
* @param {Page | Locator} options.source - The Playwright Page or Locator to monitor for DOM changes. When a Page is provided, monitors the entire document
|
|
767
|
+
* @param {Page | Locator} options.source - The Playwright Page or Locator to monitor for DOM changes. When a Page is provided, monitors the entire document. When a Locator is provided, monitors only that specific element.
|
|
649
768
|
* @param {number} [options.settleDurationMs=500] - Milliseconds the DOM must remain unchanged to be considered settled. Defaults to 500
|
|
650
769
|
* @param {number} [options.timeoutInMs=30000] - Maximum milliseconds to wait before giving up. Defaults to 30000
|
|
651
770
|
* @returns {Promise<boolean>} Promise that resolves to true if DOM settled within timeout, false if timeout or error occurred
|
|
652
771
|
*
|
|
653
772
|
* @example
|
|
654
|
-
* ```typescript Wait
|
|
773
|
+
* ```typescript Wait After Navigation
|
|
655
774
|
* import { waitForDomSettled } from '@intuned/browser';
|
|
656
|
-
*
|
|
657
|
-
* // Navigate to a dynamic page
|
|
658
|
-
* await page.goto('https://docs.intunedhq.com/docs-old/getting-started/introduction');
|
|
775
|
+
* import { BrowserContext, Page } from "playwright";
|
|
659
776
|
*
|
|
660
|
-
*
|
|
661
|
-
* const settled = await waitForDomSettled({
|
|
662
|
-
* source: page,
|
|
663
|
-
* settleDurationMs: 1000
|
|
664
|
-
* });
|
|
777
|
+
* interface Params {}
|
|
665
778
|
*
|
|
666
|
-
*
|
|
667
|
-
* //
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
779
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
780
|
+
* // Navigate to page with dynamic content
|
|
781
|
+
* await page.goto('https://sandbox.intuned.dev/lists/table');
|
|
782
|
+
*
|
|
783
|
+
* // Wait for all DOM mutations to complete
|
|
784
|
+
* const settled = await waitForDomSettled({
|
|
785
|
+
* source: page,
|
|
786
|
+
* settleDurationMs: 1000,
|
|
787
|
+
* timeoutInMs: 20000
|
|
788
|
+
* });
|
|
789
|
+
*
|
|
790
|
+
* if (settled) {
|
|
791
|
+
* // DOM is stable, safe to extract data
|
|
792
|
+
* const rows = await page.locator('table tr').all();
|
|
793
|
+
* return rows.length;
|
|
794
|
+
* }
|
|
795
|
+
* return 0;
|
|
672
796
|
* }
|
|
673
797
|
* ```
|
|
674
798
|
*
|
|
675
799
|
* @example
|
|
676
|
-
* ```typescript
|
|
800
|
+
* ```typescript Watch Specific Container
|
|
677
801
|
* import { waitForDomSettled } from '@intuned/browser';
|
|
678
|
-
*
|
|
679
|
-
* await page.goto("https://docs.intunedhq.com/")
|
|
680
|
-
* // Wait for a specific feed container to stop updating
|
|
681
|
-
* const settled = await waitForDomSettled({
|
|
682
|
-
* source: page.locator("xpath=//div[@id='sidebar-content']"),
|
|
683
|
-
* settleDurationMs: 2000,
|
|
684
|
-
* timeoutInMs: 15000,
|
|
685
|
-
* });
|
|
802
|
+
* import { BrowserContext, Page } from "playwright";
|
|
686
803
|
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
*
|
|
804
|
+
* interface Params {}
|
|
805
|
+
*
|
|
806
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
807
|
+
* await page.goto("https://sandbox.intuned.dev/lists/table");
|
|
808
|
+
*
|
|
809
|
+
* // Only watch table container (ignore header/footer changes)
|
|
810
|
+
* const table = page.locator("table");
|
|
811
|
+
* const settled = await waitForDomSettled({
|
|
812
|
+
* source: table,
|
|
813
|
+
* settleDurationMs: 800,
|
|
814
|
+
* timeoutInMs: 15000,
|
|
815
|
+
* });
|
|
816
|
+
*
|
|
817
|
+
* if (settled) {
|
|
818
|
+
* // Table has finished loading
|
|
819
|
+
* const rows = await table.locator('tr').count();
|
|
820
|
+
* return rows;
|
|
821
|
+
* }
|
|
822
|
+
* return 0;
|
|
691
823
|
* }
|
|
692
824
|
* ```
|
|
693
825
|
*/
|
|
@@ -701,53 +833,71 @@ export declare function waitForDomSettled(options: {
|
|
|
701
833
|
* Converts HTML content from a Playwright Page or Locator to semantic markdown format.
|
|
702
834
|
*
|
|
703
835
|
* @param {Object} input - The input object containing the source of the HTML content
|
|
704
|
-
* @param {Page | Locator} input.source - The source of the HTML content.
|
|
836
|
+
* @param {Page | Locator} input.source - The source of the HTML content. When a Page is provided, extracts from the entire page. When a Locator is provided, extracts from that specific element.
|
|
705
837
|
* @returns {Promise<string>} Promise that resolves to the markdown representation of the HTML content
|
|
838
|
+
*
|
|
706
839
|
* @example
|
|
707
|
-
* ```typescript
|
|
840
|
+
* ```typescript Extract Markdown from Locator
|
|
708
841
|
* import { extractMarkdown } from "@intuned/browser";
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
842
|
+
* import { BrowserContext, Page } from "playwright";
|
|
843
|
+
*
|
|
844
|
+
* interface Params {}
|
|
845
|
+
*
|
|
846
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
847
|
+
* await page.goto("https://books.toscrape.com/");
|
|
848
|
+
* const headerLocator = page.locator('h1').first(); // First title on the page
|
|
849
|
+
* const markdown = await extractMarkdown({ source: headerLocator }); // Extract markdown from the first title
|
|
850
|
+
* console.log(markdown);
|
|
851
|
+
* return markdown;
|
|
714
852
|
* }
|
|
715
853
|
* ```
|
|
854
|
+
*
|
|
716
855
|
* @example
|
|
717
|
-
* ```typescript
|
|
856
|
+
* ```typescript Extract Markdown from Page
|
|
718
857
|
* import { extractMarkdown } from "@intuned/browser";
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
858
|
+
* import { BrowserContext, Page } from "playwright";
|
|
859
|
+
*
|
|
860
|
+
* interface Params {}
|
|
861
|
+
*
|
|
862
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
863
|
+
* await page.goto("https://sandbox.intuned.dev/pdfs");
|
|
864
|
+
* const markdown = await extractMarkdown({ source: page });
|
|
865
|
+
* console.log(markdown);
|
|
866
|
+
* return markdown;
|
|
723
867
|
* }
|
|
724
868
|
* ```
|
|
725
|
-
*
|
|
726
869
|
*/
|
|
727
870
|
export declare function extractMarkdown(input: {
|
|
728
871
|
source: Page | Locator;
|
|
729
872
|
}): Promise<string>;
|
|
730
873
|
|
|
731
874
|
/**
|
|
732
|
-
* Converts any URL source to an absolute, properly encoded URL
|
|
875
|
+
* Converts any URL source to an absolute, properly encoded URL.
|
|
876
|
+
*
|
|
877
|
+
* @overload Base URL String
|
|
878
|
+
*
|
|
879
|
+
* Combines a relative URL with a base URL string. Use when you have an explicit base URL string to resolve relative paths against.
|
|
733
880
|
*
|
|
734
|
-
* @overload From Base URL String
|
|
735
881
|
* @param {Object} input - Configuration object with different properties based on the overload
|
|
736
882
|
* @param {string} input.url - The relative or absolute URL to resolve
|
|
737
883
|
* @param {string} input.baseUrl - Base URL string to resolve relative URLs against
|
|
738
884
|
* @returns {Promise<string>} Promise that resolves to the absolute, properly encoded URL string
|
|
739
885
|
* @example
|
|
740
|
-
* ```typescript String
|
|
886
|
+
* ```typescript Resolve from Base URL String
|
|
741
887
|
* import { resolveUrl } from '@intuned/browser';
|
|
742
|
-
*
|
|
743
|
-
*
|
|
888
|
+
* import { BrowserContext, Page } from "playwright";
|
|
889
|
+
*
|
|
890
|
+
* interface Params {}
|
|
744
891
|
*
|
|
745
|
-
*
|
|
892
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
893
|
+
* // Resolve from base URL string
|
|
746
894
|
* const absoluteUrl = await resolveUrl({
|
|
747
|
-
* url: "/
|
|
748
|
-
* baseUrl: "https://
|
|
895
|
+
* url: "/lists/table",
|
|
896
|
+
* baseUrl: "https://sandbox.intuned.dev"
|
|
749
897
|
* });
|
|
750
|
-
* // Returns: "https://
|
|
898
|
+
* // Returns: "https://sandbox.intuned.dev/lists/table"
|
|
899
|
+
* console.log(absoluteUrl);
|
|
900
|
+
* return absoluteUrl;
|
|
751
901
|
* }
|
|
752
902
|
* ```
|
|
753
903
|
*/
|
|
@@ -757,24 +907,33 @@ export declare function resolveUrl(input: {
|
|
|
757
907
|
}): Promise<string>;
|
|
758
908
|
|
|
759
909
|
/**
|
|
760
|
-
* Converts any URL source to an absolute, properly encoded URL
|
|
910
|
+
* Converts any URL source to an absolute, properly encoded URL.
|
|
911
|
+
*
|
|
912
|
+
* @overload Current Page's URL
|
|
913
|
+
*
|
|
914
|
+
* Uses the current page's URL as the base URL. Use when resolving URLs relative to the current page.
|
|
761
915
|
*
|
|
762
|
-
* @overload From The Current Page's URL
|
|
763
916
|
* @param {Object} input - Configuration object with different properties based on the overload
|
|
764
917
|
* @param {string} input.url - The relative or absolute URL to resolve
|
|
765
918
|
* @param {Page} input.page - Playwright Page object to extract base URL from. The current page URL will be used as the base URL
|
|
766
919
|
* @returns {Promise<string>} Promise that resolves to the absolute, properly encoded URL string
|
|
767
920
|
* @example
|
|
768
|
-
* ```typescript Page
|
|
921
|
+
* ```typescript Resolve from the Current Page's URL
|
|
769
922
|
* import { resolveUrl } from '@intuned/browser';
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
923
|
+
* import { BrowserContext, Page } from "playwright";
|
|
924
|
+
*
|
|
925
|
+
* interface Params {}
|
|
926
|
+
*
|
|
927
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
928
|
+
* await page.goto("https://sandbox.intuned.dev/");
|
|
929
|
+
* // Resolve from the current page's URL
|
|
773
930
|
* const absoluteUrl = await resolveUrl({
|
|
774
|
-
* url: "/
|
|
931
|
+
* url: "/lists/table",
|
|
775
932
|
* page: page
|
|
776
933
|
* });
|
|
777
|
-
* // Returns: "https://
|
|
934
|
+
* // Returns: "https://sandbox.intuned.dev/lists/table"
|
|
935
|
+
* console.log(absoluteUrl);
|
|
936
|
+
* return absoluteUrl;
|
|
778
937
|
* }
|
|
779
938
|
* ```
|
|
780
939
|
*/
|
|
@@ -784,21 +943,31 @@ export declare function resolveUrl(input: {
|
|
|
784
943
|
}): Promise<string>;
|
|
785
944
|
|
|
786
945
|
/**
|
|
787
|
-
* Converts any URL source to an absolute, properly encoded URL
|
|
946
|
+
* Converts any URL source to an absolute, properly encoded URL.
|
|
947
|
+
*
|
|
948
|
+
* @overload Anchor Elements
|
|
949
|
+
*
|
|
950
|
+
* Extracts the href attribute from a Playwright Locator pointing to an anchor element. Use when extracting and resolving URLs from anchor (`<a>`) elements.
|
|
788
951
|
*
|
|
789
|
-
* @overload From Anchor Element
|
|
790
952
|
* @param {Object} input - Configuration object with different properties based on the overload
|
|
791
|
-
* @param {Locator} input.url - Playwright Locator pointing to an anchor element. The href attribute will be extracted and resolved
|
|
953
|
+
* @param {Locator} input.url - Playwright Locator pointing to an anchor element. The href attribute will be extracted and resolved relative to the current page.
|
|
792
954
|
* @returns {Promise<string>} Promise that resolves to the absolute, properly encoded URL string
|
|
793
955
|
* @example
|
|
794
|
-
* ```typescript
|
|
956
|
+
* ```typescript Resolve from Anchor Element
|
|
795
957
|
* import { resolveUrl } from '@intuned/browser';
|
|
796
|
-
*
|
|
797
|
-
*
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
958
|
+
* import { BrowserContext, Page } from "playwright";
|
|
959
|
+
*
|
|
960
|
+
* interface Params {}
|
|
961
|
+
*
|
|
962
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
963
|
+
* await page.goto("https://sandbox.intuned.dev/");
|
|
964
|
+
* // Resolve from Anchor Element
|
|
965
|
+
* const absoluteUrl = await resolveUrl({
|
|
966
|
+
* url: page.locator("xpath=//a[normalize-space()='Steps Form']"),
|
|
967
|
+
* });
|
|
968
|
+
* // Returns: "https://sandbox.intuned.dev/steps-form"
|
|
969
|
+
* console.log(absoluteUrl);
|
|
970
|
+
* return absoluteUrl;
|
|
802
971
|
* }
|
|
803
972
|
* ```
|
|
804
973
|
*/
|
|
@@ -807,31 +976,64 @@ export declare function resolveUrl(input: { url: Locator }): Promise<string>;
|
|
|
807
976
|
/**
|
|
808
977
|
* Represents an uploaded file stored in AWS S3 with metadata and utility methods.
|
|
809
978
|
*
|
|
810
|
-
*
|
|
811
|
-
* in S3, including methods for generating presigned URLs, serialization, and accessing
|
|
812
|
-
* file metadata.
|
|
979
|
+
* Provides a structured way to handle file information for files stored in S3, including methods for generating presigned URLs, serialization, and accessing file metadata.
|
|
813
980
|
*
|
|
814
981
|
* @interface Attachment
|
|
982
|
+
*
|
|
815
983
|
* @example
|
|
816
|
-
* ```typescript
|
|
817
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
818
|
-
*
|
|
819
|
-
* // Typically returned from uploadFileToS3 or saveFileToS3
|
|
984
|
+
* ```typescript Basic Usage
|
|
985
|
+
* import { uploadFileToS3, Attachment } from "@intuned/browser";
|
|
986
|
+
* import { BrowserContext, Page } from "playwright";
|
|
820
987
|
*
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
988
|
+
* interface Params {}
|
|
989
|
+
*
|
|
990
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
991
|
+
* const uploadedFile: Attachment = await uploadFileToS3({
|
|
992
|
+
* file: myFile,
|
|
993
|
+
* configs: s3Config
|
|
994
|
+
* });
|
|
995
|
+
*
|
|
996
|
+
* // Access file properties
|
|
997
|
+
* console.log(uploadedFile.fileName);
|
|
998
|
+
* console.log(uploadedFile.suggestedFileName);
|
|
999
|
+
* }
|
|
1000
|
+
* ```
|
|
1001
|
+
*
|
|
1002
|
+
* @example
|
|
1003
|
+
* ```typescript Working with Presigned URLs
|
|
1004
|
+
* import { uploadFileToS3, Attachment } from "@intuned/browser";
|
|
1005
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1006
|
+
*
|
|
1007
|
+
* interface Params {}
|
|
825
1008
|
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
1009
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1010
|
+
* const uploadedFile: Attachment = await uploadFileToS3({
|
|
1011
|
+
* file: myFile
|
|
1012
|
+
* });
|
|
829
1013
|
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
1014
|
+
* // Generate a presigned URL for temporary access
|
|
1015
|
+
* const downloadUrl = await uploadedFile.getSignedUrl(3600); // 1 hour expiration
|
|
832
1016
|
*
|
|
833
|
-
*
|
|
834
|
-
*
|
|
1017
|
+
* // Get the permanent S3 URL
|
|
1018
|
+
* const s3Url = uploadedFile.getS3Key();
|
|
1019
|
+
* }
|
|
1020
|
+
* ```
|
|
1021
|
+
*
|
|
1022
|
+
* @example
|
|
1023
|
+
* ```typescript Serialization
|
|
1024
|
+
* import { uploadFileToS3, Attachment } from "@intuned/browser";
|
|
1025
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1026
|
+
*
|
|
1027
|
+
* interface Params {}
|
|
1028
|
+
*
|
|
1029
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1030
|
+
* const uploadedFile: Attachment = await uploadFileToS3({
|
|
1031
|
+
* file: myFile
|
|
1032
|
+
* });
|
|
1033
|
+
*
|
|
1034
|
+
* // Convert to dictionary for storage or API responses
|
|
1035
|
+
* const fileDict = uploadedFile.toDict();
|
|
1036
|
+
* const fileJson = uploadedFile.toJSON();
|
|
835
1037
|
* }
|
|
836
1038
|
* ```
|
|
837
1039
|
*/
|
|
@@ -860,96 +1062,36 @@ export interface Attachment {
|
|
|
860
1062
|
/**
|
|
861
1063
|
* Returns a JSON-serializable record representation of the file.
|
|
862
1064
|
*
|
|
863
|
-
* @
|
|
864
|
-
* @returns {Record<string, string>} Complete model data including all fields
|
|
865
|
-
*
|
|
866
|
-
* @example
|
|
867
|
-
* ```typescript
|
|
868
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
869
|
-
* export default async function handler(params, page, context){
|
|
870
|
-
* file.toJSON()
|
|
871
|
-
* // {
|
|
872
|
-
* // 'fileName': 'docs/report.pdf',
|
|
873
|
-
* // 'bucket': 'uploads',
|
|
874
|
-
* // 'region': 'us-east-1',
|
|
875
|
-
* // 'endpoint': undefined,
|
|
876
|
-
* // 'suggestedFileName': 'Report.pdf'
|
|
877
|
-
* // }
|
|
878
|
-
* }
|
|
879
|
-
* ```
|
|
1065
|
+
* @returns `Record<string, string>` - Complete model data including all fields
|
|
880
1066
|
*/
|
|
881
1067
|
toJSON(): Record<string, string>;
|
|
882
1068
|
|
|
883
1069
|
/**
|
|
884
|
-
* Converts the file metadata to a record
|
|
885
|
-
*
|
|
886
|
-
* @method Attachment.toDict
|
|
887
|
-
* @returns {Record<string, string>} Record with fileName, bucket, region, and suggestedFileName
|
|
1070
|
+
* Converts the file metadata to a record.
|
|
888
1071
|
*
|
|
889
|
-
* @
|
|
890
|
-
* ```typescript
|
|
891
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
892
|
-
* export default async function handler(params, page, context){
|
|
893
|
-
* file.toDict()
|
|
894
|
-
* // {
|
|
895
|
-
* // 'fileName': 'docs/report.pdf',
|
|
896
|
-
* // 'bucket': 'uploads',
|
|
897
|
-
* // 'region': 'us-east-1',
|
|
898
|
-
* // 'suggestedFileName': 'Report.pdf'
|
|
899
|
-
* // }
|
|
900
|
-
* }
|
|
901
|
-
* ```
|
|
1072
|
+
* @returns `Record<string, string>` - Record with fileName, key, bucket, region, endpoint, suggestedFileName, and fileType
|
|
902
1073
|
*/
|
|
903
1074
|
toDict(): Record<string, string>;
|
|
904
1075
|
|
|
905
1076
|
/**
|
|
906
1077
|
* Returns the full S3 URL for the file.
|
|
907
1078
|
*
|
|
908
|
-
* @
|
|
909
|
-
* @returns {string} Complete S3 URL
|
|
910
|
-
*
|
|
911
|
-
* @example
|
|
912
|
-
* ```typescript
|
|
913
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
914
|
-
* export default async function handler(params, page, context){
|
|
915
|
-
* file.getS3Key()
|
|
916
|
-
* // "https://uploads.s3.us-east-1.amazonaws.com/docs/report.pdf"
|
|
917
|
-
* }
|
|
918
|
-
* ```
|
|
1079
|
+
* @returns `string` - Complete S3 URL in format: https://bucket.s3.region.amazonaws.com/filename
|
|
919
1080
|
*/
|
|
920
1081
|
getS3Key(): string;
|
|
921
1082
|
|
|
922
1083
|
/**
|
|
923
1084
|
* Returns the file path/key within the S3 bucket.
|
|
924
1085
|
*
|
|
925
|
-
* @
|
|
926
|
-
* @returns {string} The fileName property (S3 object key)
|
|
927
|
-
*
|
|
928
|
-
* @example
|
|
929
|
-
* ```typescript
|
|
930
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
931
|
-
* export default async function handler(params, page, context){
|
|
932
|
-
* file.getFilePath()
|
|
933
|
-
* // "docs/report.pdf"
|
|
934
|
-
* }
|
|
935
|
-
* ```
|
|
1086
|
+
* @returns `string` - The fileName property (S3 object key)
|
|
936
1087
|
*/
|
|
937
1088
|
getFilePath(): string;
|
|
938
1089
|
|
|
939
1090
|
/**
|
|
940
1091
|
* Generates a presigned URL for secure, temporary access to the file.
|
|
941
1092
|
*
|
|
942
|
-
* @
|
|
943
|
-
* @
|
|
944
|
-
* @returns {Promise<string>} Promise that resolves to presigned URL for downloading the file
|
|
945
|
-
*
|
|
946
|
-
* @example
|
|
947
|
-
* ```typescript
|
|
948
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
949
|
-
* export default async function handler(params, page, context){
|
|
950
|
-
* const url = await file.getSignedUrl(3600); // 1 hour expiration
|
|
951
|
-
* }
|
|
952
|
-
* ```
|
|
1093
|
+
* @param expiration - URL expiration time in seconds. Defaults to 432000 (5 days)
|
|
1094
|
+
* @returns `Promise<string>` - Presigned URL for downloading the file
|
|
953
1095
|
*/
|
|
954
1096
|
getSignedUrl(expiration?: number): Promise<string>;
|
|
955
1097
|
}
|
|
@@ -957,124 +1099,129 @@ export interface Attachment {
|
|
|
957
1099
|
/**
|
|
958
1100
|
* A union type representing different methods to trigger file downloads in web automation.
|
|
959
1101
|
*
|
|
960
|
-
* This type
|
|
961
|
-
* multiple approaches to suit different automation scenarios.
|
|
962
|
-
*
|
|
963
|
-
* @type Trigger
|
|
1102
|
+
* This type standardizes how download operations can be initiated, providing multiple approaches for different automation scenarios.
|
|
964
1103
|
*
|
|
965
|
-
* **Type
|
|
1104
|
+
* **Type variants:**
|
|
966
1105
|
* - `string`: Direct URL string to download from
|
|
967
1106
|
* - `Locator`: Playwright Locator object pointing to a clickable download element
|
|
968
|
-
* - `(page: Page) => Promise<void>`: Custom function that takes a Page and triggers the download
|
|
1107
|
+
* - `(page: Page) => Promise<void>`: Custom async function that takes a Page and triggers the download
|
|
969
1108
|
*
|
|
970
1109
|
* @example
|
|
971
1110
|
* ```typescript URL String Trigger
|
|
972
1111
|
* import { downloadFile } from "@intuned/browser";
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
*
|
|
976
|
-
*
|
|
977
|
-
*
|
|
978
|
-
*
|
|
1112
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1113
|
+
*
|
|
1114
|
+
* interface Params {}
|
|
1115
|
+
*
|
|
1116
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1117
|
+
* // Direct download from URL
|
|
1118
|
+
* const download = await downloadFile({
|
|
1119
|
+
* page,
|
|
1120
|
+
* trigger: "https://example.com/report.pdf"
|
|
1121
|
+
* });
|
|
979
1122
|
* }
|
|
980
1123
|
* ```
|
|
981
1124
|
*
|
|
982
1125
|
* @example
|
|
983
1126
|
* ```typescript Locator Trigger
|
|
984
1127
|
* import { downloadFile } from "@intuned/browser";
|
|
985
|
-
*
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1128
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1129
|
+
*
|
|
1130
|
+
* interface Params {}
|
|
1131
|
+
*
|
|
1132
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1133
|
+
* // Click a download button
|
|
1134
|
+
* const download = await downloadFile({
|
|
1135
|
+
* page,
|
|
1136
|
+
* trigger: page.locator("#download-btn")
|
|
1137
|
+
* });
|
|
992
1138
|
* }
|
|
993
1139
|
* ```
|
|
994
1140
|
*
|
|
995
1141
|
* @example
|
|
996
|
-
* ```typescript
|
|
1142
|
+
* ```typescript Callback Trigger
|
|
997
1143
|
* import { downloadFile } from "@intuned/browser";
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
1001
|
-
*
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1144
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1145
|
+
*
|
|
1146
|
+
* interface Params {}
|
|
1147
|
+
*
|
|
1148
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1149
|
+
* // Custom download logic
|
|
1150
|
+
* const download = await downloadFile({
|
|
1151
|
+
* page,
|
|
1152
|
+
* trigger: async (p) => {
|
|
1153
|
+
* await p.locator("button.prepare").click();
|
|
1154
|
+
* await p.waitForSelector(".ready");
|
|
1155
|
+
* await p.locator("a.download-link").click();
|
|
1156
|
+
* }
|
|
1157
|
+
* });
|
|
1008
1158
|
* }
|
|
1009
1159
|
* ```
|
|
1010
|
-
*
|
|
1011
|
-
* @note
|
|
1012
|
-
* All download functions in the helpers module accept Trigger for consistency.
|
|
1013
|
-
* The trigger method determines how the download operation is initiated.
|
|
1014
1160
|
*/
|
|
1015
1161
|
export type Trigger = string | Locator | ((page: Page) => Promise<void>);
|
|
1016
1162
|
|
|
1017
1163
|
/**
|
|
1018
|
-
* Configuration
|
|
1164
|
+
* Configuration for AWS S3 storage operations.
|
|
1019
1165
|
*
|
|
1020
|
-
*
|
|
1021
|
-
* for connecting to and performing operations with AWS S3 storage. All properties
|
|
1022
|
-
* are optional and will fall back to environment variables or default configuration.
|
|
1166
|
+
* Defines the parameters needed to connect to and interact with AWS S3 storage services. Supports both standard AWS S3 and S3-compatible storage services through custom endpoints.
|
|
1023
1167
|
*
|
|
1024
1168
|
* @interface S3Configs
|
|
1025
|
-
* @example
|
|
1026
|
-
* ```typescript S3 Configuration
|
|
1027
|
-
* import { uploadFileToS3 } from "@intuned/browser";
|
|
1028
|
-
* export default async function handler(params, page, context){
|
|
1029
|
-
* // Basic S3 configuration
|
|
1030
|
-
* const s3Config: S3Configs = {
|
|
1031
|
-
* bucket: "my-app-uploads",
|
|
1032
|
-
* region: "us-east-1",
|
|
1033
|
-
* accessKeyId: "accessKeyId",
|
|
1034
|
-
* secretAccessKey: "SecretAccessKeyId"
|
|
1035
|
-
* };
|
|
1036
1169
|
*
|
|
1037
|
-
*
|
|
1038
|
-
*
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1170
|
+
* @example
|
|
1171
|
+
* ```typescript Basic Configuration
|
|
1172
|
+
* import { uploadFileToS3, S3Configs } from "@intuned/browser";
|
|
1173
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1174
|
+
*
|
|
1175
|
+
* interface Params {}
|
|
1176
|
+
*
|
|
1177
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1178
|
+
* // Using explicit credentials
|
|
1179
|
+
* const s3Config: S3Configs = {
|
|
1180
|
+
* accessKeyId: "accessKeyId",
|
|
1181
|
+
* secretAccessKey: "SecretAccessKeyId",
|
|
1182
|
+
* bucket: "my-app-uploads",
|
|
1183
|
+
* region: "us-east-1"
|
|
1184
|
+
* };
|
|
1185
|
+
* }
|
|
1186
|
+
* ```
|
|
1042
1187
|
*
|
|
1043
|
-
*
|
|
1044
|
-
*
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* ```typescript Environment Variables Configuration
|
|
1190
|
+
* import { uploadFileToS3, S3Configs } from "@intuned/browser";
|
|
1191
|
+
* export default async function handler(params, page, context){
|
|
1192
|
+
* // Credentials will be picked up from environment or IAM roles
|
|
1193
|
+
* const s3Config: S3Configs = {
|
|
1194
|
+
* bucket: "my-app-uploads",
|
|
1195
|
+
* region: "us-west-2"
|
|
1196
|
+
* };
|
|
1049
1197
|
* }
|
|
1050
1198
|
* ```
|
|
1051
1199
|
*/
|
|
1052
1200
|
export interface S3Configs {
|
|
1053
|
-
/**
|
|
1201
|
+
/** Name of the S3 bucket to store files in. Must be a valid S3 bucket name following AWS naming conventions. */
|
|
1054
1202
|
bucket?: string;
|
|
1055
1203
|
|
|
1056
|
-
/**
|
|
1204
|
+
/** AWS region where the S3 bucket is located. Examples: "us-east-1", "eu-west-1", "ap-southeast-1" */
|
|
1057
1205
|
region?: string;
|
|
1058
1206
|
|
|
1059
|
-
/** AWS access key ID for authentication
|
|
1207
|
+
/** AWS access key ID for authentication. If undefined, will attempt to use default AWS credentials or environment variables. */
|
|
1060
1208
|
accessKeyId?: string;
|
|
1061
1209
|
|
|
1062
|
-
/** AWS secret access key for authentication
|
|
1210
|
+
/** AWS secret access key for authentication. If undefined, will attempt to use default AWS credentials or environment variables. */
|
|
1063
1211
|
secretAccessKey?: string;
|
|
1064
1212
|
|
|
1065
|
-
/** Custom
|
|
1213
|
+
/** Custom endpoint URL for S3-compatible storage services. Use this for services like MinIO, DigitalOcean Spaces, or other S3-compatible APIs. For standard AWS S3, leave this undefined. */
|
|
1066
1214
|
endpoint?: string;
|
|
1067
1215
|
}
|
|
1068
1216
|
|
|
1069
1217
|
/**
|
|
1070
1218
|
* A union type representing different file formats that can be processed by the SDK.
|
|
1071
1219
|
*
|
|
1072
|
-
*
|
|
1073
|
-
* supporting multiple input formats for maximum convenience.
|
|
1220
|
+
* Provides flexibility in how files can be passed to various functions, supporting multiple input formats.
|
|
1074
1221
|
*
|
|
1075
1222
|
* @type FileType
|
|
1076
1223
|
*
|
|
1077
|
-
* **Type
|
|
1224
|
+
* **Type variants:**
|
|
1078
1225
|
* - `Download`: Playwright Download object from browser download operations
|
|
1079
1226
|
* - `Uint8Array`: Binary data as Uint8Array
|
|
1080
1227
|
* - `Buffer`: Node.js Buffer containing binary data
|
|
@@ -1130,79 +1277,59 @@ export type FileType = Download | Uint8Array | Buffer | ReadStream;
|
|
|
1130
1277
|
/**
|
|
1131
1278
|
* Downloads a file from a web page and automatically uploads it to AWS S3 storage in a single operation.
|
|
1132
1279
|
*
|
|
1133
|
-
*
|
|
1134
|
-
* providing a streamlined workflow for capturing
|
|
1135
|
-
* It supports the same flexible trigger methods as `downloadFile` with additional S3 upload configuration.
|
|
1280
|
+
* Combines [downloadFile](./downloadFile) (for trigger methods) and [uploadFileToS3](./uploadFileToS3)
|
|
1281
|
+
* (for S3 configuration), providing a streamlined workflow for capturing and storing files.
|
|
1136
1282
|
*
|
|
1137
1283
|
* @param {Object} input - Configuration object for the download and upload operation
|
|
1138
1284
|
* @param {Page} input.page - The Playwright Page object to use for downloading
|
|
1139
|
-
* @param {Trigger} input.trigger - The [Trigger](../type-
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1143
|
-
* @param {
|
|
1144
|
-
* @
|
|
1145
|
-
* @param {string} [input.fileNameOverride] - Optional filename override for the uploaded file
|
|
1146
|
-
* @param {string} [input.contentType] - Optional content type for the uploaded file
|
|
1147
|
-
* @returns {Promise<Attachment>} Promise that resolves to an [Attachment](../interfaces/Attachment) object with file metadata and S3 utilities
|
|
1285
|
+
* @param {Trigger} input.trigger - The [Trigger](../type-references/Trigger) method to initiate the download
|
|
1286
|
+
* @param {number} [input.timeoutInMs=5000] - Maximum time in milliseconds to wait for download to start. Defaults to 5000.
|
|
1287
|
+
* @param {S3Configs} [input.configs] - Optional [S3Configs](../type-references/S3Configs) to customize the S3 upload. If not provided, uses environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_ENDPOINT_URL, AWS_BUCKET). If environment variables aren't set, uses default Intuned S3 settings.
|
|
1288
|
+
* @param {string} [input.fileNameOverride] - Optional custom filename for the uploaded file. If not provided, uses the original filename or generates a unique name.
|
|
1289
|
+
* @param {string} [input.contentType] - Optional MIME type for the uploaded file (e.g., “application/pdf”, “image/png”).
|
|
1290
|
+
* @returns {Promise<Attachment>} Promise that resolves to an [Attachment](../type-references/Attachment) object with file metadata and S3 utilities
|
|
1148
1291
|
*
|
|
1149
1292
|
* @example
|
|
1150
|
-
* ```typescript URL
|
|
1151
|
-
* import { saveFileToS3 } from "@intuned/browser"
|
|
1152
|
-
*
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
*
|
|
1158
|
-
*
|
|
1293
|
+
* ```typescript URL Trigger
|
|
1294
|
+
* import { saveFileToS3 } from "@intuned/browser"
|
|
1295
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1296
|
+
*
|
|
1297
|
+
* interface Params {}
|
|
1298
|
+
*
|
|
1299
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1300
|
+
* const uploadedFile = await saveFileToS3({
|
|
1301
|
+
* page,
|
|
1302
|
+
* trigger: "https://sandbox.intuned.dev/pdfs/report.pdf",
|
|
1303
|
+
* configs: {
|
|
1304
|
+
* bucket: 'document-storage',
|
|
1159
1305
|
* region: 'us-east-1',
|
|
1160
1306
|
* accessKeyId: 'accessKeyId',
|
|
1161
1307
|
* secretAccessKey: 'SecretAccessKeyId'
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
*
|
|
1165
|
-
* });
|
|
1166
|
-
*
|
|
1167
|
-
* console.log(`File uploaded to: ${uploadedFile.getS3Key()}`);
|
|
1308
|
+
* },
|
|
1309
|
+
* fileNameOverride: 'reports/monthly-report.pdf'
|
|
1310
|
+
* });
|
|
1311
|
+
* console.log(`File uploaded to: ${uploadedFile.getS3Key()}`);
|
|
1168
1312
|
* }
|
|
1169
1313
|
* ```
|
|
1170
1314
|
*
|
|
1171
1315
|
* @example
|
|
1172
|
-
* ```typescript Locator
|
|
1316
|
+
* ```typescript Locator Trigger
|
|
1173
1317
|
* import { saveFileToS3 } from "@intuned/browser";
|
|
1174
|
-
*
|
|
1175
|
-
* // Click download link and save to S3
|
|
1176
|
-
* await page.goto("https://sandbox.intuned.dev/pdfs")
|
|
1177
|
-
* const uploadedFile = await saveFileToS3({
|
|
1178
|
-
* page,
|
|
1179
|
-
* trigger: page.locator("xpath=//tbody/tr[1]//*[name()='svg']"),
|
|
1180
|
-
* timeoutInMs: 10000,
|
|
1181
|
-
* configs: {
|
|
1182
|
-
* bucket: 'invoice-archive',
|
|
1183
|
-
* region: 'us-west-2',
|
|
1184
|
-
* accessKeyId: 'accessKeyId',
|
|
1185
|
-
* secretAccessKey: 'SecretAccessKeyId'
|
|
1186
|
-
* },
|
|
1187
|
-
* fileNameOverride: 'invoices/invoice.pdf',
|
|
1188
|
-
* contentType: 'application/pdf'
|
|
1189
|
-
* });
|
|
1318
|
+
* import { BrowserContext, Page } from "playwright";
|
|
1190
1319
|
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
*
|
|
1320
|
+
* interface Params {}
|
|
1321
|
+
*
|
|
1322
|
+
* export default async function handler(params: Params, page: Page, context: BrowserContext){
|
|
1323
|
+
* await page.goto("https://sandbox.intuned.dev/pdfs");
|
|
1324
|
+
* const uploadedFile = await saveFileToS3({
|
|
1325
|
+
* page,
|
|
1326
|
+
* trigger: page.locator("xpath=//tbody/tr[1]//*[name()='svg']"),
|
|
1327
|
+
* timeoutInMs: 10000
|
|
1328
|
+
* });
|
|
1329
|
+
* const downloadUrl = await uploadedFile.getSignedUrl(7200); // 2 hours
|
|
1330
|
+
* console.log(`Temporary access: ${downloadUrl}`);
|
|
1194
1331
|
* }
|
|
1195
1332
|
* ```
|
|
1196
|
-
* @note
|
|
1197
|
-
* **S3 Configuration hierarchy:** (same as `uploadFileToS3`):
|
|
1198
|
-
* 1. Explicit `configs` values from the input
|
|
1199
|
-
* 2. Standard AWS environment variables (`AWS_BUCKET`, `AWS_REGION`, etc.)
|
|
1200
|
-
* 3. Intuned's default S3 configuration as fallback
|
|
1201
|
-
*
|
|
1202
|
-
* **Trigger Behavior** (same as `downloadFile`):
|
|
1203
|
-
* - **URL**: Creates temporary page, navigates to URL, captures download, closes page
|
|
1204
|
-
* - **Locator**: Uses current page to click element and capture download
|
|
1205
|
-
* - **Callback**: Executes custom function and captures any resulting downloads
|
|
1206
1333
|
*/
|
|
1207
1334
|
export declare function saveFileToS3(input: {
|
|
1208
1335
|
page: Page;
|
|
@@ -1216,7 +1343,6 @@ export declare function saveFileToS3(input: {
|
|
|
1216
1343
|
/**
|
|
1217
1344
|
* Union type representing the supported attachment file types.
|
|
1218
1345
|
*
|
|
1219
|
-
* @type AttachmentType
|
|
1220
1346
|
* Currently supported types:
|
|
1221
1347
|
* - `"document"`: Document files (PDFs, Word docs, etc.)
|
|
1222
1348
|
*/
|