diff --git a/.github/workflows/codeceptjs-reporting.yml b/.github/workflows/codeceptjs-reporting.yml
new file mode 100644
index 00000000..ea3a6709
--- /dev/null
+++ b/.github/workflows/codeceptjs-reporting.yml
@@ -0,0 +1,37 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+# - cron: "0 5 */2 * *"
+name: CodeceptJS example reporting results
+
+on:
+ schedule:
+ - cron: "0 5 */6 * *"
+
+jobs:
+ reporting:
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ working-directory: ./codeceptJS
+
+ strategy:
+ matrix:
+ node-version: [18.x]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Setup dependancies
+ run: npm i
+ - name: Playwright browser updates
+ run: npx playwright install
+ - name: Run tests
+ run: bash run-tests-and-check-results.sh
+ env:
+ TESTOMATIO: "${{ secrets.TESTOMATIO }}"
+ TESTOMATIO_URL: "${{ secrets.TESTOMATIO_URL }}"
+ CODECEPT_GROUP_TESTS: "${{ secrets.CODECEPT_GROUP_TESTS }}"
\ No newline at end of file
diff --git a/.github/workflows/cypress-reporting.yml b/.github/workflows/cypress-reporting.yml
new file mode 100644
index 00000000..cd31ef83
--- /dev/null
+++ b/.github/workflows/cypress-reporting.yml
@@ -0,0 +1,34 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+# - cron: "10 5 */2 * *"
+name: Cypress example reporting results
+
+on:
+ schedule:
+ - cron: "10 5 */6 * *"
+
+jobs:
+ reporting:
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ working-directory: ./cypress
+
+ strategy:
+ matrix:
+ node-version: [18.x]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Setup dependancies
+ run: npm i
+ - name: Run tests
+ run: bash run-tests-and-check-results.sh
+ env:
+ TESTOMATIO: "${{ secrets.TESTOMATIO_CYPRESS }}"
+ TESTOMATIO_URL: "${{ secrets.TESTOMATIO_URL }}"
\ No newline at end of file
diff --git a/.github/workflows/newman-tests.yml b/.github/workflows/newman-tests.yml
new file mode 100644
index 00000000..b73999b1
--- /dev/null
+++ b/.github/workflows/newman-tests.yml
@@ -0,0 +1,35 @@
+name: newman tests
+on:
+ pull_request:
+ branches: [master]
+
+concurrency:
+ group: newman-tests-${{github.event.pull_request.number}}
+ cancel-in-progress: true
+
+jobs:
+ newman-global:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: newman
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v2
+ with:
+ node-version: 18.x
+ - run: npm i newman-reporter-testomatio newman -g
+ - run: TESTOMATIO=m6ef70356h7c newman run collection.json -e env.json -r testomatio
+
+ newman-local:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: newman
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v2
+ with:
+ node-version: 18.x
+ - run: npm i
+ - run: TESTOMATIO=m6ef70356h7c npm run test
diff --git a/.github/workflows/playwright-reporting.yml b/.github/workflows/playwright-reporting.yml
new file mode 100644
index 00000000..c98a58f8
--- /dev/null
+++ b/.github/workflows/playwright-reporting.yml
@@ -0,0 +1,36 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+# - cron: "20 5 */2 * *"
+name: Playwright example reporting results
+
+on:
+ schedule:
+ - cron: "20 5 */6 * *"
+
+jobs:
+ reporting:
+ runs-on: ubuntu-latest
+
+ defaults:
+ run:
+ working-directory: ./playwright
+
+ strategy:
+ matrix:
+ node-version: [18.x]
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Setup dependancies
+ run: npm i
+ - name: Playwright browser updates
+ run: npx playwright install
+ - name: Run tests
+ run: bash run-tests-and-check-results.sh
+ env:
+ TESTOMATIO: "${{ secrets.TESTOMATIO_PLAYWRIGHT }}"
+ TESTOMATIO_URL: "${{ secrets.TESTOMATIO_URL }}"
\ No newline at end of file
diff --git a/codeceptJS-typescript/.gitignore b/codeceptJS-typescript/.gitignore
new file mode 100644
index 00000000..b56eea18
--- /dev/null
+++ b/codeceptJS-typescript/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+output/
\ No newline at end of file
diff --git a/codeceptJS-typescript/__tests__/open-google_test.ts b/codeceptJS-typescript/__tests__/open-google_test.ts
new file mode 100644
index 00000000..e21a5690
--- /dev/null
+++ b/codeceptJS-typescript/__tests__/open-google_test.ts
@@ -0,0 +1,6 @@
+Feature('Test feature name');
+
+Scenario('test something', ({ I }) => {
+ I.amOnPage('https://www.google.com/');
+ I.see('Google');
+});
diff --git a/codeceptJS-typescript/codecept.conf.ts b/codeceptJS-typescript/codecept.conf.ts
new file mode 100644
index 00000000..181c188a
--- /dev/null
+++ b/codeceptJS-typescript/codecept.conf.ts
@@ -0,0 +1,30 @@
+import { setHeadlessWhen, setCommonPlugins } from '@codeceptjs/configure';
+// turn on headless mode when running with HEADLESS=true environment variable
+// export HEADLESS=true && npx codeceptjs run
+setHeadlessWhen(process.env.HEADLESS);
+
+// enable all common plugins https://github.com/codeceptjs/configure#setcommonplugins
+setCommonPlugins();
+
+export const config: CodeceptJS.MainConfig = {
+ tests: './__tests__/**/*_test.ts',
+ output: './output',
+ helpers: {
+ Playwright: {
+ browser: 'chromium',
+ url: 'http://localhost',
+ show: false
+ }
+ },
+ include: {
+ I: './steps_file'
+ },
+ name: 'codeceptJS-typescript',
+
+ plugins: {
+ testomatio: {
+ enabled: true,
+ require: '@testomatio/reporter/lib/adapter/codecept',
+ }
+ }
+}
\ No newline at end of file
diff --git a/codeceptJS-typescript/package.json b/codeceptJS-typescript/package.json
new file mode 100644
index 00000000..865ce9e8
--- /dev/null
+++ b/codeceptJS-typescript/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "codeceptjs-typescript",
+ "version": "1.0.0",
+ "description": "Example project for CodeceptJS + TypeScript",
+ "scripts": {
+ "test": "npx codeceptjs run --steps"
+ },
+ "author": "Oleksandr Pelykh / Testomatio",
+ "license": "ISC",
+ "dependencies": {
+ "codeceptjs": "^3.5.11",
+ "playwright": "^1.40.1"
+ },
+ "devDependencies": {
+ "@types/node": "^20.10.7",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.3.3"
+ }
+}
diff --git a/codeceptJS-typescript/steps.d.ts b/codeceptJS-typescript/steps.d.ts
new file mode 100644
index 00000000..49d8f0f8
--- /dev/null
+++ b/codeceptJS-typescript/steps.d.ts
@@ -0,0 +1,11 @@
+///
+type steps_file = typeof import('./steps_file');
+
+declare namespace CodeceptJS {
+ interface SupportObject { I: I, current: any }
+ interface Methods extends Playwright {}
+ interface I extends ReturnType {}
+ namespace Translation {
+ interface Actions {}
+ }
+}
diff --git a/codeceptJS-typescript/steps_file.ts b/codeceptJS-typescript/steps_file.ts
new file mode 100644
index 00000000..1083a858
--- /dev/null
+++ b/codeceptJS-typescript/steps_file.ts
@@ -0,0 +1,10 @@
+// in this file you can append custom step methods to 'I' object
+
+export = function() {
+ return actor({
+
+ // Define custom steps here, use 'this' to access default methods of I.
+ // It is recommended to place a general 'login' function here.
+
+ });
+}
diff --git a/codeceptJS-typescript/tsconfig.json b/codeceptJS-typescript/tsconfig.json
new file mode 100644
index 00000000..a4a3e5f9
--- /dev/null
+++ b/codeceptJS-typescript/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "ts-node": {
+ "files": true
+ },
+ "compilerOptions": {
+ "target": "es2018",
+ "lib": ["es2018", "DOM"],
+ "esModuleInterop": true,
+ "module": "commonjs",
+ "strictNullChecks": false,
+ "types": ["codeceptjs", "node"],
+ "declaration": true,
+ "skipLibCheck": true
+ },
+ "exclude": ["node_modules"]
+}
\ No newline at end of file
diff --git a/codeceptJS/artifacts/artifact-test-image.png b/codeceptJS/artifacts/artifact-test-image.png
new file mode 100644
index 00000000..f844619a
Binary files /dev/null and b/codeceptJS/artifacts/artifact-test-image.png differ
diff --git a/codeceptJS/artifacts/artifact-test-text.txt b/codeceptJS/artifacts/artifact-test-text.txt
new file mode 100644
index 00000000..a250a0b1
--- /dev/null
+++ b/codeceptJS/artifacts/artifact-test-text.txt
@@ -0,0 +1 @@
+this is test artifact content
\ No newline at end of file
diff --git a/codeceptJS/codecept.conf.js b/codeceptJS/codecept.conf.js
index 87f8ff8c..ee265def 100644
--- a/codeceptJS/codecept.conf.js
+++ b/codeceptJS/codecept.conf.js
@@ -4,12 +4,17 @@ const { setHeadlessWhen } = require('@codeceptjs/configure');
setHeadlessWhen(process.env.HEADLESS);
+const tests = process.env.codecept_GROUP_TESTS === "quick"
+ ? './todomvc-tests/todo-mvc_test.js'
+ : './todomvc-tests/**/*_test.js'
+
exports.config = {
- tests: './todomvc-tests/**/*_test.js',
+ tests,
output: './output',
helpers: {
Playwright: {
video: true,
+ trace: true,
url: 'http://localhost',
waitForTimeout: 5000,
waitForNavigation: 'networkidle0',
@@ -33,6 +38,9 @@ exports.config = {
require: '@testomatio/reporter/lib/adapter/codecept',
apiKey: process.env.TESTOMATIO,
},
+ screenshotOnFail: {
+ enabled: false
+ }
},
bootstrap: null,
mocha: {},
diff --git a/codeceptJS/package.json b/codeceptJS/package.json
index b4c4bec8..eb1d8c73 100644
--- a/codeceptJS/package.json
+++ b/codeceptJS/package.json
@@ -1,19 +1,20 @@
{
"name": "@codeceptjs/examples",
- "version": "1.1.2",
+ "version": "1.1.3",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "npx codeceptjs run",
+ "test:artifact": "npx codeceptjs run artifact-tests/**"
},
"keywords": [],
- "author": "kaflan, davert",
+ "author": "kaflan, davert, mihaylukvv",
"license": "ISC",
"dependencies": {
- "@testomatio/reporter": "^0.6.3",
- "axios": "^0.19.2",
- "check-tests": "^0.7.6",
- "dotenv": "^8.6.0",
- "playwright": "^1.23.0"
+ "@testomatio/reporter": "latest",
+ "axios": "^1.4.0",
+ "check-tests": "^0.8.16",
+ "dotenv": "^16.3.1",
+ "playwright": "^1.36.0"
},
"repository": {
"type": "git",
@@ -23,10 +24,10 @@
"url": "https://github.com/codecept-js/examples/issues"
},
"homepage": "https://github.com/codecept-js/examples#readme",
- "description": "",
+ "description": "Running and Monitoring CodeceptJS Tests with TESTOMATIO Reporter",
"devDependencies": {
- "@codeceptjs/configure": "^0.4.0",
- "@codeceptjs/ui": "^0.2.0",
- "codeceptjs": "^3.3.3"
+ "@codeceptjs/configure": "^0.10.0",
+ "@codeceptjs/ui": "^0.5.0",
+ "codeceptjs": "latest"
}
}
diff --git a/codeceptJS/run-tests-and-check-results.sh b/codeceptJS/run-tests-and-check-results.sh
new file mode 100644
index 00000000..c40cf0ba
--- /dev/null
+++ b/codeceptJS/run-tests-and-check-results.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+npx codeceptjs run > test-results.txt
+fail_tests=$(grep -oE '\b[0-9]+\s+failed\b' test-results.txt | grep -oE '[0-9]+')
+echo "Number of failed tests: $fail_tests"
+if [ "$fail_tests" -gt 12 ]; then
+ echo "More than 12 failed tests. Exiting with error."
+ exit 1
+else
+ exit 0
+fi
diff --git a/codeceptJS/tests-usage-examples/functions.test.js b/codeceptJS/tests-usage-examples/functions.test.js
new file mode 100644
index 00000000..29e8a378
--- /dev/null
+++ b/codeceptJS/tests-usage-examples/functions.test.js
@@ -0,0 +1,22 @@
+const testomat = require('@testomatio/reporter');
+
+Feature('Testomat functions');
+
+Scenario('Upload file', async () => {
+ testomat.artifact('artifacts/artifact-test-text.txt');
+});
+
+Scenario('Upload image', async () => {
+ testomat.artifact({
+ path: 'artifacts/artifact-test-image.png',
+ });
+});
+
+Scenario('Add Step to report', async () => {
+ testomat.step('This is step message');
+});
+
+Scenario('Add log message to report', async () => {
+ testomat.log('This is log message');
+ testomat.log`This is log message with template literal`;
+});
diff --git a/codeceptJS/tests-usage-examples/logger.test.js b/codeceptJS/tests-usage-examples/logger.test.js
new file mode 100644
index 00000000..e5600122
--- /dev/null
+++ b/codeceptJS/tests-usage-examples/logger.test.js
@@ -0,0 +1,20 @@
+const { logger, log } = require('@testomatio/reporter');
+
+// console messages are added to report by default when import "logger" from reporter
+// but to prevent unsused variable warning, you can call next code:
+logger;
+
+Feature('Logger @Sebd746ef');
+
+Scenario('Intercept console logs @Tebebb252', async () => {
+ console.warn('This is warning message');
+});
+
+Scenario('Add own log message @T35d1887d', async () => {
+ const someObject = {
+ name: 'John',
+ surname: 'Doe',
+ age: 30,
+ };
+ log('This is log message', someObject);
+});
diff --git a/codeceptJS/todomvc-tests/create-todos_test.js b/codeceptJS/todomvc-tests/create-todos_test.js
index 0320fcf6..0363ae15 100644
--- a/codeceptJS/todomvc-tests/create-todos_test.js
+++ b/codeceptJS/todomvc-tests/create-todos_test.js
@@ -1,3 +1,5 @@
+const {testomatioLogger} = require('@testomatio/reporter');
+
Feature('@first Create Tasks @step:06 @smoke @story:12345')
Before(async ({ I, TodosPage }) => {
@@ -8,6 +10,8 @@ Before(async ({ I, TodosPage }) => {
* Happy Path tests
*/
Scenario('Create a new todo item', async ({ I, TodosPage }) => {
+ console.log('console log message');
+ testomatioLogger.info('testomatio info log message');
I.say('Given I have an empty todo list')
I.say('When I create a todo "foo"')
diff --git a/codeceptJS/todomvc-tests/pages/todos.page.js b/codeceptJS/todomvc-tests/pages/todos.page.js
index d2377a11..717df9b0 100644
--- a/codeceptJS/todomvc-tests/pages/todos.page.js
+++ b/codeceptJS/todomvc-tests/pages/todos.page.js
@@ -8,13 +8,13 @@ const I = actor();
// const nthTodoItem = nth => `.todo-list li:nth-child(${nth})` // ({ xpath: `(//*[contains(@class,"todo-list")]/li)[${nth}]`})
const nthTodoCheckbox = nth => locate('div > input').inside(`.todo-list li:nth-child(${nth})`)
-const nthTTodoDeleteButton = nth => locate('div > button').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth delete button`)
-const nthTodoEditField = nth => locate('form > input').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth todo input`)
+const nthTTodoDeleteButton = nth => locate('div > button.destroy').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth delete button`)
+const nthTodoEditField = nth => locate('input#edit-todo-input').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth todo input`)
const nthTodoItem = nth => locate('.todo-list li').at(nth).as(`${nth} todo item`)
module.exports = {
goto() {
- I.amOnPage('http://todomvc.com/examples/angularjs/#/')
+ I.amOnPage('https://todomvc.com/examples/angular/dist/browser/#/all')
I.refreshPage()
I.executeScript(() => sessionStorage.clear())
I.executeScript(() => console.error('Boom!'))
@@ -33,7 +33,9 @@ module.exports = {
},
async markNthAsCompleted(nthTodo) {
- const classNames = await I.grabAttributeFrom(nthTodoItem(nthTodo), 'class')
+ let classNames = await I.grabAttributeFrom(nthTodoItem(nthTodo), 'class')
+ if (!classNames) classNames = [];
+
assert(classNames.indexOf('completed') < 0, 'Expected todo to be not already marked as completed')
I.click(nthTodoCheckbox(nthTodo))
},
@@ -86,7 +88,7 @@ module.exports = {
todos = [todos]
}
- assert(todos[nthTodo - 1] === 1, `Expected "${todo}" but got "${todos[nthTodo - 1]}"`)
+ assert(todos[nthTodo - 1] === todo, `Expected "${todo}" but got "${todos[nthTodo - 1]}"`)
return todos
},
diff --git a/codeceptJS/todomvc-tests/todo-mvc_test.js b/codeceptJS/todomvc-tests/todo-mvc_test.js
index b56fdfba..6061c0ee 100644
--- a/codeceptJS/todomvc-tests/todo-mvc_test.js
+++ b/codeceptJS/todomvc-tests/todo-mvc_test.js
@@ -1,7 +1,9 @@
Feature('codepress demo')
Before(async ({ I }) => {
- I.amOnPage('http://todomvc.com/examples/angularjs/#/')
+ I.amOnPage('https://todomvc.com/examples/angular/dist/browser/#/all')
+
+ console.log("Test Before hoooks quick test");
I.say('Given I already have some todos')
const todoItems = [
diff --git a/codeception/composer.json b/codeception/composer.json
index 4720a704..0553ef62 100644
--- a/codeception/composer.json
+++ b/codeception/composer.json
@@ -56,7 +56,7 @@
"symfony/phpunit-bridge": "*",
"symfony/stopwatch": "*",
"testomatio/list-tests": ">=0.1.4",
- "testomatio/reporter": "^0.1.5",
+ "testomatio/reporter": "^0.2.0",
"vlucas/phpdotenv": ">2.4"
},
"config": {
diff --git a/codeceptjs-cucumber/todomvc-tests/pages/todos.page.js b/codeceptjs-cucumber/todomvc-tests/pages/todos.page.js
index 740056fc..cbcb497c 100644
--- a/codeceptjs-cucumber/todomvc-tests/pages/todos.page.js
+++ b/codeceptjs-cucumber/todomvc-tests/pages/todos.page.js
@@ -8,13 +8,13 @@ const I = actor();
// const nthTodoItem = nth => `.todo-list li:nth-child(${nth})` // ({ xpath: `(//*[contains(@class,"todo-list")]/li)[${nth}]`})
const nthTodoCheckbox = nth => locate('div > input').inside(`.todo-list li:nth-child(${nth})`)
-const nthTTodoDeleteButton = nth => locate('div > button').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth delete button`)
-const nthTodoEditField = nth => locate('form > input').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth todo input`)
+const nthTTodoDeleteButton = nth => locate('div > button.destroy').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth delete button`)
+const nthTodoEditField = nth => locate('input#edit-todo-input').inside(`.todo-list li:nth-child(${nth})`).as(`${nth}nth todo input`)
const nthTodoItem = nth => locate('.todo-list li').at(nth).as(`${nth} todo item`)
module.exports = {
goto() {
- I.amOnPage('http://todomvc.com/examples/angularjs/#/')
+ I.amOnPage('https://todomvc.com/examples/angular/dist/browser/#/all')
I.refreshPage()
I.executeScript(() => sessionStorage.clear())
I.executeScript(() => console.error('Boom!'))
diff --git a/codeceptjs-typescript b/codeceptjs-typescript
deleted file mode 160000
index a6e0a0ee..00000000
--- a/codeceptjs-typescript
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit a6e0a0ee6a9a9813a4dcf6abeb5b0d6215b0db36
diff --git a/cucumber-new/artifacts/artifact-test-image.png b/cucumber-new/artifacts/artifact-test-image.png
new file mode 100644
index 00000000..f844619a
Binary files /dev/null and b/cucumber-new/artifacts/artifact-test-image.png differ
diff --git a/cucumber-new/features/artifact.feature b/cucumber-new/features/artifact.feature
new file mode 100644
index 00000000..7acfd907
--- /dev/null
+++ b/cucumber-new/features/artifact.feature
@@ -0,0 +1,5 @@
+Feature: Artifact
+
+ Scenario: Upload artifact
+ When I add the artifact
+ Then artifact should be attached to report
diff --git a/cucumber-new/features/greeting.feature b/cucumber-new/features/greeting.feature
new file mode 100644
index 00000000..2a92e543
--- /dev/null
+++ b/cucumber-new/features/greeting.feature
@@ -0,0 +1,5 @@
+Feature: Greeting
+
+ Scenario: Say hello
+ When the greeter says hello
+ Then I should have heard "hello"
diff --git a/cucumber-new/features/logger.feature b/cucumber-new/features/logger.feature
new file mode 100644
index 00000000..b58ed98b
--- /dev/null
+++ b/cucumber-new/features/logger.feature
@@ -0,0 +1,5 @@
+Feature: Logger
+
+ Scenario: Intercept console message
+ When The logger intercepts console message
+ Then log message should be added to report
diff --git a/cucumber-new/features/step.feature b/cucumber-new/features/step.feature
new file mode 100644
index 00000000..ae4b325a
--- /dev/null
+++ b/cucumber-new/features/step.feature
@@ -0,0 +1,5 @@
+Feature: Step
+
+ Scenario: Add step to report
+ When I add the step
+ Then step should be added to report
diff --git a/cucumber-new/features/step_definitions/steps.js b/cucumber-new/features/step_definitions/steps.js
new file mode 100644
index 00000000..7321d4a7
--- /dev/null
+++ b/cucumber-new/features/step_definitions/steps.js
@@ -0,0 +1,39 @@
+import assert from 'assert';
+import { When, Then } from '@cucumber/cucumber';
+import { Greeter } from '../../src/index.js';
+import testomat, { logger, log } from '@testomatio/reporter';
+
+logger;
+
+When('the greeter says hello', function () {
+ this.whatIHeard = new Greeter().sayHello();
+});
+
+Then('I should have heard {string}', function (expectedResponse) {
+ assert.equal(this.whatIHeard, expectedResponse);
+});
+
+When('The logger intercepts console message', function () {
+ console.error('This is error message');
+ log`This is log message`;
+});
+
+Then('log message should be added to report', function () {
+ assert.equal(true, true);
+});
+
+When('I add the step', function () {
+ testomat.step('This is step');
+});
+
+Then('step should be added to report', function () {
+ assert.equal(true, true);
+});
+
+When('I add the artifact', function () {
+ testomat.artifact('artifacts/artifact-test-image.png');
+});
+
+Then('artifact should be attached to report', function () {
+ assert.equal(true, true);
+});
diff --git a/cucumber-new/package.json b/cucumber-new/package.json
new file mode 100644
index 00000000..a12469f5
--- /dev/null
+++ b/cucumber-new/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "cucumber-new",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "type": "module",
+ "scripts": {
+ "test": "cucumber-js"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@cucumber/cucumber": "^10.0.1",
+ "@testomatio/reporter": "latest"
+ }
+}
diff --git a/cucumber-new/src/index.js b/cucumber-new/src/index.js
new file mode 100644
index 00000000..b0d37ce9
--- /dev/null
+++ b/cucumber-new/src/index.js
@@ -0,0 +1,5 @@
+export class Greeter {
+ sayHello() {
+ return 'hello';
+ }
+}
diff --git a/cucumber/package.json b/cucumber/package.json
index 4b2b730e..1a816506 100644
--- a/cucumber/package.json
+++ b/cucumber/package.json
@@ -9,9 +9,9 @@
"author": "",
"license": "ISC",
"dependencies": {
+ "@cucumber/cucumber": "^10.0.1",
"@testomatio/reporter": "latest",
"cucumber": "^6.0.5"
},
- "devDependencies": {},
"description": ""
}
diff --git a/cypress-cucumber/README.md b/cypress-cucumber/README.md
index cdae5bad..2e8e4c1d 100644
--- a/cypress-cucumber/README.md
+++ b/cypress-cucumber/README.md
@@ -4,10 +4,13 @@ This repo contains tests for **Cypress.io test application in Gherkin language**
This is a playground for your first steps in testing, so instead of installing it from NPM it is recommended to clone it from repo instead.
+**If you're using `npm` to install this example, we support only _Node.js_ 18.x and above**
+|So you should install latest Node.js or switch using `nvm`
+
1) Clone this repository
```
-git clone git@github.com:testomatio/examples.git && cd examples/cypress
+git clone git@github.com:testomatio/examples.git && cd examples/cypress-cucumber
```
2) Install dependencies via npm:
@@ -16,6 +19,18 @@ git clone git@github.com:testomatio/examples.git && cd examples/cypress
npm i
```
+### Confirm test results localy
+
+To open the example with the Cypress browser and execute .feature specs:
+```
+npx cypress open
+```
+
+To execute tests in console log only(get screens + videos + logs):
+```
+npx cypress run
+```
+
This will install cypress & Testomat.io reporter
## Loading Tests to Testomat.io
diff --git a/cypress-cucumber/cypress.config.js b/cypress-cucumber/cypress.config.js
new file mode 100644
index 00000000..11ef6b28
--- /dev/null
+++ b/cypress-cucumber/cypress.config.js
@@ -0,0 +1,23 @@
+const { defineConfig } = require("cypress");
+const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
+const addCucumberPreprocessorPlugin = require("@badeball/cypress-cucumber-preprocessor").addCucumberPreprocessorPlugin;
+const createEsbuildPlugin = require("@badeball/cypress-cucumber-preprocessor/esbuild").createEsbuildPlugin;
+const testomatioReporter = require('@testomatio/reporter/lib/adapter/cypress-plugin');
+
+module.exports = defineConfig({
+ e2e: {
+ async setupNodeEvents(on, config) {
+ // implement node event listeners here
+ const bundler = createBundler({
+ plugins: [createEsbuildPlugin(config)],
+ });
+ on("file:preprocessor", bundler);
+ await addCucumberPreprocessorPlugin(on, config);
+ //Testomat.io reporter
+ testomatioReporter(on, config);
+
+ return config;
+ },
+ specPattern: "cypress/integration/**/*.feature",
+ },
+});
\ No newline at end of file
diff --git a/cypress-cucumber/cypress.json b/cypress-cucumber/cypress.json
deleted file mode 100644
index 9e26dfee..00000000
--- a/cypress-cucumber/cypress.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/integration/features/github.feature b/cypress-cucumber/cypress/integration/features/github.feature
deleted file mode 100644
index 21d373a7..00000000
--- a/cypress-cucumber/cypress/integration/features/github.feature
+++ /dev/null
@@ -1,15 +0,0 @@
-Feature: "Github header"
-
- Scenario: Checking GitHub header
-
- When I open the GitHub home page
- Then I should see correct h1
-
- Scenario Outline: Checking web pages
-
- Given I open page
-
- Examples:
- | url |
- | "https://testomat.io" |
- | "https://lb.ua1" |
diff --git a/cypress-cucumber/cypress/integration/features/homePage.feature b/cypress-cucumber/cypress/integration/features/homePage.feature
new file mode 100644
index 00000000..aa6d9cab
--- /dev/null
+++ b/cypress-cucumber/cypress/integration/features/homePage.feature
@@ -0,0 +1,27 @@
+Feature: Home page verification
+
+ Background:
+ Given I visit Home page
+
+ Scenario: I should see the UI Test Automation Playground title
+ Then I should see UI Test Automation Playground title
+
+ Scenario: I should see that Home is active menu
+ Then I should see that Home menu is active by default
+
+ Scenario: I verify that Home menu attr equal /home
+ Then Home menu should be home
+
+ Scenario: TOP h1 header should be visisble
+ Then I should see the Playground h1 header at the TOP page part
+
+ Scenario: cube image should be visible
+ Then I should see the cude image
+
+ Scenario: I want to search the links in Home page
+ Given Verify additional links
+
+ Examples:
+ | count |
+ | 18 |
+
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/integration/features/invalidPwdLogin.feature b/cypress-cucumber/cypress/integration/features/invalidPwdLogin.feature
new file mode 100644
index 00000000..23eafd8b
--- /dev/null
+++ b/cypress-cucumber/cypress/integration/features/invalidPwdLogin.feature
@@ -0,0 +1,6 @@
+Feature: Login to App
+
+ Scenario: Login to the application as not-existing user
+ When I visit sampleapp page
+ Then I login as user with invalid pwd
+ Then I should see invalid message
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/integration/features/loginpageVerification.feature b/cypress-cucumber/cypress/integration/features/loginpageVerification.feature
new file mode 100644
index 00000000..5763b73b
--- /dev/null
+++ b/cypress-cucumber/cypress/integration/features/loginpageVerification.feature
@@ -0,0 +1,13 @@
+Feature: Login page verification
+
+ Background:
+ When I visit sampleapp page
+
+ Scenario: I should see the the h3 header
+ Then I should see the the h3 header
+
+ Scenario: I should see the Login button
+ Then I should see the Login button
+
+ Scenario: I should see placeholder in User Name field
+ Then I should see placeholder in User Name field
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/integration/features/successfullLogin.feature b/cypress-cucumber/cypress/integration/features/successfullLogin.feature
new file mode 100644
index 00000000..bee77a35
--- /dev/null
+++ b/cypress-cucumber/cypress/integration/features/successfullLogin.feature
@@ -0,0 +1,6 @@
+Feature: Login to App
+
+ Scenario: Login to the application as an exist user
+ When I visit sampleapp page
+ Then I login as valid user
+ Then I should see successfully message
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/plugins/index.js b/cypress-cucumber/cypress/plugins/index.js
deleted file mode 100644
index b1bf2c6a..00000000
--- a/cypress-cucumber/cypress/plugins/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-const cucumber = require('cypress-cucumber-preprocessor').default;
-const testomatioReporter = require('@testomatio/reporter/lib/adapter/cypress-plugin');
-
-module.exports = (on, config) => {
- // `on` is used to hook into various events Cypress emits
- // `config` is the resolved Cypress config
-
- on('file:preprocessor', cucumber());
-
- testomatioReporter(on, config);
-
- return config;
-};
diff --git a/cypress-cucumber/cypress/support/index.js b/cypress-cucumber/cypress/support/e2e.js
similarity index 88%
rename from cypress-cucumber/cypress/support/index.js
rename to cypress-cucumber/cypress/support/e2e.js
index d68db96d..0e7290a1 100644
--- a/cypress-cucumber/cypress/support/index.js
+++ b/cypress-cucumber/cypress/support/e2e.js
@@ -1,5 +1,5 @@
// ***********************************************************
-// This example support/index.js is processed and
+// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
@@ -17,4 +17,4 @@
import './commands'
// Alternatively you can use CommonJS syntax:
-// require('./commands')
+// require('./commands')
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/support/pages/HomePage.js b/cypress-cucumber/cypress/support/pages/HomePage.js
new file mode 100644
index 00000000..88846bff
--- /dev/null
+++ b/cypress-cucumber/cypress/support/pages/HomePage.js
@@ -0,0 +1,28 @@
+class HomePage {
+ openHomePage() {
+ return cy.visit("http://uitestingplayground.com");
+ }
+ verifyHomepageTitle(title) {
+ return cy.title().should('eq', title);
+ }
+ verifyHomepageActiveMenuName() {
+ return cy.get(".nav-item.active > a").should('have.text', 'Home');
+ }
+ verifyHomepageActiveMenuAttr() {
+ return cy.get(".nav-item.active > a").should('have.attr', 'href', '/home');
+ }
+ playgroundTitleShouldBeVisible() {
+ return cy.contains("Playground").should('be.visible');
+ }
+ cubeImageShouldBeVisible() {
+ return cy.get("img.img-fluid").should('be.visible');
+ }
+ verifyLinkCount(count) {
+ return cy.get("h3 > a").should('have.length', count);
+ }
+}
+
+const homePage = new HomePage();
+
+export default homePage;
+
diff --git a/cypress-cucumber/cypress/support/pages/LoginPage.js b/cypress-cucumber/cypress/support/pages/LoginPage.js
new file mode 100644
index 00000000..3c02f9e6
--- /dev/null
+++ b/cypress-cucumber/cypress/support/pages/LoginPage.js
@@ -0,0 +1,29 @@
+class LoginPage {
+ openLoginPage() {
+ return cy.visit("http://uitestingplayground.com/sampleapp");
+ }
+ loginToApp(userName, password) {
+ cy.get('input[name="UserName"]').type(userName);
+ cy.get('input[name="Password"]').type(password);
+ cy.get('#login').click();
+ }
+ verifyLoginStatus(status) {
+ return cy.get('#loginstatus').should('have.text', status);
+ }
+ verifyH3Header(header) {
+ return cy.get('.container > h3').should('have.text', header);
+ }
+ loginBtnIsVisible() {
+ return cy.get('#login').should('be.visible');
+ }
+ verifyUserNamePlaceholder() {
+ return cy.get('input[name="UserName"]')
+ .should('have.attr', 'placeholder')
+ .and('eq', 'User Name');
+ }
+}
+
+const loginPage = new LoginPage();
+
+export default loginPage;
+
diff --git a/cypress-cucumber/cypress/support/step_definitions/github.js b/cypress-cucumber/cypress/support/step_definitions/github.js
deleted file mode 100644
index cf901aa4..00000000
--- a/cypress-cucumber/cypress/support/step_definitions/github.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
-
-When('I open the GitHub home page', () => {
- cy.visit('https://github.com');
-});
-
-Then('I should see correct h1', () => {
- cy.get('h1')
- .next()
- .should(
- 'have.text',
- 'Millions of developers and companies build, ship, and maintain their software on GitHub—the largest and most advanced development platform in the world.'
- );
-});
-
-Given('I open {string} page', (url) => {
- cy.visit(url);
-});
-
diff --git a/cypress-cucumber/cypress/support/step_definitions/homePage.js b/cypress-cucumber/cypress/support/step_definitions/homePage.js
new file mode 100644
index 00000000..4d470d9d
--- /dev/null
+++ b/cypress-cucumber/cypress/support/step_definitions/homePage.js
@@ -0,0 +1,30 @@
+import { Given, Then } from "@badeball/cypress-cucumber-preprocessor";
+import homePage from "../pages/HomePage";
+
+Given("I visit Home page", () => {
+ homePage.openHomePage();
+});
+
+Then("I should see UI Test Automation Playground title", () => {
+ homePage.verifyHomepageTitle("UI Test Automation Playground");
+});
+
+Then("I should see the Playground h1 header at the TOP page part", () => {
+ homePage.playgroundTitleShouldBeVisible();
+});
+
+Then("I should see the cude image", () => {
+ homePage.cubeImageShouldBeVisible();
+});
+
+Then("I should see that Home menu is active by default", () => {
+ homePage.verifyHomepageActiveMenuName();
+});
+
+Then("Home menu should be home", () => {
+ homePage.verifyHomepageActiveMenuAttr();
+});
+
+Given('Verify additional links {int}', (count) => {
+ homePage.verifyLinkCount(count);
+});
\ No newline at end of file
diff --git a/cypress-cucumber/cypress/support/step_definitions/loginToApp.js b/cypress-cucumber/cypress/support/step_definitions/loginToApp.js
new file mode 100644
index 00000000..8ce0b094
--- /dev/null
+++ b/cypress-cucumber/cypress/support/step_definitions/loginToApp.js
@@ -0,0 +1,36 @@
+import { When, Then } from "@badeball/cypress-cucumber-preprocessor";
+import loginPage from "../pages/LoginPage";
+
+const userName = "sampleUser";
+
+When("I visit sampleapp page", () => {
+ loginPage.openLoginPage();
+});
+
+Then("I login as valid user", () => {
+ loginPage.loginToApp(userName, "pwd");
+});
+
+Then("I login as user with invalid pwd", () => {
+ loginPage.loginToApp(userName, "Errorpwd");
+});
+
+Then("I should see successfully message", () => {
+ loginPage.verifyLoginStatus(`Welcome, ${userName}!`);
+});
+
+Then("I should see invalid message", () => {
+ loginPage.verifyLoginStatus("Invalid username/password");
+});
+
+Then("I should see the the h3 header", () => {
+ loginPage.verifyH3Header("Sample App");
+});
+
+Then("I should see the Login button", () => {
+ loginPage.loginBtnIsVisible();
+});
+
+Then("I should see placeholder in User Name field", () => {
+ loginPage.verifyUserNamePlaceholder();
+});
diff --git a/cypress-cucumber/package.json b/cypress-cucumber/package.json
index bbcee635..a05807cf 100644
--- a/cypress-cucumber/package.json
+++ b/cypress-cucumber/package.json
@@ -11,10 +11,15 @@
"keywords": [],
"author": "",
"license": "ISC",
+ "dependencies": {
+ "@testomatio/reporter": "^0.7.5",
+ "cypress": "^12.7.0"
+ },
"devDependencies": {
- "@testomatio/reporter": "^0.5.10",
- "cypress": "9.2.0",
- "cypress-cucumber-preprocessor": "4.3.1",
- "mocha": "^9.1.3"
+ "@badeball/cypress-cucumber-preprocessor": "^15.1.4",
+ "@bahmutov/cypress-esbuild-preprocessor": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v18.13.0"
}
}
diff --git a/cypress/README.md b/cypress/README.md
index d359a84c..5719d2b6 100644
--- a/cypress/README.md
+++ b/cypress/README.md
@@ -24,7 +24,7 @@ npm i
2. Run `npx check-tests` to upload tests data into testomat.io. Pass `{API_KEY}` as `TESTOMATIO` environment variable:
```bash
-TESTOMATIO={API_KEY} npx check-tests cypress "**/**.spec.js" -d cypress/integration/*
+TESTOMATIO={API_KEY} npx check-tests cypress "**/**.spec.js" -d cypress/**
```
> **Environment variables** It is recommended to store Testomatio `{API_KEY}` as environment variable and never save it in the source code. Set them directly when running tests or use [dotenv](https://www.npmjs.com/package/dotenv) package to save environment variable in a file and load them for tests.
diff --git a/cypress/cypress.config.js b/cypress/cypress.config.js
index 684bf070..3d0fb259 100644
--- a/cypress/cypress.config.js
+++ b/cypress/cypress.config.js
@@ -5,8 +5,9 @@ module.exports = defineConfig({
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
- require('@testomatio/reporter/lib/adapter/cypress-plugin')(on, config);
- return require('./cypress/plugins/index.js')(on, config)
+ // require('@testomatio/reporter/lib/adapter/cypress-plugin')(on, config);
+ // return require('./cypress/plugins/index.js')(on, config)
+ return require('@testomatio/reporter/lib/adapter/cypress-plugin')(on, config)
},
},
})
diff --git a/cypress/cypress/plugins/index.js b/cypress/cypress/plugins/index.js
index c3ec1bc5..5601b0ce 100644
--- a/cypress/cypress/plugins/index.js
+++ b/cypress/cypress/plugins/index.js
@@ -12,7 +12,7 @@
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
-const testomatioReporter = require('@testomatio/reporter/lib/adapter/cypress-plugin');
+// const testomatioReporter = require('@testomatio/reporter/lib/adapter/cypress-plugin');
/**
* @type {Cypress.PluginConfig}
@@ -21,7 +21,7 @@ module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
- testomatioReporter(on, config);
+ // testomatioReporter(on, config);
return config;
};
diff --git a/cypress/package.json b/cypress/package.json
index 427012c6..c875cc3d 100644
--- a/cypress/package.json
+++ b/cypress/package.json
@@ -1,15 +1,20 @@
{
- "name": "cypress-example",
- "version": "1.0.0",
- "description": "",
+ "name": "cypress-example-project",
+ "version": "1.0.1",
+ "description": "Running and Monitoring Cypress tests with TESTOMATIO Reporter",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "npx cypress run"
},
- "author": "",
+ "keywords": [
+ "e2e",
+ "testomatio",
+ "cypress"
+ ],
+ "author": "davert, mihaylukvv",
"license": "ISC",
"devDependencies": {
- "@testomatio/reporter": "^0.6.0",
- "cypress": "^10"
+ "@testomatio/reporter": "latest",
+ "cypress": "^12.17.1"
}
}
diff --git a/cypress/run-tests-and-check-results.sh b/cypress/run-tests-and-check-results.sh
new file mode 100644
index 00000000..8846ef5b
--- /dev/null
+++ b/cypress/run-tests-and-check-results.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+npx cypress run > test-cypress-results.txt
+fail_tests=$(grep -oE '\b[0-9]+\s+failing\b' test-cypress-results.txt | grep -oE '[0-9]+')
+echo "Number of failed tests: $fail_tests"
+if [ "$fail_tests" -gt 1 ]; then
+ echo "More than 1 failed tests. Exiting with error."
+ exit 1
+else
+ exit 0
+fi
diff --git a/jest/__tests__/logger-parallel.test.js b/jest/__tests__/logger-parallel.test.js
new file mode 100644
index 00000000..472f3dad
--- /dev/null
+++ b/jest/__tests__/logger-parallel.test.js
@@ -0,0 +1,8 @@
+import { logger } from '@testomatio/reporter';
+
+describe('Logger test 2', function () {
+ it('logs should be added to the testomatio report 2', async function () {
+ console.log('this is 2nd console log message from Jest');
+ logger.warn('this is 2nd logger warn message from Jest');
+ });
+});
diff --git a/jest/__tests__/logger.test.js b/jest/__tests__/logger.test.js
new file mode 100644
index 00000000..c76e2860
--- /dev/null
+++ b/jest/__tests__/logger.test.js
@@ -0,0 +1,8 @@
+import { logger } from '@testomatio/reporter';
+
+describe('Logger test', function () {
+ it('logs should be added to the testomatio report @T9b799166', async function () {
+ console.log('this is console log message from Jest');
+ logger.warn('this is logger warn message from Jest');
+ });
+});
diff --git a/jest/__tests__/testomat-functions.test.js b/jest/__tests__/testomat-functions.test.js
new file mode 100644
index 00000000..f56ff52e
--- /dev/null
+++ b/jest/__tests__/testomat-functions.test.js
@@ -0,0 +1,15 @@
+import testomat from '@testomatio/reporter';
+
+describe('suite name', () => {
+ it('artifact is uploaded', async function () {
+ testomat.artifact('artifacts/artifact-test-text.txt');
+ });
+
+ it('log', async function () {
+ testomat.log`This is log message`;
+ });
+
+ it('step', async function () {
+ testomat.step('This is step');
+ });
+})
diff --git a/jest/artifacts/artifact-test-image.png b/jest/artifacts/artifact-test-image.png
new file mode 100644
index 00000000..f844619a
Binary files /dev/null and b/jest/artifacts/artifact-test-image.png differ
diff --git a/jest/artifacts/artifact-test-text.txt b/jest/artifacts/artifact-test-text.txt
new file mode 100644
index 00000000..a250a0b1
--- /dev/null
+++ b/jest/artifacts/artifact-test-text.txt
@@ -0,0 +1 @@
+this is test artifact content
\ No newline at end of file
diff --git a/jest/jest.config.js b/jest/jest.config.js
index 6ad480ba..17e9c53d 100644
--- a/jest/jest.config.js
+++ b/jest/jest.config.js
@@ -1,3 +1,5 @@
+require('dotenv').config();
+
module.exports = {
testEnvironment: "node",
reporters: ['default', ['@testomatio/reporter/lib/adapter/jest.js', { apiKey: process.env.TESTOMATIO }]],
diff --git a/jest/package.json b/jest/package.json
index 9b5bdefe..86767195 100644
--- a/jest/package.json
+++ b/jest/package.json
@@ -6,8 +6,9 @@
"author": "Koushik Mohan ",
"license": "MIT",
"dependencies": {
- "@testomatio/reporter": "^0.6.5",
- "check-tests": "^0.7.3",
+ "@testomatio/reporter": "latest",
+ "check-tests": "latest",
+ "jest": "^29.7.0",
"jest-junit": "^13.2.0"
},
"devDependencies": {
@@ -17,8 +18,7 @@
"eslint": "^6.7.2",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
- "eslint-plugin-import": "^2.18.2",
- "jest": "^24.9.0"
+ "eslint-plugin-import": "^2.18.2"
},
"scripts": {
"test": "jest"
diff --git a/mocha-ts-multi-reporters/.env.example b/mocha-ts-multi-reporters/.env.example
new file mode 100644
index 00000000..e95861d1
--- /dev/null
+++ b/mocha-ts-multi-reporters/.env.example
@@ -0,0 +1 @@
+TESTOMATIO=
diff --git a/mocha-ts-multi-reporters/.eslintrc.json b/mocha-ts-multi-reporters/.eslintrc.json
new file mode 100644
index 00000000..1d1c7e17
--- /dev/null
+++ b/mocha-ts-multi-reporters/.eslintrc.json
@@ -0,0 +1,55 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true,
+ "node": true
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:prettier/recommended",
+ "plugin:import/recommended",
+ "plugin:import/typescript"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaVersion": 12,
+ "sourceType": "module",
+ "project": "./tsconfig.json",
+ "tsconfigRootDir": "./"
+ },
+ "plugins": ["@typescript-eslint", "prettier", "no-only-tests"],
+ "rules": {
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/explicit-module-boundary-types": [
+ "off",
+ {
+ "allowArgumentsExplicitlyTypedAsAny": true
+ }
+ ],
+ "indent": ["error", 2],
+ "quotes": ["error", "single", {"avoidEscape": true}],
+ "semi": ["error", "never"],
+ "no-undef": "off",
+ "no-only-tests/no-only-tests": ["error", {"fix": true}],
+ "prettier/prettier": [
+ "error",
+ {
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 80,
+ "tabWidth": 2,
+ "arrowParens": "avoid",
+ "trailingComma": "none",
+ "endOfLine": "auto"
+ }
+ ]
+ },
+ "settings": {
+ "import/resolver": {
+ "typescript": {
+ "alwaysTryTypes": true
+ }
+ }
+ }
+}
diff --git a/mocha-ts-multi-reporters/.gitignore b/mocha-ts-multi-reporters/.gitignore
new file mode 100644
index 00000000..0eaacc0e
--- /dev/null
+++ b/mocha-ts-multi-reporters/.gitignore
@@ -0,0 +1,107 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+/node_modules/*
+/jspm_packages/*
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and *not* Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+#idea basic folder
+.idea/*
\ No newline at end of file
diff --git a/mocha-ts-multi-reporters/.mocharc.js b/mocha-ts-multi-reporters/.mocharc.js
new file mode 100644
index 00000000..67698760
--- /dev/null
+++ b/mocha-ts-multi-reporters/.mocharc.js
@@ -0,0 +1,6 @@
+module.exports = {
+ require: ['ts-node/register', 'dotenv/config'],
+ spec: './spec/**/*.spec.ts',
+ reporter: 'mocha-multi-reporters',
+ reporterOptions: ['configFile=reporter.conf.js']
+}
diff --git a/mocha-ts-multi-reporters/README.md b/mocha-ts-multi-reporters/README.md
new file mode 100644
index 00000000..a1b9f8e2
--- /dev/null
+++ b/mocha-ts-multi-reporters/README.md
@@ -0,0 +1,68 @@
+# 📊 Mocha + TypeScript + Multi Reporters Example
+This repo contains simple template for testing project with Multiple reports based on the stack = Mocha + TypeScript + Spec report & Testomat.io plugins.
+
+# Installation
+This is a playground for your first steps in testing, so instead of installing it from NPM it is recommended to clone it from repo instead.
+
+1) Clone this repository:
+
+```
+git clone git@github.com:testomatio/examples.git && cd examples/mocha-ts-multi-reporters
+```
+## Requirements:
+ **in order to run this project, NodeJS (version 18+) must be installed**
+
+
+2) Install dependencies via npm:
+
+```
+npm i
+```
+
+_This will install mocha & typescript env + Testomat.io reporter_
+
+3) Run tests localy without sending report to the Testomat.io:
+
+```
+npm tests
+```
+_(if the tests are completed => you can start setting up the testomat.io reporter)_
+
+## Loading Tests to Testomat.io
+
+1. Create empty project in Testomat.io
+2. Obtain API key from Testomat.io
+2. Run `npx check-tests` to upload tests data into testomat.io. Pass api key as `TESTOMATIO` environment variable:
+
+```
+TESTOMATIO={apiKey} npx check-tests@latest mocha "**/*{.,_}{test,spec}.ts" --typescript -d spec
+```
+
+## Publishing Test Results to Testomat.io
+
+1. Get API key from a project in Testomat.io.
+
+2. Create a specific .env file:
+> **Environment variables**
+```.env``` file using ```env.example``` as a template
+### SET key variable
+**(if you don't want to use the TESTOMATIO API key when running testomatIO, then you can store the token in the ```.env``` file (see env.example example))**
+
+3. Run tests and generate reports(Testomat.io):
+
+```
+npx mocha
+```
+OR
+```
+npm test
+```
+
+### reporterOptions additinal options
+**In our case, we use multiple reporters: spec & testomatio.**
+
+_!! Pay Attantion on the rpConfgi.js file. Using key-name should be equal path to the testomatio adapter(testomatio/reporter/lib/adapter/mocha.js)._
+ Like:
+```
+testomatioReporterLibAdapterMochaJsReporterOptions
+```
\ No newline at end of file
diff --git a/mocha-ts-multi-reporters/artifacts/artifact-test-image.png b/mocha-ts-multi-reporters/artifacts/artifact-test-image.png
new file mode 100644
index 00000000..f844619a
Binary files /dev/null and b/mocha-ts-multi-reporters/artifacts/artifact-test-image.png differ
diff --git a/mocha-ts-multi-reporters/artifacts/artifact-test-text.txt b/mocha-ts-multi-reporters/artifacts/artifact-test-text.txt
new file mode 100644
index 00000000..a250a0b1
--- /dev/null
+++ b/mocha-ts-multi-reporters/artifacts/artifact-test-text.txt
@@ -0,0 +1 @@
+this is test artifact content
\ No newline at end of file
diff --git a/mocha-ts-multi-reporters/package.json b/mocha-ts-multi-reporters/package.json
new file mode 100644
index 00000000..90243fdd
--- /dev/null
+++ b/mocha-ts-multi-reporters/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "mocha-typescript",
+ "version": "1.0.1",
+ "description": "Example testomatio project with Mocha+TypeScript",
+ "main": "index.js",
+ "scripts": {
+ "test": "mocha"
+ },
+ "keywords": [
+ "mocha",
+ "typescript",
+ "e2e",
+ "test automation"
+ ],
+ "author": "Vitalii Mykhailiuk (vmykhailiuk.chanel@gmail.com)",
+ "license": "MIT",
+ "dependencies": {
+ "@testomatio/reporter": "latest",
+ "@types/chai": "4.3.4",
+ "@types/mocha": "10.0.1",
+ "@types/node": "18.11.18",
+ "chai": "4.3.7",
+ "dotenv": "16.0.3",
+ "mocha": "10.2.0",
+ "mocha-multi-reporters": "1.5.1",
+ "ts-node": "10.9.1",
+ "typescript": "4.9.4"
+ },
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "5.48.2",
+ "@typescript-eslint/parser": "5.48.2",
+ "eslint": "8.32.0",
+ "eslint-config-prettier": "8.6.0",
+ "eslint-import-resolver-typescript": "3.5.3",
+ "eslint-plugin-import": "2.27.5",
+ "eslint-plugin-no-only-tests": "3.1.0",
+ "eslint-plugin-prettier": "4.2.1",
+ "prettier": "2.8.3"
+ }
+}
diff --git a/mocha-ts-multi-reporters/reporter.conf.js b/mocha-ts-multi-reporters/reporter.conf.js
new file mode 100644
index 00000000..cdb8fbfe
--- /dev/null
+++ b/mocha-ts-multi-reporters/reporter.conf.js
@@ -0,0 +1,6 @@
+module.exports = {
+ reporterEnabled: 'spec, @testomatio/reporter/lib/adapter/mocha.js',
+ testomatioReporterLibAdapterMochaJsReporterOptions: {
+ apiKey: process.env.TESTOMATIO
+ }
+}
diff --git a/mocha-ts-multi-reporters/spec/logger.spec.ts b/mocha-ts-multi-reporters/spec/logger.spec.ts
new file mode 100644
index 00000000..74234156
--- /dev/null
+++ b/mocha-ts-multi-reporters/spec/logger.spec.ts
@@ -0,0 +1,9 @@
+import { logger, log } from '@testomatio/reporter';
+
+describe('Logger test @S2f6e76f8', function () {
+ it('logs should be added to the testomatio report @T7f509392', async function () {
+ console.log('this is console log message');
+ logger.warn('this is logger warn message');
+ log`This is log message`
+ });
+});
diff --git a/mocha-ts-multi-reporters/spec/test.example.spec.ts b/mocha-ts-multi-reporters/spec/test.example.spec.ts
new file mode 100644
index 00000000..4cfd951b
--- /dev/null
+++ b/mocha-ts-multi-reporters/spec/test.example.spec.ts
@@ -0,0 +1,79 @@
+import { testomatioLogger } from '@testomatio/reporter';
+import { expect } from 'chai';
+
+describe("Array", function() {
+ let arr;
+
+ beforeEach(function() {
+ arr = [1, 2, 3];
+ });
+
+ // Test Case 1
+ it("should return -1 when the value is not present", function() {
+ expect(arr.indexOf(4)).to.equal(-1);
+ });
+
+ // Test Case 2
+ it("should return the index of the element when it is present", function() {
+ expect(arr.indexOf(2)).to.equal(1);
+ });
+
+ // Test Case 3
+ it("should return the length of the array after adding an element", function() {
+ arr.push(4);
+ expect(arr.length).to.equal(4);
+ });
+
+ it("should fail and return -1 as the value is not present", function() {
+ expect(arr.indexOf(4)).to.equal(3);
+ });
+
+ it.skip("should be skipped", function() {
+ arr.push(4);
+ expect(arr.length).to.equal(4);
+ });
+
+ // Test Case 4
+ it("should return the first element of the array", function() {
+ expect(arr[0]).to.equal(1);
+ });
+
+ // Test Case 5
+ it("should return the sum of all elements in the array", function() {
+ expect(arr.reduce((a, b) => a + b, 0)).to.equal(6);
+ });
+
+ // Test Case 6
+ it("should return the last element of the array", function() {
+ expect(arr[2]).to.equal(3);
+ });
+
+ // Test Case 7
+ it("should return a reversed array", function() {
+ expect(arr.reverse()).to.deep.equal([3, 2, 1]);
+ });
+
+ // Test Case 8
+ it("should return the array after removing the first element", function() {
+ expect(arr.slice(1)).to.deep.equal([2, 3]);
+ });
+
+ // Test Case 9
+ it("should return a new array with all elements multiplied by 2", function() {
+ expect(arr.map(x => x * 2)).to.deep.equal([2, 4, 6]);
+ });
+
+ // Test Case 10
+ it("should return a sorted array in ascending order", function() {
+ expect([3, 2, 1].sort()).to.deep.equal([1, 2, 3]);
+ });
+
+
+ // Test Case 11
+ it("should attach logs", function () {
+ console.warn('console warn message');
+ testomatioLogger.debug('testomatio logger debug message');
+ expect(arr.indexOf(4)).to.equal(-1);
+ });
+});
+
diff --git a/mocha-ts-multi-reporters/spec/testomat-functions.spec.ts b/mocha-ts-multi-reporters/spec/testomat-functions.spec.ts
new file mode 100644
index 00000000..2dfae297
--- /dev/null
+++ b/mocha-ts-multi-reporters/spec/testomat-functions.spec.ts
@@ -0,0 +1,16 @@
+import testomat, { log } from '@testomatio/reporter';
+
+describe('Testomat functions @S43849225', () => {
+ it('attach image @T93dc3526', () => {
+
+ testomat.artifact('artifacts/artifact-test-image.png');
+ });
+
+ it('log message @T6fdfc777', () => {
+ log`This is log message`;
+ });
+
+ it('add step @T2fa88ab9', () => {
+ testomat.step('This is step message');
+ });
+});
diff --git a/mocha-ts-multi-reporters/tsconfig.json b/mocha-ts-multi-reporters/tsconfig.json
new file mode 100644
index 00000000..2adf7221
--- /dev/null
+++ b/mocha-ts-multi-reporters/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "esModuleInterop": true,
+ "moduleResolution": "Node",
+ "module": "commonjs",
+ "outDir": "built",
+ "target": "ES2019",
+ "sourceMap": true
+ },
+ "include": ["**/*.ts", "**/*.js"],
+ "exclude": ["node_modules"]
+}
\ No newline at end of file
diff --git a/newman/README.md b/newman/README.md
new file mode 100644
index 00000000..3d43a935
--- /dev/null
+++ b/newman/README.md
@@ -0,0 +1,47 @@
+### Example project for newman-reporter-testomatio
+
+This is example project for [newman-reporter-testomatio](https://www.npmjs.com/package/newman-reporter-testomatio) package usage.
+
+# Usage
+
+### Running in this project
+1. Install modules:
+\
+`npm i`
+
+2. Run tests
+- `TESTOMATIO= npm run test`
+- `TESTOMATIO= npm run test:fail`
+
+
+### Running in **your** project
+1. Install package
+\
+`npm i newman-reporter-testomatio`
+
+2. Run collection and specify `testomatio` as reporter:
+\
+`TESTOMATIO= npx newman run -e -r testomatio `
+\
+> -e (environment) is optional param; others are required
+
+Examples:
+\
+`TESTOMATIO= npx newman run collection.json -e env.json -r testomatio`
+\
+`TESTOMATIO= npx newman run collection_fail.json -e env.json -r testomatio`
+
+> No need to pass `TESTOMATIO_CREATE=1`. This param is already set by default when using `newman-reporter-testomatio`.
+
+## Troubleshooting
+### If you got an error running your collection _("could not find testomatio reporter")_, read next
+\
+`newman` and `newman-reporter-testomatio` should be installed in the same directory.
+- If you run your tests using **globally** installed newman (`newman run ...`):
+\
+intall `newman-reporter-testomatio` globally too (`npm i newman-reporter-testomatio -g`).
+- If you use **locally** installed newman (within the project) (`npx newman run ...`):
+\
+Follow default flow – just `npm i`
+
+You can verify installed packages via `npm list` or `npm list -g`
diff --git a/newman/collection.json b/newman/collection.json
new file mode 100644
index 00000000..3663af09
--- /dev/null
+++ b/newman/collection.json
@@ -0,0 +1,259 @@
+{
+ "info": {
+ "_postman_id": "74f760d2-689d-4064-bd69-77752ad0c3a9",
+ "name": "Echo collection",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "11123710"
+ },
+ "item": [
+ {
+ "name": "Request with url params",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.response.to.have.status(200);",
+ "});",
+ "",
+ "pm.test(\"Status test\", function () {",
+ " const responseJson = pm.response.json();",
+ " pm.expect(responseJson.args.paramName).to.equal('paramValue');",
+ "});",
+ "",
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('textVarValue');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Request with pre-request script",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('updatedTextVar');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "pm.environment.set('textVar', 'updatedTextVar');"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Post request with env variables",
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "console.log('Printing environment variable value:', pm.environment.get('url'));",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Environment variables are got properly\", function () {",
+ " const responseJson = pm.response.json();",
+ " pm.expect(responseJson.data.testKey).to.equal(13);",
+ " ",
+ " const paramName = pm.environment.get('paramName');",
+ " const paramValue = pm.environment.get('paramValue');",
+ " pm.expect(responseJson.args[paramName]).to.equal(paramValue);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"testKey\": {{numberVar}}\n}\n",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{url}}/post?{{paramName}}={{paramValue}}",
+ "host": [
+ "{{url}}"
+ ],
+ "path": [
+ "post"
+ ],
+ "query": [
+ {
+ "key": "{{paramName}}",
+ "value": "{{paramValue}}"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Put request with body",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.response.to.have.status(200);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"key1\": \"someValue\",\n \"key2\": 13\n}\n",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "https://postman-echo.com/put",
+ "protocol": "https",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "put"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Request with auth",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.expect(pm.request.auth.type).to.equal('apikey');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "auth": {
+ "type": "apikey",
+ "apikey": [
+ {
+ "key": "key",
+ "value": "testTokenName",
+ "type": "string"
+ },
+ {
+ "key": "value",
+ "value": "testTokenValue",
+ "type": "string"
+ }
+ ]
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "https://postman-echo.com/get",
+ "protocol": "https",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/newman/collection_fail.json b/newman/collection_fail.json
new file mode 100644
index 00000000..66f32a98
--- /dev/null
+++ b/newman/collection_fail.json
@@ -0,0 +1,291 @@
+{
+ "info": {
+ "_postman_id": "74f760d2-689d-4064-bd69-77752ad0c3a9",
+ "name": "Echo collection",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "11123710"
+ },
+ "item": [
+ {
+ "name": "Request with url params",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.response.to.have.status(200);",
+ "});",
+ "",
+ "pm.test(\"Status test\", function () {",
+ " const responseJson = pm.response.json();",
+ " pm.expect(responseJson.args.paramName).to.equal('paramValue');",
+ "});",
+ "",
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('textVarValue');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Request with pre-request script",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('updatedTextVar');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "pm.environment.set('textVar', 'updatedTextVar');"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Post request with env variables",
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "console.log('Printing environment variable value:', pm.environment.get('url'));",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Environment variables are got properly\", function () {",
+ " const responseJson = pm.response.json();",
+ " pm.expect(responseJson.data.testKey).to.equal(13);",
+ " ",
+ " const paramName = pm.environment.get('paramName');",
+ " const paramValue = pm.environment.get('paramValue');",
+ " pm.expect(responseJson.args[paramName]).to.equal(paramValue);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"testKey\": {{numberVar}}\n}\n",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "{{url}}/post?{{paramName}}={{paramValue}}",
+ "host": [
+ "{{url}}"
+ ],
+ "path": [
+ "post"
+ ],
+ "query": [
+ {
+ "key": "{{paramName}}",
+ "value": "{{paramValue}}"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Put request with body",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.response.to.have.status(200);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"key1\": \"someValue\",\n \"key2\": 13\n}\n",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "https://postman-echo.com/put",
+ "protocol": "https",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "put"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Request with auth",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.expect(pm.request.auth.type).to.equal('apikey');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "auth": {
+ "type": "apikey",
+ "apikey": [
+ {
+ "key": "key",
+ "value": "testTokenName",
+ "type": "string"
+ },
+ {
+ "key": "value",
+ "value": "testTokenValue",
+ "type": "string"
+ }
+ ]
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "https://postman-echo.com/get",
+ "protocol": "https",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Failing tests",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"This test will fail\", function () {",
+ " pm.response.to.have.status(222);",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/newman/collection_with_folders.json b/newman/collection_with_folders.json
new file mode 100644
index 00000000..aece8d93
--- /dev/null
+++ b/newman/collection_with_folders.json
@@ -0,0 +1,204 @@
+{
+ "info": {
+ "_postman_id": "3ae15048-6df3-4905-b68a-ec869d4c348b",
+ "name": "Echo collection with folders",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "11123710"
+ },
+ "item": [
+ {
+ "name": "Folder 1",
+ "item": [
+ {
+ "name": "Request with url params",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Request with pre-request script",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('updatedTextVar');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "pm.environment.set('textVar', 'updatedTextVar');"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Folder 2",
+ "item": [
+ {
+ "name": "Nested folder",
+ "item": [
+ {
+ "name": "Request inside nested folder",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Status test\", function () {",
+ " pm.expect(pm.request.auth.type).to.equal('apikey');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "auth": {
+ "type": "apikey",
+ "apikey": [
+ {
+ "key": "key",
+ "value": "testTokenName",
+ "type": "string"
+ },
+ {
+ "key": "value",
+ "value": "testTokenValue",
+ "type": "string"
+ }
+ ]
+ },
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "https://postman-echo.com/get",
+ "protocol": "https",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "Empty folder",
+ "item": []
+ },
+ {
+ "name": "Request within collection (not in folder)",
+ "event": [
+ {
+ "listen": "test",
+ "script": {
+ "exec": [
+ "pm.test(\"Variable value is updated in pre-request script\", function () {",
+ " const updateVariableValue = pm.environment.get('textVar');",
+ " pm.expect(updateVariableValue).to.equal('updatedTextVar');",
+ "});",
+ ""
+ ],
+ "type": "text/javascript"
+ }
+ },
+ {
+ "listen": "prerequest",
+ "script": {
+ "exec": [
+ "console.log('This is pre-request script');",
+ "pm.environment.set('textVar', 'updatedTextVar');"
+ ],
+ "type": "text/javascript"
+ }
+ }
+ ],
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "postman-echo.com/get?paramName=paramValue",
+ "host": [
+ "postman-echo",
+ "com"
+ ],
+ "path": [
+ "get"
+ ],
+ "query": [
+ {
+ "key": "paramName",
+ "value": "paramValue"
+ }
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/newman/env.json b/newman/env.json
new file mode 100644
index 00000000..ba325f8c
--- /dev/null
+++ b/newman/env.json
@@ -0,0 +1,39 @@
+{
+ "id": "90577d60-1765-4393-a768-571eba881da3",
+ "name": "testomatio",
+ "values": [
+ {
+ "key": "url",
+ "value": "postman-echo.com",
+ "type": "default",
+ "enabled": true
+ },
+ {
+ "key": "paramName",
+ "value": "someParamName",
+ "type": "default",
+ "enabled": true
+ },
+ {
+ "key": "textVar",
+ "value": "textVarValue",
+ "type": "default",
+ "enabled": true
+ },
+ {
+ "key": "paramValue",
+ "value": "someParamValue",
+ "type": "default",
+ "enabled": true
+ },
+ {
+ "key": "numberVar",
+ "value": "13",
+ "type": "default",
+ "enabled": true
+ }
+ ],
+ "_postman_variable_scope": "environment",
+ "_postman_exported_at": "2023-03-12T08:55:53.203Z",
+ "_postman_exported_using": "Postman/10.11.2"
+}
\ No newline at end of file
diff --git a/newman/package.json b/newman/package.json
new file mode 100644
index 00000000..0d15a235
--- /dev/null
+++ b/newman/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "example-project-for-newman-reporter-testomatio",
+ "version": "0.0.1",
+ "description": "Example project for testomatio reporter using newman",
+ "main": "index.js",
+ "scripts": {
+ "test": "npx newman run collection.json -e env.json -r testomatio",
+ "test:fail": "npx newman run collection_fail.json -e env.json -r testomatio"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "newman": "^5.3.2",
+ "newman-reporter-testomatio": "latest"
+ }
+}
diff --git a/playwright/.gitignore b/playwright/.gitignore
index bf771ee0..8461164f 100644
--- a/playwright/.gitignore
+++ b/playwright/.gitignore
@@ -2,3 +2,6 @@ node_modules/
test-results/
playwright-report/
.env
+/test-results/
+/playwright-report/
+/playwright/.cache/
diff --git a/playwright/README.md b/playwright/README.md
index 838f10bb..d9f40e59 100644
--- a/playwright/README.md
+++ b/playwright/README.md
@@ -16,6 +16,24 @@ git clone git@github.com:testomatio/examples.git && cd examples/playwright
npm i
```
+2.1) Run tests to check if they work (via npm):
+
+```
+npm run test:e2e
+```
+
+2.2) Run only smoke tests (via npm):
+
+```sh
+npm run test:smoke-examples
+```
+
+2.3) Run only e2e tests (via npm):
+
+```sh
+npm run test:e2e-examples
+```
+
This will install Playwright with puppeteer & Testomat.io reporter
## Loading Tests to Testomat.io
@@ -25,17 +43,22 @@ This will install Playwright with puppeteer & Testomat.io reporter
2. Run `npx check-tests` to upload tests data into testomat.io. Pass api key as `TESTOMATIO` environment variable:
```
-TESTOMATIO={apiKey} npx check-tests playwright --typescript "**/*{.,_}spec.ts"
+TESTOMATIO={apiKey} npx check-tests@latest Playwright "**/*{.,_}{test,spec,cy}.ts" --typescript
```
> **Environment variables** It is recommended to store Testomatio API Key as environment variable and never save it in the source code. Set them directly when running tests or use [dotenv](https://www.npmjs.com/package/dotenv) package to save environment variable in a file and load them for tests.
-## Publishing Test Results to Testomat.io
+## Publishing Test Results to Testomat.io (all available tests)
Get API key from a project in Testomat.io and set it as environment variable `TESTOMATIO`:
```
-TESTOMATIO={apiKey} npx playwright tests
+TESTOMATIO={apiKey} npx playwright test
+```
+
+_or only smoke tests:_
+```
+TESTOMATIO={key} npx playwright test --config e2e-examples/playwright-smoke.config.ts
```
### Configuration
@@ -50,3 +73,7 @@ reporter: [
}]
],
```
+
+### Pay attention
+
+_One test has a "FAIL" status... to fix it, see the instructions in the TODO section in file => e2e-examples/e2e-tests/1-getting-started.spec.ts_
\ No newline at end of file
diff --git a/playwright/artifacts/artifact-test-image.png b/playwright/artifacts/artifact-test-image.png
new file mode 100644
index 00000000..f844619a
Binary files /dev/null and b/playwright/artifacts/artifact-test-image.png differ
diff --git a/playwright/artifacts/artifact-test-text.txt b/playwright/artifacts/artifact-test-text.txt
new file mode 100644
index 00000000..a250a0b1
--- /dev/null
+++ b/playwright/artifacts/artifact-test-text.txt
@@ -0,0 +1 @@
+this is test artifact content
\ No newline at end of file
diff --git a/playwright/e2e-examples/README.md b/playwright/e2e-examples/README.md
index ad807c66..3051cd2a 100644
--- a/playwright/e2e-examples/README.md
+++ b/playwright/e2e-examples/README.md
@@ -2,7 +2,23 @@
This directory contains examples for Playwright. Run them with the following command:
+### e2e tests only
+
```sh
npm run test:e2e-examples
yarn test:e2e-examples
```
+
+### smoke tests only
+
+```sh
+npm run test:smoke-examples
+yarn test:smoke-examples
+```
+
+### all available tests
+
+```sh
+npm run test:e2e
+yarn test:e2e
+```
\ No newline at end of file
diff --git a/playwright/e2e-examples/1-getting-started.spec.ts b/playwright/e2e-examples/e2e-tests/1-getting-started.spec.ts
similarity index 76%
rename from playwright/e2e-examples/1-getting-started.spec.ts
rename to playwright/e2e-examples/e2e-tests/1-getting-started.spec.ts
index fcc82835..7eb053a1 100644
--- a/playwright/e2e-examples/1-getting-started.spec.ts
+++ b/playwright/e2e-examples/e2e-tests/1-getting-started.spec.ts
@@ -13,5 +13,6 @@ test('basic test', async ({ page }) => {
await inputBox.fill('Learn Playwright');
await inputBox.press('Enter');
- await expect(todoList).toHaveText('Le1arn Playwright');
+ // example of test with status FAIL
+ await expect(todoList).toHaveText('Le1arn Playwright'); //TODO: To fix update text to => 'Learn Playwright'
});
diff --git a/playwright/e2e-examples/2-actions.spec.ts b/playwright/e2e-examples/e2e-tests/2-actions.spec.ts
similarity index 96%
rename from playwright/e2e-examples/2-actions.spec.ts
rename to playwright/e2e-examples/e2e-tests/2-actions.spec.ts
index 18634ff0..58c73804 100644
--- a/playwright/e2e-examples/2-actions.spec.ts
+++ b/playwright/e2e-examples/e2e-tests/2-actions.spec.ts
@@ -44,7 +44,7 @@ test('element selectors', async ({ page }) => {
await page.click('.todoapp .footer >> text=Completed');
// Selecting based on layout, with css selector
- expect(await page.innerText('a:right-of(:text("Active"))')).toBe('Completed');
+ expect(await page.innerText('a:right-of(:text("Active"))')).toBe('Completed1'); //TODO: to fix this test use ".toBe('Completed')"
// Only visible elements, with css selector
await page.click('text=Completed >> visible=true');
diff --git a/playwright/e2e-examples/3-assertions.spec.ts b/playwright/e2e-examples/e2e-tests/3-assertions.spec.ts
similarity index 100%
rename from playwright/e2e-examples/3-assertions.spec.ts
rename to playwright/e2e-examples/e2e-tests/3-assertions.spec.ts
diff --git a/playwright/e2e-examples/4-file-uploads.spec.ts b/playwright/e2e-examples/e2e-tests/4-file-uploads.spec.ts
similarity index 100%
rename from playwright/e2e-examples/4-file-uploads.spec.ts
rename to playwright/e2e-examples/e2e-tests/4-file-uploads.spec.ts
diff --git a/playwright/e2e-examples/5-networking.spec.ts b/playwright/e2e-examples/e2e-tests/5-networking.spec.ts
similarity index 100%
rename from playwright/e2e-examples/5-networking.spec.ts
rename to playwright/e2e-examples/e2e-tests/5-networking.spec.ts
diff --git a/playwright/e2e-examples/server/assets/api/v1/users.json b/playwright/e2e-examples/e2e-tests/server/assets/api/v1/users.json
similarity index 100%
rename from playwright/e2e-examples/server/assets/api/v1/users.json
rename to playwright/e2e-examples/e2e-tests/server/assets/api/v1/users.json
diff --git a/playwright/e2e-examples/server/assets/file-uploads.html b/playwright/e2e-examples/e2e-tests/server/assets/file-uploads.html
similarity index 100%
rename from playwright/e2e-examples/server/assets/file-uploads.html
rename to playwright/e2e-examples/e2e-tests/server/assets/file-uploads.html
diff --git a/playwright/e2e-examples/server/assets/header.html b/playwright/e2e-examples/e2e-tests/server/assets/header.html
similarity index 100%
rename from playwright/e2e-examples/server/assets/header.html
rename to playwright/e2e-examples/e2e-tests/server/assets/header.html
diff --git a/playwright/e2e-examples/server/assets/index.html b/playwright/e2e-examples/e2e-tests/server/assets/index.html
similarity index 100%
rename from playwright/e2e-examples/server/assets/index.html
rename to playwright/e2e-examples/e2e-tests/server/assets/index.html
diff --git a/playwright/e2e-examples/server/assets/network.html b/playwright/e2e-examples/e2e-tests/server/assets/network.html
similarity index 100%
rename from playwright/e2e-examples/server/assets/network.html
rename to playwright/e2e-examples/e2e-tests/server/assets/network.html
diff --git a/playwright/e2e-examples/server/index.js b/playwright/e2e-examples/e2e-tests/server/index.js
similarity index 100%
rename from playwright/e2e-examples/server/index.js
rename to playwright/e2e-examples/e2e-tests/server/index.js
diff --git a/playwright/e2e-examples/playwright.config.ts b/playwright/e2e-examples/playwright-e2e.config.ts
similarity index 65%
rename from playwright/e2e-examples/playwright.config.ts
rename to playwright/e2e-examples/playwright-e2e.config.ts
index 021eeb31..e7537f1f 100644
--- a/playwright/e2e-examples/playwright.config.ts
+++ b/playwright/e2e-examples/playwright-e2e.config.ts
@@ -5,9 +5,16 @@ const config: PlaywrightTestConfig = {
// Run your local dev server before starting the tests:
// https://playwright.dev/docs/test-advanced#launching-a-development-web-server-during-the-tests
webServer: {
- command: 'node ./server',
+ command: 'node ./e2e-tests/server',
port: 4345,
cwd: __dirname,
},
+ testMatch: '*e2e-tests/*.spec.ts',
+ reporter: [
+ ['list'],
+ ['@testomatio/reporter/lib/adapter/playwright.js', {
+ apiKey: process.env.TESTOMATIO,
+ }]
+ ]
};
export default config;
diff --git a/playwright/e2e-examples/playwright-smoke.config.ts b/playwright/e2e-examples/playwright-smoke.config.ts
new file mode 100644
index 00000000..8c3b704b
--- /dev/null
+++ b/playwright/e2e-examples/playwright-smoke.config.ts
@@ -0,0 +1,13 @@
+import { PlaywrightTestConfig } from '@playwright/test';
+
+// Reference: https://playwright.dev/docs/test-configuration
+const config: PlaywrightTestConfig = {
+ testMatch: '*smoke-tests/*.spec.ts',
+ reporter: [
+ ['list'],
+ ['@testomatio/reporter/lib/adapter/playwright.js', {
+ apiKey: process.env.TESTOMATIO,
+ }]
+ ]
+};
+export default config;
diff --git a/playwright/e2e-examples/smoke-tests/smoke-test-1.spec.ts b/playwright/e2e-examples/smoke-tests/smoke-test-1.spec.ts
new file mode 100644
index 00000000..e8e2cc9e
--- /dev/null
+++ b/playwright/e2e-examples/smoke-tests/smoke-test-1.spec.ts
@@ -0,0 +1,17 @@
+import { test, expect } from '@playwright/test';
+import Basic from "../src/Basic";
+
+const basic = new Basic();
+
+test.describe('Smoke case-1', () => {
+ const basicPage = basic.basicPageUrl();
+
+ test.beforeEach(async ({ page }) => {
+ await page.goto(basicPage);
+ });
+
+ test('has title', async ({ page }) => {
+ // Expect a title "to contain" a substring.
+ await expect(page).toHaveTitle(/Playwright/);
+ });
+});
\ No newline at end of file
diff --git a/playwright/e2e-examples/smoke-tests/smoke-test-2.spec.ts b/playwright/e2e-examples/smoke-tests/smoke-test-2.spec.ts
new file mode 100644
index 00000000..d6c6d69f
--- /dev/null
+++ b/playwright/e2e-examples/smoke-tests/smoke-test-2.spec.ts
@@ -0,0 +1,35 @@
+import { test, expect } from '@playwright/test';
+import Basic from "../src/Basic";
+
+const basic = new Basic();
+
+test.describe('Basic', () => {
+ const basicPage = basic.basicPageUrl();
+
+ test.beforeEach(async ({ page }) => {
+ await page.goto(basicPage);
+ });
+ test.describe('Main Basic tests', () => {
+ test.describe('[Case 1] Basic page checks 1', () => {
+ test('get started link', async ({ page }) => {
+ await test.step(`[Check 1.1] Basic page - click the link`, async () => {
+ await page.getByRole('link', { name: 'Get started' }).click();
+ });
+ await test.step(`[Check 1.2] Get started - Expects the URL to contain intro.`, async () => {
+ await expect(page).toHaveURL(/.*intro/);
+ });
+ });
+ });
+
+ test.describe('[Case 2] Basic page checks 2', () => {
+ test('get started link', async ({ page }) => {
+ await test.step(`[Check 2.1] Basic page - click the link`, async () => {
+ await page.getByRole('link', { name: 'Get started' }).click();
+ });
+ await test.step(`[Check 2.2] Get started - Expects the URL to contain intro.`, async () => {
+ await expect(page).toHaveURL(/.*intro/);
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/playwright/e2e-examples/smoke-tests/smoke-test-3.spec.ts b/playwright/e2e-examples/smoke-tests/smoke-test-3.spec.ts
new file mode 100644
index 00000000..982a2e85
--- /dev/null
+++ b/playwright/e2e-examples/smoke-tests/smoke-test-3.spec.ts
@@ -0,0 +1,36 @@
+import { test, expect } from '@playwright/test';
+
+test.describe(
+ 'simple url cheks',
+ () => {
+ // Suite
+ test.describe('Check home page url', () => {
+ test('get started link', async ({ page }) => {
+ // Access to the basic page
+ await page.goto('https://playwright.dev/');
+
+ // Expects the 'Get started' is shown
+ await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
+ });
+ });
+
+ test.describe.skip('Check home page url (skip)', () => {
+ test('get started link (skip)', async ({ page }) => {
+ // Access to the basic page
+ await page.goto('https://playwright.dev/');
+
+ // Expects the 'Get started' is shown
+ await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
+ });
+ });
+
+ test.describe.fixme('Check home page url (fixme)', () => {
+ test('get started link (fixme)', async ({ page }) => {
+ // Access to the basic page
+ await page.goto('https://playwright.dev/');
+
+ // Expects the 'Get started' is shown
+ await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
+ });
+ });
+ });
\ No newline at end of file
diff --git a/playwright/e2e-examples/smoke-tests/smoke-test-4.spec.ts b/playwright/e2e-examples/smoke-tests/smoke-test-4.spec.ts
new file mode 100644
index 00000000..5b93826d
--- /dev/null
+++ b/playwright/e2e-examples/smoke-tests/smoke-test-4.spec.ts
@@ -0,0 +1,20 @@
+import { test, expect } from '@playwright/test';
+
+test.describe.skip('Skip condition testing', () => {
+ test.describe('All tests should be skipped', () => {
+ test('Test-1: get started linkshould be visible (first skipped)', async ({ page }) => {
+ // Access to the basic page
+ await page.goto('https://playwright.dev/');
+
+ // Expects the 'Get started' is shown
+ await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
+ });
+ test('Test-2: get started linkshould be visible (second skipped)', async ({ page }) => {
+ // Access to the basic page
+ await page.goto('https://playwright.dev/');
+
+ // Expects the 'Get started' is shown
+ await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
+ });
+ });
+});
\ No newline at end of file
diff --git a/playwright/e2e-examples/smoke-tests/smoke-test-5.spec.ts b/playwright/e2e-examples/smoke-tests/smoke-test-5.spec.ts
new file mode 100644
index 00000000..f29110f9
--- /dev/null
+++ b/playwright/e2e-examples/smoke-tests/smoke-test-5.spec.ts
@@ -0,0 +1,69 @@
+import { test, expect, type Page } from '@playwright/test';
+
+const TODO_ITEMS = [
+ 'buy some cheese',
+ 'feed the cat',
+ 'book a doctors appointment'
+];
+const URL = 'https://demo.playwright.dev/todomvc';
+
+test.describe('New Todo', () => {
+ let newTodo: any;
+
+ test.beforeEach(async ({ page }) => {
+ await page.goto(URL);
+ });
+
+ test.fixme('[Need to fix] should allow me to add todo items', async ({ page }) => {
+ await test.step(`[Check 1.1] create a new todo locator`, async () => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create 1st todo.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Make sure the list only has one todo item.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0]
+ ]);
+ });
+ });
+ test('should allow me to add todo items', async ({ page }) => {
+ await test.step(`[Check 1.1] create a new todo locator`, async () => {
+ // create a new todo locator
+ const newTodo = page.getByPlaceholder('What needs to be done?');
+
+ // Create 1st todo.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+
+ // Make sure the list only has one todo item.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0]
+ ]);
+ });
+ });
+ test('should allow me to add todo items (part 1)', async ({ page }) => {
+ await test.step(`[Check 1.2] create a new todo locator`, async () => {
+ // create a new todo locator
+ newTodo = page.getByPlaceholder('What needs to be done?');
+ });
+ await test.step(`[Check 1.3] Create 1st todo.`, async () => {
+ // Create 1st todo.
+ await newTodo.fill(TODO_ITEMS[0]);
+ await newTodo.press('Enter');
+ });
+ // Make sure the list only has one todo item.
+ await expect(page.getByTestId('todo-title')).toHaveText([
+ TODO_ITEMS[0]
+ ]);
+ await checkNumberOfTodosInLocalStorage(page, 1);
+ });
+});
+
+async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
+ return await page.waitForFunction(e => {
+ return JSON.parse(localStorage['react-todos']).length === e;
+ }, expected);
+}
\ No newline at end of file
diff --git a/playwright/e2e-examples/src/Basic.ts b/playwright/e2e-examples/src/Basic.ts
new file mode 100644
index 00000000..80dc58d3
--- /dev/null
+++ b/playwright/e2e-examples/src/Basic.ts
@@ -0,0 +1,11 @@
+export default class Basic {
+ private url: string;
+
+ public constructor() {
+ this.url = 'https://playwright.dev/';
+ }
+
+ public basicPageUrl(): string {
+ return this.url;
+ }
+}
\ No newline at end of file
diff --git a/playwright/e2e/example.spec.ts b/playwright/e2e/example.spec.ts
deleted file mode 100644
index 5381600b..00000000
--- a/playwright/e2e/example.spec.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { test, expect } from '@playwright/test';
-
-test('basic test', async ({ page }) => {
- await page.goto('https://playwright.dev/');
- await page.locator('text=Get started').click();
- await expect(page).toHaveTitle(/Getting started/);
-});
diff --git a/playwright/package.json b/playwright/package.json
index a84b4ff6..66377af0 100644
--- a/playwright/package.json
+++ b/playwright/package.json
@@ -1,20 +1,21 @@
{
- "name": "new-project",
- "version": "1.0.0",
- "description": "",
+ "name": "playwright-new-project",
+ "version": "1.1.1",
+ "description": "Running and Monitoring Playwright tests with TESTOMATIO Reporter",
"main": "index.js",
"scripts": {
- "test:e2e-examples": "playwright test --config e2e-examples/playwright.config.ts",
+ "test:e2e-examples": "playwright test --config e2e-examples/playwright-e2e.config.ts",
+ "test:smoke-examples": "playwright test --config e2e-examples/playwright-smoke.config.ts",
"test:e2e": "playwright test"
},
- "keywords": [],
- "author": "",
+ "keywords": ["e2e", "testomatio", "playwright"],
+ "author": "davert, mihaylukvv",
"license": "ISC",
"devDependencies": {
- "@playwright/test": "^1.20.1"
+ "@playwright/test": "^1.36.1"
},
"dependencies": {
- "@testomatio/reporter": "^0.4.6",
- "dotenv": "^10.0.0"
+ "@testomatio/reporter": "latest",
+ "dotenv": "^16.3.1"
}
}
diff --git a/playwright/playwright.config.ts b/playwright/playwright.config.ts
index 199ae740..da6a79aa 100644
--- a/playwright/playwright.config.ts
+++ b/playwright/playwright.config.ts
@@ -1,7 +1,6 @@
import { PlaywrightTestConfig, devices } from '@playwright/test';
-import path from 'path';
-require('dotenv').config()
+require('dotenv').config();
// Reference: https://playwright.dev/docs/test-configuration
const config: PlaywrightTestConfig = {
@@ -16,10 +15,11 @@ const config: PlaywrightTestConfig = {
// Run your local dev server before starting the tests:
// https://playwright.dev/docs/test-advanced#launching-a-development-web-server-during-the-tests
- // webServer: {
- // command: 'npm run start',
- // port: 3000,
- // },
+ webServer: {
+ command: 'node ./e2e-examples/e2e-tests/server',
+ port: 4345,
+ cwd: __dirname,
+ },
reporter: [
['list'],
['@testomatio/reporter/lib/adapter/playwright.js', {
@@ -30,7 +30,7 @@ const config: PlaywrightTestConfig = {
use: {
// Retry a test if its failing with enabled tracing. This allows you to analyse the DOM, console logs, network traffic etc.
// More information: https://playwright.dev/docs/trace-viewer
- trace: 'on-first-retry',
+ trace: 'retain-on-failure',
// All available context options: https://playwright.dev/docs/api/class-browser#browser-new-context
contextOptions: {
@@ -39,16 +39,16 @@ const config: PlaywrightTestConfig = {
screenshot: 'on',
- // video: 'retain-on-failure',
+ video: 'retain-on-failure',
},
-
- // projects: [
- // {
- // name: 'Desktop Chrome',
- // use: {
- // ...devices['Desktop Chrome'],
- // },
- // },
+ //TODO: only Chrome mode
+ projects: [
+ {
+ name: 'Desktop Chrome',
+ use: {
+ ...devices['Desktop Chrome'],
+ },
+ },
// {
// name: 'Desktop Firefox',
// use: {
@@ -72,6 +72,6 @@ const config: PlaywrightTestConfig = {
// name: 'Mobile Safari',
// use: devices['iPhone 12'],
// },
- // ],
+ ]
};
export default config;
diff --git a/playwright/run-tests-and-check-results.sh b/playwright/run-tests-and-check-results.sh
new file mode 100644
index 00000000..4028431a
--- /dev/null
+++ b/playwright/run-tests-and-check-results.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+npx playwright test > test-playwright-results.txt
+fail_tests=$(grep -oE '\b[0-9]+\s+failed\b' test-playwright-results.txt | grep -oE '[0-9]+')
+echo "Number of failed tests: $fail_tests"
+if [ "$fail_tests" -gt 7 ]; then
+ echo "More than 7 failed tests. Exiting with error."
+ exit 1
+else
+ exit 0
+fi
diff --git a/playwright/tests/image-artifact.test.js b/playwright/tests/image-artifact.test.js
new file mode 100644
index 00000000..ed67f351
--- /dev/null
+++ b/playwright/tests/image-artifact.test.js
@@ -0,0 +1,8 @@
+import { test } from '@playwright/test';
+import testomat from '@testomatio/reporter';
+
+test.describe('upload artifact 2', () => {
+ test(`upload image`, async () => {
+ testomat.artifact('artifacts/artifact-test-image.png');
+ });
+});
diff --git a/playwright/tests/logger.test.js b/playwright/tests/logger.test.js
new file mode 100644
index 00000000..79e7441c
--- /dev/null
+++ b/playwright/tests/logger.test.js
@@ -0,0 +1,20 @@
+import { test } from '@playwright/test';
+import { logger, log } from '@testomatio/reporter';
+
+logger.configure({
+ level: 'info',
+ prettyObjects: true,
+});
+
+test.describe('Logger', () => {
+ test(`logger`, async () => {
+ logger.warn('testomatio logger warn message');
+ console.log('console log message');
+
+
+ });
+
+ test(`simple log`, async () => {
+ log`This is log message`;
+ });
+});
diff --git a/playwright/tests/multiple-artifacts.test.js b/playwright/tests/multiple-artifacts.test.js
new file mode 100644
index 00000000..d35521a1
--- /dev/null
+++ b/playwright/tests/multiple-artifacts.test.js
@@ -0,0 +1,17 @@
+import { test } from '@playwright/test';
+import testomat from '@testomatio/reporter';
+
+test.describe('upload artifacts 1', () => {
+ test.beforeEach(async () => {
+ console.log('beforeEach executed');
+ });
+
+ test(`upload text file`, async () => {
+ testomat.artifact('artifacts/artifact-test-text.txt');
+ });
+
+ test(`upload second text file`, async () => {
+ testomat.step('step 1 - login');
+ testomat.artifact('artifacts/artifact-test-text2.txt');
+ });
+});
diff --git a/playwright/tests/testomat-functions.test.js b/playwright/tests/testomat-functions.test.js
new file mode 100644
index 00000000..7d63876d
--- /dev/null
+++ b/playwright/tests/testomat-functions.test.js
@@ -0,0 +1,12 @@
+import { test } from '@playwright/test';
+import testomat from '@testomatio/reporter';
+
+test.describe('Testomat functions', () => {
+ test('artifact @T64346bdd', async () => {
+ testomat.artifact('artifacts/artifact-test-image.png');
+ });
+
+ test('testomat log', async () => {
+ testomat.log`This is log message`;
+ });
+});
diff --git a/wdio/cucumber/.gitignore b/wdio/cucumber/.gitignore
new file mode 100644
index 00000000..3c3629e6
--- /dev/null
+++ b/wdio/cucumber/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/wdio/cucumber/README.md b/wdio/cucumber/README.md
new file mode 100644
index 00000000..05adc039
--- /dev/null
+++ b/wdio/cucumber/README.md
@@ -0,0 +1,5 @@
+### Prepare
+`npm i`
+
+### Run
+`npm test`
\ No newline at end of file
diff --git a/wdio/cucumber/features/addNumbers.feature b/wdio/cucumber/features/addNumbers.feature
new file mode 100644
index 00000000..3207c7f5
--- /dev/null
+++ b/wdio/cucumber/features/addNumbers.feature
@@ -0,0 +1,13 @@
+@Sad520f3c
+Feature: Add number
+ I want to check if two numbers can be added
+
+ @some-tag1 @Tf37e0731
+ Scenario: Add two positive numbers
+ When I add two numbers 2 and 3
+ Then return the sum of 2 and 3 as 5
+
+ @some-tag2 @T6e4a0318
+ Scenario: Should fail
+ When I add two numbers 2 and 3
+ Then return the sum of 2 and 3 as 6
diff --git a/wdio/cucumber/package.json b/wdio/cucumber/package.json
new file mode 100644
index 00000000..2c2e6343
--- /dev/null
+++ b/wdio/cucumber/package.json
@@ -0,0 +1,34 @@
+{
+ "author": "Oleksandr Pelykh",
+ "license": "MIT",
+ "name": "wdio-cucumber-example",
+ "version": "0.0.1",
+ "description": "Boilerplate project to run WebdriverIO tests with Cucumber and report to Testomat.io",
+ "scripts": {
+ "test": "wdio run wdio.conf.ts"
+ },
+ "devDependencies": {
+ "@testomatio/reporter": "file:../../../reporter/testomatio-reporter-1.3.0.tgz",
+ "@types/chai": "^4.3.14",
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
+ "@typescript-eslint/parser": "^7.0.1",
+ "@wdio/cli": "^8.32.2",
+ "@wdio/config": "^8.32.2",
+ "@wdio/cucumber-framework": "^8.32.2",
+ "@wdio/globals": "^8.32.2",
+ "@wdio/local-runner": "^8.32.2",
+ "@wdio/spec-reporter": "^8.32.2",
+ "@wdio/static-server-service": "^8.32.2",
+ "eslint": "^8.56.0",
+ "eslint-config-airbnb-base": "^15.0.0",
+ "eslint-plugin-import": "^2.29.1",
+ "eslint-plugin-wdio": "^8.24.12",
+ "npm-run-all": "^4.1.5",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.3.3",
+ "webdriverio": "^8.32.2"
+ },
+ "dependencies": {
+ "chai": "^5.1.0"
+ }
+}
diff --git a/wdio/cucumber/src/steps/script.ts b/wdio/cucumber/src/steps/script.ts
new file mode 100644
index 00000000..089f6946
--- /dev/null
+++ b/wdio/cucumber/src/steps/script.ts
@@ -0,0 +1,3 @@
+export function addTwoNumbers(a: number, b: number) {
+ return a + b;
+}
diff --git a/wdio/cucumber/src/steps/then.ts b/wdio/cucumber/src/steps/then.ts
new file mode 100644
index 00000000..9e69d38b
--- /dev/null
+++ b/wdio/cucumber/src/steps/then.ts
@@ -0,0 +1,8 @@
+import { Then } from '@cucumber/cucumber';
+import { addTwoNumbers } from './script';
+import assert from 'assert';
+
+// result should correspond to the sum of the two numbers
+Then(/^return the sum of (\d+) and (\d+) as (\d+)$/, (num1: number, num2: number, result: number) => {
+ assert(addTwoNumbers(num1, num2) === result, 'The result is not correct');
+});
diff --git a/wdio/cucumber/src/steps/when.ts b/wdio/cucumber/src/steps/when.ts
new file mode 100644
index 00000000..adc1b8fe
--- /dev/null
+++ b/wdio/cucumber/src/steps/when.ts
@@ -0,0 +1,7 @@
+import { When } from '@cucumber/cucumber';
+import { addTwoNumbers } from './script';
+
+When(
+ /I add two numbers (\d+) and (\d+)/,
+ addTwoNumbers
+);
diff --git a/wdio/cucumber/tsconfig.json b/wdio/cucumber/tsconfig.json
new file mode 100644
index 00000000..f3f81fed
--- /dev/null
+++ b/wdio/cucumber/tsconfig.json
@@ -0,0 +1,75 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Basic Options */
+ // "incremental": true, /* Enable incremental compilation */
+ "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
+ "target": "es2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
+ // "lib": [], /* Specify library files to be included in the compilation. */
+ "allowJs": true, /* Allow javascript files to be compiled. */
+ // "checkJs": true, /* Report errors in .js files. */
+ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+ // "declaration": true, /* Generates corresponding '.d.ts' file. */
+ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
+ // "sourceMap": true, /* Generates corresponding '.map' file. */
+ // "outFile": "./", /* Concatenate and emit output to single file. */
+ // "outDir": "./", /* Redirect output structure to the directory. */
+ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
+ // "composite": true, /* Enable project compilation */
+ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
+ // "removeComments": true, /* Do not emit comments to output. */
+ // "noEmit": true, /* Do not emit outputs. */
+ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
+ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+ "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+
+ /* Strict Type-Checking Options */
+ "strict": true, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* Enable strict null checks. */
+ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
+ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
+ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
+ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
+
+ /* Additional Checks */
+ // "noUnusedLocals": true, /* Report errors on unused locals. */
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
+
+ /* Module Resolution Options */
+ "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
+ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
+ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
+ // "typeRoots": [], /* List of folders to include type definitions from. */
+ "types": [
+ "node",
+ "@wdio/globals/types",
+ "@wdio/cucumber-framework",
+ "expect-webdriverio"
+ ], /* Type declaration files to be included in compilation. */
+ "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
+ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
+ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+
+ /* Source Map Options */
+ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
+ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+ /* Experimental Options */
+ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
+ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
+
+ /* Advanced Options */
+ "skipLibCheck": true, /* Skip type checking of declaration files. */
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
+ }
+}
diff --git a/wdio/cucumber/wdio.conf.ts b/wdio/cucumber/wdio.conf.ts
new file mode 100644
index 00000000..facf733d
--- /dev/null
+++ b/wdio/cucumber/wdio.conf.ts
@@ -0,0 +1,176 @@
+import type { Options } from '@wdio/types'
+// const testomatio = require('@testomatio/reporter/lib/adapter/wdio-cucumber');
+const testomatio = require('@testomatio/reporter/lib/adapter/webdriver');
+
+export const config: Options.Testrunner = {
+ //
+ // ====================
+ // Runner Configuration
+ // ====================
+ // WebdriverIO supports running e2e tests as well as unit and component tests.
+ runner: 'local',
+ autoCompileOpts: {
+ autoCompile: true,
+ tsNodeOpts: {
+ project: './tsconfig.json',
+ transpileOnly: true
+ }
+ },
+
+ //
+ // ==================
+ // Specify Test Files
+ // ==================
+ // Define which test specs should run. The pattern is relative to the directory
+ // of the configuration file being run.
+ //
+ // The specs are defined as an array of spec files (optionally using wildcards
+ // that will be expanded). The test for each spec file will be run in a separate
+ // worker process. In order to have a group of spec files run in the same worker
+ // process simply enclose them in an array within the specs array.
+ //
+ // The path of the spec files will be resolved relative from the directory of
+ // of the config file unless it's absolute.
+ //
+ specs: [
+ './features/**/*.feature',
+ ],
+ // Patterns to exclude.
+ exclude: [
+ // 'path/to/excluded/files'
+ ],
+ //
+ // ============
+ // Capabilities
+ // ============
+ // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
+ // time. Depending on the number of capabilities, WebdriverIO launches several test
+ // sessions. Within your capabilities you can overwrite the spec and exclude options in
+ // order to group specific specs to a specific capability.
+ //
+ // First, you can define how many instances should be started at the same time. Let's
+ // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
+ // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
+ // files and you set maxInstances to 10, all spec files will get tested at the same time
+ // and 30 processes will get spawned. The property handles how many capabilities
+ // from the same test should run tests.
+ //
+ maxInstances: 5,
+ //
+ // If you have trouble getting all important capabilities together, check out the
+ // Sauce Labs platform configurator - a great tool to configure your capabilities:
+ // https://saucelabs.com/platform/platform-configurator
+ //
+ capabilities: [{
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ args: ['headless', 'disable-gpu']
+ }
+ }],
+
+ //
+ // ===================
+ // Test Configurations
+ // ===================
+ // Define all options that are relevant for the WebdriverIO instance here
+ //
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ logLevel: 'warn',
+ //
+ // Set specific log levels per logger
+ // loggers:
+ // - webdriver, webdriverio
+ // - @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
+ // - @wdio/mocha-framework, @wdio/jasmine-framework
+ // - @wdio/local-runner
+ // - @wdio/sumologic-reporter
+ // - @wdio/cli, @wdio/config, @wdio/utils
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ // logLevels: {
+ // webdriver: 'info',
+ // '@wdio/appium-service': 'info'
+ // },
+ //
+ // If you only want to run your tests until a specific amount of tests have failed use
+ // bail (default is 0 - don't bail, run all tests).
+ bail: 0,
+ //
+ // Set a base URL in order to shorten url command calls. If your `url` parameter starts
+ // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
+ // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
+ // gets prepended directly.
+ // baseUrl: 'http://localhost:8080',
+ //
+ // Default timeout for all waitFor* commands.
+ waitforTimeout: 10000,
+ //
+ // Default timeout in milliseconds for request
+ // if browser driver or grid doesn't send response
+ connectionRetryTimeout: 120000,
+ //
+ // Default request retries count
+ connectionRetryCount: 3,
+ //
+ // Test runner services
+ // Services take over a specific job you don't want to take care of. They enhance
+ // your test setup with almost no effort. Unlike plugins, they don't add new
+ // commands. Instead, they hook themselves up into the test process.
+ // services: [],
+ //
+ // Framework you want to run your specs with.
+ // The following are supported: Mocha, Jasmine, and Cucumber
+ // see also: https://webdriver.io/docs/frameworks
+ //
+ // Make sure you have the wdio adapter package for the specific framework installed
+ // before running any tests.
+ framework: 'cucumber',
+
+ cucumberOpts: {
+ backtrace: false,
+ requireModule: [],
+ failAmbiguousDefinitions: true,
+ failFast: false,
+ ignoreUndefinedDefinitions: false,
+ names: [],
+ snippets: true,
+ source: true,
+ profile: [],
+ require: [
+ './src/steps/then.ts',
+ './src/steps/when.ts',
+ ],
+ scenarioLevelReporter: false,
+ order: 'defined',
+ snippetSyntax: undefined,
+ strict: true,
+ tagExpression: 'not @Pending',
+ tagsInTitle: false,
+ timeout: 20000,
+ } as WebdriverIO.CucumberOpts,
+
+ //
+ // The number of times to retry the entire specfile when it fails as a whole
+ // specFileRetries: 1,
+ //
+ // Delay in seconds between the spec file retry attempts
+ // specFileRetriesDelay: 0,
+ //
+ // Whether or not retried spec files should be retried immediately or deferred to the end of the queue
+ // specFileRetriesDeferred: false,
+ //
+ // Test reporter for stdout.
+ // The only one supported by default is 'dot'
+ // see also: https://webdriver.io/docs/dot-reporter
+ reporters: ['spec',
+ [testomatio, {
+ apiKey: `${process.env.TESTOMATIO}`
+ }]
+ ],
+
+ // Options to be passed to Mocha.
+ // See the full list at http://mochajs.org/
+ mochaOpts: {
+ ui: 'bdd',
+ timeout: 60000
+ },
+}
diff --git a/wdio/v7/package.json b/wdio/v7/package.json
new file mode 100644
index 00000000..7d780306
--- /dev/null
+++ b/wdio/v7/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "testomat-example-wdio-v7",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "npx start-test-run -c 'wdio run ./test/wdio.conf.ts' --env-file .env"
+ },
+ "author": "",
+ "license": "ISC",
+ "devDependencies": {
+ "@wdio/cli": "^7.34.0",
+ "@wdio/local-runner": "^7.34.0",
+ "@wdio/mocha-framework": "^7.33.0",
+ "@wdio/spec-reporter": "^7.33.0",
+ "chromedriver": "^121.0.0",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.3.3",
+ "wdio-chromedriver-service": "^8.1.1"
+ },
+ "dependencies": {
+ "@testomatio/reporter": "file:../../../reporter/testomatio-reporter-1.1.1.tgz",
+ "webdriverio": "^7.34.0"
+ }
+}
diff --git a/wdio/v7/test/pageobjects/login.page.ts b/wdio/v7/test/pageobjects/login.page.ts
new file mode 100644
index 00000000..b117fb0d
--- /dev/null
+++ b/wdio/v7/test/pageobjects/login.page.ts
@@ -0,0 +1,42 @@
+import { ChainablePromiseElement } from 'webdriverio';
+
+import Page from './page';
+
+/**
+ * sub page containing specific selectors and methods for a specific page
+ */
+class LoginPage extends Page {
+ /**
+ * define selectors using getter methods
+ */
+ public get inputUsername () {
+ return $('#username');
+ }
+
+ public get inputPassword () {
+ return $('#password');
+ }
+
+ public get btnSubmit () {
+ return $('button[type="submit"]');
+ }
+
+ /**
+ * a method to encapsule automation code to interact with the page
+ * e.g. to login using username and password
+ */
+ public async login (username: string, password: string) {
+ await this.inputUsername.setValue(username);
+ await this.inputPassword.setValue(password);
+ await this.btnSubmit.click();
+ }
+
+ /**
+ * overwrite specific options to adapt it to page object
+ */
+ public open () {
+ return super.open('login');
+ }
+}
+
+export default new LoginPage();
diff --git a/wdio/v7/test/pageobjects/page.ts b/wdio/v7/test/pageobjects/page.ts
new file mode 100644
index 00000000..fc8be333
--- /dev/null
+++ b/wdio/v7/test/pageobjects/page.ts
@@ -0,0 +1,13 @@
+/**
+* main page object containing all methods, selectors and functionality
+* that is shared across all page objects
+*/
+export default class Page {
+ /**
+ * Opens a sub page of the page
+ * @param path path of the sub page (e.g. /path/to/page.html)
+ */
+ public open (path: string) {
+ return browser.url(`https://the-internet.herokuapp.com/${path}`)
+ }
+}
diff --git a/wdio/v7/test/pageobjects/secure.page.ts b/wdio/v7/test/pageobjects/secure.page.ts
new file mode 100644
index 00000000..35b7dca1
--- /dev/null
+++ b/wdio/v7/test/pageobjects/secure.page.ts
@@ -0,0 +1,17 @@
+import { ChainablePromiseElement } from 'webdriverio';
+
+import Page from './page';
+
+/**
+ * sub page containing specific selectors and methods for a specific page
+ */
+class SecurePage extends Page {
+ /**
+ * define selectors using getter methods
+ */
+ public get flashAlert () {
+ return $('#flash');
+ }
+}
+
+export default new SecurePage();
diff --git a/wdio/v7/test/specs/example.e2e.ts b/wdio/v7/test/specs/example.e2e.ts
new file mode 100644
index 00000000..c382b88f
--- /dev/null
+++ b/wdio/v7/test/specs/example.e2e.ts
@@ -0,0 +1,15 @@
+import LoginPage from '../pageobjects/login.page';
+import SecurePage from '../pageobjects/secure.page';
+
+describe('My Login application @S1806fa9f', () => {
+ it('should login with valid credentials @T6980b031', async () => {
+ await LoginPage.open();
+
+ await LoginPage.login('tomsmith', 'SuperSecretPassword!');
+ await expect(SecurePage.flashAlert).toBeExisting();
+ await expect(SecurePage.flashAlert).toHaveTextContaining(
+ 'You logged into a secure area!');
+ });
+});
+
+
diff --git a/wdio/v7/test/tsconfig.json b/wdio/v7/test/tsconfig.json
new file mode 100644
index 00000000..c53bd32d
--- /dev/null
+++ b/wdio/v7/test/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "moduleResolution": "node",
+ "types": [
+ "node",
+ "webdriverio/async",
+ "@wdio/mocha-framework",
+ "expect-webdriverio"
+ ],
+ "target": "es2019"
+ }
+}
\ No newline at end of file
diff --git a/wdio/v7/test/wdio.conf.ts b/wdio/v7/test/wdio.conf.ts
new file mode 100644
index 00000000..237c1df4
--- /dev/null
+++ b/wdio/v7/test/wdio.conf.ts
@@ -0,0 +1,325 @@
+import type { Options } from '@wdio/types'
+const testomatio = require('@testomatio/reporter/lib/adapter/webdriver');
+
+require('dotenv').config({ path: './.env' });
+
+export const config: Options.Testrunner = {
+ //
+ // ====================
+ // Runner Configuration
+ // ====================
+ //
+ //
+ // =====================
+ // ts-node Configurations
+ // =====================
+ //
+ // You can write tests using TypeScript to get autocompletion and type safety.
+ // You will need typescript and ts-node installed as devDependencies.
+ // WebdriverIO will automatically detect if these dependencies are installed
+ // and will compile your config and tests for you.
+ // If you need to configure how ts-node runs please use the
+ // environment variables for ts-node or use wdio config's autoCompileOpts section.
+ //
+
+ autoCompileOpts: {
+ autoCompile: true,
+ // see https://github.com/TypeStrong/ts-node#cli-and-programmatic-options
+ // for all available options
+ tsNodeOpts: {
+ transpileOnly: true,
+ project: 'test/tsconfig.json'
+ }
+ // tsconfig-paths is only used if "tsConfigPathsOpts" are provided, if you
+ // do please make sure "tsconfig-paths" is installed as dependency
+ // tsConfigPathsOpts: {
+ // baseUrl: './'
+ // }
+ },
+ //
+ // ==================
+ // Specify Test Files
+ // ==================
+ // Define which test specs should run. The pattern is relative to the directory
+ // from which `wdio` was called.
+ //
+ // The specs are defined as an array of spec files (optionally using wildcards
+ // that will be expanded). The test for each spec file will be run in a separate
+ // worker process. In order to have a group of spec files run in the same worker
+ // process simply enclose them in an array within the specs array.
+ //
+ // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script),
+ // then the current working directory is where your `package.json` resides, so `wdio`
+ // will be called from there.
+ //
+ specs: [
+ './test/specs/**/*.ts'
+ ],
+ // Patterns to exclude.
+ exclude: [
+ // 'path/to/excluded/files'
+ ],
+ //
+ // ============
+ // Capabilities
+ // ============
+ // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
+ // time. Depending on the number of capabilities, WebdriverIO launches several test
+ // sessions. Within your capabilities you can overwrite the spec and exclude options in
+ // order to group specific specs to a specific capability.
+ //
+ // First, you can define how many instances should be started at the same time. Let's
+ // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
+ // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
+ // files and you set maxInstances to 10, all spec files will get tested at the same time
+ // and 30 processes will get spawned. The property handles how many capabilities
+ // from the same test should run tests.
+ //
+ maxInstances: 10,
+ //
+ // If you have trouble getting all important capabilities together, check out the
+ // Sauce Labs platform configurator - a great tool to configure your capabilities:
+ // https://saucelabs.com/platform/platform-configurator
+ //
+ capabilities: [{
+
+ // maxInstances can get overwritten per capability. So if you have an in-house Selenium
+ // grid with only 5 firefox instances available you can make sure that not more than
+ // 5 instances get started at a time.
+ maxInstances: 5,
+ //
+ browserName: 'chrome',
+ acceptInsecureCerts: true
+ // If outputDir is provided WebdriverIO can capture driver session logs
+ // it is possible to configure which logTypes to include/exclude.
+ // excludeDriverLogs: ['*'], // pass '*' to exclude all driver session logs
+ // excludeDriverLogs: ['bugreport', 'server'],
+ }],
+ //
+ // ===================
+ // Test Configurations
+ // ===================
+ // Define all options that are relevant for the WebdriverIO instance here
+ //
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ logLevel: 'warn',
+ //
+ // Set specific log levels per logger
+ // loggers:
+ // - webdriver, webdriverio
+ // - @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
+ // - @wdio/mocha-framework, @wdio/jasmine-framework
+ // - @wdio/local-runner
+ // - @wdio/sumologic-reporter
+ // - @wdio/cli, @wdio/config, @wdio/utils
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ // logLevels: {
+ // webdriver: 'info',
+ // '@wdio/appium-service': 'info'
+ // },
+ //
+ // If you only want to run your tests until a specific amount of tests have failed use
+ // bail (default is 0 - don't bail, run all tests).
+ bail: 0,
+ //
+ // Set a base URL in order to shorten url command calls. If your `url` parameter starts
+ // with `/`, the base url gets prepended, not including the path portion of your baseUrl.
+ // If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
+ // gets prepended directly.
+ baseUrl: 'http://localhost',
+ //
+ // Default timeout for all waitFor* commands.
+ waitforTimeout: 10000,
+ //
+ // Default timeout in milliseconds for request
+ // if browser driver or grid doesn't send response
+ connectionRetryTimeout: 120000,
+ //
+ // Default request retries count
+ connectionRetryCount: 3,
+ //
+ // Test runner services
+ // Services take over a specific job you don't want to take care of. They enhance
+ // your test setup with almost no effort. Unlike plugins, they don't add new
+ // commands. Instead, they hook themselves up into the test process.
+ services: ['chromedriver'],
+
+ // Framework you want to run your specs with.
+ // The following are supported: Mocha, Jasmine, and Cucumber
+ // see also: https://webdriver.io/docs/frameworks
+ //
+ // Make sure you have the wdio adapter package for the specific framework installed
+ // before running any tests.
+ framework: 'mocha',
+ //
+ // The number of times to retry the entire specfile when it fails as a whole
+ // specFileRetries: 1,
+ //
+ // Delay in seconds between the spec file retry attempts
+ // specFileRetriesDelay: 0,
+ //
+ // Whether or not retried specfiles should be retried immediately or deferred to the end of the queue
+ // specFileRetriesDeferred: false,
+ //
+ // Test reporter for stdout.
+ // The only one supported by default is 'dot'
+ // see also: https://webdriver.io/docs/dot-reporter
+ reporters: ['spec',
+ [testomatio, { apiKey: process.env.TESTOMATIO }]
+ ],
+
+ //
+ // Options to be passed to Mocha.
+ // See the full list at http://mochajs.org/
+ mochaOpts: {
+ ui: 'bdd',
+ timeout: 60000
+ },
+ //
+ // =====
+ // Hooks
+ // =====
+ // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
+ // it and to build services around it. You can either apply a single function or an array of
+ // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
+ // resolved to continue.
+ /**
+ * Gets executed once before all workers get launched.
+ * @param {Object} config wdio configuration object
+ * @param {Array.