artes 1.0.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.
Files changed (32) hide show
  1. package/README.md +330 -0
  2. package/cucumber.config.js +98 -0
  3. package/executer.js +45 -0
  4. package/functionDefinitions.md +2065 -0
  5. package/index.js +33 -0
  6. package/package.json +35 -0
  7. package/src/helper/contextManager/browserManager.js +44 -0
  8. package/src/helper/contextManager/requestManager.js +10 -0
  9. package/src/helper/executers/cleaner.js +27 -0
  10. package/src/helper/executers/helper.js +32 -0
  11. package/src/helper/executers/projectCreator.js +152 -0
  12. package/src/helper/executers/reportGenerator.js +36 -0
  13. package/src/helper/executers/testRunner.js +35 -0
  14. package/src/helper/executers/versionChecker.js +13 -0
  15. package/src/helper/imports/commons.js +36 -0
  16. package/src/helper/pomController/elementController.js +24 -0
  17. package/src/helper/pomController/pomCollector.js +18 -0
  18. package/src/helper/stepFunctions/actionCommons.js +15 -0
  19. package/src/helper/stepFunctions/assertions.js +421 -0
  20. package/src/helper/stepFunctions/elementInteractions.js +38 -0
  21. package/src/helper/stepFunctions/frameActions.js +50 -0
  22. package/src/helper/stepFunctions/keyboardActions.js +29 -0
  23. package/src/helper/stepFunctions/mouseActions.js +97 -0
  24. package/src/helper/stepFunctions/pageActions.js +14 -0
  25. package/src/hooks/context.js +12 -0
  26. package/src/hooks/hooks.js +53 -0
  27. package/src/tests/stepDefinitions/assertions.steps.js +769 -0
  28. package/src/tests/stepDefinitions/frameActions.steps.js +76 -0
  29. package/src/tests/stepDefinitions/keyboardActions.steps.js +72 -0
  30. package/src/tests/stepDefinitions/mouseActions.steps.js +224 -0
  31. package/src/tests/stepDefinitions/page.steps.js +30 -0
  32. package/stepDefinitions.md +267 -0
package/README.md ADDED
@@ -0,0 +1,330 @@
1
+ <h1 align="center">Artes</h1>
2
+
3
+ ## 🚀 Summary
4
+
5
+ Artes is a test runner for Playwright that executes [predefined Cucumber tests](./stepDefinitions.md) and can generate Allure reports for test results. It simplifies the process of setting up Playwright with Cucumber in your automation workflow. With Artes, you can easily run tests without writing step definitions, generate reports, and customize your testing environment.
6
+
7
+ ## 🧑‍💻 Installation
8
+
9
+ You can install **Artes** via npm. To install it globally**(RECOMMENDED)**, run the following command:
10
+
11
+ ```bash
12
+ npm install -g artes
13
+ ```
14
+
15
+ To install it locally in your project, run:
16
+
17
+ ```bash
18
+ npm install artes
19
+ ```
20
+
21
+ Once installed, you can run **Artes** using:
22
+
23
+ ```bash
24
+ npx artes [options]
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 💡 Usage
30
+
31
+ **Artes** has following CLI options:
32
+
33
+ ```bash
34
+ npx artes [options]
35
+ ```
36
+
37
+ ### Options
38
+
39
+ | Option | Description | Usage Example |
40
+ | ------------------ | ------------------------------------------------------------- | --------------------------------------- |
41
+ | 🆘 `-h, --help` | Show the usage options | `artes -h` or `artes --help` |
42
+ | 🏷️ `-v, --version` | Show the current version of Artes | `artes -v` or `artes --version` |
43
+ | 🏗️ `-c, --create` | Create an example project with Artes | `artes -c` or `artes --create` |
44
+ | ✅ `-y, --yes` | Skip the confirmation prompt when creating an example project | `artes -c -y` or `artes --create --yes` |
45
+ | 📊 `-r, --report` | Run tests and generate Allure report | `artes -r` or `artes --report` |
46
+
47
+ \*\* To just run the tests: <br>
48
+ Globally: artes <br>
49
+ Locally: npx artes
50
+
51
+ ---
52
+
53
+ ## 🎯 Best Practices
54
+
55
+ - **Global Installation:**
56
+ For ease of use, it's recommended to install Artes globally. You can do this by running the following command:
57
+
58
+ ```bash
59
+ npm install -g artes
60
+ ```
61
+
62
+ - **Project Creation (Recommended):**
63
+ To create a new project with Artes, use the `-c` flag. This will automatically set up the folder structure and configuration for you. Run the command:
64
+
65
+ ```bash
66
+ artes -c
67
+ ```
68
+
69
+ 🗂️ Example Project Structure: <br/>
70
+ After running the `-c` flag to create a new project, the structure will look like this:
71
+
72
+ ```
73
+ /artes (Project Name)
74
+ /tests
75
+ /features
76
+ (Your feature files here)
77
+ /POMs // Optional
78
+ (POM JSON file here)
79
+ /steps // For custom steps
80
+ (Your step definition JS files here)
81
+ artes.config.js
82
+ /report
83
+ (Generated Allure report HTML here)
84
+ ```
85
+
86
+ **If you choose not to use the `-c` flag**, you can still download Artes to your testing project and use the prepared steps by running:
87
+
88
+ ```bash
89
+ npx artes
90
+ ```
91
+
92
+ You must customize the paths of features, steps, and other configurations by editing the `artes.config.js` file located inside your project folder (or create it).
93
+
94
+ For example:
95
+
96
+ ```javascript
97
+ module.exports = {
98
+ paths: ["tests/features/"], // Custom path for feature files
99
+ require: ["tests/steps/*.js"], // Custom path for step definitions files
100
+ pomPath: "tests/POMS/*.js", // Custom path for POM files
101
+ };
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 📝 Writing Feature Files and POM Files
107
+
108
+ Artes simplifies your test writing with structured feature files and organized Page Object Models (POM). Here’s how you can create them:
109
+
110
+ ### 1. 📄 Feature File Structure
111
+
112
+ ```gherkin
113
+ Feature: Searching on Google 🔍
114
+ Scenario Outline: Search for a term on Google
115
+ Given User is on "https://www.google.com/" page
116
+ When User types "alma" in "google_search_input"
117
+ And User clicks "google_search_button"
118
+ And User waits 10 seconds
119
+ Then "google_text" should have "Alma" text
120
+ ```
121
+
122
+ - **Feature**: Describes the main feature being tested (e.g., Google search).
123
+ - **Scenario Outline**: Defines a test case with steps.
124
+ - **Steps**: Use `Given`, `When`, `And`, `Then` keywords to describe actions and expectations.
125
+ - **Selectors**: The element names (e.g., `google_search_input`, `google_search_button`) map to the POM file or can be defined directly.
126
+
127
+ ### 2. 📂 POM File Example
128
+
129
+ ```json
130
+ {
131
+ "google_search_input": { "selector": "#APjFqb" },
132
+ "google_search_button": {
133
+ "selector": "input.gNO89b"
134
+ },
135
+ "google_text": {
136
+ "selector": "#rso div h3",
137
+ "waitTime": 5 //seconds
138
+ }
139
+ }
140
+ ```
141
+
142
+ - 📑 Using POM File is optional but it is **RECOMMENDED**
143
+ - 🔗 Using Selector in Feature File is possible
144
+ ```gherkin
145
+ When User types "alma" in "#APjFqb"
146
+ ```
147
+ - 🐍 It is good to use snake_case for element names
148
+ - ⏳ "waitTime" is to define custom wait for elements, but the feature currently under development
149
+ "selector" must be used if "waitTime" is used, but when using only selector is not needed mention in "selector"
150
+
151
+ ---
152
+
153
+ ## 🛠️ Customization
154
+
155
+ ## ✍️ Writing Custom Step Definitions
156
+
157
+ Artes allows you to extend its functionality by writing custom step definitions. Here's how you can do it:
158
+
159
+ ### Import Required APIs
160
+
161
+ ```javascript
162
+ const {
163
+ expect,
164
+ Given,
165
+ When,
166
+ Then,
167
+ element,
168
+ context,
169
+ keyboard,
170
+ mouse,
171
+ frame,
172
+ assert,
173
+ elementInteractions,
174
+ } = require("artes"); // Common JS
175
+ import { expect, Given, When, Then, element, context } from "artes"; // ES Modules (Do not RECOMMENDED)
176
+ ```
177
+
178
+ - **`Given`, `When`, `Then`**: These define your steps in Cucumber syntax. Example:
179
+
180
+ ```javascript
181
+ Given("User is on the login page", async () => {
182
+ await context.page.navigateTo("https://example.com/login");
183
+ });
184
+ ```
185
+
186
+ - **`page`**: Provides higher-level page actions such as navigation and waiting(Same as PlayWright). Examples:
187
+ - Navigate to a URL:
188
+ ```javascript
189
+ await context.page.navigate("https://example.com");
190
+ ```
191
+ - Wait for a selector:
192
+ ```javascript
193
+ await context.page.waitForSelector("#loadingSpinner");
194
+ ```
195
+ - **`request`**: Use for sending HTTP requests. _(Note: This feature is currently under development.)_
196
+
197
+ - **`element`**: Use for interacting with elements on the web page. Examples:
198
+ - Clicking a button:
199
+ ```javascript
200
+ await element("#submitButton").click();
201
+ ```
202
+ - Filling an input:
203
+ ```javascript
204
+ await element("#username").fill("testUser");
205
+ ```
206
+ - **`expect`**: Use for assertions in your steps. For example:
207
+ ```javascript
208
+ expect(actualValue).toBe(expectedValue);
209
+ expect(element("Page_Title")).toHaveText(expectedValue);
210
+ ```
211
+
212
+ ## 📋 Simplified Functions
213
+
214
+ If you don't want to deal with Playwright methods directly, you can simply use the following predefined actions methods by import them:
215
+
216
+ ```javascript
217
+ const { mouse, keyboard, frame, elementInteractions, page } = require("artes");
218
+ ```
219
+
220
+ - **Mouse Actions:**
221
+ `mouse.click(element)`
222
+
223
+ - **Keyboard Actions:**
224
+ `keyboard.press(key)`
225
+
226
+ - **Element Interactions:**
227
+ `elementInteractions.isChecked()`
228
+
229
+ - **Assertions:**
230
+ `assert.shouldBeTruthy(element)`
231
+
232
+ - **Frame Actions:**
233
+ `frame.first()`
234
+
235
+ ---
236
+
237
+ For a detailed explanation of each function, please refer to the [functionDefinitions.md](functionDefinitions.md).
238
+
239
+ ---
240
+
241
+ ### Example of a Custom Step Definition
242
+
243
+ ```javascript
244
+ const { Given, When, Then, expect, element, page } = require("artes");
245
+
246
+ Given("User is on the home page", async () => {
247
+ await page.navigate("https://example.com");
248
+ });
249
+
250
+ When("User clicks the login button", async () => {
251
+ await element("#loginButton").click();
252
+ });
253
+
254
+ Then("User should see the login form", async () => {
255
+ expect(element("#loginForm")).toBeVisible(true);
256
+ });
257
+ ```
258
+
259
+ ## ⚙️ Configuration
260
+
261
+ You can configure Artes by editing the `artes.config.js` file. Below are the default configuration options with explanations:
262
+
263
+ | **Option** | **Default Value** | **Description** |
264
+ | ---------------- | ---------------------------------------------------- | --------------------------------------- |
265
+ | `headless` | `true` | Run in headless browser mode. |
266
+ | `paths` | `["tests/features/"]` | Array of paths to feature files. |
267
+ | `pomPath` | `"tests/POMs/*.json"` | Path to Page Object Models. |
268
+ | `require` | `"tests/steps/*.js"` | Array of support code paths (CommonJS). |
269
+ | `parallel` | `2` | Number of parallel workers. |
270
+ | `tags` | `""` | Tag expression to filter scenarios. |
271
+ | `language` | `"en"` | Default language for feature files. |
272
+ | `order` | `"defined"` | Run order (defined or random). |
273
+ | `dryRun` | `false` | Prepare test run without execution. |
274
+ | `failFast` | `false` | Stop on first failure. |
275
+ | `forceExit` | `false` | Force `process.exit()` after tests. |
276
+ | `retry` | `0` | Retry attempts for failing tests. |
277
+ | `retryTagFilter` | `""` | Tag expression for retries. |
278
+ | `strict` | `true` | Fail on pending steps. |
279
+ | `backtrace` | `false` | Show full backtrace for errors. |
280
+ | `format` | `["rerun:@rerun.txt", "allure-cucumberjs/reporter"]` | Array of formatter names/paths. |
281
+ | `formatOptions` | `{ "resultsDir": "allure-result" }` | Formatter options. |
282
+ | `publish` | `false` | Publish results to `cucumber.io`. |
283
+
284
+ ---
285
+
286
+ ### Browser Configuration
287
+
288
+ | Option | Default Value | Description |
289
+ | ------------- | ------------------------------ | ------------------------------------------------------ |
290
+ | `browserType` | `"chrome"` | Browser type (`"chrome"`, `"firefox"`, or `"webkit"`). |
291
+ | `viewport` | `{ width: 1280, height: 720 }` | Browser viewport size. |
292
+ | `headless` | `true` | Run browser in headless mode (`true` or `false`). |
293
+
294
+ ## 📊 Report Generation
295
+
296
+ 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.
297
+
298
+ ---
299
+
300
+ ## 👍 Good To Use
301
+
302
+ If you don't use the -c or --create option that the package offers, save the file below under the `.vscode` folder:
303
+
304
+ - Those configurations will help autocomplete both predefined and custom step definitions in your features file
305
+
306
+ **extensions.json**
307
+
308
+ ```json
309
+ {
310
+ "recommendations": ["CucumberOpen.cucumber-official"]
311
+ }
312
+ ```
313
+
314
+ **settings.json**
315
+
316
+ ```json
317
+ {
318
+ "cucumber.glue": [
319
+ "tests/steps/*.{ts,js}",
320
+ "node_modules/artes/src/tests/stepDefinitions/*.{ts,js}"
321
+ ],
322
+ "cucumber.features": ["tests/features/*.features"],
323
+ "cucumberautocomplete.syncfeatures": true,
324
+ "cucumberautocomplete.strictGherkinCompletion": true
325
+ }
326
+ ```
327
+
328
+ ---
329
+
330
+ ## 🧑‍💻 Have a Good Testing
@@ -0,0 +1,98 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { moduleConfig } = require("./src/helper/imports/commons");
4
+
5
+ let argusConfig = {};
6
+
7
+ try {
8
+ if (fs.existsSync(moduleConfig.cucumberConfigPath)) {
9
+ const argusConf = require(moduleConfig.cucumberConfigPath);
10
+ argusConfig = argusConf || {};
11
+ }
12
+ } catch (error) {
13
+ console.warn("Error reading config file:", error.message);
14
+ console.log("Proceeding with default config.");
15
+ }
16
+
17
+ module.exports = {
18
+ default: {
19
+ // File paths and patterns
20
+ cucumberTimeout: argusConfig.cucumberTimeout || 10000, // Default timeout in milliseconds
21
+ paths: argusConfig.features
22
+ ? path.join(moduleConfig.projectPath, argusConfig.features)
23
+ : [moduleConfig.featuresPath], // Paths to feature files
24
+ require: [
25
+ argusConfig.steps
26
+ ? path.join(moduleConfig.projectPath, argusConfig.steps)
27
+ : moduleConfig.stepsPath,
28
+ "src/tests/stepDefinitions/*.js",
29
+ "src/hooks/hooks.js",
30
+ ], // Support code paths (CommonJS)
31
+ pomPath: argusConfig.pomPath
32
+ ? path.join(moduleConfig.projectPath, argusConfig.pomPath)
33
+ : moduleConfig.pomPath,
34
+ import: argusConfig.import || [], // Support code paths
35
+
36
+ // Formatting and output
37
+ format: argusConfig.format || [
38
+ "rerun:@rerun.txt",
39
+ "allure-cucumberjs/reporter",
40
+ ], // Formatter names/paths
41
+ formatOptions: argusConfig.formatOptions || {
42
+ resultsDir: `allure-result`,
43
+ }, // Formatter options
44
+
45
+ // Execution options
46
+ parallel: argusConfig.parallel || 2, // Number of parallel workers
47
+ dryRun: argusConfig.dryRun || false, // Prepare test run without execution
48
+ failFast: argusConfig.failFast || false, // Stop on first test failure
49
+ forceExit: argusConfig.forceExit || false, // Force process.exit() after tests
50
+ strict: argusConfig.strict || true, // Fail on pending steps
51
+ backtrace: argusConfig.backtrace || false, // Show full backtrace for errors
52
+
53
+ // Filtering and organization
54
+ tags: argusConfig.tags || process.env.npm_config_TAGS || "", // Tag expression to filter scenarios
55
+ name: argusConfig.name || [], // Run scenarios matching regex
56
+ order: argusConfig.order || "defined", // Run order (defined/random)
57
+ language: argusConfig.language || "en", // Default feature file language
58
+
59
+ // Module loading
60
+ loader: argusConfig.loader || [], // Module loader specifications
61
+ requireModule: argusConfig.requireModule || [], // Transpilation module names
62
+
63
+ // Retry logic
64
+ retry: argusConfig.retry || 0, // Retry attempts for failing tests
65
+ retryTagFilter: argusConfig.retryTagFilter || "", // Tag expression for retries
66
+
67
+ // Publishing
68
+ publish: argusConfig.publish || false, // Publish to cucumber.io
69
+
70
+ // World parameters
71
+ worldParameters: argusConfig.worldParameters || {}, // Custom world parameters
72
+ },
73
+
74
+ browser: {
75
+ browserType: argusConfig.browserType || "chrome",
76
+ viewport: {
77
+ width: argusConfig.viewport?.width || 1280,
78
+ height: argusConfig.viewport?.height || 720,
79
+ },
80
+ headless: argusConfig.headless !== undefined ? argusConfig.headless : true,
81
+ },
82
+
83
+ ci: {
84
+ ...this.default,
85
+ parallel: 4,
86
+ tags: "@smoke",
87
+ headless: true,
88
+ format: ["json:reports/cucumber-report.json"],
89
+ },
90
+
91
+ debug: {
92
+ ...this.default,
93
+ parallel: 1,
94
+ backtrace: true,
95
+ failFast: true,
96
+ format: ["progress-bar"],
97
+ },
98
+ };
package/executer.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ const { showHelp } = require("./src/helper/executers/helper");
3
+ const { showVersion } = require("./src/helper/executers/versionChecker");
4
+ const { createProject } = require("./src/helper/executers/projectCreator");
5
+ const { runTests } = require("./src/helper/executers/testRunner");
6
+ const { generateReport } = require("./src/helper/executers/reportGenerator");
7
+ const { cleanUp } = require("./src/helper/executers/cleaner");
8
+
9
+ const args = process.argv.slice(2);
10
+
11
+ const flags = {
12
+ help: args.includes("-h") || args.includes("--help"),
13
+ version: args.includes("-v") || args.includes("--version"),
14
+ create: args.includes("-c") || args.includes("--create"),
15
+ createYes: args.includes("-y") || args.includes("--yes"),
16
+ report: args.includes("-r") || args.includes("--report"),
17
+ };
18
+
19
+ function main() {
20
+ if (flags.help) {
21
+ showHelp();
22
+ return;
23
+ }
24
+
25
+ if (flags.version) {
26
+ showVersion();
27
+ return;
28
+ }
29
+
30
+ if (flags.create) {
31
+ createProject(flags.createYes);
32
+ return;
33
+ }
34
+
35
+ if (flags.report) {
36
+ runTests();
37
+ generateReport();
38
+ cleanUp();
39
+ } else {
40
+ runTests();
41
+ cleanUp();
42
+ }
43
+ }
44
+
45
+ main();