@testsmith/testblocks 0.5.0 → 0.7.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/dist/cli/executor.d.ts +4 -1
- package/dist/cli/executor.js +101 -5
- package/dist/cli/index.js +78 -3
- package/dist/cli/reporters/ConsoleReporter.d.ts +12 -0
- package/dist/cli/reporters/ConsoleReporter.js +39 -0
- package/dist/cli/reporters/HTMLReporter.d.ts +19 -0
- package/dist/cli/reporters/HTMLReporter.js +506 -0
- package/dist/cli/reporters/JSONReporter.d.ts +15 -0
- package/dist/cli/reporters/JSONReporter.js +80 -0
- package/dist/cli/reporters/JUnitReporter.d.ts +19 -0
- package/dist/cli/reporters/JUnitReporter.js +105 -0
- package/dist/cli/reporters/index.d.ts +17 -0
- package/dist/cli/reporters/index.js +31 -0
- package/dist/cli/reporters/types.d.ts +28 -0
- package/dist/cli/reporters/types.js +2 -0
- package/dist/cli/reporters/utils.d.ts +31 -0
- package/dist/cli/reporters/utils.js +136 -0
- package/dist/cli/reporters.d.ts +13 -62
- package/dist/cli/reporters.js +16 -719
- package/dist/client/assets/index-Boo8ZrY_.js +2195 -0
- package/dist/client/assets/{index-qyomBgyC.js.map → index-Boo8ZrY_.js.map} +1 -1
- package/dist/client/assets/index-OxNH9dW-.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/core/blocks/api.js +3 -6
- package/dist/core/blocks/assertions.d.ts +31 -0
- package/dist/core/blocks/assertions.js +72 -0
- package/dist/core/blocks/index.d.ts +1 -0
- package/dist/core/blocks/index.js +6 -1
- package/dist/core/blocks/lifecycle.js +5 -3
- package/dist/core/blocks/logic.js +2 -3
- package/dist/core/blocks/playwright/assertions.d.ts +5 -0
- package/dist/core/blocks/playwright/assertions.js +321 -0
- package/dist/core/blocks/playwright/index.d.ts +17 -0
- package/dist/core/blocks/playwright/index.js +49 -0
- package/dist/core/blocks/playwright/interactions.d.ts +5 -0
- package/dist/core/blocks/playwright/interactions.js +191 -0
- package/dist/core/blocks/playwright/navigation.d.ts +5 -0
- package/dist/core/blocks/playwright/navigation.js +133 -0
- package/dist/core/blocks/playwright/retrieval.d.ts +5 -0
- package/dist/core/blocks/playwright/retrieval.js +144 -0
- package/dist/core/blocks/playwright/types.d.ts +65 -0
- package/dist/core/blocks/playwright/types.js +5 -0
- package/dist/core/blocks/playwright/utils.d.ts +26 -0
- package/dist/core/blocks/playwright/utils.js +137 -0
- package/dist/core/blocks/playwright.d.ts +13 -2
- package/dist/core/blocks/playwright.js +14 -761
- package/dist/core/executor/BaseTestExecutor.d.ts +60 -0
- package/dist/core/executor/BaseTestExecutor.js +297 -0
- package/dist/core/executor/index.d.ts +1 -0
- package/dist/core/executor/index.js +5 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/types.d.ts +12 -0
- package/dist/core/utils/blocklyParser.d.ts +18 -0
- package/dist/core/utils/blocklyParser.js +84 -0
- package/dist/core/utils/dataLoader.d.ts +9 -0
- package/dist/core/utils/dataLoader.js +117 -0
- package/dist/core/utils/index.d.ts +2 -0
- package/dist/core/utils/index.js +12 -0
- package/dist/core/utils/logger.d.ts +14 -0
- package/dist/core/utils/logger.js +48 -0
- package/dist/core/utils/variableResolver.d.ts +24 -0
- package/dist/core/utils/variableResolver.js +92 -0
- package/dist/server/executor.d.ts +6 -0
- package/dist/server/executor.js +207 -47
- package/dist/server/globals.d.ts +6 -1
- package/dist/server/globals.js +7 -0
- package/dist/server/startServer.js +15 -0
- package/package.json +1 -1
- package/dist/client/assets/index-oTTttNKd.css +0 -1
- package/dist/client/assets/index-qyomBgyC.js +0 -2193
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertionBlocks = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
/**
|
|
6
|
+
* Assertion blocks for Playwright (visibility, text, values)
|
|
7
|
+
*/
|
|
8
|
+
exports.assertionBlocks = [
|
|
9
|
+
// Assert Element Visible
|
|
10
|
+
{
|
|
11
|
+
type: 'web_assert_visible',
|
|
12
|
+
category: 'Web',
|
|
13
|
+
color: '#FF9800',
|
|
14
|
+
tooltip: 'Assert that an element is visible (auto-waits)',
|
|
15
|
+
inputs: [
|
|
16
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
17
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
18
|
+
],
|
|
19
|
+
previousStatement: true,
|
|
20
|
+
nextStatement: true,
|
|
21
|
+
execute: async (params, context) => {
|
|
22
|
+
const page = context.page;
|
|
23
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
24
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
25
|
+
const timeout = params.TIMEOUT;
|
|
26
|
+
const expect = await (0, utils_1.getExpect)();
|
|
27
|
+
const locator = page.locator(selector);
|
|
28
|
+
context.logger.info(`Asserting ${displaySelector} is visible`);
|
|
29
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(locator).toBeVisible({ timeout }); }, `Expected element ${displaySelector} to be visible`, { stepType: 'web_assert_visible', expected: 'visible', actual: 'not visible' });
|
|
30
|
+
context.logger.info(`✓ Element ${displaySelector} is visible`);
|
|
31
|
+
return {
|
|
32
|
+
_summary: `${displaySelector} is visible`,
|
|
33
|
+
selector,
|
|
34
|
+
isVisible: true,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
// Assert Element Not Visible
|
|
39
|
+
{
|
|
40
|
+
type: 'web_assert_not_visible',
|
|
41
|
+
category: 'Web',
|
|
42
|
+
color: '#FF9800',
|
|
43
|
+
tooltip: 'Assert that an element is not visible (auto-waits)',
|
|
44
|
+
inputs: [
|
|
45
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
46
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
47
|
+
],
|
|
48
|
+
previousStatement: true,
|
|
49
|
+
nextStatement: true,
|
|
50
|
+
execute: async (params, context) => {
|
|
51
|
+
const page = context.page;
|
|
52
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
53
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
54
|
+
const timeout = params.TIMEOUT;
|
|
55
|
+
const expect = await (0, utils_1.getExpect)();
|
|
56
|
+
const locator = page.locator(selector);
|
|
57
|
+
context.logger.info(`Asserting ${displaySelector} is not visible`);
|
|
58
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(locator).toBeHidden({ timeout }); }, `Expected element ${displaySelector} to be hidden`, { stepType: 'web_assert_not_visible', expected: 'hidden', actual: 'visible' });
|
|
59
|
+
context.logger.info(`✓ Element ${displaySelector} is not visible`);
|
|
60
|
+
return {
|
|
61
|
+
_summary: `${displaySelector} is not visible`,
|
|
62
|
+
selector,
|
|
63
|
+
isVisible: false,
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
// Assert Text Contains
|
|
68
|
+
{
|
|
69
|
+
type: 'web_assert_text_contains',
|
|
70
|
+
category: 'Web',
|
|
71
|
+
color: '#FF9800',
|
|
72
|
+
tooltip: 'Assert that element text contains expected value (auto-waits)',
|
|
73
|
+
inputs: [
|
|
74
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
75
|
+
{ name: 'TEXT', type: 'field', fieldType: 'text', required: true },
|
|
76
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
77
|
+
],
|
|
78
|
+
previousStatement: true,
|
|
79
|
+
nextStatement: true,
|
|
80
|
+
execute: async (params, context) => {
|
|
81
|
+
const page = context.page;
|
|
82
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
83
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
84
|
+
const expectedText = (0, utils_1.resolveVariables)(params.TEXT, context);
|
|
85
|
+
const timeout = params.TIMEOUT;
|
|
86
|
+
const expect = await (0, utils_1.getExpect)();
|
|
87
|
+
const locator = page.locator(selector);
|
|
88
|
+
context.logger.info(`Asserting ${displaySelector} contains "${expectedText}"`);
|
|
89
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(locator).toContainText(expectedText, { timeout }); }, `Expected element ${displaySelector} to contain text "${expectedText}"`, { stepType: 'web_assert_text_contains', expected: expectedText });
|
|
90
|
+
context.logger.info(`✓ Element ${displaySelector} contains text "${expectedText}"`);
|
|
91
|
+
return {
|
|
92
|
+
_summary: `"${expectedText}" found`,
|
|
93
|
+
selector,
|
|
94
|
+
expectedText,
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
// Assert Text Equals
|
|
99
|
+
{
|
|
100
|
+
type: 'web_assert_text_equals',
|
|
101
|
+
category: 'Web',
|
|
102
|
+
color: '#FF9800',
|
|
103
|
+
tooltip: 'Assert that element text equals expected value (auto-waits)',
|
|
104
|
+
inputs: [
|
|
105
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
106
|
+
{ name: 'TEXT', type: 'field', fieldType: 'text', required: true },
|
|
107
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
108
|
+
],
|
|
109
|
+
previousStatement: true,
|
|
110
|
+
nextStatement: true,
|
|
111
|
+
execute: async (params, context) => {
|
|
112
|
+
const page = context.page;
|
|
113
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
114
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
115
|
+
const expectedText = (0, utils_1.resolveVariables)(params.TEXT, context);
|
|
116
|
+
const timeout = params.TIMEOUT;
|
|
117
|
+
const expect = await (0, utils_1.getExpect)();
|
|
118
|
+
const locator = page.locator(selector);
|
|
119
|
+
context.logger.info(`Asserting ${displaySelector} text equals "${expectedText}"`);
|
|
120
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(locator).toHaveText(expectedText, { timeout }); }, `Expected element ${displaySelector} text to equal "${expectedText}"`, { stepType: 'web_assert_text_equals', expected: expectedText });
|
|
121
|
+
context.logger.info(`✓ Element ${displaySelector} text equals "${expectedText}"`);
|
|
122
|
+
return {
|
|
123
|
+
_summary: `"${expectedText}" matches`,
|
|
124
|
+
selector,
|
|
125
|
+
expectedText,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
// Assert URL Contains
|
|
130
|
+
{
|
|
131
|
+
type: 'web_assert_url_contains',
|
|
132
|
+
category: 'Web',
|
|
133
|
+
color: '#FF9800',
|
|
134
|
+
tooltip: 'Assert that current URL contains expected value (auto-waits)',
|
|
135
|
+
inputs: [
|
|
136
|
+
{ name: 'TEXT', type: 'field', fieldType: 'text', required: true },
|
|
137
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
138
|
+
],
|
|
139
|
+
previousStatement: true,
|
|
140
|
+
nextStatement: true,
|
|
141
|
+
execute: async (params, context) => {
|
|
142
|
+
const page = context.page;
|
|
143
|
+
const expectedText = (0, utils_1.resolveVariables)(params.TEXT, context);
|
|
144
|
+
const timeout = params.TIMEOUT;
|
|
145
|
+
const expect = await (0, utils_1.getExpect)();
|
|
146
|
+
// Escape special regex characters and create a regex pattern
|
|
147
|
+
const escapedText = expectedText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
148
|
+
const urlPattern = new RegExp(escapedText);
|
|
149
|
+
context.logger.info(`Asserting URL contains "${expectedText}"`);
|
|
150
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(page).toHaveURL(urlPattern, { timeout }); }, `Expected URL to contain "${expectedText}"`, { stepType: 'web_assert_url_contains', expected: expectedText, actual: page.url() });
|
|
151
|
+
context.logger.info(`✓ URL contains "${expectedText}"`);
|
|
152
|
+
return {
|
|
153
|
+
_summary: `"${expectedText}" in URL`,
|
|
154
|
+
expectedText,
|
|
155
|
+
actualUrl: page.url(),
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
// Assert Title Contains
|
|
160
|
+
{
|
|
161
|
+
type: 'web_assert_title_contains',
|
|
162
|
+
category: 'Web',
|
|
163
|
+
color: '#FF9800',
|
|
164
|
+
tooltip: 'Assert that page title contains expected value (auto-waits)',
|
|
165
|
+
inputs: [
|
|
166
|
+
{ name: 'TEXT', type: 'field', fieldType: 'text', required: true },
|
|
167
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
168
|
+
],
|
|
169
|
+
previousStatement: true,
|
|
170
|
+
nextStatement: true,
|
|
171
|
+
execute: async (params, context) => {
|
|
172
|
+
const page = context.page;
|
|
173
|
+
const expectedText = (0, utils_1.resolveVariables)(params.TEXT, context);
|
|
174
|
+
const timeout = params.TIMEOUT;
|
|
175
|
+
const expect = await (0, utils_1.getExpect)();
|
|
176
|
+
// Escape special regex characters and create a regex pattern
|
|
177
|
+
const escapedText = expectedText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
178
|
+
const titlePattern = new RegExp(escapedText);
|
|
179
|
+
context.logger.info(`Asserting title contains "${expectedText}"`);
|
|
180
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(page).toHaveTitle(titlePattern, { timeout }); }, `Expected title to contain "${expectedText}"`, { stepType: 'web_assert_title_contains', expected: expectedText });
|
|
181
|
+
context.logger.info(`✓ Title contains "${expectedText}"`);
|
|
182
|
+
return {
|
|
183
|
+
_summary: `"${expectedText}" in title`,
|
|
184
|
+
expectedText,
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
// Assert Element Enabled
|
|
189
|
+
{
|
|
190
|
+
type: 'web_assert_enabled',
|
|
191
|
+
category: 'Web',
|
|
192
|
+
color: '#FF9800',
|
|
193
|
+
tooltip: 'Assert that an element is enabled (auto-waits)',
|
|
194
|
+
inputs: [
|
|
195
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
196
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
197
|
+
],
|
|
198
|
+
previousStatement: true,
|
|
199
|
+
nextStatement: true,
|
|
200
|
+
execute: async (params, context) => {
|
|
201
|
+
const page = context.page;
|
|
202
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
203
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
204
|
+
const timeout = params.TIMEOUT;
|
|
205
|
+
const expect = await (0, utils_1.getExpect)();
|
|
206
|
+
const locator = page.locator(selector);
|
|
207
|
+
context.logger.info(`Asserting ${displaySelector} is enabled`);
|
|
208
|
+
await (0, utils_1.executeWebAssertion)(context, async () => { await expect(locator).toBeEnabled({ timeout }); }, `Expected element ${displaySelector} to be enabled`, { stepType: 'web_assert_enabled', expected: 'enabled', actual: 'disabled' });
|
|
209
|
+
context.logger.info(`✓ Element ${displaySelector} is enabled`);
|
|
210
|
+
return {
|
|
211
|
+
_summary: `${displaySelector} is enabled`,
|
|
212
|
+
selector,
|
|
213
|
+
isEnabled: true,
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
// Assert Checkbox Checked
|
|
218
|
+
{
|
|
219
|
+
type: 'web_assert_checked',
|
|
220
|
+
category: 'Web',
|
|
221
|
+
color: '#FF9800',
|
|
222
|
+
tooltip: 'Assert that a checkbox is checked (auto-waits)',
|
|
223
|
+
inputs: [
|
|
224
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
225
|
+
{ name: 'EXPECTED', type: 'field', fieldType: 'checkbox', default: true },
|
|
226
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
227
|
+
],
|
|
228
|
+
previousStatement: true,
|
|
229
|
+
nextStatement: true,
|
|
230
|
+
execute: async (params, context) => {
|
|
231
|
+
const page = context.page;
|
|
232
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
233
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
234
|
+
const expected = params.EXPECTED;
|
|
235
|
+
const timeout = params.TIMEOUT;
|
|
236
|
+
const expect = await (0, utils_1.getExpect)();
|
|
237
|
+
const locator = page.locator(selector);
|
|
238
|
+
context.logger.info(`Asserting ${displaySelector} is ${expected ? 'checked' : 'unchecked'}`);
|
|
239
|
+
await (0, utils_1.executeWebAssertion)(context, async () => {
|
|
240
|
+
if (expected) {
|
|
241
|
+
await expect(locator).toBeChecked({ timeout });
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
await expect(locator).not.toBeChecked({ timeout });
|
|
245
|
+
}
|
|
246
|
+
}, `Expected checkbox ${displaySelector} to be ${expected ? 'checked' : 'unchecked'}`, { stepType: 'web_assert_checked', expected: expected ? 'checked' : 'unchecked' });
|
|
247
|
+
context.logger.info(`✓ Checkbox ${displaySelector} is ${expected ? 'checked' : 'unchecked'}`);
|
|
248
|
+
return {
|
|
249
|
+
_summary: `${displaySelector} is ${expected ? 'checked' : 'unchecked'}`,
|
|
250
|
+
selector,
|
|
251
|
+
expected,
|
|
252
|
+
};
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
// Assert Input Value
|
|
256
|
+
{
|
|
257
|
+
type: 'web_assert_value',
|
|
258
|
+
category: 'Web',
|
|
259
|
+
color: '#FF9800',
|
|
260
|
+
tooltip: 'Assert that an input field has a specific value (auto-waits)',
|
|
261
|
+
inputs: [
|
|
262
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
263
|
+
{ name: 'VALUE', type: 'field', fieldType: 'text', required: true },
|
|
264
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
265
|
+
],
|
|
266
|
+
previousStatement: true,
|
|
267
|
+
nextStatement: true,
|
|
268
|
+
execute: async (params, context) => {
|
|
269
|
+
const page = context.page;
|
|
270
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
271
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
272
|
+
const expectedValue = (0, utils_1.resolveVariables)(params.VALUE, context);
|
|
273
|
+
const timeout = params.TIMEOUT;
|
|
274
|
+
const expect = await (0, utils_1.getExpect)();
|
|
275
|
+
const locator = page.locator(selector);
|
|
276
|
+
context.logger.info(`Asserting ${displaySelector} has value "${expectedValue}"`);
|
|
277
|
+
await (0, utils_1.executeWebAssertion)(context, async () => {
|
|
278
|
+
await expect(locator).toHaveValue(expectedValue, { timeout });
|
|
279
|
+
}, `Expected input ${displaySelector} to have value "${expectedValue}"`, { stepType: 'web_assert_value', expected: expectedValue });
|
|
280
|
+
context.logger.info(`✓ Input ${displaySelector} has value "${expectedValue}"`);
|
|
281
|
+
return {
|
|
282
|
+
_summary: `${displaySelector} = "${expectedValue}"`,
|
|
283
|
+
selector,
|
|
284
|
+
expected: expectedValue,
|
|
285
|
+
};
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
// Assert Input Value Contains
|
|
289
|
+
{
|
|
290
|
+
type: 'web_assert_value_contains',
|
|
291
|
+
category: 'Web',
|
|
292
|
+
color: '#FF9800',
|
|
293
|
+
tooltip: 'Assert that an input field value contains specific text (auto-waits)',
|
|
294
|
+
inputs: [
|
|
295
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
296
|
+
{ name: 'VALUE', type: 'field', fieldType: 'text', required: true },
|
|
297
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
298
|
+
],
|
|
299
|
+
previousStatement: true,
|
|
300
|
+
nextStatement: true,
|
|
301
|
+
execute: async (params, context) => {
|
|
302
|
+
const page = context.page;
|
|
303
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
304
|
+
const displaySelector = (0, utils_1.getDisplaySelector)(params, context);
|
|
305
|
+
const expectedValue = (0, utils_1.resolveVariables)(params.VALUE, context);
|
|
306
|
+
const timeout = params.TIMEOUT;
|
|
307
|
+
const expect = await (0, utils_1.getExpect)();
|
|
308
|
+
const locator = page.locator(selector);
|
|
309
|
+
context.logger.info(`Asserting ${displaySelector} value contains "${expectedValue}"`);
|
|
310
|
+
await (0, utils_1.executeWebAssertion)(context, async () => {
|
|
311
|
+
await expect(locator).toHaveValue(new RegExp(expectedValue), { timeout });
|
|
312
|
+
}, `Expected input ${displaySelector} value to contain "${expectedValue}"`, { stepType: 'web_assert_value_contains', expected: expectedValue });
|
|
313
|
+
context.logger.info(`✓ Input ${displaySelector} value contains "${expectedValue}"`);
|
|
314
|
+
return {
|
|
315
|
+
_summary: `${displaySelector} contains "${expectedValue}"`,
|
|
316
|
+
selector,
|
|
317
|
+
expected: expectedValue,
|
|
318
|
+
};
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright blocks - modular organization
|
|
3
|
+
*
|
|
4
|
+
* Blocks are organized into categories:
|
|
5
|
+
* - navigation: Navigate, wait, screenshot
|
|
6
|
+
* - interactions: Click, fill, type, select, checkbox, hover
|
|
7
|
+
* - retrieval: Get text, attributes, values, title, URL
|
|
8
|
+
* - assertions: Visibility, text, value, URL, title assertions
|
|
9
|
+
*/
|
|
10
|
+
import { BlockDefinition } from '../../types';
|
|
11
|
+
export * from './types';
|
|
12
|
+
export * from './utils';
|
|
13
|
+
export { navigationBlocks } from './navigation';
|
|
14
|
+
export { interactionBlocks } from './interactions';
|
|
15
|
+
export { retrievalBlocks } from './retrieval';
|
|
16
|
+
export { assertionBlocks } from './assertions';
|
|
17
|
+
export declare const playwrightBlocks: BlockDefinition[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Playwright blocks - modular organization
|
|
4
|
+
*
|
|
5
|
+
* Blocks are organized into categories:
|
|
6
|
+
* - navigation: Navigate, wait, screenshot
|
|
7
|
+
* - interactions: Click, fill, type, select, checkbox, hover
|
|
8
|
+
* - retrieval: Get text, attributes, values, title, URL
|
|
9
|
+
* - assertions: Visibility, text, value, URL, title assertions
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
23
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.playwrightBlocks = exports.assertionBlocks = exports.retrievalBlocks = exports.interactionBlocks = exports.navigationBlocks = void 0;
|
|
27
|
+
const navigation_1 = require("./navigation");
|
|
28
|
+
const interactions_1 = require("./interactions");
|
|
29
|
+
const retrieval_1 = require("./retrieval");
|
|
30
|
+
const assertions_1 = require("./assertions");
|
|
31
|
+
// Re-export types and utilities for external use
|
|
32
|
+
__exportStar(require("./types"), exports);
|
|
33
|
+
__exportStar(require("./utils"), exports);
|
|
34
|
+
// Re-export individual block categories
|
|
35
|
+
var navigation_2 = require("./navigation");
|
|
36
|
+
Object.defineProperty(exports, "navigationBlocks", { enumerable: true, get: function () { return navigation_2.navigationBlocks; } });
|
|
37
|
+
var interactions_2 = require("./interactions");
|
|
38
|
+
Object.defineProperty(exports, "interactionBlocks", { enumerable: true, get: function () { return interactions_2.interactionBlocks; } });
|
|
39
|
+
var retrieval_2 = require("./retrieval");
|
|
40
|
+
Object.defineProperty(exports, "retrievalBlocks", { enumerable: true, get: function () { return retrieval_2.retrievalBlocks; } });
|
|
41
|
+
var assertions_2 = require("./assertions");
|
|
42
|
+
Object.defineProperty(exports, "assertionBlocks", { enumerable: true, get: function () { return assertions_2.assertionBlocks; } });
|
|
43
|
+
// Combined export of all Playwright blocks
|
|
44
|
+
exports.playwrightBlocks = [
|
|
45
|
+
...navigation_1.navigationBlocks,
|
|
46
|
+
...interactions_1.interactionBlocks,
|
|
47
|
+
...retrieval_1.retrievalBlocks,
|
|
48
|
+
...assertions_1.assertionBlocks,
|
|
49
|
+
];
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interactionBlocks = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
/**
|
|
6
|
+
* User interaction blocks for Playwright (click, type, fill, etc.)
|
|
7
|
+
*/
|
|
8
|
+
exports.interactionBlocks = [
|
|
9
|
+
// Click Element
|
|
10
|
+
{
|
|
11
|
+
type: 'web_click',
|
|
12
|
+
category: 'Web',
|
|
13
|
+
color: '#E91E63',
|
|
14
|
+
tooltip: 'Click on an element',
|
|
15
|
+
inputs: [
|
|
16
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
17
|
+
{ name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
|
|
18
|
+
],
|
|
19
|
+
previousStatement: true,
|
|
20
|
+
nextStatement: true,
|
|
21
|
+
execute: async (params, context) => {
|
|
22
|
+
const page = context.page;
|
|
23
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
24
|
+
const timeout = params.TIMEOUT;
|
|
25
|
+
context.logger.info(`Clicking: ${selector}`);
|
|
26
|
+
await page.click(selector, { timeout });
|
|
27
|
+
return {
|
|
28
|
+
_summary: params.SELECTOR,
|
|
29
|
+
selector,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
// Fill Input
|
|
34
|
+
{
|
|
35
|
+
type: 'web_fill',
|
|
36
|
+
category: 'Web',
|
|
37
|
+
color: '#E91E63',
|
|
38
|
+
tooltip: 'Fill an input field (clears existing value)',
|
|
39
|
+
inputs: [
|
|
40
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
41
|
+
{ name: 'VALUE', type: 'field', fieldType: 'text', required: true },
|
|
42
|
+
],
|
|
43
|
+
previousStatement: true,
|
|
44
|
+
nextStatement: true,
|
|
45
|
+
execute: async (params, context) => {
|
|
46
|
+
const page = context.page;
|
|
47
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
48
|
+
const rawValue = params.VALUE;
|
|
49
|
+
const value = (0, utils_1.resolveVariables)(rawValue, context);
|
|
50
|
+
context.logger.info(`Filling ${selector} with "${value}"`);
|
|
51
|
+
await page.fill(selector, value);
|
|
52
|
+
const displayValue = value.length > 30 ? value.substring(0, 30) + '...' : value;
|
|
53
|
+
return {
|
|
54
|
+
_summary: `${params.SELECTOR} = "${displayValue}"`,
|
|
55
|
+
selector,
|
|
56
|
+
value,
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
// Type Text
|
|
61
|
+
{
|
|
62
|
+
type: 'web_type',
|
|
63
|
+
category: 'Web',
|
|
64
|
+
color: '#E91E63',
|
|
65
|
+
tooltip: 'Type text character by character',
|
|
66
|
+
inputs: [
|
|
67
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
68
|
+
{ name: 'TEXT', type: 'field', fieldType: 'text', required: true },
|
|
69
|
+
{ name: 'DELAY', type: 'field', fieldType: 'number', default: 50 },
|
|
70
|
+
],
|
|
71
|
+
previousStatement: true,
|
|
72
|
+
nextStatement: true,
|
|
73
|
+
execute: async (params, context) => {
|
|
74
|
+
const page = context.page;
|
|
75
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
76
|
+
const text = (0, utils_1.resolveVariables)(params.TEXT, context);
|
|
77
|
+
const delay = params.DELAY;
|
|
78
|
+
context.logger.info(`Typing "${text}" into ${selector}`);
|
|
79
|
+
await page.type(selector, text, { delay });
|
|
80
|
+
const displayText = text.length > 30 ? text.substring(0, 30) + '...' : text;
|
|
81
|
+
return {
|
|
82
|
+
_summary: `${params.SELECTOR} = "${displayText}"`,
|
|
83
|
+
selector,
|
|
84
|
+
text,
|
|
85
|
+
delay,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
// Press Key
|
|
90
|
+
{
|
|
91
|
+
type: 'web_press_key',
|
|
92
|
+
category: 'Web',
|
|
93
|
+
color: '#E91E63',
|
|
94
|
+
tooltip: 'Press a keyboard key',
|
|
95
|
+
inputs: [
|
|
96
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
97
|
+
{ name: 'KEY', type: 'field', fieldType: 'dropdown', options: [['Enter', 'Enter'], ['Tab', 'Tab'], ['Escape', 'Escape'], ['Backspace', 'Backspace'], ['ArrowUp', 'ArrowUp'], ['ArrowDown', 'ArrowDown'], ['ArrowLeft', 'ArrowLeft'], ['ArrowRight', 'ArrowRight']] },
|
|
98
|
+
],
|
|
99
|
+
previousStatement: true,
|
|
100
|
+
nextStatement: true,
|
|
101
|
+
execute: async (params, context) => {
|
|
102
|
+
const page = context.page;
|
|
103
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
104
|
+
const key = params.KEY;
|
|
105
|
+
context.logger.info(`Pressing ${key} on ${selector}`);
|
|
106
|
+
await page.press(selector, key);
|
|
107
|
+
return {
|
|
108
|
+
_summary: `${key} on ${params.SELECTOR}`,
|
|
109
|
+
selector,
|
|
110
|
+
key,
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
// Select Option
|
|
115
|
+
{
|
|
116
|
+
type: 'web_select',
|
|
117
|
+
category: 'Web',
|
|
118
|
+
color: '#E91E63',
|
|
119
|
+
tooltip: 'Select an option from a dropdown',
|
|
120
|
+
inputs: [
|
|
121
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
122
|
+
{ name: 'VALUE', type: 'field', fieldType: 'text', required: true },
|
|
123
|
+
],
|
|
124
|
+
previousStatement: true,
|
|
125
|
+
nextStatement: true,
|
|
126
|
+
execute: async (params, context) => {
|
|
127
|
+
const page = context.page;
|
|
128
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
129
|
+
const value = (0, utils_1.resolveVariables)(params.VALUE, context);
|
|
130
|
+
context.logger.info(`Selecting "${value}" in ${selector}`);
|
|
131
|
+
await page.selectOption(selector, value);
|
|
132
|
+
return {
|
|
133
|
+
_summary: `${params.SELECTOR} = "${value}"`,
|
|
134
|
+
selector,
|
|
135
|
+
value,
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
// Check/Uncheck Checkbox
|
|
140
|
+
{
|
|
141
|
+
type: 'web_checkbox',
|
|
142
|
+
category: 'Web',
|
|
143
|
+
color: '#E91E63',
|
|
144
|
+
tooltip: 'Check or uncheck a checkbox',
|
|
145
|
+
inputs: [
|
|
146
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
147
|
+
{ name: 'ACTION', type: 'field', fieldType: 'dropdown', options: [['Check', 'check'], ['Uncheck', 'uncheck']] },
|
|
148
|
+
],
|
|
149
|
+
previousStatement: true,
|
|
150
|
+
nextStatement: true,
|
|
151
|
+
execute: async (params, context) => {
|
|
152
|
+
const page = context.page;
|
|
153
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
154
|
+
const action = params.ACTION;
|
|
155
|
+
context.logger.info(`${action === 'check' ? 'Checking' : 'Unchecking'} ${selector}`);
|
|
156
|
+
if (action === 'check') {
|
|
157
|
+
await page.check(selector);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
await page.uncheck(selector);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
_summary: `${action} ${params.SELECTOR}`,
|
|
164
|
+
selector,
|
|
165
|
+
action,
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
// Hover
|
|
170
|
+
{
|
|
171
|
+
type: 'web_hover',
|
|
172
|
+
category: 'Web',
|
|
173
|
+
color: '#E91E63',
|
|
174
|
+
tooltip: 'Hover over an element',
|
|
175
|
+
inputs: [
|
|
176
|
+
{ name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
|
|
177
|
+
],
|
|
178
|
+
previousStatement: true,
|
|
179
|
+
nextStatement: true,
|
|
180
|
+
execute: async (params, context) => {
|
|
181
|
+
const page = context.page;
|
|
182
|
+
const selector = (0, utils_1.resolveSelector)(params, context);
|
|
183
|
+
context.logger.info(`Hovering over ${selector}`);
|
|
184
|
+
await page.hover(selector);
|
|
185
|
+
return {
|
|
186
|
+
_summary: params.SELECTOR,
|
|
187
|
+
selector,
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
];
|