spectest 0.0.1 → 0.0.2

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 (44) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +13 -0
  3. data/HISTORY.md +11 -0
  4. data/README.md +1 -1
  5. data/Rakefile +22 -1
  6. data/cucumber.yml +4 -0
  7. data/lib/spectest.rb +45 -0
  8. data/lib/spectest/logger.rb +5 -0
  9. data/lib/spectest/matchers.rb +48 -0
  10. data/lib/spectest/platform_selenium.rb +18 -0
  11. data/lib/spectest/platform_selenium/platform_object.rb +31 -0
  12. data/lib/spectest/platform_watir.rb +18 -0
  13. data/lib/spectest/platform_watir/platform_object.rb +33 -0
  14. data/lib/spectest/platforms.rb +23 -0
  15. data/lib/spectest/version.rb +1 -1
  16. data/spec/browser_level_spec.rb +24 -0
  17. data/spec/page_level_spec.rb +34 -0
  18. data/spec/platform_object_spec.rb +45 -0
  19. data/spec/platform_selenium_spec.rb +28 -0
  20. data/spec/platform_watir_spec.rb +32 -0
  21. data/spec/platforms_spec.rb +40 -0
  22. data/spec/spec_helper.rb +45 -0
  23. data/spec/spectest_spec.rb +7 -0
  24. data/specs/app/favicon.ico +0 -0
  25. data/specs/app/images/mass_extinction.jpg +0 -0
  26. data/specs/app/index.html +20 -0
  27. data/specs/app/modal_1.html +41 -0
  28. data/specs/app/modal_2.html +29 -0
  29. data/specs/app/server.rb +25 -0
  30. data/specs/app/style.css +18 -0
  31. data/specs/app/success_1.html +12 -0
  32. data/specs/app/success_2.html +12 -0
  33. data/specs/app/test_event.html +39 -0
  34. data/specs/app/test_form.html +114 -0
  35. data/specs/app/test_frame.html +15 -0
  36. data/specs/app/test_iframe.html +15 -0
  37. data/specs/app/test_static.html +92 -0
  38. data/specs/engine/borg.rb +24 -0
  39. data/specs/engine/hooks.rb +18 -0
  40. data/specs/pages/landing_page.rb +4 -0
  41. data/specs/steps/page_steps.rb +11 -0
  42. data/specs/tests/page.feature +9 -0
  43. data/spectest.gemspec +1 -0
  44. metadata +57 -10
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  .idea/*
3
3
  .svn/*
4
4
  pkg/*
5
+ coverage/*
5
6
  *.gem
6
7
  *.swp
7
8
  *.swo
@@ -0,0 +1,13 @@
1
+ script: "rake"
2
+
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+
7
+ branches:
8
+ only:
9
+ - master
10
+
11
+ notifications:
12
+ recipients:
13
+ - jeffnyman@gmail.com
data/HISTORY.md CHANGED
@@ -1,6 +1,17 @@
1
1
  Change Log and History
2
2
  ======================
3
3
 
4
+ ## Version 0.0.2 / 2011-11-13
5
+
6
+ Platform object structure added. This allows browsers to be associated with a particular driver. That combination is called a "platform object." It's this object that directs the execution of tests against the browser. A full RSpec and Cucumber testing infrastructure has been added. The Cucumber file layout will match what users of the gem would have to create.
7
+
8
+ * Browser-Level Actions Supported:
9
+ * navigate to
10
+
11
+ * Page-Level Actions Supported:
12
+ * title
13
+ * text
14
+
4
15
  ## Version 0.0.1 / 2011-11-12
5
16
 
6
17
  Initial creation of the gem framework.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SpecTest
1
+ # SpecTest [![Build Status](https://secure.travis-ci.org/jnyman/spectest.png)](http://travis-ci.org/jnyman/spectest)
2
2
 
3
3
  This gem is designed to provide a testing framework for creating executable test specifications.
4
4
 
data/Rakefile CHANGED
@@ -1 +1,22 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'cucumber/rake/task'
4
+
5
+ task :default => :spec
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ namespace :specs do
10
+ Cucumber::Rake::Task.new(:watir, "Run Cucumber with Watir") do |config|
11
+ config.profile = 'watir'
12
+ end
13
+
14
+ Cucumber::Rake::Task.new(:selenium, "Run Cucumber with Selenium") do |config|
15
+ config.profile = 'selenium'
16
+ end
17
+
18
+ desc "Run Cucumber with Selenium and Watir"
19
+ task :all => [:watir, :selenium]
20
+ task :watir_driver => [:watir]
21
+ task :selenium_driver => [:selenium]
22
+ end
@@ -0,0 +1,4 @@
1
+ default: DRIVER=watir BROWSER=firefox -r specs/engine/borg.rb -r specs specs
2
+
3
+ watir: DRIVER=watir BROWSER=firefox -r specs/engine/borg.rb -r specs specs
4
+ selenium: DRIVER=selenium BROWSER=firefox -r specs/engine/borg.rb -r specs specs
@@ -1,5 +1,50 @@
1
1
  require "spectest/version"
2
+ require "spectest/logger"
3
+ require "spectest/matchers"
4
+ require "spectest/platforms"
2
5
 
3
6
  module SpecTest
7
+ include Matchers
8
+ include Platforms
4
9
 
10
+ # @return [TerminusSpec::Platforms::WatirWebDriver::PlatformObject] the platform object
11
+ # @return [TerminusSpec::Platforms::SeleniumWebDriver::PlatformObject] the platform object
12
+ attr_reader :platform
13
+
14
+ def self.version_info
15
+ "SpecTest version #{SpecTest::VERSION}"
16
+ end
17
+
18
+ def initialize(browser)
19
+ @browser = browser
20
+ establish_platform_driver_for browser
21
+ end
22
+
23
+ # Navigate to the specified URL. The URL can be specified as a domain
24
+ # address or as a file-based link.
25
+ # @param [String] url the full URL to navigate to
26
+ def navigate_to(url)
27
+ # Here is exactly why a platform object is needed. Which version do I call:
28
+ # @browser.goto(url) <-- this is for Watir
29
+ # @browser.navigate.to(url) <-- this is for Selenium
30
+ # I have to call the platform that has been established. The platform will
31
+ # be responsible for containing the correct call.
32
+ @platform.navigate_to url
33
+ end
34
+
35
+ # Returns the title of the current page as displayed in the browser.
36
+ def title
37
+ @platform.title
38
+ end
39
+
40
+ # Returns the text of the current page.
41
+ def text
42
+ @platform.text
43
+ end
44
+
45
+ private
46
+
47
+ def establish_platform_driver_for(browser)
48
+ @platform = platform_for browser, SpecTest::Platforms.list
49
+ end
5
50
  end
@@ -0,0 +1,5 @@
1
+ module SpecTest
2
+ def self.trace(message, level=1)
3
+ puts("*" * level + " #{message}") if ENV['TRACE'] == 'on'
4
+ end
5
+ end
@@ -0,0 +1,48 @@
1
+ module SpecTest
2
+ module Matchers
3
+
4
+ # Without this matcher, here's what RSpec decides to give you:
5
+ # expected "Test" to match /^Test App$/
6
+ # With the matcher, you get this:
7
+ # Expected that 'Test App' would be the title of the page; found 'Test' instead.
8
+ RSpec::Matchers.define :have_title do |text|
9
+ match do |the_page|
10
+ the_page =~ Regexp.new(text)
11
+ end
12
+
13
+ failure_message_for_should do |actual|
14
+ "Expected that '#{text}' would be the title of the page; found '#{actual}' instead."
15
+ end
16
+
17
+ failure_message_for_should_not do |actual|
18
+ "Expected that '#{text}' would not be the title of the page; it was, however."
19
+ end
20
+
21
+ description do
22
+ "checking for a title of #{text}"
23
+ end
24
+ end
25
+
26
+ # Without this matcher, here's what RSpec decides to give you:
27
+ # expected "Testing with Terminus\nLanding\nStatic Text Examples\nForm Examples\nFrame Examples\nIFrame Examples\nEvent Examples" to match /^Landing Page$/
28
+ # With the matcher, you get this:
29
+ # Expected that 'Landing Page' would be in the page content; it was not found.
30
+ RSpec::Matchers.define :contain do |text|
31
+ match do |the_page|
32
+ the_page =~ Regexp.new(text)
33
+ end
34
+
35
+ failure_message_for_should do |actual|
36
+ "Expected that '#{text}' would be in the page content; it was not found."
37
+ end
38
+
39
+ failure_message_for_should_not do |actual|
40
+ "Expected that '#{text}' would not be in the page content; it was, however."
41
+ end
42
+
43
+ description do
44
+ "checking for #{text}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ module SpecTest
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+
5
+ def self.create_platform_object_for(browser)
6
+ require "spectest/platform_selenium/platform_object"
7
+ return SeleniumWebDriver::PlatformObject.new(browser)
8
+ end
9
+
10
+ def self.works_for?(browser)
11
+ browser.is_a?(Selenium::WebDriver::Driver)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ SpecTest::Platforms.associate(:selenium_webdriver, SpecTest::Platforms::SeleniumWebDriver)
@@ -0,0 +1,31 @@
1
+ module SpecTest
2
+ module Platforms
3
+ module SeleniumWebDriver
4
+ class PlatformObject
5
+
6
+ def initialize(browser)
7
+ @browser = browser
8
+ end
9
+
10
+ # Platform method to navigate to a specified URL.
11
+ # See SpecTest#navigate_to
12
+ def navigate_to(url)
13
+ @browser.navigate.to url
14
+ end
15
+
16
+ # Platform method to retrieve the title for the current page.
17
+ # See SpecTest#title
18
+ def title
19
+ @browser.title
20
+ end
21
+
22
+ # Platform method to retrieve text from the current page.
23
+ # See SpecTest#text
24
+ def text
25
+ @browser.find_element(:tag_name, 'body').text
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module SpecTest
2
+ module Platforms
3
+ module WatirWebDriver
4
+
5
+ def self.create_platform_object_for(browser)
6
+ require "spectest/platform_watir/platform_object"
7
+ return WatirWebDriver::PlatformObject.new(browser)
8
+ end
9
+
10
+ def self.works_for?(browser)
11
+ browser.is_a?(Watir::Browser)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ SpecTest::Platforms.associate(:watir_webdriver, SpecTest::Platforms::WatirWebDriver)
@@ -0,0 +1,33 @@
1
+ module SpecTest
2
+ module Platforms
3
+ module WatirWebDriver
4
+ class PlatformObject
5
+
6
+ attr_reader :browser
7
+
8
+ def initialize(browser)
9
+ @browser = browser
10
+ end
11
+
12
+ # Platform method to navigate to a specified URL.
13
+ # See SpecTest#navigate_to
14
+ def navigate_to(url)
15
+ @browser.goto url
16
+ end
17
+
18
+ # Platform method to retrieve the title for the current page.
19
+ # See SpecTest#title
20
+ def title
21
+ @browser.title
22
+ end
23
+
24
+ # Platform method to retrieve text from the current page.
25
+ # See SpecTest#text
26
+ def text
27
+ @browser.text
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module SpecTest
2
+ module Platforms
3
+ @@drivers = {}
4
+
5
+ def self.list
6
+ @@drivers
7
+ end
8
+
9
+ def self.associate(key, driver)
10
+ @@drivers[key] = driver
11
+ end
12
+
13
+ def platform_for(browser, drivers)
14
+ drivers.each_value { |driver|
15
+ return driver.create_platform_object_for browser if driver.works_for? browser
16
+ }
17
+ raise "Unable to associate a platform using the provided browser."
18
+ end
19
+ end
20
+ end
21
+
22
+ require "spectest/platform_watir"
23
+ require "spectest/platform_selenium"
@@ -1,3 +1,3 @@
1
1
  module SpecTest
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe SpecTest do
4
+ let(:watir_browser) { mock_browser_with_watir }
5
+ let(:selenium_browser) { mock_browser_with_selenium }
6
+ let(:watir_page) { PageTester.new(watir_browser) }
7
+ let(:selenium_page) { PageTester.new(selenium_browser) }
8
+
9
+ describe "in terms of browser-level functionality" do
10
+ context "when using the watir platform" do
11
+ it "a page can be navigated to" do
12
+ watir_browser.should_receive(:goto).with("testerstories.com")
13
+ watir_page.navigate_to("testerstories.com")
14
+ end
15
+ end
16
+
17
+ context "when using the selenium platform" do
18
+ it "a page can be navigated to" do
19
+ selenium_browser.stub_chain(:navigate, :to).with("testerstories.com")
20
+ selenium_page.navigate_to("testerstories.com")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe SpecTest do
4
+ let(:watir_browser) { mock_browser_with_watir }
5
+ let(:selenium_browser) { mock_browser_with_selenium }
6
+ let(:watir_page) { PageTester.new(watir_browser) }
7
+ let(:selenium_page) { PageTester.new(selenium_browser) }
8
+
9
+ describe "in terms of page-level functionality" do
10
+ context "when using the watir platform" do
11
+ it "the title of the page will be accessible" do
12
+ watir_browser.should_receive(:title).and_return("Page Title")
13
+ watir_page.title.should == "Page Title"
14
+ end
15
+
16
+ it "the text of the page will be accessible" do
17
+ watir_browser.should_receive(:text).and_return("page text")
18
+ watir_page.text.should == "page text"
19
+ end
20
+ end
21
+
22
+ context "when using the selenium platform" do
23
+ it "the title of the page will be accessible" do
24
+ selenium_browser.should_receive(:title).and_return("Page Title")
25
+ selenium_page.title.should == "Page Title"
26
+ end
27
+
28
+ it "the text of the page will be accessible" do
29
+ selenium_browser.stub_chain(:find_element, :text).and_return("page text")
30
+ selenium_page.text.should == "page text"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ class PlatformObject
4
+ end
5
+
6
+ describe SpecTest do
7
+ let(:watir_browser) { mock_browser_with_watir }
8
+ let(:selenium_browser) { mock_browser_with_selenium }
9
+ let(:watir_page) { PageTester.new(watir_browser) }
10
+ let(:selenium_page) { PageTester.new(selenium_browser) }
11
+
12
+ context "can be included with a page that will be using watir-webdriver" do
13
+ it "which means the page should use a watir platform object" do
14
+ watir_page.platform.should be_kind_of SpecTest::Platforms::WatirWebDriver::PlatformObject
15
+ end
16
+ end
17
+
18
+ context "can be included with a page that will be using selenium-webdriver" do
19
+ it "which means the page should use a selenium platform object" do
20
+ selenium_page.platform.should be_kind_of SpecTest::Platforms::SeleniumWebDriver::PlatformObject
21
+ end
22
+ end
23
+
24
+ context "might be included with a page using an unrecognized driver" do
25
+ it "and in that case it should raise an exception" do
26
+ expect { PageTester.new("fake_browser") }.to raise_error
27
+ end
28
+ end
29
+
30
+ context "might be included with a page using an unassociated custom driver" do
31
+ let(:custom_driver) { mock_driver(:watir_browser, PlatformObject) }
32
+ it "and in that case it should raise an exception" do
33
+ expect { custom_page = PageTester.new(:watir_browser) }.to raise_error
34
+ end
35
+ end
36
+
37
+ context "might be included with a page using an associated custom driver" do
38
+ let(:custom_driver) { mock_driver(:custom_browser, PlatformObject) }
39
+ it "which means the page should use a custom platform object" do
40
+ mock_drivers_list({:custom_driver => custom_driver})
41
+ custom_page = PageTester.new(:custom_browser)
42
+ custom_page.platform.should be custom_driver.create_platform_object_for
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe SpecTest::Platforms::SeleniumWebDriver do
4
+ it "should be in the platform objects driver list" do
5
+ SpecTest::Platforms.list[:selenium_webdriver].should be SpecTest::Platforms::SeleniumWebDriver
6
+ end
7
+
8
+ describe "and when used to create a platform object" do
9
+ let(:browser) { double('browser') }
10
+ let(:platform) { SpecTest::Platforms::SeleniumWebDriver.create_platform_object_for(browser) }
11
+
12
+ it "a SeleniumPlatformObject should be created" do
13
+ platform.should be_kind_of SpecTest::Platforms::SeleniumWebDriver::PlatformObject
14
+ end
15
+ end
16
+
17
+ describe "and when checking if the platform can be associated with a browser" do
18
+ it "if the browser is of type Selenium::WebDriver, the platform will be associated " do
19
+ browser = mock_browser_with_selenium()
20
+ SpecTest::Platforms::SeleniumWebDriver.works_for?(browser).should be true
21
+ end
22
+
23
+ it "if the browser is not of type Selenium::WebDriver, the platform will not be associated" do
24
+ browser = "false_browser"
25
+ SpecTest::Platforms::SeleniumWebDriver.works_for?(browser).should be false
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe SpecTest::Platforms::WatirWebDriver do
4
+ it "should be in the platform objects driver list" do
5
+ SpecTest::Platforms.list[:watir_webdriver].should be SpecTest::Platforms::WatirWebDriver
6
+ end
7
+
8
+ describe "and when used to create a platform object" do
9
+ let(:browser) { double('browser') }
10
+ let(:platform) { SpecTest::Platforms::WatirWebDriver.create_platform_object_for(browser) }
11
+
12
+ it "a WatirPlatformObject should be created" do
13
+ platform.should be_kind_of SpecTest::Platforms::WatirWebDriver::PlatformObject
14
+ end
15
+
16
+ it "the browser should be associated with the platform object" do
17
+ platform.browser.should be browser
18
+ end
19
+ end
20
+
21
+ describe "and when checking if the platform can be associated with a browser" do
22
+ it "if the browser is of type Watir::Browser, the platform will be associated " do
23
+ browser = mock_browser_with_watir()
24
+ SpecTest::Platforms::WatirWebDriver.works_for?(browser).should be true
25
+ end
26
+
27
+ it "if the browser is not of type Watir::Browser, the platform will not be associated" do
28
+ browser = "false_browser"
29
+ SpecTest::Platforms::WatirWebDriver.works_for?(browser).should be false
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ class LoadingPlatforms
4
+ include SpecTest::Platforms
5
+ end
6
+
7
+ describe LoadingPlatforms do
8
+ let(:platform) { LoadingPlatforms.new() }
9
+ let(:drivers) { {} }
10
+
11
+ context "if a chrome browser is associated with a chrome platform" do
12
+ let(:chrome_browser) { double('browser') }
13
+ before { drivers[:chrome_browser] = mock_driver(chrome_browser, :chrome_platform) }
14
+ it "then the chrome platform will be established for the chrome browser" do
15
+ platform.platform_for(chrome_browser, drivers).should == :chrome_platform
16
+ end
17
+
18
+ context "if a firefox browser is associated with a firefox platform" do
19
+ let(:firefox_browser) { double('browser') }
20
+ before { drivers[:firefox_browser] = mock_driver(firefox_browser, :firefox_platform) }
21
+ it "then the chrome platform will still be established for the chrome platform" do
22
+ platform.platform_for(chrome_browser, drivers).should == :chrome_platform
23
+ end
24
+ end
25
+ end
26
+
27
+ context "if a firefox browser is associated with a firefox platform" do
28
+ let(:firefox_browser) { double('browser') }
29
+ before { drivers[:firefox_browser] = mock_driver(firefox_browser, :firefox_platform) }
30
+ it "then the firefox platform will be established for the firefox browser" do
31
+ platform.platform_for(firefox_browser, drivers).should == :firefox_platform
32
+ end
33
+ end
34
+
35
+ context "if an unknown browser object is associated with a platform" do
36
+ it "then it should raise an exception" do
37
+ expect { platform.platform_for("false_browser") }.to raise_error
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require 'simplecov'
2
+ SimpleCov.start { add_filter "/spec/" } if ENV['COVERAGE']
3
+
4
+ require 'rspec'
5
+ require 'spectest'
6
+
7
+ require 'watir-webdriver'
8
+ require 'selenium-webdriver'
9
+
10
+ class PageTester
11
+ include SpecTest
12
+ end
13
+
14
+ RSpec.configure do |config|
15
+ config.color_enabled = true
16
+ config.formatter = 'documentation'
17
+ end
18
+
19
+ def mock_browser_with_watir
20
+ watir_browser = double('watir')
21
+ watir_browser.stub(:is_a?).with(anything()).and_return(false)
22
+ watir_browser.stub(:is_a?).with(Selenium::WebDriver::Driver).and_return(false)
23
+ watir_browser.stub(:is_a?).with(Watir::Browser).and_return(true)
24
+ watir_browser
25
+ end
26
+
27
+ def mock_browser_with_selenium
28
+ selenium_browser = double('selenium')
29
+ selenium_browser.stub(:is_a?).with(anything()).and_return(false)
30
+ selenium_browser.stub(:is_a?).with(Watir::Browser).and_return(false)
31
+ selenium_browser.stub(:is_a?).with(Selenium::WebDriver::Driver).and_return(true)
32
+ selenium_browser
33
+ end
34
+
35
+ def mock_driver(browser, platform_object)
36
+ driver = double('driver')
37
+ driver.stub(:works_for?).with(anything()).and_return(false)
38
+ driver.stub(:works_for?).with(browser).and_return(true)
39
+ driver.stub(:create_platform_object_for).and_return platform_object
40
+ driver
41
+ end
42
+
43
+ def mock_drivers_list(drivers)
44
+ SpecTest::Platforms.stub(:list).and_return drivers
45
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe SpecTest do
4
+ it "should be able to return its version information" do
5
+ SpecTest.version_info.should == "SpecTest version #{SpecTest::VERSION}"
6
+ end
7
+ end
Binary file
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+ <body>
9
+
10
+ <h1 class="title">Testing with Terminus</h1>
11
+ <h2 class="subtitle">Landing Page</h2>
12
+
13
+ <p><a href="test_static.html">Static Text Examples</a></p>
14
+ <p><a href="test_form.html">Form Examples</a></p>
15
+ <p><a href="test_frame.html">Frame Examples</a></p>
16
+ <p><a href="test_iframe.html">IFrame Examples</a></p>
17
+ <p><a href="test_event.html">Event Examples</a></p>
18
+
19
+ </body>
20
+ </html>
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Modal Testing</title>
6
+
7
+ <script>
8
+ function delay_action(other_function) {
9
+ setTimeout(other_function, 3000);
10
+ }
11
+
12
+ function close_window() {
13
+ window.returnValue = 22
14
+ window.close()
15
+ }
16
+
17
+ function modal1() {
18
+ var retValue = window.showModalDialog(
19
+ "modal_2.html", self,
20
+ "status:no;resizable:Yes;help:no;maximize:no;minimize:no;scrollbars:no;");
21
+ }
22
+ </script>
23
+ </head>
24
+ <body>
25
+
26
+ <h1 class="title">Testing with Terminus</h1>
27
+ <h2 class="subtitle">Modal Page 1</h2>
28
+
29
+ <h3>Close buttons</h3>
30
+
31
+ <input id="close_window" type="button" onclick="close_window()" value="Close Window"/>
32
+ <input id="delayed_close" type="button" onclick="delay_action('close_window()')" value="Close Window (with delay)" />
33
+
34
+ <h3>Nested modal</h3>
35
+
36
+ <input id="launch_modal" type="button" onclick='return modal1();' value="Launch Another Modal"/>
37
+
38
+
39
+
40
+ </body>
41
+ </html>
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Modal Testing</title>
6
+
7
+ <script>
8
+ function delay_action(other_function) {
9
+ setTimeout(other_function, 3000);
10
+ }
11
+
12
+ function close_window() {
13
+ self.close()
14
+ }
15
+ </script>
16
+ </head>
17
+ <body>
18
+
19
+ <h1 class="title">Testing with Terminus</h1>
20
+ <h2 class="subtitle">Modal Page 2</h2>
21
+
22
+ <h3>Close buttons</h3>
23
+
24
+ <input id="close_window2" type="button" onclick="close_window()" value="Close Window"/>
25
+ <input id="delayed_close2" type="button" onclick="delay_action('close_window()')" value="Close Window (with delay)" />
26
+
27
+
28
+ </body>
29
+ </html>
@@ -0,0 +1,25 @@
1
+ require 'webrick'
2
+
3
+ class NonCachingFileHandler < WEBrick::HTTPServlet::FileHandler
4
+ def prevent_caching(res)
5
+ res['ETag'] = nil
6
+ res['Last-Modified'] = Time.now + 100**4
7
+ res['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
8
+ res['Pragma'] = 'no-cache'
9
+ res['Expires'] = Time.now - 100**4
10
+ end
11
+
12
+ def do_GET(req, res)
13
+ super
14
+ prevent_caching(res)
15
+ end
16
+ end
17
+
18
+ if $0 == __FILE__ then
19
+ server = WEBrick::HTTPServer.new(:Port => 1234, :AccessLog => [])
20
+ server.mount '/', NonCachingFileHandler , './'
21
+ ['INT', 'TERM'].each { |signal|
22
+ trap(signal) { server.stop }
23
+ }
24
+ server.start
25
+ end
@@ -0,0 +1,18 @@
1
+ h1.title {
2
+ font-weight: normal;
3
+ font-size: 150%;
4
+ margin-left: 1px;
5
+ text-align: center;
6
+ border-bottom: thin solid;
7
+ font-family: 'Trebuchet MS', 'Lucida Grande', Verdana, Lucida, Geneva, Helvetica, Arial, sans-serif;
8
+ }
9
+
10
+ h2.subtitle {
11
+ border: #660000 0px solid;
12
+ padding: 0.2em 0.2em 0.2em 0px;
13
+ margin: 2em 1px 1px;
14
+ text-align: center;
15
+ font-weight: bold;
16
+ font-size: 120%;
17
+ color: #600;
18
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Success</title>
6
+ </head>
7
+ <body>
8
+ <h1 id="title">Success 1</h1>
9
+
10
+ <p>This is the first success page.</p>
11
+ </body>
12
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Success</title>
6
+ </head>
7
+ <body>
8
+ <h1 id="title">Success 2</h1>
9
+
10
+ <p>This is the second success page.</p>
11
+ </body>
12
+ </html>
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Event Testing</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+
8
+ <script type="text/javascript">
9
+ function modal() {
10
+ var retValue = window.showModalDialog(
11
+ "modal_1.html", self,
12
+ "status:no;resizable:Yes;help:no;maximize:no;minimize:no;scrollbars:no;");
13
+ }
14
+ </script>
15
+ </head>
16
+
17
+ <body onload="document.senderForm.senderElement.focus()">
18
+
19
+ <h1 class="title">Testing with Terminus</h1>
20
+ <h2 class="subtitle">Event Page</h2>
21
+
22
+ <input id="alert_button" type="button" onclick="alert('I am an alert')" value="Alert">
23
+ <input id="confirm_button" type="button" onclick="this.value = confirm('set the value')" value="Confirm">
24
+ <input id="prompt_button" type="button" onclick='this.value = prompt("Favorite Sith Lord", "Darth Bane")' value="Prompt">
25
+
26
+
27
+ <p><strong>Send To Another Page:</strong></p>
28
+ <form action="" method="post" name="senderForm">
29
+ <fieldset>
30
+ <input type="text" name="senderElement" id="senderElement" value="send_this_value" />
31
+ <input type="button" id="send" onclick="parent.frame2.document.recieverForm.recieverElement.value = document.senderForm.senderElement.value" value="Send!" />
32
+ </fieldset>
33
+ </form>
34
+
35
+ <p><strong>Launch a Modal Dialog:</strong></p>
36
+ <input id="modal" type="button" onclick='return modal();' value="Launch Modal Dialog" />
37
+
38
+ </body>
39
+ </html>
@@ -0,0 +1,114 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Form Testing</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+ <body>
9
+
10
+ <h1 class="title">Testing with Terminus</h1>
11
+ <h2 class="subtitle">Form Page</h2>
12
+
13
+ <h3>Connected Form Elements</h3>
14
+
15
+ <form id="Login" name="Login" method="get" action="success_1.html">
16
+ <table cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" align="center" style="overflow:hidden;">
17
+ <tbody>
18
+ <tr>
19
+ <td style="padding-top:12px;">
20
+ <label id="lbl_server" class="Fld" no_help="true" for="server">Server:</label>
21
+ </td>
22
+ </tr>
23
+ <tr>
24
+ <td style="padding-top:8px;">
25
+ <input id="server" name="server" helpid="server" class="Fld" size="40" type="text" value="Test"/>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td style="padding-top:12px;">
30
+ <label id="lbl_customerCode" class="Fld" no_help="true" for="customerCode">Customer ID:</label>
31
+ </td>
32
+ </tr>
33
+ <tr>
34
+ <td style="padding-top:8px;">
35
+ <input id="customerCode" name="customerCode" helpid="customerCode" class="Fld" size="40" type="text"/>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <td style="padding-top:8px;">
40
+ <label id="lbl_loginName" class="Fld" no_help="true" for="loginName">Login Name:</label>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td style="padding-top:8px;">
45
+ <input id="loginName" name="loginName" helpid="loginName" class="Fld" size="40" type="text"/>
46
+ </td>
47
+ </tr>
48
+ <tr>
49
+ <td style="padding-top:8px;">
50
+ <label id="lbl_password" class="Fld" no_help="true" for="password">Password:</label>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <td style="padding-top:8px;">
55
+ <input id="password" name="password" helpid="password" class="Fld" size="40" type="text"/>
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <td>
60
+ <input id="btnSubmit" name="btnSubmit" class="btn" type="submit" value="Log In">
61
+ </td>
62
+ </tr>
63
+ </tbody>
64
+ </table>
65
+ </form>
66
+
67
+ <hr />
68
+
69
+ <h3>Standalone Form Elements</h3>
70
+
71
+ <div>
72
+ <label id="lbl_title" no_help="true"><strong>Book Title:</strong></label><br />
73
+ <input id="title" size="40" type="text"/><br />
74
+ <label id="lbl_description" no_help="true"><strong>Description:</strong></label><br />
75
+ <textarea rows="2" cols="80" id="description" class="text_area_class" name="description"></textarea>
76
+ <input id="isbn" name="isbn" class="hidden_field_class" size="40" type="hidden" value="0-85131-041-9"/>
77
+ </div>
78
+
79
+ <div>
80
+ <p><strong>Choose Your Physics Concepts:</strong></p>
81
+ <select name="concepts" id="concepts", class="sel_list_class">
82
+ <option value="option1">Quantum Entanglement</option>
83
+ <option value="option2">Tachyonic Antitravel</option>
84
+ <option value="option3">Bose-Einstein Condensates</option>
85
+ </select>
86
+ </div>
87
+
88
+ <div>
89
+ <p><strong>Choose Your Futuristic Technology:</strong></p>
90
+ <input id="camoarmor" name="camoarmor" class="cb_class" type="checkbox" value="1"/> Chameleoflage Armor<br />
91
+ <input id="shunt" name="shunt" class="cb_class" type="checkbox" value="2"/> Neural Shunts<br />
92
+ <input id="harpoon" name="harpoon" class="cb_class" type="checkbox" value="3"/> Kinetic Harpoons<br />
93
+ <input id="oc" name="oc" class="cb_class" type="checkbox" value="4"/> Organic Circuitry
94
+ </div>
95
+
96
+ <div>
97
+ <p><strong>Select Your Least Favorite Way To Vaporize:</strong></p>
98
+ <form>
99
+ <input type="radio" id="mtc" name="badstuff" class="rb_class" value="Multiphasic Temporal Convergence"> Multiphasic Temporal Convergence<br/>
100
+ <input type="radio" id="ups" name="badstuff" class="rb_class" value="Unstable Phase Shift"> Unstable Phase Shift<br />
101
+ <input type="radio" id="wcb" name="badstuff" class="rb_class" value="Warp Core Breach"> Warp Core Breach<br />
102
+ </form>
103
+ </div>
104
+
105
+
106
+ <p><strong>Received Event Goes Here:</strong></p>
107
+ <form action="" method="post" name="recieverForm">
108
+ <fieldset>
109
+ <input type="text" name="recieverElement" value="old_value" />
110
+ </fieldset>
111
+ </form>
112
+
113
+ </body>
114
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Frame Testing</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+
9
+ <frameset cols="40%, 40%, 22%">
10
+ <frame name="static" id="static" name="frame1" src="test_static.html" />
11
+ <frame name="form" id="form" name="frame2" src="test_form.html" />
12
+ <frame name="event" id="event" name="frame3" src="test_event.html" />
13
+ </frameset>
14
+
15
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Frame Testing</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+ <body>
9
+
10
+ <iframe name="static" id="static" name="frame1" class="iframe" width="500" src="test_static.html"></iframe>
11
+ <br />
12
+ <iframe name="form" id="form" name="frame2" class="iframe" width="500" src="test_form.html"></iframe>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,92 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Test App - Static Text Testing</title>
6
+ <link rel="stylesheet" href="style.css" />
7
+ </head>
8
+ <body>
9
+
10
+ <h1 class="title">Testing with Terminus</h1>
11
+ <h2 class="subtitle">Static Text Page</h2>
12
+
13
+
14
+ <h3>Links</h3>
15
+
16
+ <p><a id="avengers_unite_id" name="avengers_unite_name" class="avengers_unite_class" href="success_1.html">Avengers Unite</a></p>
17
+
18
+ <p><a href="success_1.html">Justice League Assemble</a></p>
19
+ <p><a href="success_2.html">Justice League Assemble</a></p>
20
+
21
+ <p><a id="oath" href="success_1.html">"...in the brightest day and in the darkest night..."</a></p>
22
+
23
+ <hr />
24
+
25
+ <h3>Lists</h3>
26
+
27
+ <h4>Unordered List</h4>
28
+
29
+ <ul id="ul_id" name="ul_name" class="ul_class">
30
+ <li id="li_id" name="li_name" class="li_class">Darth Nihilus</li>
31
+ <li>Darth Plagueis</li>
32
+ <li>Darth Sidious</li>
33
+ </ul>
34
+
35
+ <h4>Ordered List</h4>
36
+
37
+ <ol id="ol_id" name="ol_name" class="ol_class">
38
+ <li>USS Enterprise XCV 330</li>
39
+ <li>USS Enterprise NX-01</li>
40
+ <li>USS Enterprise NCC-1701</li>
41
+ </ol>
42
+
43
+ <hr />
44
+
45
+ <h3>Sections</h3>
46
+
47
+ <div id="div_id" name="div_name" class="div_class">
48
+ This text is stored directly inside a DIV element.
49
+ </div>
50
+
51
+ <span id="span_id" name="span_name" class="span_class">
52
+ This text is stored directly inside a SPAN element.
53
+ </span>
54
+
55
+ <hr />
56
+
57
+ <h3>Tables</h3>
58
+
59
+ <table id='table_id' name='table_name' class='table_class' border='1'>
60
+ <thead>
61
+ <tr>
62
+ <th>Month</th>
63
+ <th>Savings</th>
64
+ </tr>
65
+ </thead>
66
+ <tfoot>
67
+ <tr>
68
+ <td>Sum</td>
69
+ <td>$180</td>
70
+ </tr>
71
+ </tfoot>
72
+ <tbody>
73
+ <tr>
74
+ <td>January</td>
75
+ <td id='cell_id' name='cell_name' class='cell_class'>$100</td>
76
+ </tr>
77
+ <tr>
78
+ <td>February</td>
79
+ <td>$80</td>
80
+ </tr>
81
+ </tbody>
82
+ </table>
83
+
84
+ <hr />
85
+
86
+ <p>Technically an image isn't static text, but whatever ...</p>
87
+
88
+ <img src="images/mass_extinction.jpg" id="extinct" name="extinct" class="image_class">
89
+
90
+
91
+ </body>
92
+ </html>
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
2
+
3
+ require 'watir-webdriver'
4
+ require 'selenium-webdriver'
5
+
6
+ require "spectest"
7
+
8
+ module SpecTest
9
+ module Browser
10
+ @browser = false
11
+
12
+ def self.start
13
+ unless @browser
14
+ @browser = Watir::Browser.new(ENV['BROWSER']) if ENV['DRIVER'] == 'watir'
15
+ @browser = Selenium::WebDriver.for(ENV['BROWSER'].to_sym) if ENV['DRIVER'] == 'selenium'
16
+ end
17
+ return @browser
18
+ end
19
+
20
+ def self.stop
21
+ @browser.quit if @browser
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ Before do
2
+ @browser = SpecTest::Browser.start
3
+ end
4
+
5
+ After do |scenario|
6
+ # I don't believe the following line works at all because I don't think Cucumber
7
+ # (on Windows at least) actually runs the After logic unless a scenario is either
8
+ # failing or succeeding. I'll keep this line in until I can investigate further.
9
+ @KEEP_OPEN = true if scenario.status == :pending or scenario.status == :undefined
10
+ end
11
+
12
+ AfterConfiguration do |config|
13
+ puts("Tests are being executed from: #{config.feature_dirs}")
14
+ end
15
+
16
+ at_exit do
17
+ SpecTest::Browser.stop if not @KEEP_OPEN
18
+ end
@@ -0,0 +1,4 @@
1
+ class LandingPage
2
+ include SpecTest
3
+
4
+ end
@@ -0,0 +1,11 @@
1
+ Given /^I have gone to the test app site$/ do
2
+ @page = LandingPage.new(@browser)
3
+ @page.navigate_to("http://localhost:1234")
4
+ end
5
+
6
+ Then /^I should be on the landing page$/ do
7
+ #@page.text.should match(/^Landing Page$/)
8
+ #@page.title.should match(/^Test App$/)
9
+ @page.text.should contain("Landing Page")
10
+ @page.title.should have_title("Test App")
11
+ end
@@ -0,0 +1,9 @@
1
+ Feature: Ability to support page viewing.
2
+
3
+ As a test writer,
4
+ I need the ability to get to pages
5
+ so that I can actually do some testing.
6
+
7
+ Scenario: Navigating to a page.
8
+ Given I have gone to the test app site
9
+ Then I should be on the landing page
@@ -26,4 +26,5 @@ Gem::Specification.new do |s|
26
26
 
27
27
  s.add_development_dependency 'rspec', '>= 2.7.0'
28
28
  s.add_development_dependency 'cucumber', '>= 1.1.2'
29
+ s.add_development_dependency 'simplecov', '>= 0.5.4'
29
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-12 00:00:00.000000000Z
12
+ date: 2011-11-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: watir-webdriver
16
- requirement: &2229264 !ruby/object:Gem::Requirement
16
+ requirement: &4716876 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.3.9
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2229264
24
+ version_requirements: *4716876
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: selenium-webdriver
27
- requirement: &2227284 !ruby/object:Gem::Requirement
27
+ requirement: &4715880 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.12.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2227284
35
+ version_requirements: *4715880
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &2226504 !ruby/object:Gem::Requirement
38
+ requirement: &4715268 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.7.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2226504
46
+ version_requirements: *4715268
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: cucumber
49
- requirement: &2225508 !ruby/object:Gem::Requirement
49
+ requirement: &4714728 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: 1.1.2
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2225508
57
+ version_requirements: *4714728
58
+ - !ruby/object:Gem::Dependency
59
+ name: simplecov
60
+ requirement: &4714200 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 0.5.4
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *4714200
58
69
  description: Test framework for specifying tests and executing tests.
59
70
  email:
60
71
  - jeffnyman@gmail.com
@@ -63,13 +74,49 @@ extensions: []
63
74
  extra_rdoc_files: []
64
75
  files:
65
76
  - .gitignore
77
+ - .travis.yml
66
78
  - Gemfile
67
79
  - HISTORY.md
68
80
  - LICENSE
69
81
  - README.md
70
82
  - Rakefile
83
+ - cucumber.yml
71
84
  - lib/spectest.rb
85
+ - lib/spectest/logger.rb
86
+ - lib/spectest/matchers.rb
87
+ - lib/spectest/platform_selenium.rb
88
+ - lib/spectest/platform_selenium/platform_object.rb
89
+ - lib/spectest/platform_watir.rb
90
+ - lib/spectest/platform_watir/platform_object.rb
91
+ - lib/spectest/platforms.rb
72
92
  - lib/spectest/version.rb
93
+ - spec/browser_level_spec.rb
94
+ - spec/page_level_spec.rb
95
+ - spec/platform_object_spec.rb
96
+ - spec/platform_selenium_spec.rb
97
+ - spec/platform_watir_spec.rb
98
+ - spec/platforms_spec.rb
99
+ - spec/spec_helper.rb
100
+ - spec/spectest_spec.rb
101
+ - specs/app/favicon.ico
102
+ - specs/app/images/mass_extinction.jpg
103
+ - specs/app/index.html
104
+ - specs/app/modal_1.html
105
+ - specs/app/modal_2.html
106
+ - specs/app/server.rb
107
+ - specs/app/style.css
108
+ - specs/app/success_1.html
109
+ - specs/app/success_2.html
110
+ - specs/app/test_event.html
111
+ - specs/app/test_form.html
112
+ - specs/app/test_frame.html
113
+ - specs/app/test_iframe.html
114
+ - specs/app/test_static.html
115
+ - specs/engine/borg.rb
116
+ - specs/engine/hooks.rb
117
+ - specs/pages/landing_page.rb
118
+ - specs/steps/page_steps.rb
119
+ - specs/tests/page.feature
73
120
  - spectest.gemspec
74
121
  homepage: https://github.com/jnyman/spectest
75
122
  licenses: