Bots navigating urls and doing tasks.
damon
is a tool that runs on CasperJS which runs on PhantomJS.
It feeds on JSON files that describe what tasks he needs to achieve on specified starting URL.
via NPM :
npm install --save damon
var damon = require('damon');
// Attach the default reporter.
damon.attachReporter();
// You can attach your own reporter as well
// damon.attachReporter('./path/to/my/reporter.js');
// Start your suite(s), it accepts globs.
damon.start('./tasks.json');
You can use damon
via a CLI, available at damonjs/damon-cli
This is the json file you'll pass to damon
.
It's composed of two attributes, a config
hash and a tasks
array.
{
"config": {},
"tasks": []
}
Your task file must have a config
entry.
"config": {
"size": {
"width": 1024,
"height": 768
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A",
"timeout": 1000,
"logLevel": "fatal",
"describe": "This is a job description"
}
size
is for the viewport's size.userAgent
is a custom userAgent fordamon
to use. Default one is Chrome 44 on Windows 7.timeout
overwrite the general timeout used accross the test suite.logLevel
control at which leveldamon
will log. Can benone
,fatal
,error
,warn
,info
,debug
ortrace
describe
is used to give a description of the job. It is printed next to the filename in the default reporter.
Then you describe your tasks
entry, an array of all the tasks to achieve sequentially :
"tasks": [
{},
{}
]
Each task will have three components:
{
"type": "taskType",
"it": "should run this task",
"params": {}
}
type
the type of task.params
arguments to be passed to the task.it
description of the task, to be printed on the default reporter (optional).
It exists several kinds of tasks that damon
can achieve :
damon
can navigate to other urls at the start or during its worflow.
{
"type": "navigate",
"params": {
"url": "https://www.google.com",
"method": "GET",
"data": {
"key": "value"
},
"headers": {
"name": "value"
},
"encoding": "utf8"
}
}
Only params.url
is required.
Verify that the page answers with a specific status.
{
"type": "status",
"params": {
"url": "url",
"method": "GET",
"data": {
"key": "value"
},
"headers": {
"name": "value"
},
"encoding": "utf8",
"status": [301, 302]
}
}
damon
will navigate to params.url
and will wait until it gets the awaited status.
The request gets cancelled as soon as the status is returned.
params.status
can be a string of a single status, or an array of all status required.
In the case of the array, the first encounter will validate the task.
Only params.url
and params.status
are required.
Verify that the page redirects to another specified one.
{
"type": "redirection",
"params": {
"from": "url",
"to": "url",
"method": "GET",
"data": {
"key": "value"
},
"headers": {
"name": "value"
},
"encoding": "utf8"
}
}
damon
will navigate to params.from
and verify that we have a redirection to params.to
.
The params.method
, params.data
, params.heades
and params.encoding
are for params.from
only.
Only params.from
and params.to
are required.
A simple screen capture :
{
"type": "capture",
"params": {
"name": "start.png"
}
}
Download the target url
{
"type": "download",
"params": {
"url": "http://www.google.com",
"name": "google.html",
"method": "GET",
"data": ""
}
}
An HTTP method can be set with method
, and pass request arguments through data
.
damon
can wait for several different things.
For each one, except time
, you can overwrite the timeout
.
{
"type": "wait",
"params": {
"url": "http://www.yahoo.ca",
"regexp": false,
"timeout": 1000
}
}
damon
will wait at this step until matching url is reached.
url
will be interpreted as a regexp
if set to true
. Default value of regexp
is false
.
{
"type": "wait",
"params": {
"selector": "#content",
"timeout": 1000,
"xpath": false
}
}
damon
will wait at this step until the selector
is available on the page.
xpath
can be used to select an element by setting it to true. Default value is false.
hidden
Both are the same as selector
but will wait for these specific states of the element.
{
"type": "wait",
"params": {
"time": "1000"
}
}
damon
will wait for the specified amount of milliseconds.
{
"type": "wait",
"params": {
"resource": "resourceName",
"regexp": false,
"timeout": 1000,
"method": "DELETE"
}
}
damon
will wait at this step until something matching the resource is received.
resource
will be interpreted as a regexp
if set to true
. Default value of regexp
is false
.
A method
can be specified to filter the resource. If nothing is specified, any method
will be accepted.
damon
can perform two different actions on a dom element :
{
"type": "dom",
"params": {
"selector": "button#btnSubmit",
"xpath": false,
"do": "click",
}
}
damon
will click on the specified selector.
{
"type": "dom",
"params": {
"selector": "input#userName",
"xpath": false,
"do": "fill",
"text": "yoann.dev"
}
}
damon
will enter text in the specified field.
xpath
cannot be used when filling a file field due to PhantomJS limitiations.
damon
can perform different get
to retrieve a value and store it for subsequent tasks :
{
"type": "get",
"params": {
"selector": "div#Info",
"xpath": false,
"attribute": "title",
"key": "infoTitle",
"modifier": "[a-z]+"
}
}
damon
will get the value of the attribute
, apply the modifier
RegExp and store it as infoTitle
.
@text
can also be used as an attribute
to get the text content of the selector
{
"type": "get",
"params": {
"variable": "var.attr1['attr2']",
"key": "varAttr2"
}
}
damon
will access to the specified variable with window
as the root object and store its value as varAttr2
{
"type": "get",
"params": {
"resource": "resourceLink",
"regexp": false,
"variable": "payload.title",
"key": "title",
"method": "POST"
}
}
damon
will access to the specified variable of the matching resource
and store it.
A method
can be specified to filter the resource. If nothing is specified, any method
will be accepted.
To access to a variable in the payload of a resource, write payload.variableName
for variable
field. Resource also contains the headers
, method
, time
and url
.
{
"type": "get",
"params": {
"selector": "ul#list li",
"xpath": false,
"key": "liNumber"
}
}
damon
will store the number of elements that satisfy the selector
The value can then be accessed in any following tasks via its key
value
{
"type": "wait",
"params": {
"url": "http://www.yahoo.ca/{{key}}"
}
}
To access the stored value, call the key
in between double brackets {{key}}
damon
can perform any HTTP call.
{
"type": "request",
"params": {
"url": "https://www.google.com",
"method": "GET",
"payload": {
"q": "funny cats"
},
"headers": {
"header": "value"
},
"store": {
"key": "key",
"variable": "variable.attr1"
}
}
}
You can also store
the response for later use with {{key}}
.
If you don't pass a variable
it will store the complete response.
Otherwise, it will try to parse the response as JSON and look for your variable.
damon
can perform different assert
actions to test a value with an expected value:
{
"type": "assert",
"params": {
"selector": "div#Info",
"xpath": false,
"attribute": "title",
"modifier": "[a-z]+",
"expected": "expectedValue or {{key}}"
}
}
damon
will get
the value of the attribute
and test it against the expected
value or the value associated with {{key}}
{
"type": "assert",
"params": {
"variable": "var.attr1['attr2']",
"expected": "expectedValue or {{key}}"
}
}
damon
will get
the value of the variable
and test it against the expected
value or the value associated with {{key}}
{
"type": "assert",
"params": {
"key": "title",
"expected": "Expected Title"
}
}
damon
will get
the value of the key
and test it against the expected
value.
- Extract the CLI component.
- Extract the default reporter component.
- Extract default actions. (place them in the config file to be imported)
- Extract default plugins. (place them in the config file to be imported)
- Create Sitemap crawling plugin (almost there).
- Create Retry mecanic plugin.
- Create Github Page to use as main website.
- Create wiki to document how to create reporters/actions/plugins.
- Extract runner component.
- Extract logger component.
- Add examples.
- Test everything individually.
We welcome Your interest in Autodesk’s Open Source Damon (the “Project”).
Any Contributor to the Project must accept and sign an Agreement indicating agreement to the license terms below.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.