def __call__(self, request): if not show_toolbar(request) or request.is_ajax(): return self.get_response(request) if request.content_type != "application/json": response = super().__call__(request) content_type = response.get("Content-Type", "").split(";")[0] if content_type == "text/html": template = render_to_string("graphiql_debug_toolbar/base.html") response.write(template) set_content_length(response) return response toolbar = DebugToolbar(request, self.get_response) for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: response = toolbar.process_request(request) finally: for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() response = self.generate_server_timing_header(response, toolbar.enabled_panels) payload = get_payload(request, response, toolbar) response.content = json.dumps(payload, cls=CallableJSONEncoder) set_content_length(response) return response
def __call__(self, request): if settings.DEBUG_TOOLBAR and django_settings.DEBUG: toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) input_request_logger = getattr(request, 'input_request_logger', None) if input_request_logger: for ignored_path in settings.DEBUG_TOOLBAR_IGNORE_URL_REGEX_PATHS: if re.match(r'^{}$'.format(ignored_path), request.path): return response input_request_logger.update_extra_data( {'debug_toolbar': toolbar.render_toolbar()}) return response else: return self.get_response(request)
def __call__(self, request): if not get_show_toolbar()(request) or request.is_ajax(): return self.get_response(request) content_type = request.content_type html_type = content_type in _HTML_TYPES if html_type: response = super().__call__(request) template = render_to_string('graphiql_debug_toolbar/base.html') response.write(template) set_content_length(response) return response toolbar = DebugToolbar(request, self.get_response) for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: response = toolbar.process_request(request) finally: for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() response = self.generate_server_timing_header( response, toolbar.enabled_panels, ) payload = get_payload(request, response, toolbar) response.content = json.dumps(payload, cls=CallableJSONEncoder) set_content_length(response) return response
def __call__(self, request): if settings.DEBUG_TOOLBAR and django_settings.DEBUG: toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) if getattr(request, 'input_logged_request', False): DebugToolbarData.objects.create( logged_request=request.input_logged_request, toolbar=toolbar.render_toolbar() ) return response else: return self.get_response(request)
def __call__(self, request): # Decide whether the toolbar is active for this request. Don't render # the toolbar during AJAX requests. show_toolbar = get_show_toolbar() if not show_toolbar(request) or request.is_ajax(): return self.get_response(request) toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() # Check for responses where the toolbar can't be inserted. content_encoding = response.get("Content-Encoding", "") content_type = response.get("Content-Type", "").split(";")[0] if any( ( getattr(response, "streaming", False), "gzip" in content_encoding, content_type not in _HTML_TYPES, ) ): return response # Collapse the toolbar by default if SHOW_COLLAPSED is set. if toolbar.config["SHOW_COLLAPSED"] and "djdt" not in request.COOKIES: response.set_cookie("djdt", "hide", 864000) # Insert the toolbar in the response. content = response.content.decode(response.charset) insert_before = dt_settings.get_config()["INSERT_BEFORE"] pattern = re.escape(insert_before) bits = re.split(pattern, content, flags=re.IGNORECASE) if len(bits) > 1: # When the toolbar will be inserted for sure, generate the stats. for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) response = self.generate_server_timing_header( response, toolbar.enabled_panels ) bits[-2] += toolbar.render_toolbar() response.content = insert_before.join(bits) if response.get("Content-Length", None): response["Content-Length"] = len(response.content) return response
def __call__(self, request): # Decide whether the toolbar is active for this request. show_toolbar = get_show_toolbar() if not show_toolbar(request) or DebugToolbar.is_toolbar_request( request): return self.get_response(request) toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: clear_stack_trace_caches() # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() # Generate the stats for all requests when the toolbar is being shown, # but not necessarily inserted. for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) # Always render the toolbar for the history panel, even if it is not # included in the response. rendered = toolbar.render_toolbar() for header, value in self.get_headers(request, toolbar.enabled_panels).items(): response.headers[header] = value # Check for responses where the toolbar can't be inserted. content_encoding = response.get("Content-Encoding", "") content_type = response.get("Content-Type", "").split(";")[0] if (getattr(response, "streaming", False) or content_encoding != "" or content_type not in _HTML_TYPES): return response # Insert the toolbar in the response. content = response.content.decode(response.charset) insert_before = dt_settings.get_config()["INSERT_BEFORE"] pattern = re.escape(insert_before) bits = re.split(pattern, content, flags=re.IGNORECASE) if len(bits) > 1: bits[-2] += rendered response.content = insert_before.join(bits) if "Content-Length" in response: response["Content-Length"] = len(response.content) return response
def setUp(self): super().setUp() self._get_response = lambda request: HttpResponse() self.request = rf.get("/") self.toolbar = DebugToolbar(self.request, self.get_response) self.toolbar.stats = {} if self.panel_id: self.panel = self.toolbar.get_panel_by_id(self.panel_id) self.panel.enable_instrumentation() else: self.panel = None
def setUp(self): debug_toolbar_version = debug_toolbar.VERSION self.request = rf.post('/submit/', {'foo': 'bar'}) # django-debug-toolbar 1.x take 1 argument, 2.x take 2 arguments if debug_toolbar_version < '2.0': self.toolbar = DebugToolbar(self.request) self.panel_args = (self.toolbar, ) else: self.toolbar = DebugToolbar(self.request, None) self.panel_args = (self.toolbar, None)
def __call__(self, request): # Decide whether the toolbar is active for this request. Don't render # the toolbar during AJAX requests. show_toolbar = get_show_toolbar() if not show_toolbar(request): return self.get_response(request) toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() # Check for responses where the toolbar can't be inserted. content_encoding = response.get("Content-Encoding", "") content_type = response.get("Content-Type", "").split(";")[0] if any( ( getattr(response, "streaming", False), "gzip" in content_encoding, content_type not in _HTML_TYPES, ) ): return response # Collapse the toolbar by default if SHOW_COLLAPSED is set. if toolbar.config["SHOW_COLLAPSED"] and "djdt" not in request.COOKIES: response.set_cookie("djdt", "hide", 864000) if toolbar: # for django-debug-toolbar >= 1.4 for panel in reversed(toolbar.enabled_panels): if hasattr(panel, 'generate_stats'): panel.generate_stats(request, response) cache_key = "%f" % time.time() cache.set(cache_key, toolbar.render_toolbar()) response['X-debug-data-url'] = request.build_absolute_uri( reverse('debug_data', urlconf=debug_toolbar.urls, kwargs={'cache_key': cache_key})) return response
def test_render_panel_checks_show_toolbar(self): toolbar = DebugToolbar(None) toolbar.store() url = '/__debug__/render_panel/' data = {'store_id': toolbar.store_id, 'panel_id': 'VersionsPanel'} response = self.client.get(url, data) self.assertEqual(response.status_code, 200) response = self.client.get(url, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) with self.settings(INTERNAL_IPS=[]): response = self.client.get(url, data) self.assertEqual(response.status_code, 404) response = self.client.get(url, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 404)
class BaseTestCase(TestCase): panel_id = None def setUp(self): super().setUp() self._get_response = lambda request: HttpResponse() self.request = rf.get("/") self.toolbar = DebugToolbar(self.request, self.get_response) self.toolbar.stats = {} if self.panel_id: self.panel = self.toolbar.get_panel_by_id(self.panel_id) self.panel.enable_instrumentation() else: self.panel = None def tearDown(self): if self.panel: self.panel.disable_instrumentation() super().tearDown() def get_response(self, request): return self._get_response(request) def assertValidHTML(self, content): parser = html5lib.HTMLParser() parser.parseFragment(content) if parser.errors: msg_parts = ["Invalid HTML:"] lines = content.split("\n") for position, errorcode, datavars in parser.errors: msg_parts.append(" %s" % html5lib.constants.E[errorcode] % datavars) msg_parts.append(" %s" % lines[position[0] - 1]) raise self.failureException("\n".join(msg_parts))
def process_request(self, request): # Decide whether the toolbar is active for this request. show_toolbar = get_show_toolbar() if not show_toolbar(request): return # Don't render the toolbar during AJAX requests. if request.is_ajax(): return toolbar = DebugToolbar(request) self.__class__.debug_toolbars[ threading.current_thread().ident] = toolbar # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() # Run process_request methods of panels like Django middleware. response = None for panel in toolbar.enabled_panels: response = panel.process_request(request) if response: break return response
class FlagChecksPanelTestCase(TestCase): def setUp(self): self.request = RequestFactory().get('/') self.toolbar = DebugToolbar(self.request) self.toolbar.stats = {} self.panel = self.toolbar.get_panel_by_id('FlagChecksPanel') @override_settings(FLAGS={'MYFLAG': [('boolean', True)]}) def test_recording(self): self.assertEqual(len(self.panel.checks), 0) self.panel.enable_instrumentation() flag_state('MYFLAG') self.panel.disable_instrumentation() self.assertEqual(len(self.panel.checks), 1) response = self.panel.process_request(self.request) self.panel.generate_stats(self.request, response) checks = self.panel.get_stats()['checks'] self.assertIn('MYFLAG', checks) self.assertEqual([ True, ], checks['MYFLAG'])
def history_sidebar(request): """Returns the selected debug toolbar history snapshot.""" form = HistoryStoreForm(request.GET) if form.is_valid(): store_id = form.cleaned_data["store_id"] toolbar = DebugToolbar.fetch(store_id) exclude_history = form.cleaned_data["exclude_history"] context = {} if toolbar is None: # When the store_id has been popped already due to # RESULTS_CACHE_SIZE return JsonResponse(context) for panel in toolbar.panels: if exclude_history and not panel.is_historical: continue panel_context = {"panel": panel} context[panel.panel_id] = { "button": render_to_string("debug_toolbar/includes/panel_button.html", panel_context), "content": render_to_string("debug_toolbar/includes/panel_content.html", panel_context), } return JsonResponse(context) return HttpResponseBadRequest("Form errors")
def ready(self): from debug_toolbar.toolbar import DebugToolbar # Import the panels when the app is ready and call their ready() methods. This # allows panels like CachePanel to enable their instrumentation immediately. for cls in DebugToolbar.get_panel_classes(): cls.ready()
def check_panel_configs(app_configs, **kwargs): """Allow each panel to check the toolbar's integration for their its own purposes.""" from debug_toolbar.toolbar import DebugToolbar errors = [] for panel_class in DebugToolbar.get_panel_classes(): for check_message in panel_class.run_checks(): errors.append(check_message) return errors
def render_panel(request): """Render the contents of a panel""" toolbar = DebugToolbar.fetch(request.GET["store_id"]) if toolbar is None: content = _("Data for this panel isn't available anymore. " "Please reload the page and retry.") content = "<p>%s</p>" % escape(content) else: panel = toolbar.get_panel_by_id(request.GET["panel_id"]) content = panel.content return HttpResponse(content)
def test_render_panel_checks_show_toolbar(self): def get_response(request): return HttpResponse() toolbar = DebugToolbar(rf.get("/"), get_response) toolbar.store() url = "/__debug__/render_panel/" data = {"store_id": toolbar.store_id, "panel_id": "VersionsPanel"} response = self.client.get(url, data) self.assertEqual(response.status_code, 200) response = self.client.get(url, data, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) with self.settings(INTERNAL_IPS=[]): response = self.client.get(url, data) self.assertEqual(response.status_code, 404) response = self.client.get( url, data, HTTP_X_REQUESTED_WITH="XMLHttpRequest" ) self.assertEqual(response.status_code, 404)
def setUp(self): request = rf.get('/') response = HttpResponse() toolbar = DebugToolbar(request) DebugToolbarMiddleware.debug_toolbars[threading.current_thread().ident] = toolbar self.request = request self.response = response self.toolbar = toolbar self.toolbar.stats = {}
def render_panel(request): """Render the contents of a panel""" toolbar = DebugToolbar.fetch(request.GET['storage_id']) if toolbar is None: content = _("Data for this panel isn't available anymore. " "Please reload the page and retry.") content = "<p>%s</p>" % escape(content) else: panel = toolbar.get_panel_by_id(request.GET['panel_id']) content = panel.content() return HttpResponse(content)
def render_panel(request): """Render the contents of a panel""" toolbar = DebugToolbar.fetch(int(request.GET['storage_id'])) if toolbar is None: content = _("Data for this panel isn't available anymore. " "Please reload the page and retry.") content = "<p>%s</p>" % escape(content) else: panel_id = request.GET['panel_id'] for panel in toolbar.panels: if panel.dom_id() == panel_id: content = panel.content() break return HttpResponse(content)
def process_request(self, request): if not self.show_toolbar(request): return response = None toolbar = DebugToolbar(request) for panel in toolbar.enabled_panels: panel.enable_instrumentation() for panel in toolbar.enabled_panels: response = panel.process_request(request) if response: break self.__class__.debug_toolbars[ threading.current_thread().ident] = toolbar return response
def __call__(self, request): if not get_show_toolbar()(request) or request.is_ajax(): return self.get_response(request) response = super().__call__(request) content_type = response.get('Content-Type', '').split(';')[0] html_type = content_type in _HTML_TYPES graphql_view = getattr(request, '_graphql_view', False) if response.status_code == 200 and graphql_view and html_type: template = render_to_string('graphiql_debug_toolbar/base.html') response.write(template) set_content_length(response) if html_type or not (graphql_view and content_type == 'application/json'): return response toolbar = DebugToolbar(request, self.get_response) for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: response = toolbar.process_request(request) finally: for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() response = self.generate_server_timing_header( response, toolbar.enabled_panels, ) payload = get_payload(request, response, toolbar) response.content = json.dumps(payload, cls=CallableJSONEncoder) set_content_length(response) return response
class FlagsPanelTestCase(TestCase): def setUp(self): self.request = RequestFactory().get("/") self.get_response = lambda req: HttpResponse() self.toolbar = DebugToolbar(self.request, self.get_response) self.toolbar.stats = {} self.panel = self.toolbar.get_panel_by_id("FlagsPanel") @override_settings(FLAGS={"MYFLAG": [("boolean", True)]}) def test_flags_panel_has_flags(self): response = self.panel.process_request(self.request) self.panel.generate_stats(self.request, response) flags = self.panel.get_stats()["flags"] self.assertIn("MYFLAG", [f.name for f in flags]) self.assertIn("enabled", self.panel.content)
def render_panel(request): """Render the contents of a panel""" # Check if store_id key exist in GET request. if not request.GET.has_key("store_id"): content = _('"store_id" key is required') return HttpResponse(content) toolbar = DebugToolbar.fetch(request.GET["store_id"]) if toolbar is None: content = _("Data for this panel isn't available anymore. " "Please reload the page and retry.") content = "<p>%s</p>" % escape(content) else: panel = toolbar.get_panel_by_id(request.GET["panel_id"]) content = panel.content return HttpResponse(content)
def __call__(self, request): toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() # generate stats and timing for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) stats = self._extract_panel_stats(toolbar.enabled_panels) message = self._stats_message(stats) LOG.info(f'X-Time: {message}') response['X-Time'] = message return response
def __call__(self, request): # Decide whether the toolbar is active for this request. show_toolbar = get_show_toolbar() if not show_toolbar(request) or request.path.startswith("/__debug__/"): return self.get_response(request) toolbar = DebugToolbar(request, self.get_response) # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() try: # Run panels like Django middleware. response = toolbar.process_request(request) finally: # Deactivate instrumentation ie. monkey-unpatch. This must run # regardless of the response. Keep 'return' clauses below. for panel in reversed(toolbar.enabled_panels): panel.disable_instrumentation() # Generate the stats for all requests when the toolbar is being shown, # but not necessarily inserted. for panel in reversed(toolbar.enabled_panels): panel.generate_stats(request, response) panel.generate_server_timing(request, response) response = self.generate_server_timing_header(response, toolbar.enabled_panels) # Check for responses where the toolbar can't be inserted. content_encoding = response.get("Content-Encoding", "") content_type = response.get("Content-Type", "").split(";")[0] if any(( getattr(response, "streaming", False), "gzip" in content_encoding, content_type not in _HTML_TYPES, request.is_ajax(), )): # If a AJAX or JSON request, render the toolbar for the history. if request.is_ajax() or content_type == "application/json": toolbar.render_toolbar() return response # Insert the toolbar in the response. content = response.content.decode(response.charset) insert_before = dt_settings.get_config()["INSERT_BEFORE"] pattern = re.escape(insert_before) bits = re.split(pattern, content, flags=re.IGNORECASE) if len(bits) > 1: bits[-2] += toolbar.render_toolbar() response.content = insert_before.join(bits) if "Content-Length" in response: response["Content-Length"] = len(response.content) return response
def setUp(self): super(BaseTestCase, self).setUp() request = rf.get("/") response = HttpResponse() toolbar = DebugToolbar(request) DebugToolbarMiddleware.debug_toolbars[ threading.current_thread().ident] = toolbar self.request = request self.response = response self.toolbar = toolbar self.toolbar.stats = {} if self.panel_id: self.panel = self.toolbar.get_panel_by_id(self.panel_id) self.panel.enable_instrumentation() else: self.panel = None
def history_sidebar(request): """Returns the selected debug toolbar history snapshot.""" form = HistoryStoreForm(request.POST or None) if form.is_valid(): store_id = form.cleaned_data["store_id"] toolbar = DebugToolbar.fetch(store_id) context = {} for panel in toolbar.panels: if not panel.is_historical: continue panel_context = {"panel": panel} context[panel.panel_id] = { "button": render_to_string("debug_toolbar/includes/panel_button.html", panel_context), "content": render_to_string("debug_toolbar/includes/panel_content.html", panel_context), } return JsonResponse(context) return HttpResponseBadRequest("Form errors")
class FlagsPanelTestCase(TestCase): def setUp(self): self.request = RequestFactory().get('/') self.toolbar = DebugToolbar(self.request) self.toolbar.stats = {} self.panel = self.toolbar.get_panel_by_id('FlagsPanel') @override_settings(FLAGS={'MYFLAG': [('boolean', True)]}) def test_flags_panel_has_flags_without_middleware(self): response = self.panel.process_request(self.request) self.panel.generate_stats(self.request, response) flags = self.panel.get_stats()['flags'] self.assertIn('MYFLAG', [f.name for f in flags]) self.assertIn('enabled', self.panel.content) @override_settings(FLAGS={'MYFLAG': [('boolean', True)]}) def test_flags_panel_has_flags_with_middleware(self): self.middleware = FlagConditionsMiddleware() self.middleware.process_request(self.request) response = self.panel.process_request(self.request) self.panel.generate_stats(self.request, response) flags = self.panel.get_stats()['flags'] self.assertIn('MYFLAG', [f.name for f in flags])
def process_request(self, request): # Decide whether the toolbar is active for this request. func_path = dt_settings.CONFIG['SHOW_TOOLBAR_CALLBACK'] # Replace this with import_by_path in Django >= 1.6. mod_path, func_name = func_path.rsplit('.', 1) show_toolbar = getattr(import_module(mod_path), func_name) if not show_toolbar(request): return toolbar = DebugToolbar(request) self.__class__.debug_toolbars[threading.current_thread().ident] = toolbar # Activate instrumentation ie. monkey-patch. for panel in toolbar.enabled_panels: panel.enable_instrumentation() # Run process_request methods of panels like Django middleware. response = None for panel in toolbar.enabled_panels: response = panel.process_request(request) if response: break return response
def __call__(self, request): DebugToolbar.store = self.store() response = super().__call__(request) DebugToolbar.store = _store content_type = response.get("Content-Type", "").split(";")[0] is_html = content_type in _HTML_TYPES is_graphiql = getattr(request, "_graphiql", False) if is_html and is_graphiql and response.status_code == 200: template = render_to_string("graphiql_debug_toolbar/base.html") response.write(template) set_content_length(response) if (is_html or self.store_id is None or not (is_graphiql and content_type == "application/json")): return response toolbar = DebugToolbar.fetch(self.store_id) payload = get_payload(request, response, toolbar) response.content = json.dumps(payload, cls=CallableJSONEncoder) set_content_length(response) return response
class FlagChecksPanelTestCase(TestCase): def setUp(self): self.request = RequestFactory().get("/") self.toolbar = DebugToolbar(self.request) self.toolbar.stats = {} self.panel = self.toolbar.get_panel_by_id("FlagChecksPanel") @override_settings(FLAGS={"MYFLAG": [("boolean", True)]}) def test_recording(self): self.assertEqual(len(self.panel.checks), 0) self.panel.enable_instrumentation() flag_state("MYFLAG") self.panel.disable_instrumentation() self.assertEqual(len(self.panel.checks), 1) response = self.panel.process_request(self.request) self.panel.generate_stats(self.request, response) checks = self.panel.get_stats()["checks"] self.assertIn("MYFLAG", checks) self.assertEqual([True], checks["MYFLAG"])
class BaseTestCase(TestCase): panel_id = None def setUp(self): super().setUp() self._get_response = lambda request: HttpResponse() self.request = rf.get("/") self.toolbar = DebugToolbar(self.request, self.get_response) self.toolbar.stats = {} if self.panel_id: self.panel = self.toolbar.get_panel_by_id(self.panel_id) self.panel.enable_instrumentation() else: self.panel = None def tearDown(self): if self.panel: self.panel.disable_instrumentation() super().tearDown() def get_response(self, request): return self._get_response(request) def assertValidHTML(self, content, msg=None): parser = html5lib.HTMLParser() parser.parseFragment(self.panel.content) if parser.errors: default_msg = ["Content is invalid HTML:"] lines = content.split("\n") for position, errorcode, datavars in parser.errors: default_msg.append(" %s" % html5lib.constants.E[errorcode] % datavars) default_msg.append(" %s" % lines[position[0] - 1]) msg = self._formatMessage(msg, "\n".join(default_msg)) raise self.failureException(msg)