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 +7 -0
- data/.gitignore +17 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +128 -0
- data/Rakefile +31 -0
- data/bin/entree +9 -0
- data/entree.gemspec +28 -0
- data/lib/entree/audit.rb +45 -0
- data/lib/entree/cli.rb +16 -0
- data/lib/entree/runner.rb +31 -0
- data/lib/entree/version.rb +3 -0
- data/lib/entree.rb +11 -0
- data/test/entree/audit_test.rb +30 -0
- data/test/entree/cli_test.rb +11 -0
- data/test/entree/runner_test.rb +13 -0
- data/vendor/HTML_CodeSniffer/Contrib/PhantomJS/HTMLCS_Run.js +180 -0
- data/vendor/HTML_CodeSniffer/build/HTMLCS.js +33 -0
- data/vendor/access-lint/README.md +34 -0
- data/vendor/access-lint/bin/auditor.js +62 -0
- data/vendor/google-chrome/accessibility-developer-tools/README.md +173 -0
- data/vendor/google-chrome/accessibility-developer-tools/gen/axs_testing.js +2052 -0
- metadata +151 -0
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
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
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
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
|
data/lib/entree/audit.rb
ADDED
@@ -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
|
data/lib/entree.rb
ADDED
@@ -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,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
|