testable 0.3.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +37 -25
  3. data/.hound.yml +31 -12
  4. data/.rubocop.yml +4 -0
  5. data/.travis.yml +7 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/Gemfile +3 -1
  8. data/{LICENSE.txt → LICENSE.md} +2 -2
  9. data/README.md +36 -17
  10. data/Rakefile +52 -11
  11. data/bin/console +2 -2
  12. data/bin/setup +0 -0
  13. data/examples/testable-capybara-context.rb +64 -0
  14. data/examples/testable-capybara-rspec.rb +70 -0
  15. data/examples/testable-capybara.rb +46 -0
  16. data/examples/testable-info.rb +65 -0
  17. data/examples/testable-watir-context.rb +67 -0
  18. data/examples/testable-watir-datasetter.rb +52 -0
  19. data/examples/testable-watir-events.rb +44 -0
  20. data/examples/testable-watir-ready.rb +34 -0
  21. data/examples/testable-watir-test.rb +80 -0
  22. data/examples/testable-watir.rb +118 -0
  23. data/lib/testable.rb +142 -10
  24. data/lib/testable/attribute.rb +38 -0
  25. data/lib/testable/capybara/dsl.rb +82 -0
  26. data/lib/testable/capybara/node.rb +30 -0
  27. data/lib/testable/capybara/page.rb +29 -0
  28. data/lib/testable/context.rb +73 -0
  29. data/lib/testable/deprecator.rb +40 -0
  30. data/lib/testable/element.rb +162 -31
  31. data/lib/testable/errors.rb +6 -2
  32. data/lib/testable/extensions/core_ruby.rb +13 -0
  33. data/lib/testable/extensions/data_setter.rb +144 -0
  34. data/lib/testable/extensions/dom_observer.js +58 -4
  35. data/lib/testable/extensions/dom_observer.rb +73 -0
  36. data/lib/testable/locator.rb +63 -0
  37. data/lib/testable/logger.rb +16 -0
  38. data/lib/testable/page.rb +216 -0
  39. data/lib/testable/ready.rb +49 -7
  40. data/lib/testable/situation.rb +9 -28
  41. data/lib/testable/version.rb +7 -6
  42. data/testable.gemspec +19 -9
  43. metadata +90 -23
  44. data/circle.yml +0 -3
  45. data/lib/testable/data_setter.rb +0 -51
  46. data/lib/testable/dom_update.rb +0 -19
  47. data/lib/testable/factory.rb +0 -27
  48. data/lib/testable/interface.rb +0 -114
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9fe925fea55efebca8a07a490fb639669355cecf
4
- data.tar.gz: 750388f14ff7df442cba5c4abb60ea51125a70c6
2
+ SHA256:
3
+ metadata.gz: '083ac4911fb96ee2707e3946552a38db979b4c33d6b09442aa16a6a8cd4acdb1'
4
+ data.tar.gz: 0c9c0ccfab44a16c9536e312b3dd3c9e2bef3d14bd7a9e00e16bdad653421fc7
5
5
  SHA512:
6
- metadata.gz: 4ae956962245d4326c31028c59b96fb060d1e46765d8db56309eadfe8460bb308a79876bfcafaa57fdfde38ad9e2a9c676c83c10ce9f7eef8df231a3938d0c57
7
- data.tar.gz: 2b986d69188ff6df56efe57e3dbb5724d83ed21bc6aefc0acb19198ad2e3f8b8da21dbf1c9aa31b7cdbbce156757528bed75d1f116c635c9f66b0cc736c19598
6
+ metadata.gz: 11c1aafcde6440266d55a64ea3b8b042aa6ad79ca3e6b7295496876841b14b28dab980a74df42de0407313fecf96c558aeb8b8c2c5ba1e074447931bc6011621
7
+ data.tar.gz: cc5f40958a85ed215afce15a5377d7e4b34743bce463f8391c02976ab7330bd2e19b55681c3894a54870b7dd97447a42acc90275360063a6b09e17480e727e46
data/.gitignore CHANGED
@@ -1,41 +1,53 @@
1
- # Ruby-Specific
1
+ # Testable Generated
2
2
 
3
+ testable.log
4
+
5
+ # Ruby Generated
6
+
7
+ /Gemfile.lock
3
8
  /.bundle/
4
9
  /.yardoc
5
- /Gemfile.lock
6
10
  /_yardoc/
7
-
8
- # Ouput-Specific
9
-
10
11
  /coverage/
11
12
  /doc/
12
13
  /pkg/
13
14
  /spec/reports/
14
- /spec/examples.txt
15
+ /spec/coverage/
15
16
  /tmp/
16
- *.log
17
- *.tmp
18
- *.swp
19
- *.bak
20
17
 
21
- # IDE-Specific
18
+ # Generated Reports
19
+ reports/
22
20
 
23
- .idea
24
- .settings
25
- .project
26
- .classpath
27
- *.iws
21
+ # Rspec Failure Tracking
28
22
 
29
- # Windows-Specific
23
+ .rspec_status
30
24
 
31
- Thumbs.db
32
-
33
- # Mac OS-Specific
25
+ # IDE Files
34
26
 
35
- *.DS_Store
36
- ._*
27
+ .idea/
28
+ *.iml
29
+ *.iws
30
+ *.ipr
31
+ .vscode/
32
+ .settings/
33
+ .metadata
34
+ .classpath
35
+ .loadpath
36
+ .buildpath
37
+ .project
37
38
 
38
- # Linux-Specific
39
+ # OS Files
39
40
 
40
- .directory
41
- .Trash-*
41
+ .DS_Store
42
+ .DS_Store?
43
+ ._*
44
+ .Spotlight-V100
45
+ .Trashes
46
+ ehthumbs.db
47
+ Thumbs.db
48
+ $RECYCLE.BIN/
49
+ Desktop.ini
50
+ *.tmp
51
+ *.bak
52
+ *.swp
53
+ *~.nib
data/.hound.yml CHANGED
@@ -1,8 +1,8 @@
1
1
  AllCops:
2
2
  Exclude:
3
3
  - testable.gemspec
4
- - test/*.rb
5
4
  - spec/**/*
5
+ - examples/**/*
6
6
 
7
7
  # Removing need for frozen string literal comment.
8
8
  Style/FrozenStringLiteralComment:
@@ -30,15 +30,15 @@ Style/SignalException:
30
30
  Enabled: false
31
31
 
32
32
  # This never works for validations.
33
- Style/AlignHash:
33
+ Layout/AlignHash:
34
34
  EnforcedLastArgumentHashStyle: ignore_implicit
35
35
 
36
36
  # Align multi-line params with previous line.
37
- Style/AlignParameters:
37
+ Layout/AlignParameters:
38
38
  EnforcedStyle: with_fixed_indentation
39
39
 
40
40
  # Indent `when` clause one step from `case`.
41
- Style/CaseIndentation:
41
+ Layout/CaseIndentation:
42
42
  IndentOneStep: true
43
43
 
44
44
  # Don't force bad var names for reduce/inject loops.
@@ -46,23 +46,42 @@ Style/SingleLineBlockParams:
46
46
  Enabled: false
47
47
 
48
48
  # For method chains, keep the dot with the method name.
49
- Style/DotPosition:
49
+ Layout/DotPosition:
50
50
  EnforcedStyle: leading
51
51
 
52
- # Allow methods with has_ for predicates.
53
- Style/PredicateName:
54
- NameWhitelist:
55
- - has_correct_url?
56
- - has_correct_title?
57
-
58
52
  # Stop nesting so hard.
59
53
  Metrics/BlockNesting:
60
54
  Max: 2
61
55
 
62
56
  # Encourage short methods.
63
57
  Metrics/MethodLength:
64
- Max: 10
58
+ Max: 15
59
+
60
+ # Encourage short (as possible) modules.
61
+ Metrics/ModuleLength:
62
+ Max: 100
65
63
 
66
64
  # Encourage fewer parameters.
67
65
  Metrics/ParameterLists:
68
66
  Max: 4
67
+
68
+ # Remove execute permissions check.
69
+ Lint/ScriptPermission:
70
+ Enabled: false
71
+
72
+ # Testable Exceptions
73
+
74
+ # Allow methods with has_ for predicates.
75
+ Naming/PredicateName:
76
+ NameWhitelist:
77
+ - has_correct_title?
78
+ - has_correct_url?
79
+
80
+ # Sometimes this seems like a better way to do things.
81
+ Style/DoubleNegation:
82
+ Enabled: false
83
+
84
+ # This is entirely for the addition of the match? method to String
85
+ # and that's only needed if you are using an outdated Ruby.
86
+ Style/MultilineIfModifier:
87
+ Enabled: False
@@ -1,2 +1,6 @@
1
+ inherit_mode:
2
+ merge:
3
+ - Exclude
4
+
1
5
  inherit_from:
2
6
  - .hound.yml
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.3.4
7
+ before_install: gem install bundler -v 2.0.2
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
55
55
  ## Enforcement
56
56
 
57
57
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at jeffnyman@gmail.com. All
58
+ reported by contacting the project team at TODO: Write your email address. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
61
61
  obligated to maintain confidentiality with regard to the reporter of an incident.
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ gem "coveralls", require: false
2
4
 
3
5
  # Specify your gem's dependencies in testable.gemspec
4
6
  gemspec
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ **The MIT License (MIT)**
2
2
 
3
- Copyright (c) 2016 Jeff Nyman
3
+ Copyright © 2019 Jeff Nyman
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,14 +1,22 @@
1
1
  # Testable
2
2
 
3
- [![Build Status](https://circleci.com/gh/jeffnyman/testable.svg?style=shield)](https://circleci.com/gh/jeffnyman/testable)
3
+ > **Testable /ˈtestəb(ə)l/**
4
+ >
5
+ > _adjective_
6
+ >
7
+ > _able to be tested or tried._
8
+
9
+ ----
10
+
4
11
  [![Gem Version](https://badge.fury.io/rb/testable.svg)](http://badge.fury.io/rb/testable)
5
- [![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jeffnyman/testable/blob/master/LICENSE.txt)
12
+ [![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jeffnyman/testable/blob/master/LICENSE.md)
6
13
 
7
- [![Dependency Status](https://gemnasium.com/jeffnyman/testable.png)](https://gemnasium.com/jeffnyman/testable)
14
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/jeffnyman/testable/master/frames)
15
+ [![Inline docs](http://inch-ci.org/github/jeffnyman/testable.png)](http://inch-ci.org/github/jeffnyman/github)
8
16
 
9
- The Testable gem aims to be a micro-framework that will provide a semantic DSL to construct a fluent interface for test execution libraries.
17
+ Testable is an automated test micro-framework that provides a thin wrapper around [Watir](http://watir.com/) and [Capybara](http://teamcapybara.github.io/capybara/). Testable is based on many ideas from tools like [SitePrism](https://github.com/natritmeyer/site_prism) and [Watirsome](https://github.com/p0deje/watirsome), while also being a logical evolution of my own tool, [Tapestry](https://github.com/jeffnyman/tapestry).
10
18
 
11
- This fluent interface promotes the idea of compressibility of your test logic, allowing for more factoring, more reuse, and less repetition. You can use Testable directly as an automated test library or you can use it with other tools such as RSpec, Cucumber, or anything else that allows you to delegate down to a different level of abstraction.
19
+ One of the core goals of Testable is to be a mediating influence between higher-level tests (acceptance criteria) and lower-level implementations of those tests. You can see some of the design principles for more details on what guided construction.
12
20
 
13
21
  ## Installation
14
22
 
@@ -34,22 +42,31 @@ You can also install Testable just as you would any other gem:
34
42
 
35
43
  ## Usage
36
44
 
37
- Probably the best way to get a feel for the current state of the code is to look at the test scripts:
45
+ Probably the best way to get a feel for the current state of the code is to look at the examples:
46
+
47
+ * [Testable Info](https://github.com/jeffnyman/testable/blob/master/examples/testable-info.rb)
48
+ * [Testable Basics](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir.rb)
49
+ * [Testable Watir](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-test.rb)
50
+ * [Testable Context](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-context.rb)
51
+ * [Ready script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-ready.rb)
52
+ * [Events script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-events.rb)
53
+ * [Data setter script](https://github.com/jeffnyman/testable/blob/master/examples/testable-watir-datasetter.rb)
38
54
 
39
- * [Standard test script](https://github.com/jeffnyman/testable/blob/master/test/testable-standard.rb)
40
- * [Factory test script](https://github.com/jeffnyman/testable/blob/master/test/testable-factory.rb)
55
+ You'll see references to "Veilus" and a "localhost" in the script. I'm using my own [Veilus application](https://veilus.herokuapp.com/). As far as the localhost, you can use the [Veilus repo](https://github.com/jeffnyman/veilus) to get a local copy to play around with.
41
56
 
42
- If you clone the repository, you can see this script in action by running the command `rake script:standard` or `rake script:factory`.
57
+ ## Design Principles
43
58
 
44
- You'll see references to "Veilus" and a localhost URL. I'm using my own [Veilus application](https://veilus.herokuapp.com/). The localhost refers to using the [Veilus repo](https://github.com/jeffnyman/veilus) locally.
59
+ An automated test framework provides a machine-executable abstraction around testing and encodes a set of guiding principles and heuristics for writing tests-as-code.
45
60
 
46
- More details will be forthcoming as the project evolves.
61
+ One of the obstacles to covering the gap between principles of testing and the practice of testing is the mechanics of writing tests. These mechanics are focused on abstractions. A lot of the practice of testing comes down to that: finding the right abstractions.
47
62
 
48
- ## Implementation Ideas
63
+ An automated test framework should be capable of consuming your preferred abstractions because ultimately the automation is simply a tool that supports testing, which means how the framework encourages tests to be expressed should have high fidelity with how human tests would be expressed.
49
64
 
50
- I want to hide driver details (i.e., Selenium) as much as possible but still allow access to the full API. Ideally I'd like to avoid the low-level Selenium and use a wrapper around it while not inventing my own. Since both watir-webdriver and capybara delegate down to Selenium, it seems wise to use one of those. (Or maybe allow for both as Symbiont currently does.) An open question is whether I should proxy the driver library to my own implementation or not. Symbiont currently does exactly that, which is a very different model than [page-object](https://github.com/cheezy/page-object), which has to add an incredible amount of wasted code rather than just relying on delegation and a proxy pattern.
65
+ Testable is built around the the idea that automation should largely be small-footprint, low-fiction, and high-yield.
51
66
 
52
- I don't want to presume a particular modeling structure, such as the use of page objects. That being said, most such modeling structures are really just classes that are being utilized in a certain way, which means I really want to model the more generic notion of an interface. An interface could, theoretically, be an application (screens), a site (pages), or an API (services). An interface would be a Screen class, a Page class, or a Service class. These then become screen objects, page objects or service objects. An open question is how those distinctions are purely conceptual versus have specific implementations.
67
+ The code that a test-supporting micro-framework allows should be modular, promoting both high cohesion and low coupling, as well as promoting a single level of abstraction. These concepts together lead to lightweight design as well as support traits that make change affordable for tests.
68
+
69
+ That makes the automation code less expensive to maintain and easier to change. That, ultimately, has a positive impact on the cost of change but, more importantly, allows Testable to be fit within a cost of mistake model, where the goal is to get feedback as quickly as possible regarding when mistakes are made.
53
70
 
54
71
  ## Development
55
72
 
@@ -61,9 +78,11 @@ To install this gem onto your local machine, run `bundle exec rake install`.
61
78
 
62
79
  ## Contributing
63
80
 
64
- Bug reports and pull requests are welcome on GitHub at [https://github.com/jeffnyman/testable](https://github.com/jeffnyman/testable). The testing ecosystem of Ruby is very large and this project is intended to be a welcoming arena for collaboration on yet another testing tool. As such, contributors are very much welcome but are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
81
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/jeffnyman/testable](https://github.com/jeffnyman/testable). The testing ecosystem of Ruby is very large and this project is intended to be a welcoming arena for collaboration on yet another test-supporting tool.
82
+
83
+ Everyone interacting in the Testable project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jeffnyman/testable/blob/master/CODE_OF_CONDUCT.md).
65
84
 
66
- This gem follows [semantic versioning](http://semver.org).
85
+ The Testable gem follows [semantic versioning](http://semver.org).
67
86
 
68
87
  To contribute to Testable:
69
88
 
@@ -80,4 +99,4 @@ To contribute to Testable:
80
99
  ## License
81
100
 
82
101
  Testable is distributed under the [MIT](http://www.opensource.org/licenses/MIT) license.
83
- See the [LICENSE](https://github.com/jeffnyman/testable/blob/master/LICENSE.txt) file for details.
102
+ See the [LICENSE](https://github.com/jeffnyman/testable/blob/master/LICENSE.md) file for details.
data/Rakefile CHANGED
@@ -1,22 +1,62 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
3
4
  require "rdoc/task"
4
- require "rspec/core/rake_task"
5
5
  require "rubocop/rake_task"
6
+ require "rspec/core/rake_task"
6
7
 
7
8
  RuboCop::RakeTask.new
8
9
 
9
10
  RSpec::Core::RakeTask.new(:spec)
10
11
 
11
- namespace :script do
12
- desc "Run the Testable standard script"
13
- task :standard do
14
- system("ruby ./test/testable-standard.rb")
12
+ namespace :script_testable do
13
+ desc "Run the Testable info script"
14
+ task :info do
15
+ system("ruby ./examples/testable-info.rb")
16
+ end
17
+ end
18
+
19
+ namespace :script_capybara do
20
+ desc "Run the Testable Capybara script"
21
+ task :capybara do
22
+ system("ruby ./examples/testable-capybara.rb")
23
+ end
24
+
25
+ desc "Run the Testable Capybara context script"
26
+ task :context do
27
+ system("ruby ./examples/testable-capybara-context.rb")
28
+ end
29
+ end
30
+
31
+ namespace :script_watir do
32
+ desc "Run the Testable Watir script"
33
+ task :watir do
34
+ system("ruby ./examples/testable-watir.rb")
35
+ end
36
+
37
+ desc "Run the Testable Watir example test"
38
+ task :test do
39
+ system("ruby ./examples/testable-watir-test.rb")
40
+ end
41
+
42
+ desc "Run the Testable Watir context script"
43
+ task :context do
44
+ system("ruby ./examples/testable-watir-context.rb")
45
+ end
46
+
47
+ desc "Run the Testable Watir events script"
48
+ task :events do
49
+ system("ruby ./examples/testable-watir-events.rb")
50
+ end
51
+
52
+ desc "Run the Testable Watir ready script"
53
+ task :ready do
54
+ system("ruby ./examples/testable-watir-ready.rb")
15
55
  end
16
56
 
17
- desc "Run the Testable factory script"
18
- task :factory do
19
- system("ruby ./test/testable-factory.rb")
57
+ desc "Run the Testable Watir data setter script"
58
+ task :dataset do
59
+ system("ruby ./examples/testable-watir-datasetter.rb")
20
60
  end
21
61
  end
22
62
 
@@ -24,12 +64,13 @@ namespace :spec do
24
64
  desc 'Clean all generated reports'
25
65
  task :clean do
26
66
  system('rm -rf spec/reports')
67
+ system('rm -rf spec/coverage')
27
68
  end
28
69
 
29
70
  RSpec::Core::RakeTask.new(all: :clean) do |config|
30
- options = %w(--color)
31
- options += %w(--format documentation)
32
- options += %w(--format html --out spec/reports/unit-test-report.html)
71
+ options = %w[--color]
72
+ options += %w[--format documentation]
73
+ options += %w[--format html --out spec/reports/unit-test-report.html]
33
74
 
34
75
  config.rspec_opts = options
35
76
  end
@@ -9,5 +9,5 @@ require "testable"
9
9
  require "pry"
10
10
  Pry.start
11
11
 
12
- # require "irb"
13
- # IRB.start
12
+ require "irb"
13
+ IRB.start(__FILE__)
data/bin/setup CHANGED
File without changes
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ include RSpec::Matchers
6
+
7
+ require "testable"
8
+ include Testable::Context
9
+
10
+ Capybara.configure do |config|
11
+ config.run_server = false
12
+ config.default_driver = :selenium
13
+ config.app_host = "https://veilus.herokuapp.com"
14
+ end
15
+
16
+ class HomePage < Testable::Page
17
+ element :login_form, "#open"
18
+ element :username, "#username"
19
+ element :password, "#password"
20
+ element :login, "#login-button"
21
+
22
+ def path
23
+ "/"
24
+ end
25
+
26
+ def login_as_admin
27
+ login_form.click
28
+ username.set "admin"
29
+ password.set "admin"
30
+ login.click
31
+ end
32
+ end
33
+
34
+ class Navigation < Testable::Node
35
+ elements :items, "a"
36
+
37
+ element :page_list, "#navlist"
38
+ element :overlord, "#overlord"
39
+ element :planets, "#planets"
40
+ element :warp, "#warp"
41
+ element :stardate, "#stardate"
42
+ end
43
+
44
+ class MenuItem < Testable::Node
45
+ components :items, Navigation, "#areas"
46
+ end
47
+
48
+ class LandingPage < Testable::Page
49
+ component :navigation, Navigation, "#areas"
50
+ element :logo, "#site-image"
51
+ end
52
+
53
+ on_visit(HomePage).login_as_admin
54
+
55
+ on(LandingPage) do |action|
56
+ action.navigation.page_list.click
57
+ puts action.navigation.overlord.text
58
+ puts action.navigation.items
59
+ puts action.navigation.items[0].text
60
+ expect(action.navigation).to have_items
61
+ expect(action.navigation.items[0].text).to eq("Home")
62
+ expect(action.navigation.items.count).to be(8)
63
+ action.navigation.overlord.click
64
+ end