interactive bots: Create monkeytest.it bot.
This commit is contained in:
parent
1fd4dfc86e
commit
08bd395658
10 changed files with 487 additions and 0 deletions
0
zulip_bots/zulip_bots/bots/monkeytestit/lib/__init__.py
Normal file
0
zulip_bots/zulip_bots/bots/monkeytestit/lib/__init__.py
Normal file
28
zulip_bots/zulip_bots/bots/monkeytestit/lib/extract.py
Normal file
28
zulip_bots/zulip_bots/bots/monkeytestit/lib/extract.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""This module fetches the report from the website by doing a get request to
|
||||
the predefined url. The result is then parsed to JSON for further management
|
||||
in report.py
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def fetch(options: dict):
|
||||
"""Makes a request then returns the dictionary version of the response
|
||||
|
||||
:param options: Options dictionary containing the payload for the request
|
||||
:return: A dictionary containing keys and values to be managed by report.py
|
||||
:raises JSONDecodeError: if the get is unsuccessful. This could mean
|
||||
faulty link or any other causes.
|
||||
"""
|
||||
|
||||
res = requests.get("https://monkeytest.it/test", params=options)
|
||||
|
||||
if "server timed out" in res.text:
|
||||
return {"error": "The server timed out before sending a response to "
|
||||
"the request. Report is available at "
|
||||
"[Test Report History]"
|
||||
"(https://monkeytest.it/dashboard)."}
|
||||
|
||||
return json.loads(res.text)
|
72
zulip_bots/zulip_bots/bots/monkeytestit/lib/parse.py
Normal file
72
zulip_bots/zulip_bots/bots/monkeytestit/lib/parse.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
"""Used to parse message and return a dictionary containing a payload
|
||||
for extract.py
|
||||
"""
|
||||
|
||||
from json.decoder import JSONDecodeError
|
||||
from typing import Text
|
||||
|
||||
from zulip_bots.bots.monkeytestit.lib import extract
|
||||
from zulip_bots.bots.monkeytestit.lib import report
|
||||
|
||||
|
||||
def execute(message: Text, apikey: Text) -> Text:
|
||||
"""Parses message and returns a dictionary
|
||||
|
||||
:param message: The message
|
||||
:param apikey: A MonkeyTestit api key, presumably in the config file
|
||||
:return: A response string
|
||||
"""
|
||||
|
||||
params = message.split(" ")
|
||||
command = params[0]
|
||||
|
||||
if "check" in command.lower():
|
||||
len_params = len(params)
|
||||
|
||||
if len_params < 2:
|
||||
return failed("You **must** provide at least an URL to perform a "
|
||||
"check.")
|
||||
|
||||
options = {"secret": apikey, "url": params[1], "on_load": "true",
|
||||
"on_click": "true", "page_weight": "true", "seo": "true",
|
||||
"broken_links": "true", "asset_count": "true"}
|
||||
|
||||
# Set the options only if supplied
|
||||
|
||||
if len_params >= 3:
|
||||
options["on_load"] = "true" if params[2] == "1" else "false"
|
||||
if len_params >= 4:
|
||||
options["on_click"] = "true" if params[3] == "1" else "false"
|
||||
if len_params >= 5:
|
||||
options["page_weight"] = "true" if params[4] == "1" else "false"
|
||||
if len_params >= 6:
|
||||
options["seo"] = "true" if params[5] == "1" else "false"
|
||||
if len_params >= 7:
|
||||
options["broken_links"] = "true" if params[6] == "1" else "false"
|
||||
if len_params >= 8:
|
||||
options["asset_count"] = "true" if params[7] == "1" else "false"
|
||||
|
||||
try:
|
||||
fetch_result = extract.fetch(options)
|
||||
except JSONDecodeError:
|
||||
return failed("Cannot decode a JSON response. "
|
||||
"Perhaps faulty link. Link must start "
|
||||
"with `http://` or `https://`.")
|
||||
|
||||
return report.compose(fetch_result)
|
||||
|
||||
# The disadvantage here is that the user has to supply every params if
|
||||
# the user needs to modify the asset_count. There are probably ways
|
||||
# to counteract this, but I think this is more fast to run.
|
||||
else:
|
||||
return "Unknown command. Available commands: `check <website> " \
|
||||
"[params]`"
|
||||
|
||||
|
||||
def failed(message: Text) -> Text:
|
||||
"""Simply attaches a failed marker to a message
|
||||
|
||||
:param message: The message
|
||||
:return: String
|
||||
"""
|
||||
return "Failed: " + message
|
128
zulip_bots/zulip_bots/bots/monkeytestit/lib/report.py
Normal file
128
zulip_bots/zulip_bots/bots/monkeytestit/lib/report.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
"""Used to mainly compose a decorated report for the user
|
||||
"""
|
||||
|
||||
from typing import Dict, Text, List
|
||||
|
||||
|
||||
def compose(results: Dict) -> Text:
|
||||
"""Composes a report based on test results
|
||||
|
||||
An example would be:
|
||||
|
||||
Status: tests_failed
|
||||
Enabled checkers: seo
|
||||
Failures from checkers: seo (3)
|
||||
More info: https://monkeytest.it/...
|
||||
|
||||
This function assumes that the result dict is valid and does not contain
|
||||
any "errors" like bad url
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing the full report
|
||||
"""
|
||||
if "error" in results:
|
||||
return "Error: {}".format(results['error'])
|
||||
|
||||
response = ""
|
||||
|
||||
response += "{}\n".format(print_status(results))
|
||||
|
||||
if "success" in response.lower():
|
||||
response += "{}".format(print_test_id(results))
|
||||
return response
|
||||
|
||||
response += "{}\n".format(print_enabled_checkers(results))
|
||||
response += "{}\n".format(print_failures_checkers(results))
|
||||
response += "{}".format(print_more_info_url(results))
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def print_more_info_url(results: Dict) -> Text:
|
||||
"""Creates info for the test URL from monkeytest.it
|
||||
|
||||
Example:
|
||||
|
||||
More info: https://monkeytest.it/test/...
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing the url info
|
||||
"""
|
||||
return "More info: {}".format(results['results_url'])
|
||||
|
||||
|
||||
def print_test_id(results: Dict) -> Text:
|
||||
"""Prints the test-id with attached to the url
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing the test id
|
||||
"""
|
||||
return "Test: https://monkeytest.it/test/{}".format(results['test_id'])
|
||||
|
||||
|
||||
def print_failures_checkers(results: Dict) -> Text:
|
||||
"""Creates info for failures in enabled checkers
|
||||
|
||||
Example:
|
||||
|
||||
Failures from checkers: broken_links (3), seo (5)
|
||||
|
||||
This means that the check has 8 section failures, 3 sections in
|
||||
broken_links and the other 5 are in seo.
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing number of failures in each enabled
|
||||
checkers
|
||||
"""
|
||||
failures_checkers = [(checker, len(results['failures'][checker]))
|
||||
for checker in get_enabled_checkers(results)
|
||||
if checker in results['failures']] # [('seo', 3), ..]
|
||||
|
||||
failures_checkers_messages = ["{} ({})".format(fail_checker[0],
|
||||
fail_checker[1]) for fail_checker in
|
||||
failures_checkers]
|
||||
|
||||
failures_checkers_message = ", ".join(failures_checkers_messages)
|
||||
return "Failures from checkers: {}".format(failures_checkers_message)
|
||||
|
||||
|
||||
def get_enabled_checkers(results: Dict) -> List:
|
||||
"""Gets enabled checkers
|
||||
|
||||
For example, if enabled_checkers: {'seo' : True, 'broken_links' : False,
|
||||
'page_weight' : true}, it will return ['seo'. 'page_weight']
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A list containing enabled checkers
|
||||
"""
|
||||
checkers = results['enabled_checkers']
|
||||
enabled_checkers = []
|
||||
for checker in checkers.keys():
|
||||
if checkers[checker]: # == True/False
|
||||
enabled_checkers.append(checker)
|
||||
return enabled_checkers
|
||||
|
||||
|
||||
def print_enabled_checkers(results: Dict) -> Text:
|
||||
"""Creates info for enabled checkers. This joins the list of enabled
|
||||
checkers and format it with the current string response
|
||||
|
||||
For example, if get_enabled_checkers = ['seo', 'page_weight'] then it would
|
||||
return "Enabled checkers: seo, page_weight"
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing enabled checkers
|
||||
"""
|
||||
return "Enabled checkers: {}".format(", "
|
||||
.join(get_enabled_checkers(results)))
|
||||
|
||||
|
||||
def print_status(results: Dict) -> Text:
|
||||
"""Creates info for the check status.
|
||||
|
||||
Example: Status: tests_failed
|
||||
|
||||
:param results: A dictionary containing the results of a check
|
||||
:return: A response string containing check status
|
||||
"""
|
||||
return "Status: {}".format(results['status'])
|
Loading…
Add table
Add a link
Reference in a new issue