artes 1.1.50 → 1.2.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 CHANGED
@@ -266,7 +266,7 @@ For a detailed explanation of each function, please refer to the [function defin
266
266
 
267
267
  ---
268
268
 
269
- ### Example of a Custom Step Definition
269
+ ### Example of Custom Step Definition
270
270
 
271
271
  ```javascript
272
272
  const { Given, When, Then, expect, element, page } = require("artes");
@@ -284,6 +284,85 @@ Then("User should see the login form", async () => {
284
284
  });
285
285
  ```
286
286
 
287
+ ## 🪝 Hooks (Lifecycle Hooks)
288
+
289
+ Artes supports **hooks** that allow you to execute custom logic **before and after tests, scenarios, and steps**.
290
+
291
+ Hooks are **user-defined**.
292
+
293
+ ---
294
+
295
+ ### 📁 Hooks File Location
296
+
297
+ Create the following file **inside your project** (optional):
298
+ ```
299
+ tests/steps/hooks.js
300
+ ```
301
+
302
+ ---
303
+
304
+ ### ✍️ Writing Hooks
305
+
306
+ You can define **only the hooks you need** in hooks.js under the steps folder.
307
+ Undefined hooks are automatically skipped.
308
+ ```js
309
+ // tests/steps/hooks.js
310
+
311
+ export function BeforeStep() {
312
+ console.log("BeforeStep");
313
+ }
314
+
315
+ export function Before() {
316
+ console.log("Before");
317
+ }
318
+
319
+ export function BeforeAll() {
320
+ console.log("BeforeAll");
321
+ }
322
+
323
+ export function AfterStep() {
324
+ console.log("AfterStep");
325
+ }
326
+
327
+ export function After() {
328
+ console.log("After");
329
+ }
330
+
331
+ export function AfterAll() {
332
+ console.log("AfterAll");
333
+ }
334
+ ```
335
+
336
+ ---
337
+
338
+ ### 🔁 Supported Hook Types
339
+
340
+ | Hook Name | Execution Time |
341
+ | ------------ | ----------------------------- |
342
+ | `BeforeAll` | Once before **all scenarios** |
343
+ | `Before` | Before **each scenario** |
344
+ | `BeforeStep` | Before **each step** |
345
+ | `AfterStep` | After **each step** |
346
+ | `After` | After **each scenario** |
347
+ | `AfterAll` | Once after **all scenarios** |
348
+
349
+ ---
350
+
351
+ ### ▶️ Execution Order Example
352
+
353
+ For a scenario with steps:
354
+ ```
355
+ BeforeAll
356
+ Before
357
+ BeforeStep
358
+ (step executes)
359
+ AfterStep
360
+ After
361
+ AfterAll
362
+ ```
363
+
364
+ ---
365
+
287
366
  ## ⚙️ Configuration
288
367
 
289
368
  You can configure Artes by editing the `artes.config.js` file. Below are the default configuration options with explanations:
@@ -418,12 +497,6 @@ To achieve the best video recording quality, use the following command:
418
497
  xvfb-run -a --server-args="-screen 0 3840x1180x24" --auto-servernum npx artes --width 1600 --height 900
419
498
  ```
420
499
 
421
- ### Playwright Version
422
-
423
- The Docker image uses Playwright version `1.52.0`.
424
-
425
- This setup ensures smooth execution of tests CI/CD environments.
426
-
427
500
  ---
428
501
 
429
502
  ## 👍 Good To Use
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.1.50",
3
+ "version": "1.2.0",
4
4
  "description": "The simplest way to automate UI and API tests using Cucumber-style steps.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -123,6 +123,32 @@ const {Given,context} = require("artes");
123
123
  Given("User is on home page of SauceDemo", async () => {
124
124
  await context.page.goto("https://www.saucedemo.com/");
125
125
  });
126
+ `;
127
+
128
+ const hooksContent = `
129
+ export function BeforeStep() {
130
+ console.log("BeforeStep")
131
+ }
132
+
133
+ export function Before() {
134
+ console.log("Before")
135
+ }
136
+
137
+ export function BeforeAll() {
138
+ console.log("BeforeAll")
139
+ }
140
+
141
+ export function AfterStep() {
142
+ console.log("AfterStep")
143
+ }
144
+
145
+ export function After() {
146
+ console.log("After")
147
+ }
148
+
149
+ export function AfterAll() {
150
+ console.log("AfterAll")
151
+ }
126
152
  `;
127
153
 
128
154
  const vsCodeExtension = JSON.stringify({
@@ -148,6 +174,7 @@ await context.page.goto("https://www.saucedemo.com/");
148
174
  );
149
175
  fs.writeFileSync(path.join(srcDir, "POMs", "example.pom.json"), pomContent);
150
176
  fs.writeFileSync(path.join(srcDir, "steps", "common.steps.js"), stepsContent);
177
+ fs.writeFileSync(path.join(srcDir, "steps", "common.steps.js"), hooksContent);
151
178
 
152
179
  fs.writeFileSync(
153
180
  path.join(projectDir, ".vscode", "settings.json"),
@@ -31,6 +31,11 @@ function getMimeType(filePath) {
31
31
  function processForm(requestBody) {
32
32
  let formData = {};
33
33
  for (const [key, value] of Object.entries(requestBody)) {
34
+
35
+ if (value === null || value === undefined) {
36
+ continue;
37
+ }
38
+
34
39
  if (typeof value === "object") {
35
40
  if (value.contentType) {
36
41
  const content =
@@ -46,10 +46,27 @@ function saveTestStatus(result, pickle) {
46
46
  );
47
47
  }
48
48
 
49
+
50
+ const projectHooksPath = path.resolve(moduleConfig.projectPath, "tests/steps/hooks.js");
51
+
52
+ let projectHooks = {};
53
+
54
+ if (fs.existsSync(projectHooksPath)) {
55
+ try {
56
+ projectHooks = require(projectHooksPath);
57
+ } catch (err) {
58
+ console.warn("⚠️ Failed to load project hooks.js:", err.message);
59
+ }
60
+ } else {
61
+ projectHooks = {};
62
+ }
63
+
49
64
  /* ------------------- Hooks ------------------- */
50
65
 
51
66
  BeforeAll(() => {
52
67
  pomCollector();
68
+
69
+ projectHooks.BeforeAll()
53
70
  });
54
71
 
55
72
  Before(async function () {
@@ -92,18 +109,24 @@ Before(async function () {
92
109
  snapshots: true,
93
110
  });
94
111
  }
112
+
113
+ projectHooks.Before()
95
114
  });
96
115
 
97
116
  BeforeStep(({ pickleStep }) => {
98
117
  if (HTTP_METHODS.some((method) => pickleStep.text.includes(method))) {
99
118
  context.response = {};
100
119
  }
120
+
121
+ projectHooks.BeforeStep()
101
122
  });
102
123
 
103
124
  AfterStep(async function ({ pickleStep }) {
104
125
  if (HTTP_METHODS.some((method) => pickleStep.text.includes(method))) {
105
126
  await attachResponse(this.attach);
106
127
  }
128
+
129
+ projectHooks.AfterStep()
107
130
  });
108
131
 
109
132
  After(async function ({ pickle, result }) {
@@ -187,6 +210,8 @@ After(async function ({ pickle, result }) {
187
210
  }
188
211
  }
189
212
  }
213
+
214
+ projectHooks.After()
190
215
  });
191
216
 
192
217
  AfterAll(() => {
@@ -213,4 +238,6 @@ AfterAll(() => {
213
238
  fs.writeFileSync(path.join(process.cwd(), "EXIT_CODE.txt"), "1");
214
239
  }
215
240
  }
241
+
242
+ projectHooks.AfterAll()
216
243
  });