def __init__(self, headless=True): self.web_page = '/vis-js/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser( headless=headless, auto_close=headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root)
def __init__(self, tmp_img=None, clip=None, headless=False): self.headless = headless self.path_views = Files.path_combine(Files.parent_folder(__file__), '../../src/web_root') self.render_page = Render_Page(headless=self.headless, auto_close=self.headless, web_root=self.path_views) self.tmp_img = tmp_img self.clip = clip
def __init__(self, web_page, headless=True): self.web_page = web_page self.title = 'browser view' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser( headless=headless, auto_close=headless).sync__setup_browser() self.web_server = Web_Server(self.web_root) self.render_page = Render_Page(api_browser=self.api_browser, web_server=self.web_server)
def __init__(self): self.web_page = '/google_charts/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser().sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.table_width = '100%' self.columns_defs = None self.table_title = None
class View_Examples: def __init__(self, tmp_img=None, clip=None, headless=False): self.headless = headless self.path_views = Files.path_combine(Files.parent_folder(__file__), '../../src/web_root') self.render_page = Render_Page(headless=self.headless, auto_close=self.headless, web_root=self.path_views) self.tmp_img = tmp_img self.clip = clip def _open_file_and_get_html(self, filename): file = '{0}{1}{2}'.format(self.path_views, '/examples/', filename) return self.render_page.render_file(file) def _open_file_and_take_screenshot(self, filename): file = '{0}{1}{2}'.format(self.path_views, '/examples/', filename) return self.render_page.screenshot_file(file, self.tmp_img, self.clip) def set_clip(self, clip): self.clip = clip return self def render_file_from_zip(self, target): with Zip_Folder(self.path_views) as zip_file: with Unzip_File(zip_file, '/tmp/test_render_from_zip', True) as web_root: return self.render_page.screenshot_file_in_folder( web_root, target, self.tmp_img) def open_file_in_browser(self, path, js_code=None): with self.render_page.web_server as web_server: url = web_server.url(path) return self.render_page.get_page_html_via_browser(url, js_code) # def open_file_in_browser_and_invoke_js(self, path, js_to_invoke): # with self.render_page.web_server as web_server: # url = web_server.url(path) # return self.render_page.get_page_html_via_browser(url) def hello_world__html(self): return self._open_file_and_get_html('hello-world.html') def hello_world(self): return self._open_file_and_take_screenshot('hello-world.html') def bootstrap_cdn(self): return self._open_file_and_take_screenshot('bootstrap-cdn.html') def bootstrap_local(self): return self.render_file_from_zip('/examples/bootstrap-local.html') def folder_root(self): return self.render_page.screenshot_folder(self.path_views, self.tmp_img)
def __init__(self): self.web_page = '/gs/risk/risks-dashboard.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.headless = False self.api_browser = API_Browser(self.headless, self.headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.graph_name = None self.jira_key = None
def setup(self): if os.getenv('AWS_REGION'): load_dependency('syncer') load_dependency('requests') #self.setup_AWS() # else: # self.setup_local() from browser.API_Browser import API_Browser from browser.Render_Page import Render_Page self.api_browser = API_Browser( headless=self.headless, auto_close=self.auto_close).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root()) return self
class Base_View_Helpers: def __init__(self, web_page, headless=True): self.web_page = web_page self.title = 'browser view' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser( headless=headless, auto_close=headless).sync__setup_browser() self.web_server = Web_Server(self.web_root) self.render_page = Render_Page(api_browser=self.api_browser, web_server=self.web_server) # common methods (move to base class) def browser(self): return self.api_browser def browser_width(self, value): self.browser().sync__browser_width(value) return self def load_page(self, reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def create_dashboard_screenshot(self): #clip = {'x': 1, 'y': 1, 'width': 945, 'height': 465} clip = None return self.browser().sync__screenshot(clip=clip) def send_screenshot_to_slack(self, team_id=None, channel=None): png_file = self.create_dashboard_screenshot() return Browser_Lamdba_Helper().send_png_file_to_slack( team_id, channel, self.title, png_file) def get_graph_data(self, graph_name): params = {'params': ['raw_data', graph_name, 'details'], 'data': {}} data = Lambdas('gsbot.gsbot_graph').invoke(params) if type(data) is str: s3_key = data s3_bucket = 'gs-lambda-tests' tmp_file = S3().file_download_and_delete(s3_bucket, s3_key) data = Json.load_json_and_delete(tmp_file) return data return data def exec_js(self, js_code): return self.browser().sync__js_execute(js_code) def invoke_js(self, name, params): return self.browser().sync_js_invoke_function(name, params) def assign_variable_js(self, variable, data): return self.browser().sync_js_assign_variable(variable, data) def set_browser_width_based_on_nodes(self, nodes): if len(nodes) < 30: self.browser().sync__browser_width(800) elif len(nodes) < 100: self.browser().sync__browser_width(1500) elif len(nodes) < 200: self.browser().sync__browser_width(2000) else: self.browser().sync__browser_width(3000) def render(self, nodes, edges, js_code=None, options=None, team_id=None, channel=None, sleep_for=None, width=None): if len(nodes) > 0: if width: self.browser().sync__browser_width(width) else: self.set_browser_width_based_on_nodes(nodes) # if len(nodes) < 50 : sleep_for = 2 # elif 50 < len(nodes) < 100: self.browser().sync__browser_width(1000) ; sleep_for = 3 # elif 100 < len(nodes) < 200: self.browser().sync__browser_width(2000) ; sleep_for = 5 # elif len(nodes) > 200: self.browser().sync__browser_width(3000) ; sleep_for = 10 self.create_graph(nodes, edges, options) self.api_browser.sync__js_execute(js_code) if sleep_for: sleep(sleep_for) return self.send_screenshot_to_slack(team_id, channel)
class Vis_Js: def __init__(self, headless=True): self.web_page = '/vis-js/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser( headless=headless, auto_close=headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) # #self.base_html_file = '/vis-js/empty.html' # self.base_html_file = '/vis-js/simple.html' # #window.api_visjs # self.headless = False # self.browser = None # common methods (move to base class) def browser(self): return self.api_browser def browser_width(self, value): self.browser().sync__browser_width(value) return self def load_page(self, reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def create_dashboard_screenshot(self): #clip = {'x': 1, 'y': 1, 'width': 945, 'height': 465} clip = None return self.browser().sync__screenshot(clip=clip) def send_screenshot_to_slack(self, team_id, channel): png_file = self.create_dashboard_screenshot() return Browser_Lamdba_Helper().send_png_file_to_slack( team_id, channel, 'risk dashboard', png_file) def create_graph_and_send_screenshot_to_slack(self, graph_name, nodes, edges, options, team_id, channel): if len(nodes) > 0: self.create_graph(nodes, edges, options, graph_name) return self.send_screenshot_to_slack(team_id, channel) # @use_local_cache_if_available def get_graph_data(self, graph_name): params = {'params': ['raw_data', graph_name, 'details'], 'data': {}} data = Lambdas('gsbot.gsbot_graph').invoke(params) if type(data) is str: s3_key = data s3_bucket = 'gs-lambda-tests' tmp_file = S3().file_download_and_delete(s3_bucket, s3_key) data = Json.load_json_and_delete(tmp_file) return data return data # Vis js specific def add_edge__js_code(self, from_node, to_node): edge = {'from': str(from_node), 'to': str(to_node)} return 'network.body.data.edges.add({0});'.format(json.dumps(edge)) def add_edge(self, from_node, to_node): self.exec_js(self.add_edge__js_code(from_node, to_node)) return self def add_node__js_code(self, node_id, node_label, shape='box', color=None): node = { 'id': str(node_id), 'label': str(node_label), 'shape': shape, 'color': color } return 'network.body.data.nodes.add({0});'.format(json.dumps(node)) def add_node(self, node_id, node_label, shape='box', color=None): self.exec_js(self.add_node__js_code(node_id, node_label, shape, color)) return self def create_graph(self, nodes=[], edges=[], options=None, graph_name=None): def show_debug_message(graph_name): if graph_name is None: graph_name = '' today = datetime.date.today().strftime('%d %b %Y') self.exec_js( "$('#message').html('{0} | {1} nodes {2} edges | created on {3} | by GSBot')" .format(graph_name, len(nodes), len(edges), today)) self.exec_js("$('#status').html('Loading Graph')") self.load_page(True) if options is None or options == {}: options = self.get_default_options() #options = self.get_advanced_options() data = {'nodes': nodes, 'edges': edges} base64_data = base64.b64encode(json.dumps(data).encode()).decode() base64_options = base64.b64encode( json.dumps(options).encode()).decode() js_code = "window.network = new vis.Network(container, JSON.parse(atob('{0}')), JSON.parse(atob('{1}')));".format( base64_data, base64_options) self.exec_js(js_code) #self.browser().sync__browser_width(500, 400) if len(nodes) > 30: self.browser().sync__browser_width(2000) show_debug_message(graph_name) js_code = "network.on('stabilizationIterationsDone', function(data){ $('body').append('<span style=\"display:none\" id=stabilizationIterationsDone>....done...</span') })" self.exec_js(js_code) if self.exec_js("network.physics.ready") is False: wait_timeout = 10000 self.browser().sync__await_for_element( '#stabilizationIterationsDone', wait_timeout) # attempts = 10 # for i in range(1,attempts): # self.exec_js("$('#status').html('waiting #{0}')".format(i)) # # #wait_timeout = 1000 # result = self.exec_js("$('#stabilizationIterationsDone').html()") # if result == '....done...': # Dev.pprint(">>>> done") # break # #if self.browser().sync__await_for_element('#stabilizationIterationsDone', wait_timeout): # # # # break # Dev.pprint("attempt: {0}".format(i)) # sleep(1) self.exec_js('network.stopSimulation()') self.exec_js("$('#status').html('')") #break #Dev.pprint('dont') # # js_code = [ # "network.on('startStabilizing' , function(data){console.log('startStabilizing', data)})", # "network.on('stabilizationProgress' , function(data){console.log('stabilizationProgress', data)})", # "network.on('stabilizationIterationsDone', function(data){console.log('stabilizationIterationsDone', data) })", # "network.on('stabilized', function(data) {console.log('stabilized', data) })"] # self.exec_js(js_code) #self.exec_js("network.on('stabilizationIterationsDone', function(data){console.log('stabilizationIterationsDone', data) })") #Dev.print(self.exec_js("network.physics.ready")) # need to handle the case when rendering happens very quickly #if len(nodes) > 10: #js_code = "$('#vis_js').css({ top : '5px', bottom : '5px', left : '5px', right : '5px', position : 'fixed', border: '1px solid lightgray'})" return self def exec_js(self, js_code): return self.browser().sync__js_execute(js_code) def invoke_js(self, name, params): return self.browser().sync_js_invoke_function(name, params) def get_default_options(self): return { 'nodes': { 'shape': 'box' }, 'edges': { 'arrows': 'to' }, 'physics': { 'barnesHut': { 'avoidOverlap': 0.1 }, } } def get_advanced_options(self): options = { 'nodes': { 'font': { 'face': 'Arial', 'size': 20 }, 'shape': 'box' }, 'edges': { 'smooth': False, 'arrows': 'to', 'color': { 'color': 'black' }, 'font': { 'size': 10 } }, 'layout': { 'randomSeed': 0 }, 'physics': { 'barnesHut': { 'gravitationalConstant': -700, # (-2000 'centralGravity': 0.01, # (0.01) no central gravity since we don't need that 'springLength': 50, # (100) this value is also set by the anchor edges 'springConstant': 0.0015, # (0.08) this is how hard the spring is 'damping': 0.4, # (0.4 'avoidOverlap': 0.3 }, 'maxVelocity': 10, # (50) keep this low so that the nodes don'y move too far from each other 'minVelocity': 1, # (0.1) 'solver': 'barnesHut', # other good option is forceAtlas2Based', 'timestep': 1.35, # (0.5) this value can be used to slow down the animation (for ex 0.015) 'stabilization': { 'enabled': True, 'iterations': 2000, 'updateInterval': 100 } }, 'interaction': { 'dragNodes': True, 'zoomView': True, 'dragView': True } } return options def show_jira_graph(self, graph_name, label_key='Summary'): self.load_page(False) graph_data = self.get_graph_data(graph_name) if graph_data: nodes = [] edges = [] for key, issue in graph_data.get('nodes').items(): #label = "{0} \n \n{1}".format(issue.get(label_key),issue.get('Labels')) label = key nodes.append({'id': key, 'label': label}) #Dev.pprint(issue) for edge in graph_data.get('edges'): from_node = edge[0] link_type = edge[1] to_node = edge[2] edges.append({ 'from': from_node, 'to': to_node, 'label': link_type }) self.create_graph(nodes, edges) return graph_data def wait_n_seconds(self, seconds): sleep(seconds) return self def set_fixed_r1_nodes(self): r1s = { 'RISK-1498': { 'x': -1000, 'y': -1000 }, # 1 'RISK-1496': { 'x': 0, 'y': -1000 }, # 2 'RISK-1495': { 'x': 1000, 'y': -1000 }, # 3 'RISK-1494': { 'x': -1000, 'y': 1000 }, # 4 'RISK-1534': { 'x': 0, 'y': 1000 }, # 5 'RISK-1592': { 'x': 1000, 'y': 1000 } } # 6 for key, value in r1s.items(): data = { 'id': key, 'x': value['x'], 'y': value['y'], 'fixed': True, 'mass': 5 } self.invoke_js('network.body.data.nodes.update', data) options = { 'position': { 'x': 0, 'y': 0 }, 'offset': { 'x': 100, 'y': -50 }, 'scale': 1.0 } self.invoke_js('network.moveTo', options) return self
class Google_Charts_Js: def __init__(self): self.web_page = '/google_charts/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser().sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.table_width = '100%' self.columns_defs = None self.table_title = None # helper methods (to move to base class) def browser(self): return self.api_browser def show_chrome(self): self.render_page.api_browser.headless = False self.render_page.api_browser.auto_close = False return self def load_page(self, reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def js_execute(self, name, params=None): return self.browser().sync_js_invoke_function(name, params) def js_eval(self, js_code): return self.browser().sync__js_execute(js_code) def send_screenshot_to_slack(self, team_id, channel): png_file = self.create_dashboard_screenshot() return Browser_Lamdba_Helper().send_png_file_to_slack( team_id, channel, 'risk dashboard', png_file) def create_dashboard_screenshot(self): #clip = {'x': 1, 'y': 1, 'width': 945, 'height': 465} clip = None return self.browser().sync__screenshot(clip=clip) # main datatable methods def create_data_table(self): #, cols, rows): cols = [{ 'id': 'task', 'label': 'Task', 'type': 'string' }, { 'id': 'hours', 'label': 'Hours per Day', 'type': 'number' }] rows = [{ 'c': [{ 'v': 'Work' }, { 'v': 11 }] }, { 'c': [{ 'v': 'Play' }, { 'v': 2 }] }, { 'c': [{ 'v': 'Other' }, { 'v': 5 }] }] data = {'cols': cols, 'rows': rows} options = { 'title': 'My first chart', 'width': 500, 'height': 500 } chart_type = 'LineChart' #'BarChart' # PieChart' self.js_execute('window.data_table=new google.visualization.DataTable', data) self.js_execute('window.options = ', options) self.js_eval( """window.chart = new google.visualization.{0}(document.getElementById('chart_div')); chart.draw(data_table, options);""".format(chart_type))
class Risk_Dashboard: def __init__(self): self.web_page = '/gs/risk/risks-dashboard.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.headless = False self.api_browser = API_Browser(self.headless, self.headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.graph_name = None self.jira_key = None def browser(self): return self.api_browser def get_dashboard_data(self, path): json_file = Files.parent_folder_combine(__file__, path) return Json.load_json(json_file) def get_test_params(self, cells, rows): params = {'cells': cells, 'rows': rows, 'data_R1s': {}, 'data_R2s': {}} for i in range(1, params.get('cells') + 1): header_id = 'r{0}'.format(i) params['data_R1s'][header_id] = header_id for j in range(1, params.get('cells') + 1): for i in range(1, params.get('rows') + 1): header_id = 'r{0}_{1}'.format(j, i) params['data_R1s'][header_id] = header_id return params def show_chrome(self): self.render_page.api_browser.headless = False self.render_page.api_browser.auto_close = False return self def load_page(self, reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def execute(self, method, params=None): self.js_execute('window.r1_and_r2.{0}'.format(method), params) return self def js_execute(self, name, params=None): return self.browser().sync_js_invoke_function(name, params) def js_eval(self, js_code): return self.browser().sync__js_execute(js_code) def js_apply_css_color(self, js_codes, r2_id, index, diff=None, show_diff_delta=False): # if index < 1: # min value is 1 # index = 1 # since we start the rows on 1 # if index > 15: # max value can be bigger than 16 # index = 16 # since that is the size of the Hex digits # hex_values = 'FEDCBA9876543210' # color = '#{0}{0}{1}{1}00'.format(hex_values[index - 1], hex_values[16 - index]) # get the color changing the RGB values (R = Red , G = Green) js_code = "" if diff is not None: if diff > 0: value = '+' + str(diff) if diff == 0: value = '=' if diff < 0: value = diff badge_code = '<br><span class="badge badge-secondary">{0}</span>'.format( value) js_code += "if ($('#{0}').text() != '') {{ $('#{0}').append('{1}') }}".format( r2_id, badge_code) if show_diff_delta: index = diff * 2 + 4 if show_diff_delta and index == 4: index = None if index is not None: if index < 1: index = 1 if index > 9: index = 9 colors = [ 'darkred', '#DE4108', '#F7794B', '#E67F0D', '#EA9639', '#FAAE28', '#4F9300', 'green', 'darkgreen' ] color = colors[index - 1] else: color = "#555555" css = {'background-color': color} js_code += "if ($('#{0}').text() != '') {{ $('#{0}').css({1}) }}".format( r2_id, json.dumps(css)) js_codes.append(js_code) return self def send_screenshot_to_slack(self, team_id=None, channel=None, with_diffs=False): png_file = self.create_dashboard_screenshot(with_diffs) return Browser_Lamdba_Helper().send_png_file_to_slack( team_id, channel, 'risk dashboard', png_file) def send_graph_name_to_slack(self, team_id, channel): from utils.Lambdas_Helpers import slack_message slack_message( ":point_right: Created graph `{0}` from jira key `{1}`".format( self.graph_name, self.jira_key), [], channel, team_id) return self def create_dashboard_screenshot(self, with_diffs=False): if with_diffs: height = 560 else: height = 465 clip = {'x': 1, 'y': 1, 'width': 945, 'height': height} return self.browser().sync__screenshot(clip=clip) def create_dashboard_with_scores(self, scores, diffs=None, show_diff_delta=False): self.create_dashboard_with_R1_R2() rows = 6 cells = 6 js_codes = [] for i in range(1, cells + 1): for j in range(1, rows + 1): r2_id = "r{0}_{1}".format(i, j) # if scores.get(r2_id): # color = scores.get(r2_id) # else: # color = 1 color = scores.get(r2_id) if diffs and diffs.get(r2_id) is not None: diff = color - diffs.get(r2_id) else: diff = None self.js_apply_css_color(js_codes, r2_id, color, diff, show_diff_delta) self.js_eval(js_codes) return self def create_dashboard_with_R1_R2(self): self.load_page(False) data = self.get_dashboard_data('gs-dashboard.json') data_R1s = data.get('data_R1s') data_R2s = data.get('data_R2s') risks = data.get('risks') params = { 'cells': len(data_R1s), 'rows': len(data_R2s), 'data_R1s': data_R1s, 'data_R2s': data_R2s, 'risks': risks } self.execute('create_risk_table', params) return data_R1s, data_R2s def create_dashboard_with_test_data(self): self.create_dashboard_with_R1_R2() rows = 6 cells = 6 js_codes = [] for i in range(1, cells + 1): for j in range(1, rows + 1): r2_id = "r{0}_{1}".format(i, j) color = Misc.random_number(1, 5) #color = j self.js_apply_css_color(js_codes, r2_id, color) self.js_eval(js_codes) return self def create_dashboard_for_graph(self, graph_name, root_node): from utils.aws.Lambdas import Lambdas from view_helpers.Vis_Js import Vis_Js self.graph_name = graph_name self.jira_key = root_node payload = {"graph_name": graph_name, 'destination_node': root_node} graph_paths = Lambdas('gs.graph_paths').invoke(payload) self.create_dashboard_with_R1_R2() graph_data = Vis_Js().get_graph_data(graph_name) nodes = graph_data.get('nodes') colors_scores = {} for key, node in nodes.items(): if node: if 'R2' in node.get('Labels'): summary = node.get('Summary') cell_key = ( "r" + summary.split('-')[0].replace('.', '_')).strip() #Dev.pprint(graph_paths.get(key)) if graph_paths.get(key): score = len(graph_paths.get(key)) colors_scores[cell_key] = score #Dev.pprint(score) #Dev.pprint(key + ' ' + cell_key + ' ' + str(score) + ' ' + summary) #return colors_scores #Dev.pprint(colors_scores) js_codes = [] for i in range(1, 7): for j in range(1, 7): r2_id = "r{0}_{1}".format(i, j) color = colors_scores.get(r2_id) self.js_apply_css_color(js_codes, r2_id, color) self.js_eval(js_codes) return self def create_dashboard_for_jira_key(self, jira_key): from utils.aws.Lambdas import Lambdas lambda_graph = Lambdas('gsbot.gsbot_graph') payload = { 'data': {}, "params": ['expand', jira_key, 9, 'delivered by,risks_up'] } result = lambda_graph.invoke(payload) graph_data = json.loads(result) graph_name = graph_data.get('graph_name') sleep(1.0) # to give time for ELK to index return self.create_dashboard_for_graph(graph_name, jira_key) def calculate_score(self, scores, title): size = len(scores) min = size max = size * 8 #print(min, max) score = 0 for value in scores.values(): score += value #print(value, score) score = int((score - size) / max * 100) print("The score for {0:23} {1:3} / 100".format(title, score)) return score, size
class VivaGraph_Js: def __init__(self, headless=True): self.web_page = '/vivagraph/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser(headless=headless,auto_close=headless).sync__setup_browser() self.web_server = Web_Server(self.web_root) self.render_page = Render_Page(api_browser=self.api_browser, web_server=self.web_server) # #self.base_html_file = '/vis-js/empty.html' # self.base_html_file = '/vis-js/simple.html' # #window.api_visjs # self.headless = False # self.browser = None # common methods (move to base class) def browser(self): return self.api_browser def browser_width(self,value): self.browser().sync__browser_width(value) return self def load_page(self,reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def create_dashboard_screenshot(self): #clip = {'x': 1, 'y': 1, 'width': 945, 'height': 465} clip = None return self.browser().sync__screenshot(clip=clip) def send_screenshot_to_slack(self, team_id, channel): png_file = self.create_dashboard_screenshot() return Browser_Lamdba_Helper().send_png_file_to_slack(team_id, channel, 'risk dashboard', png_file) def get_graph_data(self, graph_name): params = {'params': ['raw_data', graph_name, 'details'], 'data': {}} data = Lambdas('gsbot.gsbot_graph').invoke(params) if type(data) is str: s3_key = data s3_bucket = 'gs-lambda-tests' tmp_file = S3().file_download_and_delete(s3_bucket, s3_key) data = Json.load_json_and_delete(tmp_file) return data return data def exec_js(self,js_code): return self.browser().sync__js_execute(js_code) def invoke_js(self, name, params): return self.browser().sync_js_invoke_function(name,params) def create_graph_and_send_screenshot_to_slack(self, nodes, edges, options=None, team_id=None, channel=None): if len(nodes) >0: self.create_graph(nodes, edges,options) if len(nodes) < 20 : sleep(1) elif 20 < len(nodes) < 100: self.browser().sync__browser_width(1500) ; sleep(2) elif 100 < len(nodes) < 200: self.browser().sync__browser_width(2000) ; sleep(5) elif len(nodes) > 200: self.browser().sync__browser_width(3000) ; sleep(10) return self.send_screenshot_to_slack(team_id, channel) #self.create_graph(nodes, edges,options,graph_name) #return self.send_screenshot_to_slack(t§eam_id, channel) # main methods def create_graph(self, nodes, edges,options=None): self.web_server.start() url = self.web_server.url(self.web_page) self.render_page.get_page_html_via_browser(url) self.load_page(True) layout = { "springLength" : 100, "springCoeff" : 0.0008, "dragCoeff" : 0.02, "gravity" : -10.2 }; self.invoke_js("set_layout",layout) js_code = "" #for key,issue in nodes.items(): for node in nodes: key = node.get('key') label = node.get('label') img = node.get('img') params = { "label" : label, "img": img} js_code += 'graph.addNode("{0}",{1});'.format(key,Misc.json_dumps(params)) for edge in edges: js_code += 'graph.addLink("{0}","{1}");\n'.format(edge[0],edge[2]) js_code += "run_graph()" self.exec_js(js_code) self.web_server.stop() return 42 def resolve_icon_from_issue_type(self, issue,key): none_icon = 'icons/none.jpg' mappings = { 'Risk' : 'icons/risk_theme.svg', 'Risk Theme' : 'icons/risk_theme.svg', 'Vulnerability' : 'icons/vuln.png', 'GS-Project' : 'icons/gs_project.svg', 'Business entity': 'icons/business_entity.svg', 'GS Service ' : 'icons/gs_service.svg', 'IT Asset' : 'icons/it_asset.svg', 'IT System' : 'icons/it_asset.svg', 'People' : 'icons/people.svg', 'Programme' : 'icons/programme.svg', 'Threat Model' : 'icons/threat_model.svg', 'Key Result' : 'icons/key-result.svg', 'Objective' : 'icons/objective.svg', 'Task' : 'icons/task.svg', 'Epic' : 'icons/epic.svg', 'Data Journey' : 'icons/data_journey.svg', 'Project' : 'icons/project.svg', 'Fact' : 'icons/fact.svg', 'Incident' : 'icons/incident.png', 'Incident Task' : 'icons/incident_task.png', 'User Access' : 'icons/user_access.svg', 'Security Event' : 'icons/security_event.svg', } if issue and issue.get("Issue Type"): issue_type = issue.get("Issue Type") icon = mappings.get(issue_type, none_icon) #if icon == none_icon: # Dev.pprint(key + ' ' + issue_type) else: icon = none_icon return icon
class Test_Render_Page(TestCase): def setUp(self): self.render_page = Render_Page(headless = False, auto_close = False) self.random_value = Misc.random_string_and_numbers(6, "dynamic text ") self.html = "<html><script>document.write('{0}')</script></html>".format(self.random_value) def test_render_file(self): with Temp_File(self.html, 'html') as temp_file: result = self.render_page.render_file(temp_file.file_path) assert result('body').html() == self.random_value def test_render_folder(self): result = self.render_page.render_folder(Files.current_folder()) Dev.print(result.html()) def test_render_html(self): result = self.render_page.render_html(self.html) assert result('body').html() == self.random_value def test_screenshot_html(self): tmp_img = '/tmp/test_screenshot_html.png' img_file = self.render_page.screenshot_html(self.html,tmp_img) assert Files.exists(img_file) def test_screenshot_file(self): with Temp_File(self.html, 'html') as temp_file: tmp_img = '/tmp/test_screenshot_html.png' clip = {'x': 1, 'y': 1, 'width': 180, 'height': 30} img_file = self.render_page.screenshot_file(temp_file.file_path,tmp_img,clip=clip) assert Files.exists(img_file) def test_screenshot_folder(self): web_root = Files.current_folder() tmp_img = '/tmp/test_screenshot_html.png' clip = {'x': 1, 'y': 1, 'width':280, 'height': 200} self.render_page.screenshot_folder(web_root, tmp_img,clip) def test_screenshot_file_in_folder(self): web_root = Files.current_folder() tmp_img = '/tmp/test_screenshot_html.png' html_file = 'aaaa.html' self.render_page.screenshot_file_in_folder(web_root, html_file, tmp_img) def test_screenshot_url(self): #url = 'https://github.com/GoogleChrome/puppeteer' #url = 'https://www.google.co.uk' #url = 'http://visjs.org/examples/network/other/manipulation.html' #url = 'http://visjs.org/examples/graph3d/01_basics.html' url = 'https://getbootstrap.com/docs/4.3/examples/dashboard/' tmp_img = '/tmp/test_screenshot_html.png' self.render_page.screenshot_url(url, tmp_img)
def setUp(self): self.render_page = Render_Page(headless = False, auto_close = False) self.random_value = Misc.random_string_and_numbers(6, "dynamic text ") self.html = "<html><script>document.write('{0}')</script></html>".format(self.random_value)
class DataTable_Js: def __init__(self): self.web_page = '/datatables/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser().sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.table_width = '100%' self.columns_defs = None self.table_title = None # helper methods (to move to base class) def browser(self): return self.api_browser def show_chrome(self): self.render_page.api_browser.headless = False self.render_page.api_browser.auto_close = False return self def load_page(self, reload=False): if reload or self.web_page not in self.browser().sync__url(): self.render_page.open_file_in_browser(self.web_page) return self def js_execute(self, name, params=None): return self.browser().sync_js_invoke_function(name, params) def js_eval(self, js_code): return self.browser().sync__js_execute(js_code) def send_screenshot_to_slack(self, team_id, channel): png_file = self.create_dashboard_screenshot() return Browser_Lamdba_Helper().send_png_file_to_slack( team_id, channel, 'risk dashboard', png_file) def create_dashboard_screenshot(self): #clip = {'x': 1, 'y': 1, 'width': 945, 'height': 465} clip = None return self.browser().sync__screenshot(clip=clip) # main datatable methods def create_table(self, headers, rows): self.load_page(True) columns = [] for header in headers: columns.append({'title': header}), # headers_html = "" # for header in headers: # headers_html += "<th>{0}</th>".format(header) # # headers_html = "<tr>{0}</tr>".format(headers_html) # # rows_html = "" # for row in rows: # row_html = "" # for cell in row: # row_html += "<td>{0}</td>".format(cell) # row_html = "<tr>{0}</tr>\n".format(row_html) # Dev.print(rows_html) # rows_html += row_html # # #rows_html = "<tr><td>an row</td></tr>" # # table_html = """ <table id='{table_id}' class='display'> # <thead> # {headers} # </thead> # <tbody> # {rows} # </tbody> # </table> # """.format(table_id=table_id,headers=headers_html, rows = rows_html) #self.js_execute("$('#dynamic_data_table').html",table_html) options = { 'columns': columns, "columnDefs": self.columns_defs, 'data': rows, "paging": False, "ordering": False, "info": False, "searching": False } table_html = '<table id="data_table" class="display" width="{0}"></table>'.format( self.table_width) self.js_execute("$('#dynamic_data_table').html", table_html) # create table html element self.js_eval( "$.fn.dataTable.ext.errMode = 'none';") # disable table errors self.js_execute("$('#data_table').DataTable", options) # create table if self.table_title: self.js_execute("$('#table_title').html", self.table_title) return self