@intuned/browser-dev 0.1.4-dev.1 → 0.1.5-dev.1
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 +0 -1
- package/dist/ai/export.d.ts +1 -1
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/isPageLoaded.js +14 -3
- package/dist/ai/tests/testIsPageLoaded.spec.js +3 -3
- package/dist/helpers/downloadFile.js +37 -0
- package/dist/helpers/export.d.ts +10 -7
- package/dist/helpers/frame_utils/constants.js +8 -0
- package/dist/helpers/frame_utils/findAllIframes.js +79 -0
- package/dist/helpers/frame_utils/getContainerFrame.js +22 -0
- package/dist/helpers/frame_utils/index.js +44 -0
- package/dist/helpers/frame_utils/tests/testFindAllIframes.spec.js +170 -0
- package/dist/helpers/gotoUrl.js +1 -1
- package/dist/helpers/index.d.ts +10 -7
- package/dist/helpers/index.js +0 -19
- package/dist/helpers/tests/testDownloadFile.spec.js +41 -6
- package/dist/helpers/tests/testInjectAttachmentType.spec.js +482 -0
- package/dist/helpers/tests/testValidateDataUsingSchema.spec.js +35 -31
- package/dist/helpers/tests/testWithDomSettledWait.spec.js +119 -0
- package/dist/helpers/types/Attachment.js +11 -6
- package/dist/helpers/types/index.js +1 -20
- package/dist/helpers/uploadFileToS3.js +2 -2
- package/dist/helpers/validateDataUsingSchema.js +30 -71
- package/dist/helpers/waitForDomSettled.js +57 -40
- package/dist/intunedServices/ApiGateway/tests/testApiGateway.spec.js +4 -4
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/testArrayExtractorFromPage.spec.js +271 -2
- package/dist/optimized-extractors/listExtractionHelpers/runAiExtraction.js +55 -8
- package/generated-docs/ai/functions/extractStructuredData.mdx +5 -5
- package/generated-docs/ai/functions/isPageLoaded.mdx +1 -0
- package/generated-docs/helpers/functions/clickButtonAndWait.mdx +63 -0
- package/generated-docs/helpers/functions/clickUntilExhausted.mdx +112 -0
- package/generated-docs/helpers/functions/scrollToLoadContent.mdx +1 -7
- package/generated-docs/helpers/functions/validateDataUsingSchema.mdx +5 -5
- package/how-to-generate-docs.md +1 -0
- package/package.json +2 -2
- package/dist/helpers/types/CustomTypeRegistry.js +0 -48
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: clickUntilExhausted
|
|
3
|
+
description: ""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
```typescript
|
|
7
|
+
export declare function clickUntilExhausted(input: {
|
|
8
|
+
page: Page;
|
|
9
|
+
buttonLocator: Locator;
|
|
10
|
+
heartbeat?: CallableFunction;
|
|
11
|
+
containerLocator?: Locator;
|
|
12
|
+
maxClicks?: number;
|
|
13
|
+
clickDelay?: number;
|
|
14
|
+
noChangeThreshold?: number;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Repeatedly click a button until no new content appears or max clicks reached.
|
|
19
|
+
|
|
20
|
+
This function is useful for "Load More" buttons or paginated content where you need to
|
|
21
|
+
keep clicking until all content is loaded. It provides several stopping conditions:
|
|
22
|
+
- Button becomes invisible
|
|
23
|
+
- Button becomes disabled
|
|
24
|
+
- Maximum number of clicks reached
|
|
25
|
+
- No change detected in container content (when containerLocator is provided)
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
<CodeGroup>
|
|
30
|
+
|
|
31
|
+
```typescript Load All Items
|
|
32
|
+
import { clickUntilExhausted } from "@intuned/browser";
|
|
33
|
+
export default async function handler(params, page, context){
|
|
34
|
+
await page.goto("https://example.com/products");
|
|
35
|
+
const loadMoreButton = page.locator("button:has-text('Load More')");
|
|
36
|
+
|
|
37
|
+
// Click until button disappears or is disabled
|
|
38
|
+
await clickUntilExhausted({
|
|
39
|
+
page,
|
|
40
|
+
buttonLocator: loadMoreButton,
|
|
41
|
+
maxClicks: 20
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```typescript Track Container Changes
|
|
47
|
+
import { clickUntilExhausted } from "@intuned/browser";
|
|
48
|
+
export default async function handler(params, page, context){
|
|
49
|
+
await page.goto("https://example.com/products");
|
|
50
|
+
const loadMoreButton = page.locator("#load-more");
|
|
51
|
+
const productsContainer = page.locator("#products-list");
|
|
52
|
+
|
|
53
|
+
let clickCount = 0;
|
|
54
|
+
await clickUntilExhausted({
|
|
55
|
+
page,
|
|
56
|
+
buttonLocator: loadMoreButton,
|
|
57
|
+
containerLocator: productsContainer,
|
|
58
|
+
heartbeat: () => {
|
|
59
|
+
clickCount++;
|
|
60
|
+
console.log(`Clicked ${clickCount} times`);
|
|
61
|
+
},
|
|
62
|
+
maxClicks: 30,
|
|
63
|
+
clickDelay: 0.5,
|
|
64
|
+
noChangeThreshold: 0
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
</CodeGroup>
|
|
70
|
+
|
|
71
|
+
## Arguments
|
|
72
|
+
|
|
73
|
+
<ParamField path="input" type="Object" required
|
|
74
|
+
>
|
|
75
|
+
Configuration options
|
|
76
|
+
|
|
77
|
+
<Expandable title="input">
|
|
78
|
+
<ParamField path="input.page" type="Page">
|
|
79
|
+
Playwright Page object
|
|
80
|
+
</ParamField>
|
|
81
|
+
|
|
82
|
+
<ParamField path="input.buttonLocator" type="Locator">
|
|
83
|
+
Locator for the button to click repeatedly
|
|
84
|
+
</ParamField>
|
|
85
|
+
|
|
86
|
+
<ParamField path="input.heartbeat" type="CallableFunction">
|
|
87
|
+
Optional callback invoked after each click
|
|
88
|
+
</ParamField>
|
|
89
|
+
|
|
90
|
+
<ParamField path="input.containerLocator" type="Locator">
|
|
91
|
+
Optional content container to detect changes
|
|
92
|
+
</ParamField>
|
|
93
|
+
|
|
94
|
+
<ParamField path="input.maxClicks" type="number">
|
|
95
|
+
Maximum number of times to click the button
|
|
96
|
+
</ParamField>
|
|
97
|
+
|
|
98
|
+
<ParamField path="input.clickDelay" type="number">
|
|
99
|
+
Delay after each click (in seconds)
|
|
100
|
+
</ParamField>
|
|
101
|
+
|
|
102
|
+
<ParamField path="input.noChangeThreshold" type="number">
|
|
103
|
+
Minimum change in content size to continue clicking
|
|
104
|
+
</ParamField>
|
|
105
|
+
|
|
106
|
+
</Expandable>
|
|
107
|
+
|
|
108
|
+
</ParamField>
|
|
109
|
+
|
|
110
|
+
## Returns: `Promise<void>`
|
|
111
|
+
|
|
112
|
+
Promise that resolves when clicking is exhausted
|
|
@@ -7,7 +7,6 @@ description: ""
|
|
|
7
7
|
export declare function scrollToLoadContent(input: {
|
|
8
8
|
source: Page | Locator;
|
|
9
9
|
onScrollProgress?: CallableFunction;
|
|
10
|
-
scrollableContainer?: Locator | null;
|
|
11
10
|
maxScrolls?: number;
|
|
12
11
|
delayInMs?: number;
|
|
13
12
|
minHeightChange?: number;
|
|
@@ -40,8 +39,7 @@ export default async function handler(params, page, context){
|
|
|
40
39
|
await page.goto("https://docs.intunedhq.com/docs-old/getting-started/introduction")
|
|
41
40
|
const container = page.locator("xpath=//div[@id='sidebar-content']");
|
|
42
41
|
await scrollToLoadContent({
|
|
43
|
-
source:
|
|
44
|
-
scrollableContainer: container,
|
|
42
|
+
source: container,
|
|
45
43
|
maxScrolls: 20
|
|
46
44
|
});
|
|
47
45
|
}
|
|
@@ -64,10 +62,6 @@ The Playwright Page or Locator to scroll
|
|
|
64
62
|
Optional callback function to call during each scroll iteration
|
|
65
63
|
</ParamField>
|
|
66
64
|
|
|
67
|
-
<ParamField path="input.scrollableContainer" type="Locator">
|
|
68
|
-
Specific scrollable element to scroll within. If not provided, scrolls the entire page
|
|
69
|
-
</ParamField>
|
|
70
|
-
|
|
71
65
|
<ParamField path="input.maxScrolls" type="number">
|
|
72
66
|
Maximum number of scroll attempts before stopping. Defaults to 50
|
|
73
67
|
</ParamField>
|
|
@@ -7,7 +7,7 @@ description: ""
|
|
|
7
7
|
export declare function validateDataUsingSchema(input: {
|
|
8
8
|
data: Record<string, any>[] | Record<string, any>;
|
|
9
9
|
schema: Record<string, any>;
|
|
10
|
-
}):
|
|
10
|
+
}): void;
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Validates data against a JSON schema using the AJV validator.
|
|
@@ -36,7 +36,7 @@ const userSchema = {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
validateDataUsingSchema({ data: userData, schema: userSchema });
|
|
40
40
|
// Validation passes, no error thrown
|
|
41
41
|
}
|
|
42
42
|
```
|
|
@@ -59,7 +59,7 @@ const userSchema = {
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
validateDataUsingSchema({ data: userData, schema: userSchema });
|
|
63
63
|
// Validation fails, throws ValidationError
|
|
64
64
|
}
|
|
65
65
|
```
|
|
@@ -85,6 +85,6 @@ JSON schema object defining validation rules
|
|
|
85
85
|
|
|
86
86
|
</ParamField>
|
|
87
87
|
|
|
88
|
-
## Returns: `
|
|
88
|
+
## Returns: `void`
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
Returns nothing if validation passes, throws ValidationError if it fails
|
package/how-to-generate-docs.md
CHANGED
|
@@ -59,3 +59,4 @@ The script in `./scripts/generate-docs.ts` reads JSDocs from `export.d.ts` files
|
|
|
59
59
|
- The markdown converters parse JSDocs into Mintlify-compatible format
|
|
60
60
|
- Include `@example` blocks with TypeScript code snippets
|
|
61
61
|
- Use `@param`, `@returns`, and `@interface` tags for proper documentation
|
|
62
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intuned/browser-dev",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5-dev.1",
|
|
4
4
|
"description": "runner package for intuned functions",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"typesVersions": {
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"openai": "4.77.3",
|
|
77
77
|
"stack-utils": "2.0.6",
|
|
78
78
|
"tslib": "2.6.0",
|
|
79
|
-
"uuid": "
|
|
79
|
+
"uuid": "11.0.0",
|
|
80
80
|
"zod": "^3.25.76",
|
|
81
81
|
"zod-to-json-schema": "^3.24.6",
|
|
82
82
|
"zod-validation-error": "3.0.3"
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.CustomTypeRegistry = exports.AttachmentValidator = void 0;
|
|
7
|
-
class AttachmentValidator {
|
|
8
|
-
validate(data) {
|
|
9
|
-
if (!data || typeof data !== "object") {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const requiredFields = ["fileName", "bucket", "region", "suggestedFileName"];
|
|
13
|
-
return requiredFields.every(field => field in data && typeof data[field] === "string" && data[field].length > 0);
|
|
14
|
-
}
|
|
15
|
-
getName() {
|
|
16
|
-
return "attachment";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.AttachmentValidator = AttachmentValidator;
|
|
20
|
-
class CustomTypeRegistry {
|
|
21
|
-
registry = new Map();
|
|
22
|
-
constructor(registerIntunedTypes = true) {
|
|
23
|
-
if (registerIntunedTypes) {
|
|
24
|
-
this.registerIntunedTypes();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
registerIntunedTypes() {
|
|
28
|
-
this.register(new AttachmentValidator());
|
|
29
|
-
}
|
|
30
|
-
register(validator) {
|
|
31
|
-
const typeName = validator.getName().toLowerCase();
|
|
32
|
-
this.registry.set(typeName, validator);
|
|
33
|
-
}
|
|
34
|
-
get(typeName) {
|
|
35
|
-
return this.registry.get(typeName.toLowerCase());
|
|
36
|
-
}
|
|
37
|
-
isCustomType(typeName) {
|
|
38
|
-
return this.registry.has(typeName.toLowerCase());
|
|
39
|
-
}
|
|
40
|
-
validate(typeName, data) {
|
|
41
|
-
const validator = this.get(typeName);
|
|
42
|
-
return validator ? validator.validate(data) : false;
|
|
43
|
-
}
|
|
44
|
-
getAllTypes() {
|
|
45
|
-
return Array.from(this.registry.keys());
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
exports.CustomTypeRegistry = CustomTypeRegistry;
|