entree 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5ea2fc0302c380e238bf85c53b6431547992282d
4
+ data.tar.gz: 41b7226457ea08c5ebe0535cfaa4346a7fadedbc
5
+ SHA512:
6
+ metadata.gz: 14dc75f4f7648e7145e0a7050d44d208703780386c683565781d1acfcbc90ac14ecfa956a3793b23f8e19d475b9438277949162f60346563e2b0b971e8a1d9ee
7
+ data.tar.gz: a676c99e4fad9e4a56e4a6b475173b98040f8ecbf7a6e7d6cfbc4baf0abcc4108348335da00d855648ec279e2fbb14159234821b58b25b6ea27e9101b5dfbceb
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # entree Changelog
2
+
3
+ ## v0.0.1
4
+
5
+ * Rename from accesslint.rb to entree.rb
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in entree.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "minitest"
8
+ gem "pry"
9
+ gem "thor"
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Cameron Cundiff
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # entree.rb
2
+
3
+ Entree is a ruby gem allowing accessibility audits to be run on URLs or files,
4
+ from the command line or within your Ruby applications.
5
+
6
+ This library was copied from Cameron Cundiff's (@ckundo) excellent
7
+ [access_lint.rb](https://github.com/accesslint/accesslint.rb) project. It has
8
+ been renamed to reflect what it's attempting to provide: entrance to the web for
9
+ everyone.
10
+
11
+ ## About
12
+
13
+ Entree uses the
14
+ [HTML_CodeSniffer](https://github.com/squizlabs/HTML_CodeSniffer) client-side JS
15
+ application to make assertions on the DOM via PhantomJS. The rules that are applied are [listed below](#rules).
16
+
17
+ ## Installation
18
+
19
+ First, install PhantomJS ([full guide](http://phantomjs.org/)). On OS X:
20
+
21
+ $ brew install phantomjs
22
+
23
+ Then install the rubygem:
24
+
25
+ $ gem install entree
26
+
27
+ ## Usage
28
+
29
+ ### Command Line
30
+
31
+ From the command line, specify a url or filename to be audited:
32
+
33
+ $ entree audit http://archaccessibility.com # url or a path to a file
34
+ # results ...
35
+
36
+ ### Ruby
37
+
38
+ Run the audit from a Ruby application like so
39
+
40
+ $ irb
41
+ > require 'entree'
42
+ => true
43
+ > Entree::Audit.new('http://archaccessibility.com').run
44
+ => results ...
45
+
46
+ ### Results Object
47
+
48
+ {
49
+ "PASS": [ # Status group
50
+ {
51
+ "element_names": ["<p class=\"foo\">relevant element</p>"], # applicable DOM elements
52
+ "severity": "WARNING", # 'WARNING' or 'SEVERE'
53
+ "status": "PASS", # 'PASS', 'FAIL', or 'NA'
54
+ "title": "Some description" # rule description
55
+ },
56
+ { ... }
57
+ ],
58
+ "NA": [ { ... } ],
59
+ "FAIL": [ { ... }]
60
+ ]
61
+
62
+ ## Rules
63
+
64
+ For full descriptions of the audit rules, visit the [Accessibility Developer Tools project wiki](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules).
65
+
66
+ Code | Title
67
+ ---------------------------|----------------------------------------------------
68
+ [AX_ARIA_01][AX_ARIA_01] | Elements with ARIA roles must use a valid, non-abstract ARIA role.
69
+ [AX_ARIA_02][AX_ARIA_02] | ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM.
70
+ [AX_ARIA_03][AX_ARIA_03] | Elements with ARIA roles must have all required attributes for that role.
71
+ [AX_ARIA_04][AX_ARIA_04] | ARIA state and property values must be valid.
72
+ [AX_ARIA_05][AX_ARIA_05] | role=main should only appear on significant elements.
73
+ [AX_ARIA_06][AX_ARIA_06] | aria-owns should not be used if ownership is implicit in the DOM.
74
+ [AX_ARIA_07][AX_ARIA_07] | An element's ID must not be present in more that one aria-owns attribute at any time.
75
+ [AX_ARIA_08][AX_ARIA_08] | Elements with ARIA roles must ensure required owned elements are present.
76
+ [AX_ARIA_09][AX_ARIA_09] | Elements with ARIA roles must be in the correct scope.
77
+ [AX_ARIA_10][AX_ARIA_10] | This element has an unsupported ARIA attribute.
78
+ [AX_ARIA_11][AX_ARIA_11] | This element has an invalid ARIA attribute.
79
+ [AX_ARIA_12][AX_ARIA_12] | This element does not support ARIA roles, states and properties.
80
+ [AX_AUDIO_01][AX_AUDIO_01] | Audio elements should have controls.
81
+ [AX_COLOR_01][AX_COLOR_01] | Text elements should have a reasonable contrast ratio.
82
+ [AX_FOCUS_01][AX_FOCUS_01] | These elements are focusable but either invisible or obscured by another element.
83
+ [AX_FOCUS_02][AX_FOCUS_02] | Elements with onclick handlers must be focusable.
84
+ [AX_FOCUS_03][AX_FOCUS_03] | Avoid positive integer values for tabIndex.
85
+ [AX_HTML_01][AX_HTML_01] | The web page should have the content's human language indicated in the markup.
86
+ [AX_HTML_02][AX_HTML_02] | An element's ID must be unique in the DOM.
87
+ [AX_IMAGE_01][AX_IMAGE_01] | Meaningful images should not be used in element backgrounds.
88
+ [AX_TEXT_01][AX_TEXT_01] | Controls and media elements should have labels.
89
+ [AX_TEXT_02][AX_TEXT_02] | Images should have an alt attribute.
90
+ [AX_TEXT_04][AX_TEXT_04] | The purpose of each link should be clear from the link text.
91
+ [AX_TITLE_01][AX_TITLE_01] | The web page should have a title that describes topic or purpose.
92
+ [AX_VIDEO_01][AX_VIDEO_01] | Video elements should use <track> elements to provide captions.
93
+
94
+ [AX_ARIA_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_01
95
+ [AX_ARIA_02]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02
96
+ [AX_ARIA_03]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_03
97
+ [AX_ARIA_04]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_04
98
+ [AX_ARIA_05]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_05
99
+ [AX_ARIA_06]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_06
100
+ [AX_ARIA_07]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_07
101
+ [AX_ARIA_08]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_08
102
+ [AX_ARIA_09]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_09
103
+ [AX_ARIA_10]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_10
104
+ [AX_ARIA_11]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_11
105
+ [AX_ARIA_12]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_12
106
+ [AX_AUDIO_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_audio_01
107
+ [AX_COLOR_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_color_01
108
+ [AX_FOCUS_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_01
109
+ [AX_FOCUS_02]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02
110
+ [AX_FOCUS_03]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_03
111
+ [AX_HTML_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_01
112
+ [AX_HTML_02]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_02
113
+ [AX_IMAGE_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_image_01
114
+ [AX_TEXT_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_01
115
+ [AX_TEXT_02]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_02
116
+ [AX_TEXT_04]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_04
117
+ [AX_TITLE_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_title_01
118
+ [AX_VIDEO_01]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_video_01
119
+
120
+ ## Roadmap
121
+
122
+ ## Contributing
123
+
124
+ 1. Fork it
125
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
126
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
127
+ 4. Push to the branch (`git push origin my-new-feature`)
128
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ # require "bundler/gem_tasks"
2
+ # require 'rspec/core/rake_task'
3
+
4
+ # # RSpec::Core::RakeTask.new do |t|
5
+ # # t.pattern = "spec/**/*_spec.rb"
6
+ # # end
7
+
8
+ # desc "Default: run all specs"
9
+ # task :default => [:spec]
10
+
11
+ # task :build => ["axs:make"]
12
+
13
+ # desc "Google Accessibility Developer Tools"
14
+ # namespace :axs do
15
+ # desc "Generate Accessibility Developer Tools axs_testing.js"
16
+ # task :make do
17
+ # system "cd vendor/accessibility-developer-tools/ && make"
18
+ # end
19
+ # end
20
+ require 'rake/testtask'
21
+
22
+ lib_dir = File.expand_path('lib')
23
+ test_dir = File.expand_path('test')
24
+
25
+ Rake::TestTask.new(:test) do |t|
26
+ t.libs = [lib_dir, test_dir]
27
+ t.pattern = 'test/**/*rb'
28
+ end
29
+
30
+ desc "Run tests"
31
+ task :default => :test
data/bin/entree ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path("../lib/", __FILE__)
3
+
4
+ Signal.trap("INT") { exit 1 } #
5
+
6
+ require 'entree'
7
+ require 'entree/cli'
8
+
9
+ Entree::CLI.start(ARGV)
data/entree.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'entree/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "entree"
8
+ spec.version = Entree::VERSION
9
+ spec.authors = ["Samuel Mullen"]
10
+ spec.email = ["samullen@gmail.com"]
11
+ spec.description = %q{Run an accessibility audit on a file or URL from the command line.}
12
+ spec.summary = %q{Entree runs HTML_CodeSniffer assertions on a page via PhantomJS}
13
+ spec.homepage = "https://github.com/samullen/entree"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.test_files = spec.files.grep(%r{^spec/})
18
+ spec.require_paths = ["lib"]
19
+ spec.executables = ['entree']
20
+
21
+ spec.add_dependency "thor", "~> 0.19"
22
+ spec.add_dependency "awesome_print", "~> 1.6"
23
+ spec.add_dependency "command_line_reporter", "~> 3.3"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake", "~> 11"
27
+ spec.add_development_dependency "oj", "~> 2.17"
28
+ end
@@ -0,0 +1,45 @@
1
+ require 'entree'
2
+ require 'oj'
3
+
4
+ module Entree
5
+ class Audit
6
+ attr_reader :target
7
+
8
+ def initialize(target)
9
+ @target = target
10
+ end
11
+
12
+ def run
13
+ perform_audit
14
+ end
15
+
16
+ def runner
17
+ @runner ||= Runner.new(self.target)
18
+ end
19
+
20
+ private
21
+
22
+ def perform_audit
23
+ runner.run
24
+ @output = runner.output
25
+ parse_output
26
+ end
27
+
28
+ def parse_output
29
+ # refactor into new class
30
+ raw_results = Oj.load(@output).map {|record|
31
+ if record["code"][0..3] == "WCAG"
32
+ record["code"].match /(WCAG2A+\.\w+?\.Guideline(\d_\d)\.\2_\d)\.((?:[A-Z]+\d+,?)+)/
33
+ record["code"] = $1
34
+ record["techniques"] = $3.split /,/
35
+ end
36
+
37
+ record
38
+ }
39
+
40
+ @results = raw_results.group_by { |result| result['type'] }
41
+ rescue Exception => e
42
+ raise Entree::ParserError.new(e.message)
43
+ end
44
+ end
45
+ end
data/lib/entree/cli.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'thor'
2
+ require 'command_line_reporter'
3
+ require 'awesome_print'
4
+
5
+ module Entree
6
+ class CLI < Thor
7
+ include CommandLineReporter
8
+
9
+ desc 'audit', 'audit TARGET'
10
+ def audit(target)
11
+ report(message: "auditing #{target}", color: "blue") do
12
+ ap Audit.new(target).run, index: false
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module Entree
2
+ class Runner
3
+ RUNNER_PATH = File.expand_path("../../../vendor/HTML_CodeSniffer/Contrib/PhantomJS/HTMLCS_Run.js", __FILE__)
4
+ attr_reader :output
5
+
6
+ def initialize(target)
7
+ @target = target
8
+ end
9
+
10
+ def run
11
+ @output = `phantomjs #{RUNNER_PATH} #{@target} WCAG2AA json`
12
+ return if audit_success?
13
+
14
+ if !phantomjs_installed?
15
+ fail Entree::RunnerError.new("Please install PhantomJS. Visit http://phantomjs.org/ for instructions.")
16
+ else
17
+ fail Entree::RunnerError.new("PhantomJS exited without success: #{@output}")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def audit_success?
24
+ $?.success?
25
+ end
26
+
27
+ def phantomjs_installed?
28
+ $?.exitstatus != 127
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Entree
2
+ VERSION = "0.0.1"
3
+ end
data/lib/entree.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "entree/version"
2
+
3
+ module Entree
4
+ autoload :Audit, 'entree/runner'
5
+ autoload :Runner, 'entree/audit'
6
+
7
+ class Error < StandardError; end
8
+ class AuditError < Error; end
9
+ class ParserError < Error; end
10
+ class RunnerError < Error; end
11
+ end
@@ -0,0 +1,30 @@
1
+ require "minitest/autorun"
2
+ require "entree"
3
+
4
+ describe Entree::Audit do
5
+ describe "Initialization" do
6
+ it "requires a target to audit" do
7
+ Entree::Audit.new("http://example.com").must_be_instance_of Entree::Audit
8
+ end
9
+ end
10
+
11
+ describe '#run' do
12
+ it 'return a parsed set of results' do
13
+ skip
14
+ # target = double
15
+ # output = JSON.generate([{status: 'passing', foo: 'bar'}])
16
+
17
+ # audit = Entree::Audit.new(target)
18
+ # audit.stub(:runner) { double(:runner, output: output, run: double) }
19
+
20
+ # expect(audit.run).to eq "passing"=>[{"status"=>"passing", "foo"=>"bar"}]
21
+ end
22
+ end
23
+
24
+ describe "#runner" do
25
+ it "returns an Entree::Runner object" do
26
+ audit = Entree::Audit.new("http://example.com")
27
+ audit.runner.must_be_instance_of Entree::Runner
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ # Commenting out until I can fix command_line_reporter conflicts with minitest
2
+
3
+ # require "minitest/autorun"
4
+ # require "entree/cli"
5
+
6
+ # describe Entree::CLI do
7
+ # it "creates an audit" do
8
+ # skip
9
+ # # expect { CLI.start([]) }.to_not raise_error
10
+ # end
11
+ # end
@@ -0,0 +1,13 @@
1
+ require "minitest/autorun"
2
+ require "entree"
3
+
4
+ describe Entree::Runner do
5
+ it 'runs phantomjs' do
6
+ skip
7
+ target = double
8
+ runner = Runner.new(target)
9
+
10
+ expect(runner).to receive(:`).with(/^phantomjs.*/)
11
+ runner.run
12
+ end
13
+ end
@@ -0,0 +1,180 @@
1
+ var page = require('webpage').create(),
2
+ system = require('system'),
3
+ address, standard, reportType, cwd;
4
+ var messages = {
5
+ 'ERROR': [],
6
+ 'WARNING': [],
7
+ 'NOTICE': []
8
+ };
9
+
10
+ if (system.args.length < 3 || system.args.length > 4) {
11
+ console.log('Usage: phantomjs HTMLCS_Run.js URL standard [report]');
12
+ console.log(' available standards: "WCAG2A", "WCAG2AA", "WCAG2AAA", "Section508"');
13
+ console.log(' available reports: "default" (default if omitted), "table", "json"');
14
+ phantom.exit();
15
+ } else {
16
+ address = system.args[1];
17
+ standard = system.args[2];
18
+ reportType = 'default';
19
+ if (system.args.length > 3) {
20
+ reportType = system.args[3];
21
+ }
22
+
23
+ // Get the absolute working directory from the PWD var and
24
+ // and the command line $0 argument.
25
+ cwd = system.env['PWD'];
26
+ if (system.args[0].substr(0, 1) === '/') {
27
+ cwd = system.args[0];
28
+ } else {
29
+ cwd += '/' + system.args[0];
30
+ }
31
+
32
+ cwd = cwd.substr(0, cwd.lastIndexOf('/'));
33
+
34
+ // Default reporter.
35
+ var reportDefaultFn = function(cb) {
36
+ var levels = ['ERROR', 'WARNING', 'NOTICE'];
37
+ for (var lvl = 0; lvl < levels.length; lvl++) {
38
+ for (var i = 0; i < messages[levels[lvl]].length; i++) {
39
+ var thisMsg = messages[levels[lvl]][i];
40
+ var line = thisMsg.join('|');
41
+ console.log(line);
42
+ }
43
+ }
44
+
45
+ cb();
46
+ }
47
+
48
+ // Table reporter.
49
+ var reportTableFn = function(cb) {
50
+ console.log('LEVEL | MESSAGE CODE | NODE NAME | ELEMENT ID');
51
+ console.log('--------+------------------------------------------+------------+---------------------');
52
+ var levels = ['ERROR', 'WARNING', 'NOTICE'];
53
+ for (var lvl = 0; lvl < levels.length; lvl++) {
54
+ for (var i = 0; i < messages[levels[lvl]].length; i++) {
55
+ var thisMsg = messages[levels[lvl]][i];
56
+ var line = '';
57
+ var stdMsg = thisMsg[1].split('.');
58
+ stdMsg.splice(0, 3);
59
+ stdMsg = stdMsg.join('.');
60
+ if (stdMsg.length > 40) {
61
+ stdMsg = '...' + stdMsg.substr(stdMsg.length - 37);
62
+ }
63
+
64
+ line += (thisMsg[0] + Array(8).join(' ')).substr(0, 7) + ' | ';
65
+ line += (stdMsg + Array(41).join(' ')).substr(0, 40) + ' | ';
66
+ line += (thisMsg[2] + Array(11).join(' ')).substr(0, 10) + ' | ';
67
+ line += (thisMsg[3] + Array(21).join(' ')).substr(0, 20);
68
+ console.log(line);
69
+
70
+ var remText = thisMsg[4];
71
+ while (remText.length > 0) {
72
+ line = '';
73
+ line += (Array(8).join(' ')).substr(0, 7) + ' | ';
74
+
75
+ if (remText.length < 75) {
76
+ line += remText;
77
+ console.log(line);
78
+ break;
79
+ } else {
80
+ var lastSpace = remText.substr(0, 75).lastIndexOf(' ');
81
+ line += remText.substr(0, lastSpace);
82
+ console.log(line);
83
+ remText = remText.substr(lastSpace + 1);
84
+ }
85
+ }
86
+
87
+ console.log('--------+------------------------------------------+------------+---------------------');
88
+
89
+ }
90
+ }
91
+
92
+ console.log('');
93
+ console.log('Errors: ' + messages['ERROR'].length + ', Warnings: ' + messages['WARNING'].length +
94
+ ', Notices: ' + messages['NOTICE'].length);
95
+ cb();
96
+ }
97
+
98
+ var reportJSONFn = function(cb) {
99
+ var reportJSONData = [];
100
+ var levels = ['ERROR', 'WARNING', 'NOTICE'];
101
+ for (var lvl = 0; lvl < levels.length; lvl++) {
102
+ for (var i = 0; i < messages[levels[lvl]].length; i++) {
103
+ var thisMsg = messages[levels[lvl]][i];
104
+ reportJSONData.push({
105
+ type: thisMsg[0],
106
+ code: thisMsg[1],
107
+ nodeName: thisMsg[2],
108
+ id: thisMsg[3],
109
+ msg: thisMsg[4],
110
+ outerHTML: thisMsg[5]
111
+ });
112
+ }
113
+ }
114
+
115
+ console.log('[');
116
+ reportJSONData.forEach(function(report, i) {
117
+ console.log(JSON.stringify(report, null, ' '));
118
+ if (i < reportJSONData.length-1) {
119
+ console.log(',');
120
+ }
121
+ });
122
+ console.log(']');
123
+ cb();
124
+ };
125
+
126
+ page.open(address, function (status) {
127
+ if (status !== 'success') {
128
+ console.log('Unable to load the address!');
129
+ phantom.exit();
130
+ } else {
131
+ window.setTimeout(function () {
132
+
133
+ // Override onConsoleMessage function for outputting.
134
+ page.onConsoleMessage = function (msg) {
135
+ var thisMsg;
136
+ if (msg.indexOf('[HTMLCS] ') === 0) {
137
+ thisMsg = msg.substr(9, msg.length).split('|');
138
+ messages[thisMsg[0]].push(thisMsg);
139
+ } else if (msg === 'done') {
140
+ var cb = function() {
141
+ phantom.exit();
142
+ }
143
+ switch (reportType.toLowerCase()) {
144
+ case 'table':
145
+ reportTableFn(cb);
146
+ break;
147
+
148
+ case 'json':
149
+ reportJSONFn(cb);
150
+ break;
151
+
152
+ default:
153
+ reportDefaultFn(cb);
154
+ break;
155
+ }
156
+ } else {
157
+ console.log(msg);
158
+ }
159
+ };
160
+
161
+ page.injectJs(cwd + '/../../build/HTMLCS.js');
162
+
163
+ // Now Run. Note that page.evaluate() function is sanboxed to
164
+ // the loaded page's context. We can't pass any variable to it.
165
+ switch (standard) {
166
+ case 'WCAG2A':
167
+ case 'WCAG2AA':
168
+ case 'WCAG2AAA':
169
+ case 'Section508':
170
+ page.evaluate(function(standard) {HTMLCS_RUNNER.run(standard);}, standard);
171
+ break;
172
+ default:
173
+ console.log('Unknown standard.');
174
+ phantom.exit();
175
+ break;
176
+ }
177
+ }, 200);
178
+ }//end if
179
+ });//end
180
+ }//end if