@testsmith/testblocks 0.9.0 → 0.9.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.
@@ -16,7 +16,7 @@
16
16
  overflow: hidden;
17
17
  }
18
18
  </style>
19
- <script type="module" crossorigin src="/assets/index-Ivy7T1Qk.js"></script>
19
+ <script type="module" crossorigin src="/assets/index-BCKY2YTp.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 (auto-waits for element)',
14
+ tooltip: 'Click on an element (auto-waits for element to be visible and stable)',
15
15
  inputs: [
16
16
  { name: 'SELECTOR', type: 'field', fieldType: 'text', required: true },
17
17
  { name: 'TIMEOUT', type: 'field', fieldType: 'number', default: 30000 },
@@ -24,6 +24,11 @@ exports.interactionBlocks = [
24
24
  const timeout = params.TIMEOUT;
25
25
  context.logger.info(`Clicking: ${selector}`);
26
26
  const locator = page.locator(selector);
27
+ // Wait for element to be visible and stable before clicking
28
+ await locator.waitFor({ state: 'visible', timeout });
29
+ // Scroll into view to ensure element is in viewport
30
+ await locator.scrollIntoViewIfNeeded({ timeout });
31
+ // Click with retry on intercept (handles overlays/animations)
27
32
  await locator.click({ timeout });
28
33
  return {
29
34
  _summary: params.SELECTOR,
@@ -4,6 +4,7 @@
4
4
  export interface PlaywrightLocator {
5
5
  click(options?: {
6
6
  timeout?: number;
7
+ force?: boolean;
7
8
  }): Promise<void>;
8
9
  fill(value: string, options?: {
9
10
  timeout?: number;
@@ -51,6 +52,9 @@ export interface PlaywrightLocator {
51
52
  state?: 'attached' | 'detached' | 'visible' | 'hidden';
52
53
  timeout?: number;
53
54
  }): Promise<void>;
55
+ scrollIntoViewIfNeeded(options?: {
56
+ timeout?: number;
57
+ }): Promise<void>;
54
58
  }
55
59
  export interface PlaywrightPage {
56
60
  goto(url: string, options?: {
@@ -197,6 +197,30 @@ class TestExecutor {
197
197
  testIdAttribute: this.options.testIdAttribute,
198
198
  procedures: mergedProcedures,
199
199
  };
200
+ // Check if there are any enabled tests
201
+ const enabledTests = testFile.tests.filter(t => !t.disabled);
202
+ const hasEnabledTests = enabledTests.length > 0;
203
+ // Add skipped results for disabled tests first
204
+ for (const test of testFile.tests) {
205
+ if (test.disabled) {
206
+ results.push({
207
+ testId: test.id,
208
+ testName: test.name,
209
+ status: 'skipped',
210
+ duration: 0,
211
+ steps: [],
212
+ error: { message: 'Test is disabled' },
213
+ startedAt: new Date().toISOString(),
214
+ finishedAt: new Date().toISOString(),
215
+ });
216
+ }
217
+ }
218
+ // Only run hooks and tests if there are enabled tests
219
+ if (!hasEnabledTests) {
220
+ sharedContext.logger.info('All tests disabled, skipping hooks');
221
+ await this.cleanup();
222
+ return results;
223
+ }
200
224
  let beforeAllFailed = false;
201
225
  try {
202
226
  // Run beforeAll hooks
@@ -211,22 +235,8 @@ class TestExecutor {
211
235
  }
212
236
  // Only run tests if beforeAll succeeded
213
237
  if (!beforeAllFailed) {
214
- // Run each test with beforeEach/afterEach
215
- for (const test of testFile.tests) {
216
- // Skip disabled tests
217
- if (test.disabled) {
218
- results.push({
219
- testId: test.id,
220
- testName: test.name,
221
- status: 'skipped',
222
- duration: 0,
223
- steps: [],
224
- error: { message: 'Test is disabled' },
225
- startedAt: new Date().toISOString(),
226
- finishedAt: new Date().toISOString(),
227
- });
228
- continue;
229
- }
238
+ // Run each enabled test with beforeEach/afterEach
239
+ for (const test of enabledTests) {
230
240
  // Load data from file if specified
231
241
  let testData = test.data;
232
242
  if (test.dataFile && !testData) {
@@ -720,7 +730,7 @@ class TestExecutor {
720
730
  if (status === 'failed' && isWebStep && context.page) {
721
731
  try {
722
732
  const page = context.page;
723
- const screenshotBuffer = await page.screenshot({ fullPage: false });
733
+ const screenshotBuffer = await page.screenshot({ fullPage: true });
724
734
  screenshot = `data:image/png;base64,${screenshotBuffer.toString('base64')}`;
725
735
  }
726
736
  catch (screenshotErr) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testsmith/testblocks",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Visual test automation tool with Blockly - API and Playwright testing",
5
5
  "author": "Roy de Kleijn",
6
6
  "license": "MIT",