@testsmith/testblocks 0.8.9 → 0.9.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.
@@ -16,7 +16,7 @@
16
16
  overflow: hidden;
17
17
  }
18
18
  </style>
19
- <script type="module" crossorigin src="/assets/index-DGmSW0q0.js"></script>
19
+ <script type="module" crossorigin src="/assets/index-Ivy7T1Qk.js"></script>
20
20
  <link rel="stylesheet" crossorigin href="/assets/index-C5yUtTzz.css">
21
21
  </head>
22
22
  <body>
@@ -11,7 +11,7 @@ exports.interactionBlocks = [
11
11
  type: 'web_click',
12
12
  category: 'Web',
13
13
  color: '#E91E63',
14
- tooltip: 'Click on an element',
14
+ tooltip: 'Click on an element (auto-waits for element)',
15
15
  inputs: [
16
16
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
17
17
  { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
@@ -23,7 +23,8 @@ exports.interactionBlocks = [
23
23
  const selector = (0, utils_1.resolveSelector)(params, context);
24
24
  const timeout = params.TIMEOUT;
25
25
  context.logger.info(`Clicking: ${selector}`);
26
- await page.click(selector, { timeout });
26
+ const locator = page.locator(selector);
27
+ await locator.click({ timeout });
27
28
  return {
28
29
  _summary: params.SELECTOR,
29
30
  selector,
@@ -35,10 +36,11 @@ exports.interactionBlocks = [
35
36
  type: 'web_fill',
36
37
  category: 'Web',
37
38
  color: '#E91E63',
38
- tooltip: 'Fill an input field (clears existing value)',
39
+ tooltip: 'Fill an input field (clears existing value, auto-waits)',
39
40
  inputs: [
40
41
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
41
42
  { name: 'VALUE', type: 'field', fieldType: 'text', required: true },
43
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
42
44
  ],
43
45
  previousStatement: true,
44
46
  nextStatement: true,
@@ -47,8 +49,10 @@ exports.interactionBlocks = [
47
49
  const selector = (0, utils_1.resolveSelector)(params, context);
48
50
  const rawValue = params.VALUE;
49
51
  const value = (0, utils_1.resolveVariables)(rawValue, context);
52
+ const timeout = params.TIMEOUT;
50
53
  context.logger.info(`Filling ${selector} with "${value}"`);
51
- await page.fill(selector, value);
54
+ const locator = page.locator(selector);
55
+ await locator.fill(value, { timeout });
52
56
  const displayValue = value.length > 30 ? value.substring(0, 30) + '...' : value;
53
57
  return {
54
58
  _summary: `${params.SELECTOR} = "${displayValue}"`,
@@ -62,11 +66,12 @@ exports.interactionBlocks = [
62
66
  type: 'web_type',
63
67
  category: 'Web',
64
68
  color: '#E91E63',
65
- tooltip: 'Type text character by character',
69
+ tooltip: 'Type text character by character (auto-waits)',
66
70
  inputs: [
67
71
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
68
72
  { name: 'TEXT', type: 'field', fieldType: 'text', required: true },
69
73
  { name: 'DELAY', type: 'field', fieldType: 'number', default: 50 },
74
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
70
75
  ],
71
76
  previousStatement: true,
72
77
  nextStatement: true,
@@ -75,8 +80,10 @@ exports.interactionBlocks = [
75
80
  const selector = (0, utils_1.resolveSelector)(params, context);
76
81
  const text = (0, utils_1.resolveVariables)(params.TEXT, context);
77
82
  const delay = params.DELAY;
83
+ const timeout = params.TIMEOUT;
78
84
  context.logger.info(`Typing "${text}" into ${selector}`);
79
- await page.type(selector, text, { delay });
85
+ const locator = page.locator(selector);
86
+ await locator.pressSequentially(text, { delay, timeout });
80
87
  const displayText = text.length > 30 ? text.substring(0, 30) + '...' : text;
81
88
  return {
82
89
  _summary: `${params.SELECTOR} = "${displayText}"`,
@@ -91,10 +98,11 @@ exports.interactionBlocks = [
91
98
  type: 'web_press_key',
92
99
  category: 'Web',
93
100
  color: '#E91E63',
94
- tooltip: 'Press a keyboard key',
101
+ tooltip: 'Press a keyboard key (auto-waits)',
95
102
  inputs: [
96
103
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
97
104
  { name: 'KEY', type: 'field', fieldType: 'dropdown', options: [['Enter', 'Enter'], ['Tab', 'Tab'], ['Escape', 'Escape'], ['Backspace', 'Backspace'], ['ArrowUp', 'ArrowUp'], ['ArrowDown', 'ArrowDown'], ['ArrowLeft', 'ArrowLeft'], ['ArrowRight', 'ArrowRight']] },
105
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
98
106
  ],
99
107
  previousStatement: true,
100
108
  nextStatement: true,
@@ -102,8 +110,10 @@ exports.interactionBlocks = [
102
110
  const page = context.page;
103
111
  const selector = (0, utils_1.resolveSelector)(params, context);
104
112
  const key = params.KEY;
113
+ const timeout = params.TIMEOUT;
105
114
  context.logger.info(`Pressing ${key} on ${selector}`);
106
- await page.press(selector, key);
115
+ const locator = page.locator(selector);
116
+ await locator.press(key, { timeout });
107
117
  return {
108
118
  _summary: `${key} on ${params.SELECTOR}`,
109
119
  selector,
@@ -116,10 +126,11 @@ exports.interactionBlocks = [
116
126
  type: 'web_select',
117
127
  category: 'Web',
118
128
  color: '#E91E63',
119
- tooltip: 'Select an option from a dropdown',
129
+ tooltip: 'Select an option from a dropdown (auto-waits)',
120
130
  inputs: [
121
131
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
122
132
  { name: 'VALUE', type: 'field', fieldType: 'text', required: true },
133
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
123
134
  ],
124
135
  previousStatement: true,
125
136
  nextStatement: true,
@@ -127,8 +138,10 @@ exports.interactionBlocks = [
127
138
  const page = context.page;
128
139
  const selector = (0, utils_1.resolveSelector)(params, context);
129
140
  const value = (0, utils_1.resolveVariables)(params.VALUE, context);
141
+ const timeout = params.TIMEOUT;
130
142
  context.logger.info(`Selecting "${value}" in ${selector}`);
131
- await page.selectOption(selector, value);
143
+ const locator = page.locator(selector);
144
+ await locator.selectOption(value, { timeout });
132
145
  return {
133
146
  _summary: `${params.SELECTOR} = "${value}"`,
134
147
  selector,
@@ -141,10 +154,11 @@ exports.interactionBlocks = [
141
154
  type: 'web_checkbox',
142
155
  category: 'Web',
143
156
  color: '#E91E63',
144
- tooltip: 'Check or uncheck a checkbox',
157
+ tooltip: 'Check or uncheck a checkbox (auto-waits)',
145
158
  inputs: [
146
159
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
147
160
  { name: 'ACTION', type: 'field', fieldType: 'dropdown', options: [['Check', 'check'], ['Uncheck', 'uncheck']] },
161
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
148
162
  ],
149
163
  previousStatement: true,
150
164
  nextStatement: true,
@@ -152,12 +166,14 @@ exports.interactionBlocks = [
152
166
  const page = context.page;
153
167
  const selector = (0, utils_1.resolveSelector)(params, context);
154
168
  const action = params.ACTION;
169
+ const timeout = params.TIMEOUT;
155
170
  context.logger.info(`${action === 'check' ? 'Checking' : 'Unchecking'} ${selector}`);
171
+ const locator = page.locator(selector);
156
172
  if (action === 'check') {
157
- await page.check(selector);
173
+ await locator.check({ timeout });
158
174
  }
159
175
  else {
160
- await page.uncheck(selector);
176
+ await locator.uncheck({ timeout });
161
177
  }
162
178
  return {
163
179
  _summary: `${action} ${params.SELECTOR}`,
@@ -171,17 +187,20 @@ exports.interactionBlocks = [
171
187
  type: 'web_hover',
172
188
  category: 'Web',
173
189
  color: '#E91E63',
174
- tooltip: 'Hover over an element',
190
+ tooltip: 'Hover over an element (auto-waits)',
175
191
  inputs: [
176
192
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
193
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
177
194
  ],
178
195
  previousStatement: true,
179
196
  nextStatement: true,
180
197
  execute: async (params, context) => {
181
198
  const page = context.page;
182
199
  const selector = (0, utils_1.resolveSelector)(params, context);
200
+ const timeout = params.TIMEOUT;
183
201
  context.logger.info(`Hovering over ${selector}`);
184
- await page.hover(selector);
202
+ const locator = page.locator(selector);
203
+ await locator.hover({ timeout });
185
204
  return {
186
205
  _summary: params.SELECTOR,
187
206
  selector,
@@ -11,15 +11,19 @@ exports.retrievalBlocks = [
11
11
  type: 'web_get_text',
12
12
  category: 'Web',
13
13
  color: '#2196F3',
14
- tooltip: 'Get text content of an element',
14
+ tooltip: 'Get text content of an element (auto-waits)',
15
15
  inputs: [
16
16
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
17
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
17
18
  ],
18
19
  output: { type: 'String' },
19
20
  execute: async (params, context) => {
20
21
  const page = context.page;
21
22
  const selector = (0, utils_1.resolveSelector)(params, context);
22
- const text = await page.textContent(selector);
23
+ const timeout = params.TIMEOUT;
24
+ const locator = page.locator(selector);
25
+ await locator.waitFor({ state: 'visible', timeout });
26
+ const text = await locator.textContent({ timeout });
23
27
  context.logger.debug(`Text content of ${selector}: "${text}"`);
24
28
  const displayText = text && text.length > 40 ? text.substring(0, 40) + '...' : text;
25
29
  return {
@@ -35,17 +39,21 @@ exports.retrievalBlocks = [
35
39
  type: 'web_get_attribute',
36
40
  category: 'Web',
37
41
  color: '#2196F3',
38
- tooltip: 'Get attribute value of an element',
42
+ tooltip: 'Get attribute value of an element (auto-waits)',
39
43
  inputs: [
40
44
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
41
45
  { name: 'ATTRIBUTE', type: 'field', fieldType: 'text', required: true },
46
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
42
47
  ],
43
48
  output: { type: 'String' },
44
49
  execute: async (params, context) => {
45
50
  const page = context.page;
46
51
  const selector = (0, utils_1.resolveSelector)(params, context);
47
52
  const attribute = params.ATTRIBUTE;
48
- const value = await page.getAttribute(selector, attribute);
53
+ const timeout = params.TIMEOUT;
54
+ const locator = page.locator(selector);
55
+ await locator.waitFor({ state: 'attached', timeout });
56
+ const value = await locator.getAttribute(attribute, { timeout });
49
57
  context.logger.debug(`Attribute ${attribute} of ${selector}: "${value}"`);
50
58
  return {
51
59
  _summary: `${attribute} = "${value}"`,
@@ -61,15 +69,19 @@ exports.retrievalBlocks = [
61
69
  type: 'web_get_input_value',
62
70
  category: 'Web',
63
71
  color: '#2196F3',
64
- tooltip: 'Get current value of an input field',
72
+ tooltip: 'Get current value of an input field (auto-waits)',
65
73
  inputs: [
66
74
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
75
+ { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
67
76
  ],
68
77
  output: { type: 'String' },
69
78
  execute: async (params, context) => {
70
79
  const page = context.page;
71
80
  const selector = (0, utils_1.resolveSelector)(params, context);
72
- const value = await page.inputValue(selector);
81
+ const timeout = params.TIMEOUT;
82
+ const locator = page.locator(selector);
83
+ await locator.waitFor({ state: 'visible', timeout });
84
+ const value = await locator.inputValue({ timeout });
73
85
  context.logger.debug(`Input value of ${selector}: "${value}"`);
74
86
  const displayValue = value.length > 40 ? value.substring(0, 40) + '...' : value;
75
87
  return {
@@ -5,23 +5,52 @@ export interface PlaywrightLocator {
5
5
  click(options?: {
6
6
  timeout?: number;
7
7
  }): Promise<void>;
8
- fill(value: string): Promise<void>;
8
+ fill(value: string, options?: {
9
+ timeout?: number;
10
+ }): Promise<void>;
9
11
  type(text: string, options?: {
10
12
  delay?: number;
13
+ timeout?: number;
14
+ }): Promise<void>;
15
+ pressSequentially(text: string, options?: {
16
+ delay?: number;
17
+ timeout?: number;
18
+ }): Promise<void>;
19
+ selectOption(values: string | string[], options?: {
20
+ timeout?: number;
21
+ }): Promise<string[]>;
22
+ check(options?: {
23
+ timeout?: number;
24
+ }): Promise<void>;
25
+ uncheck(options?: {
26
+ timeout?: number;
11
27
  }): Promise<void>;
12
- selectOption(values: string | string[]): Promise<string[]>;
13
- check(): Promise<void>;
14
- uncheck(): Promise<void>;
15
- hover(): Promise<void>;
16
- focus(): Promise<void>;
17
- press(key: string): Promise<void>;
18
- textContent(): Promise<string | null>;
19
- getAttribute(name: string): Promise<string | null>;
20
- inputValue(): Promise<string>;
28
+ hover(options?: {
29
+ timeout?: number;
30
+ }): Promise<void>;
31
+ focus(options?: {
32
+ timeout?: number;
33
+ }): Promise<void>;
34
+ press(key: string, options?: {
35
+ timeout?: number;
36
+ }): Promise<void>;
37
+ textContent(options?: {
38
+ timeout?: number;
39
+ }): Promise<string | null>;
40
+ getAttribute(name: string, options?: {
41
+ timeout?: number;
42
+ }): Promise<string | null>;
43
+ inputValue(options?: {
44
+ timeout?: number;
45
+ }): Promise<string>;
21
46
  isVisible(): Promise<boolean>;
22
47
  isEnabled(): Promise<boolean>;
23
48
  isChecked(): Promise<boolean>;
24
49
  count(): Promise<number>;
50
+ waitFor(options?: {
51
+ state?: 'attached' | 'detached' | 'visible' | 'hidden';
52
+ timeout?: number;
53
+ }): Promise<void>;
25
54
  }
26
55
  export interface PlaywrightPage {
27
56
  goto(url: string, options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testsmith/testblocks",
3
- "version": "0.8.9",
3
+ "version": "0.9.0",
4
4
  "description": "Visual test automation tool with Blockly - API and Playwright testing",
5
5
  "author": "Roy de Kleijn",
6
6
  "license": "MIT",