This repository has been archived by the owner on Aug 4, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Support for variables in scenarios (variable types: random/constant)
- Better error logging and warnings - Added wait_for_element and sleep functions - Open url can accept an array now and it will pick one of the urls randomly - Added screenshot option to have easier debuging - Added support for comments in the scenario json (this requires the user to install commentjson (pip install commentjson) - Various fixes to make sure that the scenario will run correctly without failing
- Loading branch information
Hatem Mostafa
committed
Feb 29, 2016
1 parent
e266b79
commit 030b834
Showing
4 changed files
with
607 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// This scenario is written for a magento application with sample data v1.9 | ||
// You can follow the steps in the documentation to install it and test this scenario | ||
// http://devdocs.magento.com/guides/m1x/ce18-ee113/ht_magento-ce-sample.data.html | ||
// You can change the baseUrl to the url of your magento installation. | ||
{ | ||
"variables":[ | ||
{ | ||
"type": "randomString", | ||
"length": 7, | ||
"name": "emailPrefix" | ||
}, | ||
{ | ||
"type": "constant", | ||
"value": "http://magento001", | ||
"name": "baseUrl" | ||
}, | ||
{ | ||
"type": "constant", | ||
"value": [ | ||
"$[baseUrl]/accessories/bags-luggage.html", | ||
"$[baseUrl]/accessories/eyewear.html", | ||
"$[baseUrl]/vip.html", | ||
"$[baseUrl]/accessories/jewelry.html", | ||
"$[baseUrl]/home-decor/bed-bath.html", | ||
"$[baseUrl]/home-decor/electronics.html", | ||
"$[baseUrl]/home-decor/decorative-accents.html", | ||
"$[baseUrl]/sale/home-decor.html" | ||
], | ||
"name": "productPages" | ||
} | ||
|
||
], | ||
"steps": [ | ||
|
||
// ---------------------------------------------------------------------- | ||
// Signing up the user. | ||
// ---------------------------------------------------------------------- | ||
{ | ||
"action": "open_url", | ||
"value": "$[baseUrl]/customer/account/create/" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#firstname", | ||
"value": "John" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#lastname", | ||
"value": "Doe" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#email_address", | ||
"value": "$[emailPrefix]@example.com" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#password", | ||
"value": "qwerty" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#confirmation", | ||
"value": "qwerty" | ||
}, | ||
{ | ||
"action": "submit", | ||
"selector": "#form-validate" | ||
}, | ||
|
||
// ---------------------------------------------------------------------- | ||
// Adding products to the cart. | ||
// ---------------------------------------------------------------------- | ||
{ | ||
"action": "open_url", | ||
"value": "$[productPages]" | ||
}, | ||
{ | ||
"action": "click_one", | ||
"selector": "button.button.btn-cart[type=button]" | ||
}, | ||
{ | ||
"action": "open_url", | ||
"value": "$[productPages]" | ||
}, | ||
{ | ||
"action": "click_one", | ||
"selector": "button.button.btn-cart[type=button]" | ||
}, | ||
{ | ||
"action": "open_url", | ||
"value": "$[productPages]" | ||
}, | ||
{ | ||
"action": "click_one", | ||
"selector": "button.button.btn-cart[type=button]" | ||
}, | ||
|
||
// ---------------------------------------------------------------------- | ||
// Checking out. | ||
// ---------------------------------------------------------------------- | ||
{ | ||
"action": "open_url", | ||
"value": "$[baseUrl]/checkout/onepage/" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#billing\\:street1", | ||
"value": "Nowhere 1" | ||
}, | ||
|
||
{ | ||
"action": "set_value", | ||
"selector": "input#billing\\:city", | ||
"value": "Utopia" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "select#billing\\:region_id", | ||
"value": "1" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#billing\\:postcode", | ||
"value": "555AL" | ||
}, | ||
{ | ||
"action": "set_value", | ||
"selector": "input#billing\\:telephone", | ||
"value": "0123456789" | ||
}, | ||
{ | ||
"action": "click", | ||
"selector": "#checkout-step-billing button.button[title=Continue]" | ||
}, | ||
{ | ||
"action": "wait_for_element", | ||
"selector": "input[type=radio][name=shipping_method]" | ||
}, | ||
{ | ||
"action": "click_one", | ||
"selector": "input[type=radio][name=shipping_method]" | ||
}, | ||
{ | ||
"action": "click", | ||
"selector": "#shipping-method-buttons-container button.button" | ||
}, | ||
{ | ||
"action": "wait_for_element", | ||
"selector": "#shipping-method-buttons-container button.button" | ||
}, | ||
{ | ||
"action": "click", | ||
"selector": "div#payment-buttons-container button" | ||
}, | ||
{ | ||
"action": "wait_for_element", | ||
"selector": "#checkout-review-submit button.button" | ||
}, | ||
{ | ||
"action": "click", | ||
"selector": "#checkout-review-submit button.button" | ||
} | ||
] | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,14 +9,18 @@ | |
import time | ||
import json | ||
import os.path | ||
import string | ||
import random | ||
import commentjson | ||
import copy | ||
from Queue import Queue, Empty | ||
from threading import Thread | ||
|
||
__license__ = "MIT" | ||
__maintainer__ = "Samuel Vandamme" | ||
__email__ = "[email protected]" | ||
__author__ = "Samuel Vandamme" | ||
__credits__ = ["Stijn Polfliet", "Samuel Vandamme"] | ||
__credits__ = ["Stijn Polfliet", "Samuel Vandamme", "Hatem Mostafa"] | ||
__version__ = "alpha" | ||
|
||
threadQueue = Queue() | ||
|
@@ -34,7 +38,7 @@ def main(args): | |
# Load in scenario | ||
with open(options['scenario'], 'r') as content_file: | ||
content = content_file.read() | ||
scenario = json.loads(content) | ||
scenario = commentjson.loads(content) | ||
|
||
# Test option | ||
if options['test']: | ||
|
@@ -72,6 +76,8 @@ def parse_arguments(args): | |
help="run a scenario only once") | ||
parser.add_argument('--slimerjs', action='store_true', | ||
help="use slimerjs instead of phantomjs") | ||
parser.add_argument('--screenshot', action='store_true', | ||
help="provide screenshots after each step") | ||
parser.add_argument('scenario') | ||
args = parser.parse_args() | ||
|
||
|
@@ -92,7 +98,8 @@ def parse_arguments(args): | |
'threads': args.threads, | ||
'verbose': args.verbose, | ||
'debug': args.debug, | ||
'test': args.test | ||
'test': args.test, | ||
'screenshot': args.screenshot | ||
} | ||
|
||
return options | ||
|
@@ -182,7 +189,7 @@ def execute(threadId, scenario, options): | |
options['browser'], | ||
'worker.js', | ||
str(threadId), | ||
json.dumps(scenario), | ||
json.dumps(preprocessScenario(scenario)), | ||
json.dumps(options) | ||
] | ||
process = subprocess.Popen( | ||
|
@@ -204,5 +211,50 @@ def execute(threadId, scenario, options): | |
|
||
return None | ||
|
||
# Preprocess the scenario json so that tha variables are filled in the steps. | ||
def preprocessScenario(obj): | ||
variables = copy.deepcopy(obj['variables']) | ||
steps = copy.deepcopy(obj['steps']); | ||
for idx in range(len(variables)): | ||
variable = variables[idx] | ||
varType = variable['type'] | ||
searchForExactMatch = False | ||
if varType == 'randomString': | ||
value = getRandomString(variable['length']) | ||
elif varType == 'constant': | ||
value = variable['value'] | ||
if isinstance(value, list): | ||
# We will be searching for exact match in case of arrays because we will replace the whole variable. | ||
searchForExactMatch = True | ||
else: | ||
value = None | ||
print 'Unknown variable type `' + variable['type'] + '`' | ||
|
||
if value != None: | ||
# Replacing the variable name with its value in the following variables. | ||
for idx2 in range(idx + 1, len(variables)): | ||
variable2 = variables[idx2] | ||
if 'value' in variable2: | ||
if searchForExactMatch: | ||
if variable2['value'] == '$[' + variable['name'] + ']': | ||
variable2['value'] = value | ||
else: | ||
variable2['value'] = json.loads(json.dumps(variable2['value']).replace('$[' + variable['name'] + ']', value)) | ||
|
||
# Replacing the variable name with its value in the steps. | ||
for step in steps: | ||
if 'value' in step: | ||
if searchForExactMatch: | ||
if step['value'] == '$[' + variable['name'] + ']': | ||
step['value'] = value | ||
else: | ||
step['value'] = json.loads(json.dumps(step['value']).replace('$[' + variable['name'] + ']', value)) | ||
|
||
return steps; | ||
|
||
# Generate random string. | ||
def getRandomString(size=6, chars=string.ascii_lowercase + string.digits): | ||
return ''.join(random.choice(chars) for x in range(size)) | ||
|
||
if __name__ == "__main__": | ||
sys.exit(main(sys.argv[1:])) |
Oops, something went wrong.