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).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, tmp_img=None, clip=None, headless=False): self.headless = headless self.path_views = Files.path_combine(Files.parent_folder(__file__), '../../osbot_browser/web_root') self.render_page = Render_Page(headless=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).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 = '/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
def __init__(self, headless=True): self.web_page = '/gs/risk/risks-dashboard.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.headless = headless 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
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__), '../../osbot_browser/web_root') self.render_page = Render_Page(headless=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, headless=True): self.web_page = '/vis-js/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') chrome = Chrome().headless(headless) self.api_browser = API_Browser(chrome.sync().browser()) self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root) self.bot_name = 'GS_Bot' self.options = None
def setup(self): self.load_browser_dependencies() from osbot_browser.browser.API_Browser import API_Browser from osbot_browser.browser.Render_Page import Render_Page self.api_browser = API_Browser( headless=self.headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root()) return self
def setup(self): if os.getenv('AWS_REGION'): load_dependency('syncer') load_dependency('requests') #self.setup_AWS() # else: # self.setup_local() from osbot_browser.browser.API_Browser import API_Browser from osbot_browser.browser.Render_Page import Render_Page self.api_browser = API_Browser(headless=self.headless).sync__setup_browser() self.render_page = Render_Page(api_browser=self.api_browser, web_root=self.web_root()) return self
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
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).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 = Lambda('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_url = node.get('img_url') img_size = node.get('img_size') params = {"label": label, "img_url": img_url, 'img_size': img_size} 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): label = key img_size = 20 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 = 'icons/none.jpg' #icon = 'https://dummyimage.com/100x40/2c2f87/FFFFFF&text={0}'.format(key) #img_size = 10 return label, img_size, icon
class Google_Charts_Js: def __init__(self, headless=True): self.web_page = '/google_charts/simple.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.api_browser = API_Browser(headless=headless).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} return self.browser().sync__screenshot() # main datatable methods def create_data_table(self, chart_type, options, data): #, cols, rows): # cols = [{'id': 'task', 'label': 'Task', 'type': 'string'}, # {'id': 'hours', 'label': 'Hours per Day', 'type': 'number'}, # {'id': 'hours', 'label': '2nd key', 'type': 'number'}] # rows = [{'c': [{'v': 'Work' }, {'v': 11}, {'v': 2} ]}, # {'c': [{'v': 'Play' }, {'v': 2 }]}, # {'c': [{'v': 'Other'}, {'v': 5 }]}] # # data = { 'cols' : cols, 'rows' : rows} #'BarChart' # PieChart' self.js_execute( 'window.data_table=new google.visualization.arrayToDataTable', 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)) def create_chart(self, chart_type, options, width, height, data, clip): if width is None: width = 800 if height is None: height = 500 if clip is None: clip = {'x': 100, 'y': 50, 'width': 580, 'height': 450} options['height'] = height options['width'] = width self.create_data_table(chart_type, options, data) return self.browser().sync__screenshot_base64(clip=clip)
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).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 = Lambda('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 Risk_Dashboard: def __init__(self, headless=True): self.web_page = '/gs/risk/risks-dashboard.html' self.web_root = Files.path_combine(Files.parent_folder(__file__), '../web_root') self.headless = headless 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 #value = "" 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 pbx_gs_python_utils.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 osbot_browser.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 = Lambda('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): lambda_graph = Lambda('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 test_Render_Page(TestCase): def setUp(self): self.render_page = Render_Page(headless=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) self.tmp_img = '/tmp/lambda_png_file.png' def test_render_file(self): with Temp_File(self.html, 'html') as temp_file: #Dev.pprint(temp_file.file_path) 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()) assert "Directory listing for " in 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): img_file = self.render_page.screenshot_html(self.html, self.tmp_img) assert Files.exists(img_file) def test_screenshot_file(self): with Temp_File(self.html, 'html') as temp_file: clip = {'x': 1, 'y': 1, 'width': 180, 'height': 30} img_file = self.render_page.screenshot_file(temp_file.file_path, self.tmp_img, clip=clip) assert Files.exists(img_file) def test_screenshot_folder(self): web_root = Files.current_folder() clip = {'x': 1, 'y': 1, 'width': 280, 'height': 200} Files.delete(self.tmp_img) self.render_page.screenshot_folder(web_root, self.tmp_img, clip) assert Files.exists(self.tmp_img) def test_screenshot_file_in_folder(self): web_root = Files.current_folder() html_file = 'aaaa.html' self.render_page.screenshot_file_in_folder(web_root, html_file, self.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' Files.delete(tmp_img) self.render_page.screenshot_url(url, tmp_img) assert Files.exists(tmp_img)
def setUp(self): self.render_page = Render_Page(headless=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) self.tmp_img = '/tmp/lambda_png_file.png'
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).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, height=None): self.browser().sync__browser_width(value, height) 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=None): #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, clip=None): png_file = self.create_dashboard_screenshot(clip) 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 = Lambda('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)