From a9a73f45fa28e8ee5e9cb8929f87ae45b2ac24d9 Mon Sep 17 00:00:00 2001 From: Judson Date: Mon, 18 Jan 2016 10:34:09 -0800 Subject: [PATCH] Updates to the history logger --- README.md | 91 +++++++++++++++++++++++++- lib/waterpig/browser-console-logger.rb | 26 ++++++-- 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4e063fe..8916b1f 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,6 @@ The Waterpig::BrowserConsoleLogger class can execute a remote call to console.hi the contents of the browser console, and log it to file. This is extremely useful for debugging front-end issues during integration specs. -For browser console logging to work, the console.history() method must have already been defined in your browser. -This must be handled separately, see the console history injector in Xing for an example. - To turn on browser console logging: At the command line: @@ -69,6 +66,94 @@ RSpec.configure do |config| end ``` +For browser console logging to work, the console.history() method must have +already been defined in your browser. Arrange for something like this to be +loaded: +``` + //very simple console wrapper to preserve history +(function(){ + + // Returns a version of obj without functions + // or recursive references. Recursive references + // will blow out the stack when we try to + // serialize. + function strippedObject(obj, cache = []) { + var newObj = {}; + for (var property in obj) { + if (obj.hasOwnProperty(property)) { + var value = obj[property]; + switch (typeof value) { + case "function": + break; + case "object": + if (cache.indexOf(property) == -1) { + cache.push(property); + newObj[property] = strippedObject(value, cache); + } + break; + default: + newObj[property] = obj[property]; + } + } + } + return newObj; + } + function serializable(value) { + switch (typeof value) { + case "function": + return ""; + case "object": + return strippedObject(value); + default: + return value; + } + } + + function addItem(type, item, extra){ + console.history.push({ + time: (new Date()).toString(), + value: serializable(item), + type: type, + extra: extra + }); + } + + function decorate(name, processFn) { + var undecorated = console[name]; + console[name] = function(){ + processFn.apply(null, arguments); + undecorated.apply(console, arguments); + }; + } + + console.history = console.history || []; + + decorate('log', function(){ + for( var arg of arguments ){ addItem('message', arg, 'log'); } + }); + decorate('warn', function(){ + for( var arg of arguments ){ addItem('message', arg, 'warn'); } + }); + decorate('error', function(){ + for( var arg of arguments ){ addItem('message', arg, 'error'); } + }); + + decorate('group', function(){ + addItem('groupStart', null); + }); + decorate('groupCollapsed', function(){ + addItem('groupStart', null); + }); + decorate('groupEnd', function(){ + addItem('groupEnd', null); + }); + + decorate('table', function(){ + addItem('table', Array.prototype.slice.call(arguments)[0]); + }); +})(); +``` + # Database Cleaning Because database cleaning is sich a tricky problem, Waterpig tries to handle it diff --git a/lib/waterpig/browser-console-logger.rb b/lib/waterpig/browser-console-logger.rb index e07186c..829658e 100644 --- a/lib/waterpig/browser-console-logger.rb +++ b/lib/waterpig/browser-console-logger.rb @@ -17,10 +17,14 @@ def emit_header(string) def emit_log(entry) file.write( entry['time'] + "\n") - if entry['type'] == 'table' + case entry['type'] + when 'table' emit_table(entry['value']) - else + when 'message' file.write(entry['value'].to_s + "\n\n") + when 'groupStart', 'groupEnd' + else + file.write(entry.inspect + "\n") end end @@ -76,10 +80,22 @@ def emit_simple_table(hash, table) # | bar | 5 | | 3 | # +-------+---+---+---+ def emit_complex_table(hash, table) - keys = hash.reduce([]){ |memo, arr| memo + arr[1].keys }.uniq + keys = hash.values.reduce({}) do |memo, row| + case row + when Hash + memo.merge(row) + else + memo.merge(value: true) + end + end.keys table.head = [ "index" ] + keys hash.each do |name, row| - table.rows << [ name ] + keys.map{ |key| row.fetch(key, nil)} + case row + when Hash + table.rows << [ name ] + keys.map{ |key| row.fetch(key, nil)} + else + table.rows << [ name ] + keys.map{ |key| key == :value ? row : nil } + end end end @@ -89,7 +105,7 @@ def handle_example(page, example) if console_entries console_entries.each do |entry| - logger.emit_log(entry) + emit_log(entry) end end end