entree 0.0.1

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.
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