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