artes 1.5.11 → 1.6.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.
package/README.md CHANGED
@@ -627,7 +627,7 @@ Artes supports environment-specific configurations through environment variables
627
627
 
628
628
  Artes can generate Allure reports. After running tests with the `-r` flag, the reports will be stored in the `report` folder in HTML format. You can view them in your browser after the tests complete.
629
629
 
630
- ## 📊 Integration with Artes Reporting System
630
+ ### Integration with Artes Reporting System
631
631
 
632
632
  Artes has a built-in integration with the Artes Reporting System. By configuring the options below, you can automatically upload your test reports and keep your pipeline stages clean and organized.
633
633
 
@@ -656,7 +656,7 @@ To achieve the best video recording quality, use the following command:
656
656
  xvfb-run -a --server-args="-screen 0 3840x1180x24" --auto-servernum npx artes --width 1600 --height 900
657
657
  ```
658
658
 
659
- ### 🔬 CI/CD Executor on Report
659
+ ### CI/CD Executor on Report
660
660
 
661
661
  Artes automatically detects your CI/CD environment and displays executor information — pipeline name, build number, and a direct link to the build — on the generated report.
662
662
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  - [Mouse Actions](#mouse-actions)
6
6
  - [Keyboard Actions](#keyboard-actions)
7
+ - [Browser Actions](#browser-actions)
7
8
  - [Page Actions](#page-actions)
8
9
  - [Frame Actions](#frame-actions)
9
10
  - [API Actions](#api-actions)
@@ -107,6 +108,30 @@
107
108
  - User releases `{string}`
108
109
  - User presses `{string}`
109
110
 
111
+ # Browser Actions
112
+
113
+ ## Cookie Actions
114
+
115
+ - User sets `{string}` cookies
116
+
117
+ ## Accessibility Actions
118
+
119
+ ### Full Page Checks
120
+ - User checks accessibility of current page
121
+ - User checks accessibility of `{string}` page
122
+
123
+ ### Element Checks
124
+ - User checks accessibility of `{string}` element
125
+ - User checks accessibility of `{string}` element on the `{string}` page
126
+
127
+ ### WCAG-Specific Checks
128
+ > For valid WCAG tags, refer to the [axe-core Tags Documentation](https://www.deque.com/axe/core-documentation/api-documentation/#axecore-tags)
129
+
130
+ - User checks accessibility of current page due to `{string}` WCAG
131
+ - User checks accessibility of `{string}` page due to `{string}` WCAG
132
+ - User checks accessibility of `{string}` element due to `{string}` WCAG
133
+ - User checks accessibility of `{string}` element on the `{string}` page due to `{string}` WCAG
134
+
110
135
  ---
111
136
 
112
137
  # Page Actions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artes",
3
- "version": "1.5.11",
3
+ "version": "1.6.1",
4
4
  "description": "The simplest way to automate UI and API tests using Cucumber-style steps.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,6 +29,7 @@
29
29
  "dayjs": "1.11.13",
30
30
  "deasync": "^0.1.31",
31
31
  "playwright": "^1.58.2",
32
+ "@axe-core/playwright": "^4.11.1",
32
33
  "ffmpeg-static": "^5.3.0",
33
34
  "ffprobe-static": "^3.1.0",
34
35
  "pixelmatch": "^5.3.0",
@@ -17,7 +17,7 @@ async function uploadReport({
17
17
  formData.append("project", projectName);
18
18
  formData.append("type", projectType);
19
19
 
20
- const response = await fetch(`${reporterURL}/api/report`, {
20
+ const response = await fetch(reporterURL, {
21
21
  method: "POST",
22
22
  body: formData,
23
23
  });
@@ -0,0 +1,52 @@
1
+ const EXACT_TAGS = new Set([
2
+ 'wcag2a', 'wcag2aa', 'wcag2aaa',
3
+ 'wcag21a', 'wcag21aa',
4
+ 'wcag22aa',
5
+ 'best-practice',
6
+ 'wcag2a-obsolete',
7
+ 'ACT',
8
+ 'section508',
9
+ 'TTv5',
10
+ 'EN-301-549',
11
+ 'RGAAv4',
12
+ 'experimental'
13
+ ]);
14
+
15
+ const PATTERN_TAGS = [
16
+ /^wcag\d{3,}$/,
17
+ /^section508\.\d+\.\d+$/,
18
+ /^TT\d+\.\d+$/,
19
+ /^EN-9\.\d+(\.\d+)*$/,
20
+ /^RGAA-\d+\.\d+\.\d+$/,
21
+ /^cat\..+$/
22
+ ];
23
+
24
+ const isValidTag = (tag) => {
25
+ if (EXACT_TAGS.has(tag)) return true;
26
+ return PATTERN_TAGS.some(pattern => pattern.test(tag));
27
+ };
28
+
29
+ const validateWCAGTags = (tags) => {
30
+ const normalized = tags.split(",").map(tag => tag.trim());
31
+
32
+ if (normalized.length === 0) {
33
+ throw new Error('At least one WCAG tag must be provided.');
34
+ }
35
+
36
+ const invalid = normalized.filter(tag => !isValidTag(tag));
37
+
38
+ if (invalid.length > 0) {
39
+ throw new Error(
40
+ `Invalid WCAG tag(s): "${invalid.join('", "')}"\n` +
41
+ `Valid tags: wcag2a, wcag2aa, wcag2aaa, wcag21a, wcag21aa, wcag22aa, ` +
42
+ `best-practice, wcag2a-obsolete, wcag111 (SC pattern), ACT, section508, ` +
43
+ `section508.x.x, TTv5, TT*.*, EN-301-549, EN-9.*, RGAAv4, RGAA-*.*.*, ` +
44
+ `experimental, cat.* `+
45
+ `For more information: https://www.deque.com/axe/core-documentation/api-documentation/#axecore-tags`
46
+ );
47
+ }
48
+
49
+ return normalized;
50
+ };
51
+
52
+ module.exports = { validateWCAGTags };
@@ -1,4 +1,16 @@
1
- const { context, selector, resolveVariable } = require("../imports/commons");
1
+ const { page: p } = require("artes/src/helper/stepFunctions/pageActions");
2
+ const {
3
+ context,
4
+ resolveVariable,
5
+ expect,
6
+ selector,
7
+ } = require("../imports/commons");
8
+ const { AxeBuilder } = require("@axe-core/playwright");
9
+ const {
10
+ validateWCAGTags,
11
+ } = require("artes/src/helper/controller/validateWCAGTags ");
12
+ require("allure-cucumberjs");
13
+ const allure = require("allure-js-commons");
2
14
 
3
15
  const browser = {
4
16
  setCookies: async (cookies) => {
@@ -15,6 +27,59 @@ const browser = {
15
27
 
16
28
  await context.browserContext.addCookies(cookieData);
17
29
  },
30
+ checkAccessibilityOfPage: async (page, url, element) => {
31
+ if (url) {
32
+ await p.navigateTo(url);
33
+ }
34
+
35
+ if (element) {
36
+ element = await selector(element);
37
+ await page.locator(element).waitFor();
38
+ }
39
+
40
+ const accessibilityScanResults = await new AxeBuilder({ page })
41
+ .include(element)
42
+ .analyze();
43
+ await allure.attachment(
44
+ "Accessibility Results",
45
+ JSON.stringify(accessibilityScanResults, null, 2),
46
+ "application/json",
47
+ );
48
+
49
+ try {
50
+ expect(accessibilityScanResults.violations).toEqual([]);
51
+ } catch (e) {
52
+ e.name = "AssertionError";
53
+ throw e;
54
+ }
55
+ },
56
+ checkAccessibilityOfPageDueToWCAG: async (page, url, element, tags) => {
57
+ if (url) {
58
+ await p.navigateTo(url);
59
+ }
60
+
61
+ if (element) {
62
+ element = await selector(element);
63
+ await page.locator(element).waitFor();
64
+ }
65
+ if (tags) {
66
+ tags = validateWCAGTags(tags);
67
+ }
68
+
69
+ expect(accessibilityScanResults.violations).toEqual([]);
70
+ await allure.attachment(
71
+ "Accessibility Results",
72
+ JSON.stringify(accessibilityScanResults, null, 2),
73
+ "application/json",
74
+ );
75
+
76
+ try {
77
+ expect(accessibilityScanResults.violations).toEqual([]);
78
+ } catch (e) {
79
+ e.name = "AssertionError";
80
+ throw e;
81
+ }
82
+ },
18
83
  };
19
84
 
20
85
  module.exports = {
@@ -1,7 +1,74 @@
1
- const { When } = require("../helper/imports/commons");
1
+ const { When, context } = require("../helper/imports/commons");
2
2
  const { browser } = require("../helper/stepFunctions/exporter");
3
3
 
4
4
  // User sets cookies in json format
5
5
  When("User sets {string} cookies", async function (cookies) {
6
6
  await browser.setCookies(cookies);
7
7
  });
8
+
9
+ When("User checks accessibility of current page", async function () {
10
+ await browser.checkAccessibilityOfPage(context.page, null, null);
11
+ });
12
+
13
+ When("User checks accessibility of {string} page", async function (url) {
14
+ await browser.checkAccessibilityOfPage(context.page, url, null);
15
+ });
16
+
17
+ When("User checks accessibility of {string} element", async function (element) {
18
+ await browser.checkAccessibilityOfPage(context.page, null, element);
19
+ });
20
+
21
+ When(
22
+ "User checks accessibility of {string} element on the {string} page",
23
+ async function (element, url) {
24
+ await browser.checkAccessibilityOfPage(context.page, url, element);
25
+ },
26
+ );
27
+
28
+ When(
29
+ "User checks accessibility of current page due to {string} WCAG",
30
+ async function (wcag) {
31
+ await browser.checkAccessibilityOfPageDueToWCAG(
32
+ context.page,
33
+ null,
34
+ null,
35
+ wcag,
36
+ );
37
+ },
38
+ );
39
+
40
+ When(
41
+ "User checks accessibility of {string} page due to {string} WCAG",
42
+ async function (url, wcag) {
43
+ await browser.checkAccessibilityOfPageDueToWCAG(
44
+ context.page,
45
+ url,
46
+ null,
47
+ wcag,
48
+ );
49
+ },
50
+ );
51
+
52
+ When(
53
+ "User checks accessibility of {string} element due to {string} WCAG",
54
+ async function (element, wcag) {
55
+ await browser.checkAccessibilityOfPageDueToWCAG(
56
+ context.page,
57
+ null,
58
+ element,
59
+ wcag,
60
+ );
61
+ },
62
+ );
63
+
64
+ When(
65
+ "User checks accessibility of {string} element on the {string} page due to {string} WCAG",
66
+ async function (element, url, wcag) {
67
+ await browser.checkAccessibilityOfPageDueToWCAG(
68
+ context.page,
69
+ url,
70
+ element,
71
+ wcag,
72
+ );
73
+ },
74
+ );