sapphire 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/sapphire CHANGED
@@ -3,24 +3,24 @@ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
3
3
  require 'sapphire'
4
4
  include Sapphire::Sapphire
5
5
 
6
- reporter = ConsoleReporter.new()
6
+ reporter = TeamCityReporter.new()
7
7
 
8
8
  ARGV.each do |arg|
9
9
  if !arg.end_with? ".rb"
10
10
  next
11
11
  end
12
12
  require arg
13
- Runner.instance.last_scenario.file_name = arg
13
+ Runner.instance.last_scenario.file_name = arg if Runner.instance.last_scenario and Runner.instance.last_scenario.file_name == ""
14
14
  end
15
15
 
16
+ reporter.BeginTesting
17
+
16
18
  if Runner.instance.test_plans.count > 0
17
- Runner.instance.last_test_plan.execute reporter
19
+ Runner.instance.last_test_plan.execute
18
20
  else
19
21
  Runner.instance.scenarios.each do |scenario|
20
22
  scenario.execute reporter
21
23
  end
22
24
  end
23
25
 
24
-
25
-
26
26
  reporter.OutputResults
data/lib/sapphire.rb CHANGED
@@ -11,6 +11,7 @@ require 'colorize'
11
11
  require File.expand_path(File.dirname(__FILE__) +'/sapphire/Strategies/Strategy.rb', __FILE__)
12
12
  require File.expand_path(File.dirname(__FILE__) +'/sapphire/Testing/Reporter.rb', __FILE__)
13
13
  Dir[File.dirname(__FILE__) + '/sapphire/Testing/*.rb'].each {|file| require file }
14
+ Dir[File.dirname(__FILE__) + '/sapphire/TeamCity/*.rb'].each {|file| require file }
14
15
  Dir[File.dirname(__FILE__) + '/sapphire/Configuration/*.rb'].each {|file| require file }
15
16
  Dir[File.dirname(__FILE__) + '/sapphire/WebAbstractions/Controls/Base/*.rb'].each {|file| require file }
16
17
  Dir[File.dirname(__FILE__) + '/sapphire/WebAbstractions/Controls/*.rb'].each {|file| require file }
@@ -22,6 +23,7 @@ Dir[File.dirname(__FILE__) + '/sapphire/DSL/Configuration/*.rb'].each {|file| re
22
23
  Dir[File.dirname(__FILE__) + '/sapphire/DSL/Data/*.rb'].each {|file| require file }
23
24
  Dir[File.dirname(__FILE__) + '/sapphire/DSL/Scenarios/*.rb'].each {|file| require file }
24
25
  Dir[File.dirname(__FILE__) + '/sapphire/DSL/TestPlans/*.rb'].each {|file| require file }
26
+ Dir[File.dirname(__FILE__) + '/sapphire/UI/*.rb'].each {|file| require file }
25
27
 
26
28
  module Sapphire
27
29
  module Sapphire
@@ -37,5 +39,7 @@ module Sapphire
37
39
  include JobAbstractions
38
40
  include WebAbstractions
39
41
  include Testing
42
+ include Testing::TeamCity
43
+ include UI
40
44
  end
41
45
  end
@@ -0,0 +1,15 @@
1
+ module Sapphire
2
+ module DSL
3
+ module Browser
4
+ def Virtually(&block)
5
+ ui = VirtualUI.new
6
+ begin
7
+ ui.Create()
8
+ block.call
9
+ ensure
10
+ ui.Close()
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,6 +6,7 @@ class Background
6
6
  attr_reader :block
7
7
  attr_reader :parent
8
8
  attr_reader :results
9
+ attr_reader :and
9
10
 
10
11
  def initialize(parent, pre, text, &block)
11
12
  @block = block
@@ -13,6 +14,7 @@ class Background
13
14
  @text = pre + text.to_s
14
15
  @parent = parent
15
16
  @results = []
17
+ @and = []
16
18
  end
17
19
 
18
20
  def AddResult(result)
@@ -21,4 +23,12 @@ class Background
21
23
  self.parent.result.AddChild(result)
22
24
  end
23
25
 
26
+ def add_and(pre, text, &block)
27
+ if(self.value.is_a? Pending)
28
+ self.and << And.new(self, Pending.new(pre + text), &block)
29
+ else
30
+ self.and << And.new(self, pre + text, &block)
31
+ end
32
+ end
33
+
24
34
  end
@@ -20,7 +20,7 @@ module Sapphire
20
20
  def And(text, &block)
21
21
 
22
22
  if(Runner.instance.last_scenario.last_given == nil && Runner.instance.last_scenario.last_background != nil)
23
- Runner.instance.last_scenario.add_background(Background.new(Runner.instance.last_scenario, "And ", text, &block))
23
+ Runner.instance.last_scenario.last_background.add_and("And ", text, &block)
24
24
  return
25
25
  end
26
26
 
@@ -51,7 +51,6 @@ module Sapphire
51
51
  def Scenario(text, &block)
52
52
  Runner.instance.add_scenario(Scenario.new(text, &block))
53
53
  Runner.instance.last_scenario.block.call
54
- #Runner.instance.last_scenario.execute 1
55
54
  end
56
55
  end
57
56
  end
@@ -19,6 +19,7 @@ module Sapphire
19
19
  @givens = []
20
20
  @backgrounds = []
21
21
  @result = Testing::ScenarioResult.new(text)
22
+ @file_name = ""
22
23
  end
23
24
 
24
25
  def add_given(given)
@@ -19,10 +19,10 @@ class Then
19
19
 
20
20
  def add_and(pre, text, &block)
21
21
  if(!self.value.instance_of? Pending)
22
- x = Then.new(self, pre, text, &block)
22
+ x = And.new(self, pre + text, &block)
23
23
  self.and << x
24
24
  else
25
- self.and << Then.new(self, pre, Pending.new(pre + text), &block)
25
+ self.and << And.new(self, Pending.new(pre + text), &block)
26
26
  end
27
27
  end
28
28
 
@@ -3,9 +3,8 @@ module Sapphire
3
3
  module TestPlans
4
4
 
5
5
  def TestPlan(text, &block)
6
- reporter = ConsoleReporter.new()
7
- Runner.instance.add_test_plan(TestPlan.new(text, &block))
8
- Runner.instance.last_test_plan.execute reporter
6
+ reporter = TeamCityReporter.new()
7
+ Runner.instance.add_test_plan(TestPlan.new(text, reporter, &block))
9
8
  end
10
9
 
11
10
  class TestPlan
@@ -14,10 +13,11 @@ module Sapphire
14
13
  attr_reader :value
15
14
  attr_reader :text
16
15
 
17
- def initialize(text, &block)
16
+ def initialize(text, reporter, &block)
18
17
  @value = text
19
18
  @text = text.to_s
20
19
  @block = block
20
+ @reporter = reporter
21
21
 
22
22
  @items = []
23
23
  @handlers = []
@@ -36,7 +36,7 @@ module Sapphire
36
36
  @handlers.each do |handler|
37
37
  handler.keys.each do |handler_key|
38
38
  if(handler_key == key)
39
- handler[handler_key].Handle item[key]
39
+ handler[handler_key].Handle item[key], @reporter
40
40
  end
41
41
  end
42
42
  end
@@ -47,10 +47,11 @@ module Sapphire
47
47
  @handlers << handler
48
48
  end
49
49
 
50
- def execute(reporter)
50
+ def execute
51
+ @reporter.BeginTesting
51
52
  $stdout.puts ""
52
53
  @block.call
53
- reporter.OutputResults
54
+ @reporter.OutputResults
54
55
  end
55
56
  end
56
57
  end
@@ -2,7 +2,7 @@ require 'teamcity/utils/logger_util'
2
2
  require 'teamcity/rake_exceptions'
3
3
  require 'teamcity/rakerunner_consts'
4
4
 
5
- SPEC_FORMATTER_LOG = ::Rake::TeamCity::Utils::RSpecFileLogger.new
5
+ SPEC_FORMATTER_LOG = ::Rake::TeamCity::Utils::RakeFileLogger.new
6
6
  SPEC_FORMATTER_LOG.log_msg("spec formatter.rb loaded.")
7
7
 
8
8
  require 'teamcity/runner_common'
@@ -50,13 +50,13 @@ module Sapphire
50
50
  # Initializes
51
51
  @groups_stack = []
52
52
 
53
- @example_count = 100
54
53
  if ::Rake::TeamCity.is_in_idea_mode
55
- log(@message_factory.create_tests_count(@example_count))
54
+ #log(@message_factory.create_tests_count(@example_count))
56
55
  elsif ::Rake::TeamCity.is_in_buildserver_mode
57
- log(@message_factory.create_progress_message("Starting.. (#{@example_count} examples)"))
56
+ log(@message_factory.create_progress_message("Starting..."))
58
57
  end
59
58
 
59
+ @current = 0
60
60
  end
61
61
 
62
62
  def PrintItem(result, depth)
@@ -64,11 +64,13 @@ module Sapphire
64
64
  end
65
65
 
66
66
  def ScenarioStart(scenario)
67
- @message_factory.create_suite_started(scenario.text, scenario.file_name)
67
+ log(@message_factory.create_suite_started("Scenario: " + scenario.text))
68
68
  end
69
69
 
70
70
  def ScenarioComplete(scenario)
71
- @message_factory.create_suite_finished(scenario.text)
71
+ log(@message_factory.create_suite_finished("Finally"))
72
+ log(@message_factory.create_suite_finished("Assuming"))
73
+ log(@message_factory.create_suite_finished("Scenario: " + scenario.text))
72
74
  end
73
75
 
74
76
  def PrintHeader()
@@ -92,25 +94,65 @@ module Sapphire
92
94
  end
93
95
 
94
96
  def TestStarted(test)
95
- @@RUNNING_EXAMPLES_STORAGE[test.object_id] = test
97
+
98
+ if test.is_a? Given and @current > 0
99
+ log(@message_factory.create_suite_finished("Then"))
100
+ log(@message_factory.create_suite_finished("When"))
101
+ log(@message_factory.create_suite_finished("Given"))
102
+ elsif test.is_a? Finally
103
+ log(@message_factory.create_suite_finished("Then"))
104
+ log(@message_factory.create_suite_finished("When"))
105
+ log(@message_factory.create_suite_finished("Given"))
106
+ end
107
+
108
+ @current = 1
109
+
110
+ if test.is_a? Given
111
+ log(@message_factory.create_suite_started("Given"))
112
+ elsif test.is_a? When
113
+ log(@message_factory.create_suite_started("When"))
114
+ elsif test.is_a? Then
115
+ log(@message_factory.create_suite_started("Then"))
116
+ elsif test.is_a? Background
117
+ log(@message_factory.create_suite_started("Assuming"))
118
+ elsif test.is_a? Finally
119
+ log(@message_factory.create_suite_started("Finally"))
120
+ end
121
+
122
+ @current = @current + 1
123
+
124
+ log(@message_factory.create_test_started(test.text))
96
125
  end
97
126
 
98
127
  def TestCompleted(test)
99
128
  if test.type == "pending"
100
- @message_factory.create_test_output_message(test.text, true, "Pending: Not Yet Implemented")
101
- @message_factory.create_test_ignored(test.text, "Pending: Not Yet Implemented")
102
- return
129
+ log(@message_factory.create_test_ignored(test.text, "Pending: Not Yet Implemented"))
130
+ elsif test.type == "pass"
131
+ log(@message_factory.create_test_finished(test.text, test.time))
132
+ elsif test.type == "fail"
133
+
134
+ if test.messages.is_a? Array
135
+ messages = test.messages.join("\n")
136
+ else
137
+ messages = test.messages
138
+ end
139
+ stack = ""
140
+ test.stack.each do |line|
141
+ if (!line.include? "sapphire")
142
+ stack += line + "\n"
143
+ end
103
144
  end
104
- if test.type == "pass"
105
- @message_factory.create_test_finished(test.text, test.time)
106
- return
145
+ log(@message_factory.create_test_failed(test.text, messages, stack))
107
146
  end
108
- if test.type == "fail"
109
- @message_factory.create_test_output_message(test.text, true, "enter error here")
110
- @message_factory.create_test_failed(test.text, test.message, "enter backtrace here")
147
+
148
+ if test.item.is_a? Finally
149
+ log(@message_factory.create_suite_finished("Finally"))
111
150
  end
112
151
 
113
- @@RUNNING_EXAMPLES_STORAGE.delete(test.object_id)
152
+ end
153
+
154
+ def BeginTesting
155
+ log(@message_factory.create_test_reported_attached)
114
156
  end
115
157
  end
116
158
  end
@@ -83,6 +83,10 @@ module Sapphire
83
83
  $stdout.print "F".red if test.type == "fail"
84
84
  end
85
85
 
86
+ def BeginTesting
87
+
88
+ end
89
+
86
90
  end
87
91
  end
88
92
  end
@@ -3,7 +3,7 @@ module Sapphire
3
3
  module Executable
4
4
  def execute(reporter)
5
5
  start = Time.now
6
- reporter.TestStarted(self.text)
6
+ reporter.TestStarted(self)
7
7
  begin
8
8
  if(self.value.is_a? Pending)
9
9
  result = ResultTree.new(self.text, TestResult.new("pending", self, "Pending", "", Time.now - start))
@@ -42,6 +42,9 @@ module Sapphire
42
42
 
43
43
  end
44
44
 
45
+ def BeginTesting
46
+
47
+ end
45
48
  end
46
49
  end
47
50
  end
@@ -4,18 +4,20 @@ module Sapphire
4
4
 
5
5
  def execute(reporter)
6
6
  reporter.ScenarioStart self
7
- @failures = []
8
- @pendings = []
9
- @success = []
10
7
 
11
8
  self.backgrounds.each do |b|
12
9
 
13
10
  b.execute reporter
14
11
 
12
+ b.and.each do |g_a|
13
+
14
+ g_a.execute reporter
15
+
16
+ end
17
+
15
18
  end
16
19
 
17
20
  self.givens.each do |g|
18
-
19
21
  g.when.each do |w|
20
22
 
21
23
  g.execute reporter
@@ -0,0 +1,286 @@
1
+ module ChildProcess
2
+ module Windows
3
+ module Lib
4
+
5
+ def self.create_proc(cmd, opts = {})
6
+ cmd_ptr = FFI::MemoryPointer.from_string cmd
7
+
8
+ flags = 0
9
+ inherit = !!opts[:inherit]
10
+
11
+ flags |= DETACHED_PROCESS if opts[:detach]
12
+
13
+ si = StartupInfo.new
14
+ pi = ProcessInfo.new
15
+
16
+ if opts[:stdout] || opts[:stderr]
17
+ si[:dwFlags] ||= 0
18
+ si[:dwFlags] |= STARTF_USESTDHANDLES
19
+ inherit = true
20
+
21
+ si[:hStdOutput] = handle_for(opts[:stdout].fileno) if opts[:stdout]
22
+ si[:hStdError] = handle_for(opts[:stderr].fileno) if opts[:stderr]
23
+ end
24
+
25
+ if opts[:duplex]
26
+ read_pipe_ptr = FFI::MemoryPointer.new(:pointer)
27
+ write_pipe_ptr = FFI::MemoryPointer.new(:pointer)
28
+ sa = SecurityAttributes.new(:inherit => true)
29
+
30
+ ok = create_pipe(read_pipe_ptr, write_pipe_ptr, sa, 0)
31
+ ok or raise Error, last_error_message
32
+
33
+ read_pipe = read_pipe_ptr.read_pointer
34
+ write_pipe = write_pipe_ptr.read_pointer
35
+
36
+ si[:hStdInput] = read_pipe
37
+ end
38
+
39
+ si[:lpDesktop] = FFI::MemoryPointer.from_string("test") if $isVirtual
40
+
41
+ ok = create_process(nil, cmd_ptr, nil, nil, inherit, flags, nil, nil, si, pi)
42
+ ok or raise Error, last_error_message
43
+
44
+ close_handle pi[:hProcess]
45
+ close_handle pi[:hThread]
46
+
47
+ if opts[:duplex]
48
+ opts[:stdin] = io_for(duplicate_handle(write_pipe), File::WRONLY)
49
+ close_handle read_pipe
50
+ close_handle write_pipe
51
+ end
52
+
53
+ pi[:dwProcessId]
54
+ end
55
+
56
+ def self.last_error_message
57
+ errnum = get_last_error
58
+ buf = FFI::MemoryPointer.new :char, 512
59
+
60
+ size = format_message(
61
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
62
+ nil, errnum, 0, buf, buf.size, nil
63
+ )
64
+
65
+ buf.read_string(size).strip
66
+ end
67
+
68
+ def self.handle_for(fd_or_io)
69
+ case fd_or_io
70
+ when IO
71
+ handle = get_osfhandle(fd.fileno)
72
+ when Fixnum
73
+ handle = get_osfhandle(fd_or_io)
74
+ else
75
+ if fd_or_io.respond_to?(:to_io)
76
+ io = fd_or_io.to_io
77
+
78
+ unless io.kind_of?(IO)
79
+ raise TypeError, "expected #to_io to return an instance of IO"
80
+ end
81
+
82
+ handle = get_osfhandle(io.fileno)
83
+ else
84
+ raise TypeError, "invalid type: #{fd_or_io.inspect}"
85
+ end
86
+ end
87
+
88
+ if handle == INVALID_HANDLE_VALUE
89
+ raise Error, last_error_message
90
+ end
91
+
92
+ handle
93
+ end
94
+
95
+ def self.io_for(handle, flags = File::RDONLY)
96
+ fd = open_osfhandle(handle, flags)
97
+ if fd == -1
98
+ raise Error, last_error_message
99
+ end
100
+
101
+ ::IO.for_fd fd, flags
102
+ end
103
+
104
+ def self.duplicate_handle(handle)
105
+ dup = FFI::MemoryPointer.new(:pointer)
106
+ proc = current_process
107
+
108
+ ok = _duplicate_handle(
109
+ proc, handle, proc, dup, 0, false, DUPLICATE_SAME_ACCESS)
110
+
111
+ ok or raise Error, last_error_message
112
+
113
+ dup.read_pointer
114
+ ensure
115
+ close_handle proc
116
+ end
117
+
118
+ #
119
+ # BOOL WINAPI CreateProcess(
120
+ # __in_opt LPCTSTR lpApplicationName,
121
+ # __inout_opt LPTSTR lpCommandLine,
122
+ # __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
123
+ # __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
124
+ # __in BOOL bInheritHandles,
125
+ # __in DWORD dwCreationFlags,
126
+ # __in_opt LPVOID lpEnvironment,
127
+ # __in_opt LPCTSTR lpCurrentDirectory,
128
+ # __in LPSTARTUPINFO lpStartupInfo,
129
+ # __out LPPROCESS_INFORMATION lpProcessInformation
130
+ # );
131
+ #
132
+
133
+ attach_function :create_process, :CreateProcessA, [
134
+ :pointer,
135
+ :pointer,
136
+ :pointer,
137
+ :pointer,
138
+ :bool,
139
+ :ulong,
140
+ :pointer,
141
+ :pointer,
142
+ :pointer,
143
+ :pointer],
144
+ :bool
145
+
146
+ #
147
+ # DWORD WINAPI GetLastError(void);
148
+ #
149
+
150
+ attach_function :get_last_error, :GetLastError, [], :ulong
151
+
152
+ #
153
+ # DWORD WINAPI FormatMessage(
154
+ # __in DWORD dwFlags,
155
+ # __in_opt LPCVOID lpSource,
156
+ # __in DWORD dwMessageId,
157
+ # __in DWORD dwLanguageId,
158
+ # __out LPTSTR lpBuffer,
159
+ # __in DWORD nSize,
160
+ # __in_opt va_list *Arguments
161
+ # );
162
+ #
163
+
164
+ attach_function :format_message, :FormatMessageA, [
165
+ :ulong,
166
+ :pointer,
167
+ :ulong,
168
+ :ulong,
169
+ :pointer,
170
+ :ulong,
171
+ :pointer],
172
+ :ulong
173
+
174
+
175
+ attach_function :close_handle, :CloseHandle, [:pointer], :bool
176
+
177
+ #
178
+ # HANDLE WINAPI OpenProcess(
179
+ # __in DWORD dwDesiredAccess,
180
+ # __in BOOL bInheritHandle,
181
+ # __in DWORD dwProcessId
182
+ # );
183
+ #
184
+
185
+ attach_function :open_process, :OpenProcess, [:ulong, :bool, :ulong], :pointer
186
+
187
+ #
188
+ # DWORD WINAPI WaitForSingleObject(
189
+ # __in HANDLE hHandle,
190
+ # __in DWORD dwMilliseconds
191
+ # );
192
+ #
193
+
194
+ attach_function :wait_for_single_object, :WaitForSingleObject, [:pointer, :ulong], :wait_status
195
+
196
+ #
197
+ # BOOL WINAPI GetExitCodeProcess(
198
+ # __in HANDLE hProcess,
199
+ # __out LPDWORD lpExitCode
200
+ # );
201
+ #
202
+
203
+ attach_function :get_exit_code, :GetExitCodeProcess, [:pointer, :pointer], :bool
204
+
205
+ #
206
+ # BOOL WINAPI GenerateConsoleCtrlEvent(
207
+ # __in DWORD dwCtrlEvent,
208
+ # __in DWORD dwProcessGroupId
209
+ # );
210
+ #
211
+
212
+ attach_function :generate_console_ctrl_event, :GenerateConsoleCtrlEvent, [:ulong, :ulong], :bool
213
+
214
+ #
215
+ # BOOL WINAPI TerminateProcess(
216
+ # __in HANDLE hProcess,
217
+ # __in UINT uExitCode
218
+ # );
219
+ #
220
+
221
+ attach_function :terminate_process, :TerminateProcess, [:pointer, :uint], :bool
222
+
223
+ #
224
+ # long _get_osfhandle(
225
+ # int fd
226
+ # );
227
+ #
228
+
229
+ attach_function :get_osfhandle, :_get_osfhandle, [:int], :long
230
+
231
+ #
232
+ # int _open_osfhandle (
233
+ # intptr_t osfhandle,
234
+ # int flags
235
+ # );
236
+ #
237
+
238
+ attach_function :open_osfhandle, :_open_osfhandle, [:pointer, :int], :int
239
+
240
+ # BOOL WINAPI SetHandleInformation(
241
+ # __in HANDLE hObject,
242
+ # __in DWORD dwMask,
243
+ # __in DWORD dwFlags
244
+ # );
245
+
246
+ attach_function :set_handle_information, :SetHandleInformation, [:long, :ulong, :ulong], :bool
247
+
248
+ # BOOL WINAPI CreatePipe(
249
+ # __out PHANDLE hReadPipe,
250
+ # __out PHANDLE hWritePipe,
251
+ # __in_opt LPSECURITY_ATTRIBUTES lpPipeAttributes,
252
+ # __in DWORD nSize
253
+ # );
254
+
255
+ attach_function :create_pipe, :CreatePipe, [:pointer, :pointer, :pointer, :ulong], :bool
256
+
257
+ #
258
+ # HANDLE WINAPI GetCurrentProcess(void);
259
+ #
260
+
261
+ attach_function :current_process, :GetCurrentProcess, [], :pointer
262
+
263
+ #
264
+ # BOOL WINAPI DuplicateHandle(
265
+ # __in HANDLE hSourceProcessHandle,
266
+ # __in HANDLE hSourceHandle,
267
+ # __in HANDLE hTargetProcessHandle,
268
+ # __out LPHANDLE lpTargetHandle,
269
+ # __in DWORD dwDesiredAccess,
270
+ # __in BOOL bInheritHandle,
271
+ # __in DWORD dwOptions
272
+ # );
273
+ #
274
+
275
+ attach_function :_duplicate_handle, :DuplicateHandle, [
276
+ :pointer,
277
+ :pointer,
278
+ :pointer,
279
+ :pointer,
280
+ :ulong,
281
+ :bool,
282
+ :ulong
283
+ ], :bool
284
+ end # Lib
285
+ end # Windows
286
+ end # ChildProcess
@@ -0,0 +1,68 @@
1
+ require 'ffi'
2
+
3
+ module Sapphire
4
+ module UI
5
+ extend FFI::Library
6
+
7
+ ffi_lib 'user32'
8
+ ffi_convention :stdcall
9
+ attach_function :CreateDesktop, :CreateDesktopA, [ :string, :pointer, :pointer, :int, :long, :pointer ], :int
10
+ attach_function :CloseDesktop, [ :int ], :bool
11
+
12
+ ffi_lib 'kernel32'
13
+ attach_function :CreateProcess, :CreateProcessA, [ :pointer, :pointer, :pointer, :pointer, :int, :ushort, :pointer, :pointer, :pointer, :pointer], :int
14
+ attach_function :GetLastError, [ ], :ushort
15
+
16
+ class StartUpInfo < FFI::Struct
17
+ layout :cb, :ushort,
18
+ :lpReserved, :pointer,
19
+ :lpDesktop, :pointer,
20
+ :lpTitle, :pointer,
21
+ :dwX, :ushort,
22
+ :dwY, :ushort,
23
+ :dwXSize, :ushort,
24
+ :dwYSize, :ushort,
25
+ :dwXCountChars, :ushort,
26
+ :dwYCountChars, :ushort,
27
+ :dwFillAttribute, :ushort,
28
+ :dwFlags, :ushort,
29
+ :wShowWindow, :short,
30
+ :cbReserved2, :short,
31
+ :lpReserved2, :pointer,
32
+ :hStdInput, :pointer,
33
+ :hStdOutput, :pointer,
34
+ :hStdError, :pointer
35
+ end
36
+
37
+ class ProcessInformation < FFI::Struct
38
+ layout :hProcess, :pointer,
39
+ :hThread, :pointer,
40
+ :dwProcessId, :ushort,
41
+ :dwThreadId, :ushort
42
+ end
43
+
44
+ class VirtualUI
45
+
46
+ def Create()
47
+
48
+ @off_screen = UI::CreateDesktop("test", nil, nil, 0, 0x02000000, nil)
49
+
50
+ if(@off_screen == nil)
51
+ raise "Could not create a virtual desktop :("
52
+ end
53
+
54
+ $isVirtual = true
55
+
56
+ end
57
+
58
+ def Close()
59
+ $isVirtual = false
60
+ result = UI::CloseDesktop(@off_screen)
61
+
62
+ if(result == 0)
63
+ raise "Could not close the virtual desktop :("
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,3 +1,3 @@
1
1
  module Sapphire
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sapphire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
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-09-24 00:00:00.000000000Z
12
+ date: 2011-09-30 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: selenium-webdriver
16
- requirement: &9381432 !ruby/object:Gem::Requirement
16
+ requirement: &9888888 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *9381432
24
+ version_requirements: *9888888
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: colorize
27
- requirement: &9381132 !ruby/object:Gem::Requirement
27
+ requirement: &9888636 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *9381132
35
+ version_requirements: *9888636
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: win32console
38
- requirement: &9380832 !ruby/object:Gem::Requirement
38
+ requirement: &9888384 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *9380832
46
+ version_requirements: *9888384
47
47
  description: An automated web acceptance test framework for non-technical resources
48
48
  using selenium-wedriver.
49
49
  email:
@@ -91,6 +91,7 @@ files:
91
91
  - lib/sapphire/DSL/Browser/Tracker.rb
92
92
  - lib/sapphire/DSL/Browser/Transition.rb
93
93
  - lib/sapphire/DSL/Browser/Uncheck.rb
94
+ - lib/sapphire/DSL/Browser/Virtually.rb
94
95
  - lib/sapphire/DSL/Browser/With.rb
95
96
  - lib/sapphire/DSL/Configuration/ConfiguredBrowser.rb
96
97
  - lib/sapphire/DSL/Configuration/ConfiguredUser.rb
@@ -138,6 +139,8 @@ files:
138
139
  - lib/sapphire/Testing/ScenarioResult.rb
139
140
  - lib/sapphire/Testing/TestResult.rb
140
141
  - lib/sapphire/Testing/TestRunnerAdapter.rb
142
+ - lib/sapphire/UI/Functions.rb
143
+ - lib/sapphire/UI/VirtualUI.rb
141
144
  - lib/sapphire/version.rb
142
145
  - lib/sapphire/WebAbstractions/Controls/Base/Control.rb
143
146
  - lib/sapphire/WebAbstractions/Controls/Base/Page.rb