https://github.com/simple-automation-testing/protractor-parallel-retrier
https://github.com/simple-automation-testing/protractor-parallel-retrier
automation-test parallel-execution protractor-flaky protractor-parallel tetry-tests
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/simple-automation-testing/protractor-parallel-retrier
- Owner: Simple-Automation-Testing
- License: mit
- Created: 2020-09-05T09:19:25.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2021-01-22T09:47:42.000Z (over 4 years ago)
- Last Synced: 2025-02-23T12:05:03.272Z (4 months ago)
- Topics: automation-test, parallel-execution, protractor-flaky, protractor-parallel, tetry-tests
- Language: TypeScript
- Homepage:
- Size: 27.3 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# protractor-parallel-retrier
🛠Development in progress, beta version

## This library is a wrapper around ```process-rerun```
### The purpose of this library is - build simple and flexible interface for protractor framework parallel execution with rerun (on fail) possibility
[Usage and Example](#usage)
[Documentation](#documentation)
* [buildExecutor](#buildexecutor)
* [byIt](#byit)
* [byFile](#byit)
* [asQueue](#asqueue)
* [executor](#executor)
* [execute](#execute)### usage
```js
const {buildExecutor} = require('protractor-parallel-retrier');executeAsQueue();
async function executeAsQueue() {const testCaseRegPattern = /(?<=it\(').+(?=')/ig;
const cwd = process.cwd();const result = await buildExecutor(resolve(cwd, './protractor.conf.js'), resolve(cwd, './built/specs'))
.asQueue(testCaseRegPattern, ['test case it name 1', 'test case it name 2', 'test case it name 3'])
.command({'--process-argument': 'process-argument-value'}, {ENV_VARIABLE: 'en-varialbe-value'})
.executor({attemptsCount: 2, maxThreads: 1, logLevel: 'VERBOSE', longestProcessTime: 60 * 1000, pollTime: 100})
.execute();console.log(result);
if(result.retriable.length || result.notRetriable.length) {
process.exit(1);
}
}executeOnlyRequiredCases();
async function executeAsQueue() {const testCaseRegPattern = /(?<=it\(').+(?=')/ig;
const cwd = process.cwd();const result = await buildExecutor(resolve(cwd, './protractor.conf.js'), resolve(cwd, './built/specs'))
.asQueue(testCaseRegPattern, ['test case it name 1', 'test case it name 2', 'test case it name 3'])
.command({'--process-argument': 'process-argument-value'}, {ENV_VARIABLE: 'en-varialbe-value'})
.executor({attemptsCount: 2, maxThreads: 10, logLevel: 'VERBOSE', longestProcessTime: 60 * 1000, pollTime: 100})
.execute();console.log(result);
if(result.retriable.length || result.notRetriable.length) {
process.exit(1);
}
}executeByFile();
async function executeByFile() {
const cwd = process.cwd();
const result = await buildExecutor(resolve(cwd, './protractor.conf.js'), resolve(cwd, './built/specs'))
.byFile()
.command({'--process-argument': 'process-argument-value'}, {ENV_VARIABLE: 'en-varialbe-value'})
.executor({attemptsCount: 2, maxThreads: 5, logLevel: 'VERBOSE', longestProcessTime: 60 * 1000, pollTime: 100})
.execute();console.log(result);
if(result.retriable.length || result.notRetriable.length) {
process.exit(1);
}
}executeByIt();
async function executeByIt() {
const cwd = process.cwd();
const testCaseRegPattern = /(?<=it\(').+(?=')/ig;
const result = await buildExecutor(resolve(cwd, './protractor.conf.js'), resolve(cwd, './built/specs'))
.byIt(testCaseRegPattern)
.command({'--process-argument': 'process-argument-value'}, {ENV_VARIABLE: 'en-varialbe-value'})
.executor({attemptsCount: 2, maxThreads: 2, logLevel: 'VERBOSE', longestProcessTime: 60 * 1000, pollTime: 100})
.execute();console.log(result);
if(result.retriable.length || result.notRetriable.length) {
process.exit(1);
}
}
```## Documentation
## buildExecutor
**`buildExecutor('./path/to/protractor.conf.js', './path/to/specs/folder')`**
arguments | description
--- | ---
**`pathToProtractorConfigFile`** | Type: `string`
Path to protractor config file
**`pathToSpecFolderOrSpecsFilesList`** | Type: `string` or `string[]`
Path to specs folder, or list (array) with specs files path;**`returns {byIt: function; byFile: function; asQueue: function}`**
## byIt
**`buildExecutor(...args).byIt(/(?<=it\(').+(?=')/ig) or .byIt()`**
arguments | description
--- | ---
**`itPattern`** | Type: OPTIONAL `RegEx`
RegEx for it title. example it('test item'); -> itRegEx = /(?<=it\(').+(?=')/ig;
in case of undefined library will define ***itPattern*** based on first symbol in it title;
**`pathToSpecFolderOrSpecsFilesList`** | Type: `string` or `string[]`
Path to specs folder, or list (array) with specs files path;**`returns {command: function}`**
## byFile
**`buildExecutor(...args).byFile()`**
#### no arguments here
**`returns {command: function}`**
## asQueue
**`buildExecutor(...args).asQueue(/(?<=it\(').+(?=')/ig, ['test1', 'test2', 'test 10']) or buildExecutor(...args).asQueue(['test1', 'test2', 'test 10'])`**
arguments | description
--- | ---
**`itPattern`** | Type: OPTIONAL `RegEx`
RegEx for it title. example it('test item'); -> itRegEx = /(?<=it\(').+(?=')/ig;
in case of undefined library will define ***itPattern*** based on first symbol in it title;
**`casesList`** | Type: `string[]`
List with tests what should be executed one by on `can be first argument, because itPattern is an optional`**`returns {command: function}`**
## command
**`buildExecutor(...args).asQueue(...args1).command({'--test': 'test'}, {ENV: 'test'}) or buildExecutor(...args).asQueue(...args1).command()`**
arguments | description
--- | ---
**`processArgs`** | Type: `undefined` or `null` or `{[prop: string]: string}`
Object with required process argumentss, use format prop name with - or --, example '--prop' or '-p'
**`processEnvVars`** | Type: `undefined` or `null` or `{[prop: string]: string}`
Object with required process env variables, use format prop name upper snake_case, LOG_LEVEL**`returns {executor: function}`**
## executor
**`buildExecutor(...args).asQueue(...args1).command().executor({maxThreads: 1, attemptsCount: 2, logLevel: 'ERROR'})`**
arguments | description
--- | ---
**`buildOpts`** | Type: `object`
Options for executor
**`buildOpts.maxThreads`** | Type: `number`,
How many threads can be executed in same time
**Default threads count is 5**
**`buildOpts.attemptsCount`** | Type: `number`,
How many times can we try to execute command for success result **in next cycle will be executed only faild command, success commands will not be reexecuted**
**Default attempts count is 2**
**`buildOpts.pollTime`** | Type: `number` ,
Period for recheck about free thread
**Default is 1 second**
**`buildOpts.logLevel`** | Type: `string`, one of 'ERROR', 'WARN', 'INFO', 'VERBOSE',
ERROR - only errors, WARN - errors and warnings, INFO - errors, warnings and information, VERBOSE - full logging
**Default is 'ERROR'**
**`buildOpts.currentExecutionVariable`** | Type: `string`, will be execution variable with execution index for every cycle will be ++
**`buildOpts.everyCycleCallback`** | Type: `function`,
Optional. everyCycleCallback will be executed after cycle, before next execution cycle.
**Default is false**
**`buildOpts.processResultAnalyzer`** | Type: `function`,
Optional. processResultAnalyzer is a function where arguments are original command, execution stack trace and notRetriable array processResultAnalyzer should return a new command what will be executed in next cycle or **null** - if satisfactory result
**`buildOpts.longestProcessTime`** | Type: `number`,
In case if command execution time is longer than longest Process Time - executor will kill it automatically and will try to execute this command again.
**Default time is 45 seconds****`returns {execute: async function}`**
## execute
**`buildExecutor(...args).asQueue(...args1).command().executor(...args2).execute()`**
#### no arguments here
**`returns {retriable: string[]; notRetriable: string[]}`**