wsl 0.1.4

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.
@@ -0,0 +1,18 @@
1
+ examples/ClickExample.rb
2
+ examples/DemoExample.rb
3
+ examples/DemoTestSuite.rb
4
+ examples/GoogleSearchExample_WSL.rb
5
+ examples/SelectExample.rb
6
+ examples/SuiteCleanup.rb
7
+ examples/SuiteStartup.rb
8
+ lib/IEContext.rb
9
+ lib/utils/Logger.rb
10
+ lib/utils/TestSuiteCleanup.rb
11
+ lib/utils/TestSuiteStartup.rb
12
+ lib/wsl.rb
13
+ lib/wslPrivate.rb
14
+ lib/wslSuite.rb
15
+ Manifest
16
+ Rakefile
17
+ README.txt
18
+ wsl.gemspec
@@ -0,0 +1,18 @@
1
+ This is the WSL gem. Currently there is no licence associated with it, and the source is not open source yet.
2
+
3
+ Legal mumbo-jumbo disclaimer (just to cover my ass) -
4
+ The software is provided as is, and there is no guarantee of its suitability for a particular task.
5
+ You use it at your own risk, and the creator(s) of the software accept no liability whatsoever.
6
+
7
+ Go to http;//wsl.xqoob.com for more details.
8
+
9
+ NOTE: if after installing WSL you get the following error -
10
+ "C:/Ruby/lib/ruby/gems/1.8/gems/windows-pr-0.9.3/lib/windows/thread.rb:59:
11
+ uninitialized constant Windows::API::Error (NameError)"
12
+ run these commands-
13
+ $> Gem uninstall windows-pr
14
+ $> Gem install windows-pr
15
+ See http://groups.google.com/group/watir-general/browse_thread/thread/3f6741eccf0cb7b8 for more details.
16
+
17
+ 30-apr-2009
18
+ Wadud Ruf
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ spec = Echoe.new('wsl', '0.1.4') do |s|
6
+ s.platform = Gem::Platform::RUBY
7
+ s.author = "Wadud Ruf"
8
+ s.email = "wadud.ruf@xqoob.com"
9
+ s.summary = "WSL (WATiR Scripting Language) is a DSL built on top of WATiR that allows for the automation of web application testing through Internet Explorer."
10
+ s.files = FileList['lib/*.rb', 'lib/utils/*.rb', 'lib/utils/cache/', 'test/*', 'examples/*'].to_a
11
+ s.runtime_dependencies = ["watir >=1.6.2"]
12
+ s.url = "http://wsl.xqoob.com"
13
+ s.project = "wsl"
14
+ s.need_tar_gz = false
15
+ end
@@ -0,0 +1,37 @@
1
+ require "wsl" # You require this file for all the WSL keywords.
2
+
3
+ # You start all test scripts by specifying a name for it.
4
+ start "Click Keyword Example"
5
+
6
+ rem "This example will show you how to use the 'click' keyword by searching for a stock quote through yahoo."
7
+
8
+ open_url "http://www.yahoo.co.uk"
9
+
10
+ rem "We will get a quote for the google (goog) share price."
11
+ enter_text_in "Enter ticker symbol", ":title", "goog"
12
+
13
+ rem "We need to click the go button to look up the share price."
14
+ click "quote-submit"
15
+
16
+ rem "We need to do a test to ensure it has worked properly."
17
+ assert_text "NasdaqGS: GOOG", "Exists on screen for Google stock quote lookup."
18
+
19
+ rem "Go back a page."
20
+ back
21
+
22
+ rem "This time we'll use the text of the button with the 'click' keyword (it is case sensitive)."
23
+ click "Go", ":value"
24
+
25
+ rem "Re-assert that it has worked."
26
+ assert_text "NasdaqGS: GOOG", "Exists on screen for Google stock quote lookup."
27
+
28
+ rem "Let's click something other than a button and asset it has worked ok."
29
+ click "Google Inc. (GOOG)", ":alt"
30
+ assert_all_text ["Basic Chart", "Full Screen", "Print", "Share", "Send Feedback"]
31
+
32
+ rem "Finally let's click a link to go back to the summary page."
33
+ click "/q?s=GOOG", ":href"
34
+
35
+ rem "Finish all test scripts using the 'finish' keyword.
36
+ This closes the browser and outputs a test summary of passed and failed tests in the script."
37
+ finish
@@ -0,0 +1,41 @@
1
+ require "wsl"
2
+
3
+ #-------------------------------------------------------------#
4
+ # Demo test for the WSL.
5
+ #
6
+ # Purpose: to demonstrate the following Watir functionality:
7
+ # * entering text into a text field,
8
+ # * clicking a button,
9
+ # * checking to see if a page contains text.
10
+ # Test will search Google for the "pickaxe" Ruby book and buy
11
+ # from amazon.
12
+ #-------------------------------------------------------------#
13
+
14
+ # open a browser
15
+ start "Google Search Test"
16
+
17
+ # print some comments
18
+ rem "Beginning of test: Google search."
19
+
20
+ open_url "http://www.google.com"
21
+
22
+ rem "Enter 'pickaxe' in the search text field."
23
+ enter_text_in "Google Search", ":title", "pickaxe book"
24
+
25
+ rem "Click the 'Google Search' button."
26
+ click "Google Search", ":value"
27
+
28
+ assert_text "Programming Ruby: The Pragmatic Programmer's", "is shown high on the list."
29
+
30
+ rem "Lets buy the book!"
31
+ click "http://www.amazon.co.uk/Programming-Ruby-Pragmatic-Programmers-Second/dp/0974514055", ":href"
32
+
33
+ assert_url "http://www.amazon.co.uk/Programming-Ruby-Pragmatic-Programmers-Second/dp/0974514055", "is the current page."
34
+
35
+ rem "Lets buy 10 copies."
36
+ select "quantity", ":id", "10"
37
+ click "Add to Shopping Basket", ":alt"
38
+ click "Proceed to Checkout", ":alt"
39
+
40
+ assert_text "Enter your e-mail address:", "exists on screen for the sign in page."
41
+ finish
@@ -0,0 +1,18 @@
1
+ #-------------------------------------------------------------#
2
+ # This script declares a suite of tests that are to be run sequentially.
3
+ # Before the tests are run a startup script is run, and after a cleanup script.
4
+ #
5
+ #-------------------------------------------------------------#
6
+
7
+ require "wslSuite"
8
+
9
+ # The startup script.
10
+ startup_script "SuiteStartup"
11
+
12
+ # The test suite.
13
+ test_suite "DemoExample",
14
+ "ClickExample",
15
+ "SelectExample"
16
+
17
+ # The cleanup script.
18
+ cleanup_script "SuiteCleanup"
@@ -0,0 +1,19 @@
1
+ #-------------------------------------------------------------#
2
+ # Demo test for the Watir controller.
3
+ #
4
+ # Purpose: to demonstrate the following WSL functionality:
5
+ # * entering text into a text field,
6
+ # * clicking a button,
7
+ # * checking to see if a page contains text.
8
+ # Test will search Google for the "pickaxe" Ruby book.
9
+ #-------------------------------------------------------------#
10
+
11
+ require "wsl"
12
+
13
+ start "Google Search Test"
14
+ open_url "http://www.google.com"
15
+ enter_text_in "Google Search", ":title", "pickaxe book"
16
+ click "Google Search", ":value"
17
+ assert_text "The Pragmatic Bookshelf | Programming Ruby", "is shown high on the list."
18
+
19
+ finish
@@ -0,0 +1,50 @@
1
+ require "wsl" # You require this file for all the WSL keywords.
2
+
3
+ # You start all test scripts by specifying a name for it.
4
+ start "Select Keyword Example"
5
+
6
+ rem "This example will show you how to use the 'select' keyword by searching for some train times."
7
+
8
+ open_url "http://www.thetrainline.com"
9
+
10
+ enter_text_in "fromfield", ":id", "Bristol temple meads"
11
+ enter_text_in "tofield", ":id", "glasgow"
12
+
13
+ rem "Enter our departure date as tomorrow."
14
+ click "Tomorrow", ":text"
15
+
16
+ rem "Lets set our departure time as 11:15am."
17
+ select "ttl-e842cbdc-2bda-4ad4-bb17-1c6ddad60de1", ":id", "11"
18
+ select "outMinuteField", ":name", "15"
19
+
20
+ rem "and I want it to be one-way"
21
+ select "outonly"
22
+
23
+ rem "actually I change my mind and want to make it an open return for the next day."
24
+ select "outonly", ":id", false
25
+ click "Next Day", ":text"
26
+
27
+ rem "Let's get the train times."
28
+ click "Get times & tickets", ":value"
29
+
30
+ rem "Test to see that we have successfully performed a search."
31
+ assert_text "Bristol Temple Meads to Glasgow", "exists on screen for a successful search."
32
+
33
+ rem "Ensure we have selected the return ticket option."
34
+ select "ttl-4b048d62-93a1-4408-b4b5-28159e1f8de7", ":id", "Return"
35
+
36
+ rem "And the correct railcard"
37
+ select "ttl-6c1cba59-9ffd-4a5c-a188-2234b04a2419", ":id", "16-25 RAILCARD"
38
+
39
+ click "Advanced Options >>", ":text"
40
+ select "ttl-e8d8a9b9-5c78-44d1-9635-98e5c0203339"
41
+ enter_text_in "ttl-cfa9a1a7-e970-4f98-ac90-8e7dc35ff759", ":id", "MANCHESTER PICCADILLY"
42
+
43
+ click "CHECK_AVAILABILITY", ":name"
44
+
45
+ rem "Test for the success of the availability search."
46
+ assert_text "Tickets /", "Exists on screen for a successful search."
47
+
48
+ rem "Finish all test scripts using the 'finish' keyword.
49
+ This closes the browser and outputs a test summary of passed and failed tests in the script."
50
+ finish
@@ -0,0 +1,9 @@
1
+ # You must call the TestSuiteCleanup script.
2
+ require "utils/TestSuiteCleanup"
3
+ require "wsl"
4
+
5
+ # Do any additonal cleanup activities here.
6
+
7
+
8
+ # Finished cleanup.
9
+ rem "Cleanup activities completed."
@@ -0,0 +1,9 @@
1
+ # You must call the TestSuiteStartup script.
2
+ require "utils/TestSuiteStartup"
3
+ require "wsl"
4
+
5
+ # Do any additonal startup activities.
6
+
7
+
8
+ # Finished startup.
9
+ rem "Startup activities completed."
@@ -0,0 +1,73 @@
1
+ require "watir"
2
+ require "watir/watir_simple"
3
+ require "utils/Logger"
4
+
5
+
6
+ class BrowserContext
7
+ include Watir::Simple
8
+ include Watir
9
+ include Test::Unit::Assertions
10
+
11
+ attr_accessor :testName
12
+ attr_reader :logger # Readonly access to logger.
13
+
14
+ ##
15
+ # Initialises a new BrowserContext object.
16
+ # Essentially this is inherits from Watir.Simple,
17
+ # and uses it's class variable '@@browser'.
18
+ #
19
+ # testName: The name you want to give the test.
20
+ # logFile: The file you want to log to. Defaults to
21
+ # a log file with the same name as the script in the logs directory.
22
+ #
23
+ def initialize(testName=nil, logFile=nil)
24
+ # Set the test name.
25
+ @testName = testName
26
+
27
+ # Put the log file in the logs directory.
28
+ if logFile == nil then
29
+ logFile = $0.to_s.split("/")[-1].chomp(".rb") + ".log"
30
+ end
31
+
32
+ logFile = "logs/" + logFile
33
+
34
+ # Create the logger.
35
+ @logger = Wsl::CustomLogger.new(logFile)
36
+
37
+ # Output name if passed in.
38
+ @logger.logTestName(testName) if testName != nil
39
+ end
40
+
41
+ ##
42
+ # Returns the browser url.
43
+ #
44
+ def currentUrl
45
+ if defined? @@browser then
46
+ return @@browser.url()
47
+ else
48
+ return ""
49
+ end
50
+ end
51
+
52
+ ##
53
+ # Provides access to the browser class variable.
54
+ #
55
+ def browser
56
+ return @@browser
57
+ end
58
+
59
+ ##
60
+ # Attaches to a titled browser window.
61
+ #
62
+ def attach(windowTitle)
63
+ @@browser = Watir::IE.attach(:title, windowTitle)
64
+ end
65
+
66
+ ##
67
+ # The tags which are valid within the browser context.
68
+ # Note: Ordering of the tags is important.
69
+ #
70
+ def tagsInContext()
71
+ %w[button link image div span text_field checkbox radio select_list]
72
+ end
73
+ end
@@ -0,0 +1,311 @@
1
+
2
+ #-------------------------------------------------------------#
3
+ # Summary: Lightweight logger implementation.
4
+ #
5
+ # Purpose: To allow logging of messages to console and file.
6
+ # It is anticipated that the logging mechanism will evolve
7
+ # in general so having a logger class that implements the
8
+ # standard logger is the best way to go.
9
+ # Pre-con: Ensure log file directory exists.
10
+ # Post-con: None.
11
+ #-------------------------------------------------------------#
12
+
13
+ require "log4r"
14
+ require "log4r/formatter/patternformatter"
15
+
16
+ module Wsl
17
+ class CustomLogger
18
+
19
+ # Class constant cannot be accessed outside of class.
20
+ @@HEADER = "======"
21
+ @@localCacheFile = ".\\logs\\.cache\\TestSummary.dat"
22
+
23
+ # Static methods to get log level (cannot assign to these).
24
+ # Within class, but outside of method, use 'self.debug' to call.
25
+ # within method use 'CustomLogger.debug' to call.
26
+ def self.debug; "debug"; end
27
+ def self.info; "info"; end
28
+ def self.warn; "warn"; end
29
+ def self.error; "error"; end
30
+ def self.fatal; "fatal"; end
31
+
32
+ # Actual results constants.
33
+ def self.pass; "PASS"; end
34
+ def self.fail; "FAIL"; end
35
+
36
+ attr_reader :passedTests, :failedTests
37
+
38
+ ##
39
+ # Constructor logs to file as well
40
+ # as screen if specified.
41
+ #
42
+ # logFile: path to log file.
43
+ #
44
+ def initialize(logFile)
45
+ # Initialise instance counters.
46
+ @step = 1
47
+ @passedTests = 0
48
+ @failedTests = 0
49
+ @logFile = logFile
50
+
51
+ # Create the log dir and cache dir structure.
52
+ createDirs()
53
+ end
54
+
55
+ ##
56
+ # Logs the name of the test.
57
+ #
58
+ def logTestName(testName)
59
+ @testName = testName
60
+ # logEntry(CustomLogger.info, "")
61
+ logEntry(CustomLogger.info, @@HEADER + " Started Test: " + @testName + " " + @@HEADER)
62
+ end
63
+
64
+ ##
65
+ # Logs a test step.
66
+ #
67
+ def logStep(description)
68
+ logEntry(CustomLogger.info, " Step " + @step.to_s + ": " + description)
69
+ @step += 1
70
+ end
71
+
72
+ ##
73
+ # Logs a test comment.
74
+ #
75
+ def logComment(description)
76
+ logEntry(CustomLogger.info, ">" + description)
77
+ end
78
+
79
+ ##
80
+ # Logs the expected results.
81
+ #
82
+ def logExpectedResult(expectedResults)
83
+ logEntry(CustomLogger.info, "")
84
+ logEntry(CustomLogger.info, " Expected Result:")
85
+ logEntry(CustomLogger.info, " " + expectedResults)
86
+ end
87
+
88
+ ##
89
+ # Resets the logger by doing the following -
90
+ # Step counter starts from 1 again.
91
+ #
92
+ def reset
93
+ @step = 1
94
+ end
95
+
96
+ ##
97
+ # Logs the actual results.
98
+ #
99
+ def logActualResult(passOrFail, message)
100
+ logEntry(CustomLogger.info, " Actual Result:")
101
+ logEntry(CustomLogger.info, " " + passOrFail + ": " + message)
102
+ logEntry(CustomLogger.info, "")
103
+
104
+ if passOrFail == CustomLogger.pass then
105
+ @passedTests += 1
106
+ else
107
+ @failedTests += 1
108
+ end
109
+ end
110
+
111
+ ##
112
+ # Logs an exception.
113
+ #
114
+ # exception: The exception to log.
115
+ #
116
+ def logException(exception)
117
+ logEntry(CustomLogger.error, " FAIL WITH EXCEPTION: " + exception.message + "\n" +
118
+ exception.backtrace.join("\n"))
119
+
120
+ @failedTests += 1
121
+ end
122
+
123
+ def logEndTest()
124
+ logEntry(CustomLogger.info, @@HEADER + " Finished Test: " + @testName + " " + @@HEADER)
125
+ end
126
+
127
+ ##
128
+ # Prints a summary of passed and failed tests for
129
+ # a script.
130
+ #
131
+ def summary
132
+ logEntry(CustomLogger.info, "")
133
+ logEntry(CustomLogger.info, "Test Summary:")
134
+ logEntry(CustomLogger.info, " Passed Tests: " + @passedTests.to_s)
135
+ logEntry(CustomLogger.info, " Failed Tests: " + @failedTests.to_s)
136
+ logEntry(CustomLogger.info, "")
137
+
138
+ file = File.open(@@localCacheFile, "a")
139
+ file.puts("Passed:" + @passedTests.to_s + "\tFailed:" + @failedTests.to_s + "\t" + @testName)
140
+ file.close
141
+ end
142
+
143
+ ##
144
+ # Prints a summary of the total passed and failed tests for
145
+ # all scripts in a run.
146
+ #
147
+ def totalSummary
148
+
149
+ # Ensure cache file exists first.
150
+ if !File.exist?(@@localCacheFile) then
151
+ return
152
+ end
153
+
154
+ # Output the total summary to logger.
155
+
156
+ logEntry(CustomLogger.info, "+-------------------------------------------------------------------------------+")
157
+ logEntry(CustomLogger.info, " Total Test Summary:")
158
+
159
+ lines = IO.readlines(@@localCacheFile)
160
+ lines.each do |line|
161
+ if line != nil then
162
+ logEntry(CustomLogger.info, " " + line.chomp)
163
+ end
164
+ end
165
+
166
+ logEntry(CustomLogger.info, "+-------------------------------------------------------------------------------+")
167
+
168
+ # Delete the file.
169
+ clearCache
170
+ end
171
+
172
+ ##
173
+ # Clears the cache with the results of any old tests that have run.
174
+ #
175
+ def clearCache
176
+ # Delete the file.
177
+ if File.exist?(@@localCacheFile) then
178
+ File.delete(@@localCacheFile)
179
+ end
180
+ end
181
+
182
+ ##
183
+ # Logs an entry to the log.
184
+ #
185
+ # entry: What to log
186
+ #
187
+ def log(entry)
188
+ logEntry(CustomLogger.info, entry)
189
+ end
190
+
191
+ ##
192
+ # Initialises a logger with the standard WSL logger settings
193
+ # and returns it.
194
+ #
195
+ def self.initializeSuiteLogger(logFile)
196
+ CustomLogger.initializeLogger(logFile)
197
+ end
198
+
199
+ ##
200
+ # Private method from here onwards.
201
+ #
202
+ private
203
+
204
+ def logEntry(level, entry)
205
+ # Initialise the logger if it is not already defined.
206
+ if ! defined? $logger then
207
+ CustomLogger.initializeLogger(@logFile)
208
+ end
209
+
210
+ # Log to file at correct level.
211
+ if level == CustomLogger.debug then
212
+ $logger.debug(entry)
213
+ elsif level == CustomLogger.info then
214
+ $logger.info(entry)
215
+ elsif level == CustomLogger.warn then
216
+ $logger.warn(entry)
217
+ elsif level == CustomLogger.error then
218
+ $logger.error(entry)
219
+ elsif level == CustomLogger.fatal then
220
+ $logger.fatal(entry)
221
+ end
222
+ end
223
+
224
+ ##
225
+ # Creates the directories required by the logger class to
226
+ # output the log files to.
227
+ #
228
+ def createDirs()
229
+ if(@logFile == nil) then
230
+ return
231
+ end
232
+
233
+ tmp = ""
234
+ elems = @logFile.split("/")
235
+ elems.length.times do |elem|
236
+ # If it's the current dir '.' skip it.
237
+ if elems[elem] == "." then
238
+ next
239
+ elsif elem == (elems.length - 1) then
240
+ # Create the .cache directory in the leaf dir.
241
+ if File.exist?(tmp + ".cache") == false then
242
+ FileUtils.mkdir(tmp + ".cache")
243
+ end
244
+ next
245
+ end
246
+
247
+ # Aggregate the files.
248
+ tmp += elems[elem] + "/"
249
+
250
+ # If subdir doesn't exist create it.
251
+ if File.exist?(tmp) == false then
252
+ FileUtils.mkdir(tmp)
253
+ end
254
+ end
255
+ end
256
+
257
+ ##
258
+ # Static method that initialises a Log4r logger instance
259
+ # with default values.
260
+ #
261
+ # logFile: The name of the log file.
262
+ #
263
+ def self.initializeLogger(logFile)
264
+ Log4r::Logger.root.level = Log4r::INFO
265
+ $logger = Log4r::Logger.new("WSL")
266
+
267
+ consoleFormat = Log4r::PatternFormatter.new(:pattern => "%.2000m")
268
+ fileFormat = Log4r::PatternFormatter.new(:pattern => "[%d] [%l] : %.2000m")
269
+
270
+ # Create an outputter for $stderr. It defaults to the root level
271
+ stdOutputter = Log4r::StderrOutputter.new('console', :formatter => consoleFormat)
272
+
273
+ # for the file, we want to log only INFO, FATAL and ERROR and don't trunc
274
+ fileOutputter = Log4r::FileOutputter.new('logfile', :filename=>logFile,
275
+ :trunc=>true, :level=>Log4r::INFO,
276
+ :formatter => fileFormat)
277
+
278
+ # add the outputters (this method accepts outputter names or references)
279
+ $logger.add('console','logfile')
280
+ end
281
+ end
282
+ end
283
+
284
+ # ===================================
285
+ # test methods - comment when released!
286
+ # =====================================
287
+ # log = Wsl::CustomLogger.new(".\\test\\test2\\testfile.log")
288
+ # log = Wsl::CustomLogger.new
289
+ # log.logStep "test step 1"
290
+ # log.logStep "test step 2"
291
+ # log.logStep "test step 3"
292
+
293
+ # log = Wsl::CustomLogger.new("testfile.log")
294
+ # log.logStep "Step 1"
295
+ # log.logStep "Step 2"
296
+ # log.logStep "Step 3"
297
+ # log.logStep "Step 4"
298
+ # log.logStep "Step 5"
299
+ # log.logStep "Step 6"
300
+ # log.logStep "Step 7"
301
+ # log.logStep "Step 8"
302
+ # log.logStep "Step 9"
303
+ # log.logStep "Step 10"
304
+
305
+ # puts Wsl::CustomLogger::Fail # Access class constant
306
+ # puts Wsl::CustomLogger::Fail = "unknown" # Get warning cannot assign to constant more than once.
307
+ # puts Wsl::CustomLogger::Pass
308
+ # puts log.logTestName("something")
309
+ # puts Wsl::CustomLogger::HEADER = "$$$$"
310
+ # puts Wsl::CustomLogger::info
311
+ # log.logEndTest "something"