artes 1.0.40 → 1.0.42

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.
@@ -71,13 +71,20 @@ module.exports = {
71
71
  worldParameters: artesConfig.worldParameters || {}, // Custom world parameters
72
72
  },
73
73
 
74
+ api: {
75
+ baseURL: artesConfig?.baseURL ? artesConfig?.baseURL : "",
76
+ },
77
+
74
78
  browser: {
75
79
  browserType: artesConfig?.browser || "chrome",
76
80
  viewport: {
77
81
  width: artesConfig?.width || 1280,
78
82
  height: artesConfig?.height || 720,
79
83
  },
80
- maximizeScreen: artesConfig?.maximizeScreen !== undefined ? artesConfig.maximizeScreen : true,
84
+ maximizeScreen:
85
+ artesConfig?.maximizeScreen !== undefined
86
+ ? artesConfig.maximizeScreen
87
+ : true,
81
88
  headless: artesConfig?.headless !== undefined ? artesConfig.headless : true,
82
89
  },
83
90
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "description": "The package provide step definitions and user writes feature files, and the package handles automation, with optional POM files and custom step definitions.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -35,6 +35,7 @@
35
35
  "allure-cucumberjs": "^3.0.5",
36
36
  "allure-js-commons": "^3.0.5",
37
37
  "playwright": "^1.48.2",
38
+ "ajv": "^8.17.1",
38
39
  "rimraf": "^6.0.1"
39
40
  },
40
41
  "repository": {
@@ -20,6 +20,7 @@ const invokeBrowser = async () => {
20
20
  dir: "./test-results/visualReport/",
21
21
  size: cucumberConfig.browser.viewport,
22
22
  },
23
+ ignoreHTTPSErrors: true,
23
24
  };
24
25
 
25
26
  switch (browserType) {
@@ -1,10 +1,13 @@
1
1
  const { request } = require("playwright");
2
+ const cucumberConfig = require("../../../cucumber.config.js");
2
3
 
3
- const requestContextOptions = {};
4
+ const requestContextOptions = {
5
+ baseURL: cucumberConfig.api.baseURL,
6
+ };
4
7
 
5
8
  async function invokeRequest() {
6
9
  const context = await request.newContext(requestContextOptions);
7
- return await context;
10
+ return context;
8
11
  }
9
12
 
10
13
  module.exports = { invokeRequest };
@@ -39,6 +39,7 @@ function createProject(createYes) {
39
39
  headless: false, // Set to true for headless browser mode
40
40
 
41
41
  // Configuration options:
42
+ // baseURL: "", // string - Base URL for API tests
42
43
  // paths: [], // string[] - Paths to feature files
43
44
  // steps: "", // string - Step definitions files
44
45
  // pomPath: "", // string - Path to POM files
@@ -2,22 +2,100 @@ const { context } = require("../imports/commons");
2
2
 
3
3
  const api = {
4
4
  get: async (url) => {
5
- return await context.request.get(url);
5
+ const res = await context.request.get(url);
6
+ const header = await res.headers();
7
+ const body = await res.json();
8
+
9
+ const response = {
10
+ url: res.url(),
11
+ response: res,
12
+ responseHeaders: header,
13
+ responseBody: body,
14
+ };
15
+
16
+ context.response = response;
6
17
  },
7
18
  head: async (url) => {
8
- return await context.request.head(url);
19
+ const res = await context.request.head(url);
20
+ const header = await res.headers();
21
+
22
+ const response = {
23
+ url: res.url(),
24
+ response: res,
25
+ responseHeaders: header,
26
+ responseBody: body,
27
+ };
28
+
29
+ context.response = response;
9
30
  },
10
- post: async (url) => {
11
- return await context.request.post(url);
31
+ post: async (url, reqHeader, reqBody) => {
32
+ const res = await context.request.post(url, {
33
+ headers: reqHeader,
34
+ body: reqBody,
35
+ });
36
+ const header = await res.headers();
37
+ const body = await res.json();
38
+
39
+ const response = {
40
+ url: res.url(),
41
+ requestHeaders: reqHeader,
42
+ requestBody: reqBody,
43
+ response: res,
44
+ responseHeaders: header,
45
+ responseBody: body,
46
+ };
47
+
48
+ context.response = response;
12
49
  },
13
- put: async (url) => {
14
- return await context.request.put(url);
50
+ put: async (url, reqHeader, reqBody) => {
51
+ const res = await context.request.put(url, {
52
+ body: JSON.stringify(reqBody),
53
+ });
54
+ const header = await res.headers();
55
+ const body = await res.json();
56
+
57
+ const response = {
58
+ url: res.url(),
59
+ requestHeaders: reqHeader,
60
+ requestBody: reqBody,
61
+ response: res,
62
+ responseHeaders: header,
63
+ responseBody: body,
64
+ };
65
+
66
+ context.response = response;
15
67
  },
16
- patch: async (url) => {
17
- return await context.request.patch(url);
68
+ patch: async (url, reqHeader, reqBody) => {
69
+ const res = await context.request.patch(url, {
70
+ body: JSON.stringify(reqBody),
71
+ });
72
+ const header = await res.headers();
73
+ const body = await res.json();
74
+
75
+ const response = {
76
+ url: res.url(),
77
+ requestHeaders: reqHeader,
78
+ requestBody: reqBody,
79
+ response: res,
80
+ responseHeaders: header,
81
+ responseBody: body,
82
+ };
83
+
84
+ context.response = response;
18
85
  },
19
86
  delete: async (url) => {
20
- return await context.request.head(url);
87
+ const res = await context.request.delete(url);
88
+ const header = await res.headers();
89
+ const body = await res.json();
90
+
91
+ const response = {
92
+ url: res.url(),
93
+ response: res,
94
+ responseHeaders: header,
95
+ responseBody: body,
96
+ };
97
+
98
+ context.response = response;
21
99
  },
22
100
  };
23
101
 
@@ -1,5 +1,10 @@
1
- const path = require('path');
2
- const { element, context, selector, moduleConfig } = require("../imports/commons");
1
+ const path = require("path");
2
+ const {
3
+ element,
4
+ context,
5
+ selector,
6
+ moduleConfig,
7
+ } = require("../imports/commons");
3
8
  const { frame } = require("../stepFunctions/frameActions");
4
9
 
5
10
  const mouse = {
@@ -127,7 +132,7 @@ const mouse = {
127
132
  await element(selector).scrollIntoViewIfNeeded();
128
133
  },
129
134
  upload: async (filePath, fileInput) => {
130
- const file = selector(filePath)
135
+ const file = selector(filePath);
131
136
  const fileChooserPromise = context.page.waitForEvent("filechooser");
132
137
  await element(fileInput).click();
133
138
  const fileChooser = await fileChooserPromise;
@@ -3,6 +3,8 @@ class Context {
3
3
  this.browser = undefined;
4
4
  this.page = undefined;
5
5
  this.request = undefined;
6
+ this.response = undefined;
7
+ this.vars = {};
6
8
  }
7
9
  }
8
10
 
@@ -30,6 +30,7 @@ Before(async function () {
30
30
  context.browser = await browser;
31
31
  context.page = await browser.newPage();
32
32
  await context.page.setDefaultTimeout(cucumberConfig.default.timeout * 1000);
33
+
33
34
  context.request = await request;
34
35
 
35
36
  await browser.tracing.start({
@@ -53,8 +54,17 @@ After(async function ({ pickle, result }) {
53
54
  await browser.tracing.stop({
54
55
  path: path.join(moduleConfig.projectPath, "./trace.zip"),
55
56
  });
57
+
58
+ if (context.response) {
59
+ await this.attach(
60
+ `Request Payload:\n${JSON.stringify(context.response, null, 2)}`,
61
+ "text/plain",
62
+ );
63
+ }
64
+
56
65
  await context.page.close();
57
66
  await browser.close();
67
+ await context.request.dispose();
58
68
 
59
69
  if (result?.status != Status.PASSED) {
60
70
  const videoPath = await context.page.video().path();
@@ -1,26 +1,114 @@
1
- const { When, context } = require("../helper/imports/commons");
2
- const { api, assert } = require("../helper/stepFunctions/exporter");
1
+ const {
2
+ When,
3
+ context,
4
+ expect,
5
+ selector,
6
+ } = require("../helper/imports/commons");
7
+ const { api } = require("../helper/stepFunctions/exporter");
8
+ const Ajv = require("ajv");
3
9
 
4
10
  When("User sends GET request to {string}", async function (url) {
5
11
  await api.get(url);
6
12
  });
7
13
 
14
+ When(
15
+ "User sends GET request to {string} and saves {string} variables",
16
+ async function (url, vars) {
17
+ await api.get(url);
18
+ vars = vars.split(",").map((v) => v.trim());
19
+ console.log(vars);
20
+ },
21
+ );
22
+
8
23
  When("User sends HEAD request to {string}", async function (url) {
9
- await api.get(url);
24
+ await api.head(url);
10
25
  });
11
26
 
12
- When("User sends POST request to {string}", async function (url) {
13
- await api.get(url);
14
- });
27
+ When(
28
+ "User sends POST request to {string} with payload:",
29
+ async function (url, reqParams) {
30
+ const payload = JSON.parse(reqParams);
31
+ await api.post(url, payload.headers, payload.body);
32
+ },
33
+ );
15
34
 
16
- When("User sends PUT request to {string}", async function (url) {
17
- await api.get(url);
35
+ When("User sends PUT request to {string} with payload:", async function (url) {
36
+ const payload = JSON.parse(reqParams);
37
+ await api.put(url, payload.headers, payload.body);
18
38
  });
19
39
 
20
- When("User sends PATCH request to {string}", async function (url) {
21
- await api.get(url);
22
- });
40
+ When(
41
+ "User sends PATCH request to {string} with payload:",
42
+ async function (url) {
43
+ const payload = JSON.parse(reqParams);
44
+ await api.patch(url, payload.headers, payload.body);
45
+ },
46
+ );
23
47
 
24
48
  When("User sends DELETE request to {string}", async function (url) {
25
- await api.get(url);
49
+ await api.delete(url);
26
50
  });
51
+
52
+ When(
53
+ "User sends {string} request to {string}",
54
+ async function (method, url, reqParams) {
55
+ const httpMethod = method.toUpperCase();
56
+
57
+ let headers = {};
58
+ let body;
59
+
60
+ if (["POST", "PUT", "PATCH"].includes(httpMethod)) {
61
+ const payload = JSON.parse(reqParams);
62
+ headers = payload.headers || {};
63
+ body = payload.body || {};
64
+ }
65
+
66
+ switch (httpMethod) {
67
+ case "GET":
68
+ await api.get(url);
69
+ break;
70
+ case "HEAD":
71
+ await api.head(url);
72
+ break;
73
+ case "POST":
74
+ await api.post(url, headers, body);
75
+ break;
76
+ case "PUT":
77
+ await api.put(url, headers, body);
78
+ break;
79
+ case "PATCH":
80
+ await api.patch(url, headers, body);
81
+ break;
82
+ case "DELETE":
83
+ await api.delete(url);
84
+ break;
85
+ default:
86
+ throw new Error(`Unsupported HTTP method: ${httpMethod}`);
87
+ }
88
+ },
89
+ );
90
+
91
+ When(
92
+ "User expects that request should have {int} status code",
93
+ async function (expectedStatusCode) {
94
+ const actualStatusCode = await context.response.response.status();
95
+ expect(actualStatusCode).toBe(expectedStatusCode);
96
+ },
97
+ );
98
+
99
+ When(
100
+ "User expects that response body should match {string} schema",
101
+ async function (expectedSchema) {
102
+ const schema = selector(expectedSchema);
103
+
104
+ const ajv = new Ajv();
105
+
106
+ const validate = ajv.compile(schema);
107
+
108
+ const responseBody = context.response?.responseBody;
109
+
110
+ const valid = validate(responseBody);
111
+
112
+ expect(valid).toBe(true);
113
+ },
114
+ );