har 0.0.1.dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.mdown +36 -0
- data/Rakefile +28 -0
- data/bin/har +4 -0
- data/har.gemspec +27 -0
- data/lib/har.rb +32 -0
- data/lib/har/archive.rb +135 -0
- data/lib/har/page.rb +19 -0
- data/lib/har/schema_type.rb +78 -0
- data/lib/har/schemas/browserType +19 -0
- data/lib/har/schemas/cacheEntryType +25 -0
- data/lib/har/schemas/cacheType +15 -0
- data/lib/har/schemas/contentType +26 -0
- data/lib/har/schemas/cookieType +32 -0
- data/lib/har/schemas/creatorType +18 -0
- data/lib/har/schemas/entryType +46 -0
- data/lib/har/schemas/logType +40 -0
- data/lib/har/schemas/pageTimingsType +17 -0
- data/lib/har/schemas/pageType +29 -0
- data/lib/har/schemas/postDataType +38 -0
- data/lib/har/schemas/recordType +17 -0
- data/lib/har/schemas/requestType +53 -0
- data/lib/har/schemas/responseType +51 -0
- data/lib/har/schemas/timingsType +43 -0
- data/lib/har/serializable.rb +22 -0
- data/lib/har/version.rb +3 -0
- data/lib/har/viewer.rb +99 -0
- data/lib/har/viewer/css/SyntaxHighlighter.css +1 -0
- data/lib/har/viewer/css/aboutTab.css +1 -0
- data/lib/har/viewer/css/domTab.css +1 -0
- data/lib/har/viewer/css/domTree.css +1 -0
- data/lib/har/viewer/css/harPreview.css +1 -0
- data/lib/har/viewer/css/harView.css +1 -0
- data/lib/har/viewer/css/harViewer.css +1 -0
- data/lib/har/viewer/css/homeTab.css +1 -0
- data/lib/har/viewer/css/images/ajax-loader.gif +0 -0
- data/lib/har/viewer/css/images/bg-button.gif +0 -0
- data/lib/har/viewer/css/images/blank.gif +0 -0
- data/lib/har/viewer/css/images/button-background.png +0 -0
- data/lib/har/viewer/css/images/checkmark.gif +0 -0
- data/lib/har/viewer/css/images/checkmark.png +0 -0
- data/lib/har/viewer/css/images/close-sprites.png +0 -0
- data/lib/har/viewer/css/images/contextMenuTarget.png +0 -0
- data/lib/har/viewer/css/images/contextMenuTargetHover.png +0 -0
- data/lib/har/viewer/css/images/download-sprites.png +0 -0
- data/lib/har/viewer/css/images/downloadButtons-aero.png +0 -0
- data/lib/har/viewer/css/images/group.gif +0 -0
- data/lib/har/viewer/css/images/loading_16.gif +0 -0
- data/lib/har/viewer/css/images/menu/Thumbs.db +0 -0
- data/lib/har/viewer/css/images/menu/shadowAlpha.png +0 -0
- data/lib/har/viewer/css/images/menu/tabMenuCheckbox.png +0 -0
- data/lib/har/viewer/css/images/menu/tabMenuPin.png +0 -0
- data/lib/har/viewer/css/images/menu/tabMenuRadio.png +0 -0
- data/lib/har/viewer/css/images/netBarBlocking.gif +0 -0
- data/lib/har/viewer/css/images/netBarBlocking2.gif +0 -0
- data/lib/har/viewer/css/images/netBarCached.gif +0 -0
- data/lib/har/viewer/css/images/netBarConnecting.gif +0 -0
- data/lib/har/viewer/css/images/netBarLoaded.gif +0 -0
- data/lib/har/viewer/css/images/netBarReceiving.gif +0 -0
- data/lib/har/viewer/css/images/netBarResolving.gif +0 -0
- data/lib/har/viewer/css/images/netBarResponded.gif +0 -0
- data/lib/har/viewer/css/images/netBarSending.gif +0 -0
- data/lib/har/viewer/css/images/netBarWaiting.gif +0 -0
- data/lib/har/viewer/css/images/page-timeline.png +0 -0
- data/lib/har/viewer/css/images/save.png +0 -0
- data/lib/har/viewer/css/images/spriteArrows.gif +0 -0
- data/lib/har/viewer/css/images/spriteArrows.png +0 -0
- data/lib/har/viewer/css/images/tabEnabled.png +0 -0
- data/lib/har/viewer/css/images/timeline-sprites.png +0 -0
- data/lib/har/viewer/css/images/tooltipConnectorUp.png +0 -0
- data/lib/har/viewer/css/images/twisty-sprites.png +0 -0
- data/lib/har/viewer/css/images/twistyClosed.png +0 -0
- data/lib/har/viewer/css/images/twistyOpen.png +0 -0
- data/lib/har/viewer/css/infoTip.css +1 -0
- data/lib/har/viewer/css/pageList.css +1 -0
- data/lib/har/viewer/css/pageStats.css +1 -0
- data/lib/har/viewer/css/pageTimeline.css +1 -0
- data/lib/har/viewer/css/popupMenu.css +1 -0
- data/lib/har/viewer/css/previewTab.css +1 -0
- data/lib/har/viewer/css/requestBody.css +1 -0
- data/lib/har/viewer/css/requestList.css +1 -0
- data/lib/har/viewer/css/schemaTab.css +1 -0
- data/lib/har/viewer/css/tabView.css +1 -0
- data/lib/har/viewer/css/toolTip.css +1 -0
- data/lib/har/viewer/css/toolbar.css +1 -0
- data/lib/har/viewer/css/xhrSpy.css +1 -0
- data/lib/har/viewer/index.html +13 -0
- data/lib/har/viewer/scripts/app.build.js +0 -0
- data/lib/har/viewer/scripts/core/cookies.js +2 -0
- data/lib/har/viewer/scripts/core/lib.js +23 -0
- data/lib/har/viewer/scripts/core/trace.js +26 -0
- data/lib/har/viewer/scripts/domplate/domTree.js +5 -0
- data/lib/har/viewer/scripts/domplate/domplate.js +263 -0
- data/lib/har/viewer/scripts/domplate/infoTip.js +4 -0
- data/lib/har/viewer/scripts/domplate/popupMenu.js +14 -0
- data/lib/har/viewer/scripts/domplate/tabView.js +6 -0
- data/lib/har/viewer/scripts/domplate/toolTip.js +3 -0
- data/lib/har/viewer/scripts/domplate/toolbar.js +3 -0
- data/lib/har/viewer/scripts/downloadify/LICENSE.txt +22 -0
- data/lib/har/viewer/scripts/downloadify/README.textile +89 -0
- data/lib/har/viewer/scripts/downloadify/js/downloadify.min.js +6 -0
- data/lib/har/viewer/scripts/downloadify/js/swfobject.js +18 -0
- data/lib/har/viewer/scripts/downloadify/media/downloadify.swf +0 -0
- data/lib/har/viewer/scripts/downloadify/src/Downloadify.as +162 -0
- data/lib/har/viewer/scripts/downloadify/src/downloadify.js +6 -0
- data/lib/har/viewer/scripts/excanvas/excanvas.js +21 -0
- data/lib/har/viewer/scripts/harPreview.js +149 -0
- data/lib/har/viewer/scripts/harViewer.js +244 -0
- data/lib/har/viewer/scripts/jquery-plugins/jquery.json.js +6 -0
- data/lib/har/viewer/scripts/nls/harViewer.js +1 -0
- data/lib/har/viewer/scripts/nls/homeTab.js +1 -0
- data/lib/har/viewer/scripts/nls/pageStats.js +2 -0
- data/lib/har/viewer/scripts/nls/pageTimeline.js +1 -0
- data/lib/har/viewer/scripts/nls/previewTab.js +1 -0
- data/lib/har/viewer/scripts/nls/requestBody.js +1 -0
- data/lib/har/viewer/scripts/nls/requestList.js +2 -0
- data/lib/har/viewer/scripts/preview/harModel.js +7 -0
- data/lib/har/viewer/scripts/preview/harSchema.js +308 -0
- data/lib/har/viewer/scripts/preview/jsonSchema.js +7 -0
- data/lib/har/viewer/scripts/preview/pageList.js +4 -0
- data/lib/har/viewer/scripts/preview/ref.js +5 -0
- data/lib/har/viewer/scripts/preview/requestBody.js +11 -0
- data/lib/har/viewer/scripts/preview/requestList.js +27 -0
- data/lib/har/viewer/scripts/requireplugins-jquery-1.4.2.js +204 -0
- data/lib/har/viewer/scripts/syntax-highlighter/README.txt +9 -0
- data/lib/har/viewer/scripts/syntax-highlighter/shCore.js +20 -0
- data/lib/har/viewer/scripts/tabs/aboutTab.html +93 -0
- data/lib/har/viewer/scripts/tabs/aboutTab.js +2 -0
- data/lib/har/viewer/scripts/tabs/domTab.js +1 -0
- data/lib/har/viewer/scripts/tabs/homeTab.html +34 -0
- data/lib/har/viewer/scripts/tabs/homeTab.js +5 -0
- data/lib/har/viewer/scripts/tabs/pageStats.js +14 -0
- data/lib/har/viewer/scripts/tabs/pageTimeline.js +10 -0
- data/lib/har/viewer/scripts/tabs/previewTab.js +6 -0
- data/lib/har/viewer/scripts/tabs/schemaTab.js +2 -0
- data/lib/har/viewer/scripts/xhr-spy/spy.js +2 -0
- data/lib/har/viewer/scripts/xhr-spy/spy.php +13 -0
- data/lib/har/viewer/scripts/xhr-spy/xhr.js +6 -0
- data/lib/har/viewer/scripts/xhr-spy/xhrSpyBookmarklet.js +1 -0
- data/schema.json +201 -0
- data/spec/fixtures/entry1.json +124 -0
- data/spec/fixtures/hars/bad.har +2563 -0
- data/spec/fixtures/hars/browser-blocking-time.har +2567 -0
- data/spec/fixtures/hars/google.com.har +612 -0
- data/spec/fixtures/hars/inline-scripts-block.har +1066 -0
- data/spec/fixtures/hars/softwareishard.com.har +5323 -0
- data/spec/har/archive_spec.rb +130 -0
- data/spec/har/entry_spec.rb +16 -0
- data/spec/har/page_spec.rb +24 -0
- data/spec/har/viewer_spec.rb +17 -0
- data/spec/spec_helper.rb +34 -0
- metadata +283 -0
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Copyright (c) 2010 Jari Bakken
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
harviewer by Jan Odvarko is covered by the New BSD License
|
|
23
|
+
http://www.opensource.org/licenses/bsd-license.php
|
|
24
|
+
http://code.google.com/p/harviewer/
|
data/README.mdown
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
HAR
|
|
2
|
+
===
|
|
3
|
+
|
|
4
|
+
Ruby library to work with and view HTTP archives.
|
|
5
|
+
This includes [harviewer](http://code.google.com/p/harviewer/), which can be launched through the "har" command.
|
|
6
|
+
|
|
7
|
+
Usage
|
|
8
|
+
=============
|
|
9
|
+
|
|
10
|
+
HAR::Archive.from_string(json) #=> #<Har::Archive:0x5e7cac>
|
|
11
|
+
HAR::Archive.from_file(path) #=> #<Har::Archive:0x5e7cac>
|
|
12
|
+
|
|
13
|
+
Or from command the command line:
|
|
14
|
+
|
|
15
|
+
har /path/to/some.har
|
|
16
|
+
|
|
17
|
+
Links
|
|
18
|
+
=====
|
|
19
|
+
|
|
20
|
+
* [harviewer](http://code.google.com/p/harviewer/)
|
|
21
|
+
|
|
22
|
+
Note on Patches/Pull Requests
|
|
23
|
+
=============================
|
|
24
|
+
|
|
25
|
+
* Fork the project.
|
|
26
|
+
* Make your feature addition or bug fix.
|
|
27
|
+
* Add tests for it. This is important so I don't break it in a
|
|
28
|
+
future version unintentionally.
|
|
29
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
30
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
31
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
32
|
+
|
|
33
|
+
Copyright
|
|
34
|
+
=========
|
|
35
|
+
|
|
36
|
+
Copyright (c) 2010 Jari Bakken. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
Bundler::GemHelper.install_tasks
|
|
3
|
+
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
RSpec::Core::RakeTask.new
|
|
6
|
+
|
|
7
|
+
desc 'Regenerate the schema files'
|
|
8
|
+
task :schema do
|
|
9
|
+
require "json"
|
|
10
|
+
|
|
11
|
+
out = File.expand_path("../lib/har/schemas", __FILE__)
|
|
12
|
+
schema = JSON.parse(File.read("schema.json"))
|
|
13
|
+
|
|
14
|
+
# cleanup
|
|
15
|
+
Dir[File.join(out, "*.json")].each { |f|
|
|
16
|
+
rm f
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# generate
|
|
20
|
+
schema.each do |type, schema|
|
|
21
|
+
path = File.join(out, type)
|
|
22
|
+
puts path
|
|
23
|
+
|
|
24
|
+
File.open(path, "w") { |file|
|
|
25
|
+
file << JSON.pretty_generate(schema)
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
data/bin/har
ADDED
data/har.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "har/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "har"
|
|
7
|
+
s.version = HAR::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ["Jari Bakken"]
|
|
10
|
+
s.email = ["jari.bakken@gmail.com"]
|
|
11
|
+
s.homepage = ""
|
|
12
|
+
s.summary = %q{Ruby library to work with HTTP archives}
|
|
13
|
+
s.description = %q{Ruby library to work with HTTP archives}
|
|
14
|
+
|
|
15
|
+
s.rubyforge_project = "har"
|
|
16
|
+
|
|
17
|
+
s.add_dependency "json"
|
|
18
|
+
s.add_dependency "json-schema"
|
|
19
|
+
s.add_dependency "launchy"
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency "rspec", "~> 2.0"
|
|
22
|
+
|
|
23
|
+
s.files = `git ls-files`.split("\n")
|
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
26
|
+
s.require_paths = ["lib"]
|
|
27
|
+
end
|
data/lib/har.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'json-schema'
|
|
3
|
+
require 'time'
|
|
4
|
+
|
|
5
|
+
module HAR
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
class ValidationError < StandardError; end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
require 'har/serializable'
|
|
11
|
+
require 'har/schema_type'
|
|
12
|
+
require 'har/page'
|
|
13
|
+
require 'har/archive'
|
|
14
|
+
require 'har/viewer'
|
|
15
|
+
|
|
16
|
+
module Enumerable
|
|
17
|
+
def group_by
|
|
18
|
+
assoc = {}
|
|
19
|
+
|
|
20
|
+
each do |element|
|
|
21
|
+
key = yield(element)
|
|
22
|
+
|
|
23
|
+
if assoc.has_key?(key)
|
|
24
|
+
assoc[key] << element
|
|
25
|
+
else
|
|
26
|
+
assoc[key] = [element]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
assoc
|
|
31
|
+
end unless [].respond_to?(:group_by)
|
|
32
|
+
end
|
data/lib/har/archive.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
module HAR
|
|
2
|
+
class Archive
|
|
3
|
+
include Serializable
|
|
4
|
+
|
|
5
|
+
def self.from_string(str, uri = nil)
|
|
6
|
+
new JSON.parse(str), uri
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.from_file(path)
|
|
10
|
+
from_string File.read(path), path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :uri
|
|
14
|
+
|
|
15
|
+
def initialize(input, uri = nil)
|
|
16
|
+
@data = input
|
|
17
|
+
@uri = uri
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def pages
|
|
21
|
+
@pages ||= raw_log.fetch('pages').map { |page|
|
|
22
|
+
Page.new page, entries_for(page['id'])
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def entries
|
|
27
|
+
@entries ||= raw_entries.map { |e| Entry.new(e) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# create a new archive by merging this and another archive
|
|
31
|
+
|
|
32
|
+
def merge(other)
|
|
33
|
+
assert_archive other
|
|
34
|
+
|
|
35
|
+
data = deep_clone(@data)
|
|
36
|
+
merge_data data, other.as_json, other.uri
|
|
37
|
+
|
|
38
|
+
self.class.new data
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# destructively merge this with the given archive
|
|
42
|
+
|
|
43
|
+
def merge!(other)
|
|
44
|
+
assert_archive other
|
|
45
|
+
clear_caches
|
|
46
|
+
|
|
47
|
+
merge_data @data, other.as_json, other.uri
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def save_to(path)
|
|
52
|
+
File.open(path, "w") { |io| io << @data.to_json }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def valid?
|
|
56
|
+
JSON::Validator.validate schema_file, @data
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def validate!
|
|
60
|
+
JSON::Validator.validate2 schema_file, @data
|
|
61
|
+
rescue JSON::ValidationError => ex
|
|
62
|
+
# add archive uri to the message
|
|
63
|
+
if @uri
|
|
64
|
+
raise ValidationError, "#{@uri}: #{ex.message}"
|
|
65
|
+
else
|
|
66
|
+
raise ValidationError, ex.message
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
protected
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def schema_file
|
|
75
|
+
@schema_file ||= File.expand_path("../schemas/logType", __FILE__)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def merge_data(left, right, uri)
|
|
79
|
+
log = left.fetch('log')
|
|
80
|
+
other_log = right.fetch('log')
|
|
81
|
+
|
|
82
|
+
pages = log.fetch('pages')
|
|
83
|
+
entries = log.fetch('entries')
|
|
84
|
+
|
|
85
|
+
other_pages = other_log.fetch("pages")
|
|
86
|
+
other_entries = other_log.fetch("entries")
|
|
87
|
+
|
|
88
|
+
if uri
|
|
89
|
+
deep_clone(other_pages).each do |page|
|
|
90
|
+
c = page['comment'] ||= ''
|
|
91
|
+
c << "(merged from #{File.basename uri})"
|
|
92
|
+
|
|
93
|
+
pages << page
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
pages.concat other_pages
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
entries.concat other_entries
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def assert_archive(other)
|
|
103
|
+
unless other.kind_of?(self.class)
|
|
104
|
+
raise TypeError, "expected #{self.class}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def clear_caches
|
|
109
|
+
@raw_entries = @entries_map = @pages = @entries = @log = nil
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def entries_for(page_id)
|
|
113
|
+
entries = entries_map[page_id] || []
|
|
114
|
+
entries.map { |e| Entry.new(e) }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def raw_entries
|
|
118
|
+
@raw_entries ||= raw_log.fetch('entries')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def raw_log
|
|
122
|
+
@raw_log ||= @data.fetch 'log'
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def entries_map
|
|
126
|
+
@entries_map ||= raw_entries.group_by { |e| e['pageref'] }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def deep_clone(obj)
|
|
130
|
+
Marshal.load Marshal.dump(obj)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
end # Archive
|
|
134
|
+
end # HAR
|
|
135
|
+
|
data/lib/har/page.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module HAR
|
|
2
|
+
class Page < SchemaType
|
|
3
|
+
|
|
4
|
+
attr_reader :entries
|
|
5
|
+
|
|
6
|
+
def initialize(input, entries)
|
|
7
|
+
super(input)
|
|
8
|
+
@entries = entries
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def title
|
|
12
|
+
@data.fetch 'title'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# a little sugar
|
|
16
|
+
alias_method :timings, :page_timings
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require "pp"
|
|
2
|
+
|
|
3
|
+
module HAR
|
|
4
|
+
class SchemaType
|
|
5
|
+
include Serializable
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def load_from(file)
|
|
11
|
+
schema = JSON.parse(File.read(file))
|
|
12
|
+
|
|
13
|
+
klass = Class.new(self) do
|
|
14
|
+
schema['properties'].each do |name, definition|
|
|
15
|
+
define_property name, definition
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
HAR.const_set type_name_from(schema['id']), klass
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def define_property(name, definition)
|
|
23
|
+
required = definition['required']
|
|
24
|
+
type = definition['type']
|
|
25
|
+
|
|
26
|
+
wrapper = extract_wrapper(name, definition)
|
|
27
|
+
|
|
28
|
+
fetch_code = required ? "@data.fetch(#{name.inspect})" : "@data[#{name.inspect}]"
|
|
29
|
+
fetch_code = "#{wrapper} #{fetch_code}" if wrapper
|
|
30
|
+
|
|
31
|
+
class_eval "
|
|
32
|
+
def #{snake_case name}
|
|
33
|
+
@#{name} ||= #{fetch_code}
|
|
34
|
+
end
|
|
35
|
+
"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def extract_wrapper(name, definition)
|
|
39
|
+
type = definition['type']
|
|
40
|
+
|
|
41
|
+
case type
|
|
42
|
+
when 'object'
|
|
43
|
+
return "#{name.capitalize}.new"
|
|
44
|
+
when 'string'
|
|
45
|
+
if definition['format'] == 'date-time'
|
|
46
|
+
return 'Time.parse'
|
|
47
|
+
end
|
|
48
|
+
when Hash
|
|
49
|
+
ref = type['$ref']
|
|
50
|
+
when nil
|
|
51
|
+
ref = definition['$ref']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
"#{type_name_from(ref)}.new" if ref
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def type_name_from(str)
|
|
58
|
+
t = str[/^(.+)Type/, 1] or raise Error, "could not extract type name from #{str.inspect}"
|
|
59
|
+
t[0] = t[0].chr.upcase
|
|
60
|
+
|
|
61
|
+
t
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def snake_case(str)
|
|
65
|
+
str.gsub(/\B[A-Z][^A-Z]/, '_\&').downcase.gsub(' ', '_')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def initialize(data)
|
|
70
|
+
@data = data
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# load in schemas
|
|
74
|
+
Dir[File.expand_path("../schemas/*", __FILE__)].each do |file|
|
|
75
|
+
load_from file
|
|
76
|
+
end
|
|
77
|
+
end # SchemaType
|
|
78
|
+
end # HAR
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "browserType",
|
|
3
|
+
"description": "Name and version info of used browser.",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"optional": true,
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"required": true
|
|
10
|
+
},
|
|
11
|
+
"version": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true
|
|
14
|
+
},
|
|
15
|
+
"comment": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cacheEntryType",
|
|
3
|
+
"optional": true,
|
|
4
|
+
"description": "Info about cache entry.",
|
|
5
|
+
"properties": {
|
|
6
|
+
"expires": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"lastAccess": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"required": true
|
|
12
|
+
},
|
|
13
|
+
"eTag": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
"hitCount": {
|
|
18
|
+
"type": "integer",
|
|
19
|
+
"required": true
|
|
20
|
+
},
|
|
21
|
+
"comment": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|