Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
abainczyk committed Jul 26, 2019
2 parents 79dece1 + cc16f99 commit c0d9222
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 87 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ALEX CLI

A command line interface for running tests and learning experiments with [ALEX](https://github.com/LearnLib/alex) **(v1.6.0)**.
A command line interface for running tests and learning experiments with [ALEX](https://github.com/LearnLib/alex) **(v1.7.0)**.

## Requirements

Expand All @@ -27,9 +27,9 @@ node alex-cli.js -h

## Usage

1. Export the symbols from ALEX ([see here](http://learnlib.github.io/alex/book/1.4.0/contents/user-manual/symbol-modeling/#export--import)).
1. Export the symbols from ALEX ([see here](http://learnlib.github.io/alex/book/1.7.0/contents/user-manual/symbol-modeling/#export--import)).
* When asked, select the option **Export symbols only**
2. Export the tests from ALEX ([see here](http://learnlib.github.io/alex/book/1.4.0/contents/user-manual/testing.html)).
2. Export the tests from ALEX ([see here](http://learnlib.github.io/alex/book/1.7.0/contents/user-manual/testing.html)).

Execute `node alex-cli.js -h` to see a complete list of parameters and their descriptions.
For examples see the section below.
Expand All @@ -46,9 +46,8 @@ For examples see the section below.
"implicitlyWait": 0,
"pageLoadTimeout": 10,
"scriptTimeout": 10,
"name": "firefox",
"headless": true,
"xvfbPort": null
"name": "chrome",
"headless": true
}
}
```
Expand All @@ -60,31 +59,32 @@ For examples see the section below.
|implicitlyWait|Selenium implicit timeout value|
|pageLoadTimeout|Selenium page load timeout value|
|scriptTimeout|Selenium script timeout value|
|name|The name of the browser, 'firefox', 'chrome', 'htmlUnit'|
|name|The name of the browser, 'firefox', 'chrome', 'htmlUnit', 'ie', 'safari', 'edge'|
|headless|If the browser is run headless. Only for Firefox and Chrome|
|xvfbPort|The port of the virtual display. Only for Firefox and Chrome|

### CLI

#### Testing

```bash
node alex-cli.js --uri "http://alex.some-server.de" \
--target "https://www.google.com" \
node alex-cli.js --uri "http://localhost:8080" \
--targets "https://www.google.com,https://www.google.com" \
-a "test" \
-u "[email protected]:admin" \
-s "./symbols.json" \
-t "./tests.json" \
-c "./config.testing.json"
--clean-up
```

#### Learning

```bash
node alex-cli.js --uri "http://alex.some-server.de" \
--target "https://www.google.com" \
--target "https://www.google.com,https://www.google.com" \
-a "learn" \
-u "[email protected]:admin" \
-s "./symbols.json" \
-c "./config.learning.json"
--clean-up
```
56 changes: 35 additions & 21 deletions alex-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ function credentials(value) {
}

program
.version('1.1.0')
.version('1.2.0')
.option('--uri [uri]', 'The URI where ALEX is running without trailing \'/\'')
.option('--target [target]', 'The base URL of the target application')
.option('--targets [targets]', 'The base URL and mirrors of the target application as comma separated list')
.option('--clean-up', 'If the project is deleted after a test or learning process')
.option('-a, --action [action]', 'What do you want to do with ALEX? [test|learn]')
.option('-u, --user [credentials]', 'Credentials with the pattern "email:password"', credentials)
.option('-s, --symbols [file]', 'Add the json file that contains all necessary symbols')
Expand Down Expand Up @@ -152,7 +153,7 @@ function login(user) {
*/
function createProject() {
const createProjectName = () => {
let text = 'cli-';
let text = 'alex-cli-';
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

for (let i = 0; i < 24; i++) {
Expand All @@ -162,6 +163,9 @@ function createProject() {
return text;
};

const urls = program.targets.split(',').map(u => ({url: u, default: false}));
urls[0].default = true;

return request({
method: 'POST',
uri: `${_uri}/projects`,
Expand All @@ -171,9 +175,7 @@ function createProject() {
},
body: JSON.stringify({
name: createProjectName(),
urls: [
{url: program.target, default: true}
]
urls: urls
})
});
}
Expand Down Expand Up @@ -223,7 +225,7 @@ function createTests() {
function prepareTestCase(tc) {
const mapSymbolIds = (steps) => {
steps.forEach(step => {
step.pSymbol.symbol = _symbols.find(s => s.name === step.pSymbol.symbolFromName).id;
step.pSymbol.symbol = {id: _symbols.find(s => s.name === step.pSymbol.symbol.name).id};
});
};

Expand Down Expand Up @@ -366,8 +368,22 @@ function startTesting() {
* @return {Promise<*>}
*/
function startLearning() {

// symbolId -> parameterName -> parameter
// needed to set the ids of the parameters by name
const inputParamMap = {};
_symbols.forEach(sym => {
inputParamMap[sym.id] = inputParamMap[sym.id] == null ? {} : inputParamMap[sym.id];
sym.inputs.forEach(input => {
inputParamMap[sym.id][input.name] = input;
});
});

const mapSymbolIds = (pSymbol) => {
pSymbol.symbol = _symbols.find(s => s.name === pSymbol.symbolFromName).id;
pSymbol.symbol = {id: _symbols.find(s => s.name === pSymbol.symbol.name).id};
pSymbol.parameterValues.forEach(pv => {
pv.parameter.id = inputParamMap[pSymbol.symbol.id][pv.parameter.name].id;
})
};

_config.symbols.forEach(mapSymbolIds);
Expand All @@ -387,7 +403,7 @@ function startLearning() {
'Authorization': `Bearer ${_jwt}`
},
body: JSON.stringify(_config)
}).then(() => {
}).then(res => {
const poll = () => {
getLearnerStatus()
.then(res1 => {
Expand All @@ -397,9 +413,7 @@ function startLearning() {
.then(res2 => {
const data2 = JSON.parse(res2);
if (!data2.error) {
console.log('\n');
console.log(data2.hypothesis);
console.log('\n');
console.log('\n', data2.hypothesis, '\n');
resolve('The learning process finished.');
} else {
reject(data2.errorMessage);
Expand All @@ -412,7 +426,6 @@ function startLearning() {
})
.catch(reject);
};

poll();
}).catch(reject);
});
Expand All @@ -438,7 +451,7 @@ try {
}

// validate target URL
if (!program.target) {
if (!program.targets) {
throw 'You haven\'t specified the URL of the target application.';
}

Expand Down Expand Up @@ -521,26 +534,27 @@ try {
* @param {Function} fn The callback that processes the message.
*/
function terminate(message, fn) {
if (_action === 'test') {
if (program.cleanUp) {
deleteProject()
.then(() => {
console.log(chalk.white.dim(`Project has been deleted.`));
fn(message);
})
.catch(() => fn(message));
.then(() => {
console.log(chalk.white.dim(`Project has been deleted.`));
fn(message);
})
.catch(() => fn(message));
} else {
fn(message);
}
}


// execute the tests / learning process
login(_user).then((data) => {
_jwt = JSON.parse(data).token;
console.log(chalk.white.dim(`User "${_user.email}" logged in.`));

return createProject().then((data) => {
_project = JSON.parse(data);
console.log(chalk.white.dim(`Project has been created.`));
console.log(chalk.white.dim(`Project ${_project.name} has been created.`));

return createSymbols().then((data) => {
_symbols = JSON.parse(data);
Expand Down
63 changes: 43 additions & 20 deletions examples/google/config.learning.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,51 @@
{
"symbols": [{
"symbolFromName": "search",
"parameterValues": [{
"parameter": {
"type": "input",
"name": "term",
"parameterType": "STRING",
"private": false
"symbols": [
{
"symbol": {
"name": "search"
},
"value": "potato"
}]
}],
"parameterValues": [
{
"parameter": {
"type": "input",
"name": "term",
"parameterType": "STRING",
"private": false
},
"value": "test"
}
]
}
],
"urls": [],
"maxAmountOfStepsToLearn": -1,
"eqOracle": {"type": "random_word", "minLength": 5, "maxLength": 5, "maxNoOfTests": 5, "seed": 42},
"algorithm": {"name": "TTT"},
"resetSymbol": {"symbolFromName": "reset", "parameterValues": []},
"eqOracle": {
"batchSize": 1,
"minLength": 5,
"maxLength": 5,
"maxNoOfTests": 5,
"seed": 42,
"type": "random_word"
},
"algorithm": {
"name": "TTT"
},
"resetSymbol": {
"symbol": {
"name": "reset"
},
"parameterValues": []
},
"comment": null,
"driverConfig": {
"width": 1920,
"height": 1080,
"name": "chrome",
"headless": true,
"height": 1661,
"implicitlyWait": 0,
"pageLoadTimeout": 10,
"scriptTimeout": 10,
"name": "firefox",
"headless": true
"width": 2953
},
"useMQCache": true
}
"useMQCache": true,
"postSymbol": null
}
5 changes: 2 additions & 3 deletions examples/google/config.testing.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
"implicitlyWait": 0,
"pageLoadTimeout": 10,
"scriptTimeout": 10,
"name": "firefox",
"headless": true,
"xvfbPort": null
"name": "chrome",
"headless": true
}
}
2 changes: 1 addition & 1 deletion examples/google/symbols.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.6.0",
"version": "1.7.0",
"type": "symbols",
"symbols": [
{
Expand Down
10 changes: 7 additions & 3 deletions examples/google/tests.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.6.0",
"version": "1.7.0",
"type": "tests",
"tests": [
{
Expand All @@ -12,7 +12,9 @@
"expectedResult": "",
"pSymbol": {
"parameterValues": [],
"symbolFromName": "reset"
"symbol": {
"name": "reset"
}
}
},
{
Expand All @@ -30,7 +32,9 @@
"value": "potato"
}
],
"symbolFromName": "search"
"symbol": {
"name": "search"
}
}
}
],
Expand Down
Loading

0 comments on commit c0d9222

Please sign in to comment.