testable 0.3.0 → 0.8.0

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.
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
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ # Run this with:
5
+ # rspec ./examples/testable-capybara-rspec.rb
6
+
7
+ require "rspec"
8
+ include RSpec::Matchers
9
+
10
+ require "testable"
11
+ include Testable::Context
12
+
13
+ require "capybara/rspec"
14
+
15
+ RSpec.configure do |config|
16
+ config.expose_dsl_globally = true
17
+ end
18
+
19
+ Capybara.configure do |config|
20
+ config.run_server = false
21
+ config.default_driver = :selenium
22
+ config.app_host = "https://veilus.herokuapp.com"
23
+ end
24
+
25
+ class HomePage < Testable::Page
26
+ element :login_form, "#open"
27
+ element :username, "#username"
28
+ element :password, "#password"
29
+ element :login, "#login-button"
30
+
31
+ def path
32
+ "/"
33
+ end
34
+
35
+ def login_as_admin
36
+ login_form.click
37
+ username.set "admin"
38
+ password.set "admin"
39
+ login.click
40
+ end
41
+ end
42
+
43
+ class Navigation < Testable::Node
44
+ elements :items, "a"
45
+
46
+ element :page_list, "#navlist"
47
+ element :overlord, "#overlord"
48
+ element :planets, "#planets"
49
+ element :warp, "#warp"
50
+ element :stardate, "#stardate"
51
+ end
52
+
53
+ class LandingPage < Testable::Page
54
+ component :navigation, Navigation, "#areas"
55
+
56
+ def go_to_overlord
57
+ navigation.page_list.click
58
+ navigation.overlord.click
59
+ end
60
+ end
61
+
62
+ feature "navigation" do
63
+ background do
64
+ on_visit(HomePage).login_as_admin
65
+ end
66
+
67
+ scenario "navigates to overlord" do
68
+ on(LandingPage).go_to_overlord
69
+ end
70
+ end
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ include RSpec::Matchers
6
+
7
+ require "testable"
8
+
9
+ Capybara.configure do |config|
10
+ config.run_server = false
11
+ config.default_driver = :selenium
12
+ config.app_host = "https://veilus.herokuapp.com"
13
+ end
14
+
15
+ class HomePage < Testable::Page
16
+ element :login_form, "#open"
17
+ element :username, "#username"
18
+ element :password, "#password"
19
+ element :login, "#login-button"
20
+
21
+ def path
22
+ "/"
23
+ end
24
+ end
25
+
26
+ home_page = HomePage.visit
27
+
28
+ puts home_page.current?
29
+ expect(home_page).to be_current
30
+
31
+ puts home_page.find("article").text
32
+
33
+ puts home_page.login_form.inspect
34
+
35
+ puts home_page.has_login_form?
36
+ puts home_page.has_no_login_form?
37
+
38
+ expect(home_page).to have_login_form
39
+
40
+ # The next statement would (correctly) fail.
41
+ # expect(home_page).to have_no_login_form
42
+
43
+ home_page.login_form.click
44
+ home_page.username.set "admin"
45
+ home_page.password.set "admin"
46
+ home_page.login.click
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "testable"
5
+
6
+ require "rspec"
7
+ # rubocop:disable Style/MixinUsage
8
+ include RSpec::Matchers
9
+ # rubocop:enable Style/MixinUsage
10
+
11
+ puts Testable::VERSION
12
+
13
+ puts "================================="
14
+ puts "Testable's Version"
15
+ puts "================================="
16
+ puts Testable.version
17
+
18
+ puts "================================="
19
+ puts "Testable's Dependencies"
20
+ puts "================================="
21
+ puts Testable.dependencies
22
+
23
+ puts "================================="
24
+ puts "Testable's API"
25
+ puts "================================="
26
+ puts Testable.api
27
+
28
+ class Home
29
+ include Testable
30
+ end
31
+
32
+ Testable.start_browser :firefox, headless: true
33
+
34
+ page = Home.new
35
+
36
+ expect(Testable.browser).to be_an_instance_of(Watir::Browser)
37
+ expect(Testable.browser.driver).to be_an_instance_of(
38
+ Selenium::WebDriver::Firefox::Marionette::Driver
39
+ )
40
+
41
+ expect(page).to be_a_kind_of(Testable)
42
+ expect(page).to be_an_instance_of(Home)
43
+
44
+ puts "================================="
45
+ puts "Testable's Watir API"
46
+ puts "================================="
47
+ puts Testable.watir_api
48
+
49
+ puts "================================="
50
+ puts "Testable's Selenium API"
51
+ puts "================================="
52
+ puts Testable.selenium_api
53
+
54
+ puts "================================="
55
+ puts "Testable's Definition API"
56
+ puts "================================="
57
+ puts page.definition_api
58
+
59
+ puts "================================="
60
+ puts "Testable's Elements"
61
+ puts "================================="
62
+ puts Testable.elements?
63
+ puts Testable.recognizes?("div")
64
+
65
+ Testable.quit_browser
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ # rubocop:disable Style/MixinUsage
6
+ include RSpec::Matchers
7
+ # rubocop:enable Style/MixinUsage
8
+
9
+ require "testable"
10
+ # rubocop:disable Style/MixinUsage
11
+ include Testable::Context
12
+ # rubocop:enable Style/MixinUsage
13
+
14
+ class Home
15
+ include Testable
16
+
17
+ url_is "https://veilus.herokuapp.com/"
18
+ url_matches(/heroku/)
19
+ title_is "Veilus"
20
+
21
+ # Elements can be defined with HTML-style names as found in Watir.
22
+ p :login_form, id: "open", visible: true
23
+ text_field :username, id: "username"
24
+ text_field :password
25
+ button :login, id: "login-button"
26
+ div :message, class: "notice"
27
+
28
+ # Elements can be defined with a generic name.
29
+ # element :login_form, id: "open", visible: true
30
+ # element :username, id: "username"
31
+ # element :password
32
+ # element :login, id: "login-button"
33
+ # element :message, class: "notice"
34
+
35
+ def begin_with
36
+ move_to(0, 0)
37
+ resize_to(screen_width, screen_height)
38
+ end
39
+ end
40
+
41
+ class Navigation
42
+ include Testable
43
+
44
+ p :page_list, id: "navlist"
45
+ link :planets, id: "planets"
46
+
47
+ image :planet_logo, id: "planet-logo"
48
+ end
49
+
50
+ Testable.start_browser :firefox
51
+
52
+ on_visit(Home) do
53
+ @context.login_form.click
54
+ @context.username.set "admin"
55
+ @context.password(id: 'password').set "admin"
56
+ @context.login.click
57
+ expect(@context.message.text).to eq('You are now logged in as admin.')
58
+ end
59
+
60
+ on(Navigation) do |page|
61
+ page.page_list.click
62
+ # page.page_list.wait_until(&:dom_updated?).click
63
+ page.planets.click
64
+ expect(page.planet_logo.exists?).to be true
65
+ end
66
+
67
+ Testable.quit_browser
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ # rubocop:disable Style/MixinUsage
6
+ include RSpec::Matchers
7
+ # rubocop:enable Style/MixinUsage
8
+
9
+ require "testable"
10
+ # rubocop:disable Style/MixinUsage
11
+ include Testable::Context
12
+ # rubocop:enable Style/MixinUsage
13
+
14
+ class Home
15
+ include Testable
16
+
17
+ url_is "https://veilus.herokuapp.com/"
18
+
19
+ p :login_form, id: "open", visible: true
20
+ text_field :username, id: "username"
21
+ text_field :password
22
+ button :login, id: "login-button"
23
+ div :message, class: 'notice'
24
+
25
+ def begin_with
26
+ move_to(0, 0)
27
+ resize_to(screen_width, screen_height)
28
+ end
29
+ end
30
+
31
+ class WarpTravel
32
+ include Testable
33
+
34
+ url_is "https://veilus.herokuapp.com/warp"
35
+
36
+ text_field :warp_factor, id: 'warpInput'
37
+ text_field :velocity, id: 'velocityInput'
38
+ text_field :distance, id: 'distInput'
39
+ end
40
+
41
+ Testable.start_browser :firefox
42
+
43
+ on_visit(Home) do
44
+ @active.login_form.click
45
+ @active.username.set "admin"
46
+ @active.password(id: 'password').set "admin"
47
+ @active.login.click
48
+ end
49
+
50
+ on_visit(WarpTravel).using_data("warp factor": 1, velocity: 1, distance: 4.3)
51
+
52
+ Testable.quit_browser
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ # rubocop:disable Style/MixinUsage
6
+ include RSpec::Matchers
7
+ # rubocop:enable Style/MixinUsage
8
+
9
+ require "testable"
10
+
11
+ class Dynamic
12
+ include Testable
13
+
14
+ url_is "https://veilus.herokuapp.com/practice/dynamic_events"
15
+
16
+ button :long, id: 'long'
17
+ button :quick, id: 'quick'
18
+ button :stale, id: 'stale'
19
+ button :fade, id: 'fade'
20
+
21
+ div :dom_events, id: 'container1'
22
+ div :stale_event, id: 'container2'
23
+ div :effect_events, id: 'container3'
24
+ end
25
+
26
+ Testable.start_browser :firefox
27
+
28
+ page = Dynamic.new
29
+
30
+ page.visit
31
+
32
+ expect(page.dom_events.dom_updated?).to be_truthy
33
+ expect(page.dom_events.wait_until(&:dom_updated?).spans.count).to eq(0)
34
+
35
+ page.long.click
36
+
37
+ expect(page.dom_events.dom_updated?).to be_falsey
38
+ expect(page.dom_events.wait_until(&:dom_updated?).spans.count).to eq(4)
39
+
40
+ page.quick.click
41
+
42
+ expect(page.dom_events.wait_until(&:dom_updated?).spans.count).to eq(23)
43
+
44
+ Testable.quit_browser
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ # rubocop:disable Style/MixinUsage
6
+ include RSpec::Matchers
7
+ # rubocop:enable Style/MixinUsage
8
+
9
+ require "testable"
10
+
11
+ class PageReady
12
+ include Testable
13
+
14
+ url_is "https://veilus.herokuapp.com"
15
+
16
+ element :logo, id: 'site-'
17
+ element :login_form, id: 'openski'
18
+
19
+ page_ready { [logo.exists?, "Test Gorilla logo is not present"] }
20
+ end
21
+
22
+ Testable.start_browser :firefox
23
+
24
+ page = PageReady.new
25
+
26
+ page.visit
27
+
28
+ # Uncomment one of these at a time to see that the page_ready part
29
+ # is working. The element definitions above are purposely incorrect.
30
+
31
+ # page.when_ready { page.login_form.click }
32
+ # page.login_form.click
33
+
34
+ Testable.quit_browser
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << "./lib"
3
+
4
+ require "rspec"
5
+ include RSpec::Matchers
6
+
7
+ require "testable"
8
+
9
+ class Home
10
+ include Testable
11
+
12
+ url_is "https://veilus.herokuapp.com/"
13
+ url_matches(/heroku/)
14
+ title_is "Veilus"
15
+
16
+ # Elements can be defined with HTML-style names as found in Watir.
17
+ p :login_form, id: "open", visible: true
18
+ text_field :username, id: "username"
19
+ text_field :password
20
+ button :login, id: "login-button"
21
+ div :message, class: "notice"
22
+
23
+ # Elements can be defined with a generic name.
24
+ # element :login_form, id: "open", visible: true
25
+ # element :username, id: "username"
26
+ # element :password
27
+ # element :login, id: "login-button"
28
+ # element :message, class: "notice"
29
+
30
+ def begin_with
31
+ move_to(0, 0)
32
+ resize_to(screen_width, screen_height)
33
+ end
34
+ end
35
+
36
+ class Navigation
37
+ include Testable
38
+
39
+ p :page_list, id: "navlist"
40
+ link :planets, id: "planets"
41
+
42
+ image :planet_logo, id: "planet-logo"
43
+ end
44
+
45
+ Testable.start_browser :firefox
46
+
47
+ # Will default to UNKNOWN.
48
+ puts Testable.log_level
49
+
50
+ # Will not actually log.
51
+ Testable.logger.info("Testing an info log message.")
52
+
53
+ # Change the log.
54
+ Testable.log_level = :debug
55
+
56
+ # Will actually log.
57
+ Testable.logger.debug("Testing a debug log message.")
58
+
59
+ # Sets the Watir wire protocol level logging.
60
+ Testable.wire_level_logging = :info
61
+
62
+ page = Home.new
63
+
64
+ page.visit
65
+
66
+ page.login_form.click
67
+ page.username.set "admin"
68
+ page.password(id: 'password').set "admin"
69
+ page.login.click
70
+ expect(page.message.text).to eq('You are now logged in as admin.')
71
+
72
+ page = Navigation.new
73
+
74
+ page.page_list.click
75
+ # page.page_list.wait_until(&:dom_updated?).click
76
+
77
+ page.planets.click
78
+ expect(page.planet_logo.exists?).to be true
79
+
80
+ Testable.quit_browser