zucchini-ios 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +11 -1
- data/CHANGELOG.md +6 -0
- data/lib/zucchini.rb +2 -0
- data/lib/zucchini/compiler.rb +59 -0
- data/lib/zucchini/config.rb +19 -15
- data/lib/zucchini/detector.rb +5 -19
- data/lib/zucchini/device.rb +32 -0
- data/lib/zucchini/feature.rb +7 -22
- data/lib/zucchini/runner.rb +1 -2
- data/lib/zucchini/uia/lib/compat.coffee +9 -0
- data/lib/zucchini/uia/lib/mechanic.js +556 -0
- data/lib/zucchini/uia/lib/uia.coffee +14 -0
- data/lib/zucchini/uia/lib/util.coffee +41 -0
- data/lib/zucchini/uia/screen.coffee +29 -31
- data/lib/zucchini/uia/zucchini.coffee +32 -0
- data/lib/zucchini/version.rb +1 -1
- data/spec/lib/zucchini/compiler_spec.rb +40 -0
- data/spec/lib/zucchini/config_spec.rb +6 -14
- data/spec/lib/zucchini/detector_spec.rb +1 -1
- data/spec/lib/zucchini/feature_spec.rb +1 -25
- data/spec/spec_helper.rb +3 -6
- metadata +12 -4
- data/lib/zucchini/uia/base.coffee +0 -89
@@ -0,0 +1,14 @@
|
|
1
|
+
# Expose global objects to the user
|
2
|
+
target = UIATarget.localTarget()
|
3
|
+
app = target.frontMostApp()
|
4
|
+
view = app.mainWindow()
|
5
|
+
|
6
|
+
# Prevent UIA from auto handling alerts
|
7
|
+
UIATarget.onAlert = (alert) -> return true
|
8
|
+
|
9
|
+
# Prepend screenshot names with numbers
|
10
|
+
screensCount = 0
|
11
|
+
target.captureScreenWithName_ = target.captureScreenWithName
|
12
|
+
target.captureScreenWithName = (name) ->
|
13
|
+
number = (if (++screensCount < 10) then "0#{screensCount}" else screensCount)
|
14
|
+
@captureScreenWithName_ "#{number}_#{name}"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Function::bind = (context) ->
|
2
|
+
return this unless context
|
3
|
+
fun = this
|
4
|
+
-> fun.apply context, arguments
|
5
|
+
|
6
|
+
String::camelCase = ->
|
7
|
+
@replace /([\-\ ][A-Za-z])/g, ($1) ->
|
8
|
+
$1.toUpperCase().replace /[\-\ ]/g, ''
|
9
|
+
|
10
|
+
# Instruments >= 4.5 crash when a JS primitive is thrown
|
11
|
+
# http://apple.stackexchange.com/questions/69484/unknown-xcode-instruments-crash
|
12
|
+
raise = (message) -> throw new Error(message)
|
13
|
+
|
14
|
+
# A finder could return an UIAElement or an array from a mechanic.js selector
|
15
|
+
# Handle both cases
|
16
|
+
_elementFrom = (finder) ->
|
17
|
+
res = finder()
|
18
|
+
res = res[0] if (typeof res.length is 'number')
|
19
|
+
res
|
20
|
+
|
21
|
+
# Execute a finder function until the element appears
|
22
|
+
wait = (finder) ->
|
23
|
+
found = false
|
24
|
+
counter = 0
|
25
|
+
element = null
|
26
|
+
|
27
|
+
while not found and (counter < 10)
|
28
|
+
element = _elementFrom finder
|
29
|
+
|
30
|
+
if element? and element.isValid() and element.isVisible()
|
31
|
+
found = true
|
32
|
+
else
|
33
|
+
target.delay 0.5
|
34
|
+
counter++
|
35
|
+
if found then element else false
|
36
|
+
|
37
|
+
rotateTo = (orientation) ->
|
38
|
+
target.setDeviceOrientation(
|
39
|
+
if orientation is 'portrait' then UIA_DEVICE_ORIENTATION_PORTRAIT
|
40
|
+
else UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT
|
41
|
+
)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Screen
|
2
|
-
takeScreenshot: (
|
2
|
+
takeScreenshot: (screenshotName) ->
|
3
|
+
$.delay 0.5
|
3
4
|
orientation = switch app.interfaceOrientation()
|
4
5
|
when 0 then 'Unknown'
|
5
6
|
when 1 then 'Portrait'
|
@@ -8,51 +9,53 @@ class Screen
|
|
8
9
|
when 4 then 'LandscapeRight'
|
9
10
|
when 5 then 'FaceUp'
|
10
11
|
when 6 then 'FaceDown'
|
11
|
-
|
12
|
-
target.captureScreenWithName("#{orientation}_#{@name}-screen_#{
|
12
|
+
$.log "Screenshot of screen '#{@name}' taken"
|
13
|
+
target.captureScreenWithName("#{orientation}_#{@name}-screen_#{screenshotName}")
|
14
|
+
|
15
|
+
element: (name) ->
|
16
|
+
finder = @elements[name] || -> $('#' + name)
|
17
|
+
|
18
|
+
unless el = wait finder
|
19
|
+
raise "Element '#{name}' was not found on '#{@name}'"
|
20
|
+
el
|
13
21
|
|
14
22
|
constructor: (@name) ->
|
15
23
|
|
16
24
|
elements: {}
|
17
|
-
actions
|
18
|
-
'Take a screenshot$'
|
19
|
-
|
25
|
+
actions:
|
26
|
+
'Take a screenshot$': -> @takeScreenshot(@name)
|
27
|
+
|
28
|
+
'Take a screenshot named "([^"]*)"$': (name) -> @takeScreenshot(name)
|
20
29
|
|
21
|
-
'
|
22
|
-
@takeScreenshot(screenshot_name)
|
30
|
+
'Show elements' : -> view.logElementTree()
|
23
31
|
|
24
|
-
'
|
25
|
-
raise "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
|
26
|
-
@elements[element]().tap()
|
32
|
+
'Show elements for "([^"]*)"$': (name) -> @element(name).logElementTree()
|
27
33
|
|
28
|
-
'
|
29
|
-
@actions['Tap "([^"]*)"$'].bind(this)(element)
|
34
|
+
'Tap "([^"]*)"$': (name) -> @element(name).tap()
|
30
35
|
|
31
|
-
'
|
32
|
-
target.delay(seconds)
|
36
|
+
'Confirm "([^"]*)"$': (element) -> @actions['Tap "([^"]*)"$'].bind(this)(element)
|
33
37
|
|
34
|
-
'
|
35
|
-
|
36
|
-
|
38
|
+
'Wait for "([^"]*)" second[s]*$': (seconds) -> target.delay(seconds)
|
39
|
+
|
40
|
+
'Type "([^"]*)" in the "([^"]*)" field$': (text, name) ->
|
41
|
+
@element(name).tap()
|
37
42
|
app.keyboard().typeString text
|
38
43
|
|
39
|
-
'Clear the "([^"]*)" field$': (element)
|
40
|
-
raise "Element '#{element}' not defined for the screen '#{@name}'" unless @elements[element]
|
41
|
-
@elements[element]().setValue ""
|
44
|
+
'Clear the "([^"]*)" field$': (name) -> @element(name).setValue ''
|
42
45
|
|
43
46
|
'Cancel the alert$' : ->
|
44
47
|
alert = app.alert()
|
45
|
-
raise "No alert found to dismiss on screen '#{@name}'"
|
48
|
+
raise "No alert found to dismiss on screen '#{@name}'" unless alert.isValid()
|
46
49
|
alert.cancelButton().tap()
|
47
50
|
|
48
51
|
'Confirm the alert$' : ->
|
49
52
|
alert = app.alert()
|
50
|
-
raise "No alert found to dismiss on screen '#{@name}'"
|
53
|
+
raise "No alert found to dismiss on screen '#{@name}'" unless alert.isValid()
|
51
54
|
alert.defaultButton().tap()
|
52
55
|
|
53
56
|
'Select the date "([^"]*)"$' : (dateString) ->
|
54
57
|
datePicker = view.pickers()[0]
|
55
|
-
raise "No date picker available to enter the date #{dateString}" unless (
|
58
|
+
raise "No date picker available to enter the date #{dateString}" unless datePicker.isValid() and datePicker.isVisible()
|
56
59
|
dateParts = dateString.match(/^(\d{2}) (\D*) (\d{4})$/)
|
57
60
|
raise "Date is in the wrong format. Need DD Month YYYY. Got #{dateString}" unless dateParts?
|
58
61
|
# Set Day
|
@@ -64,13 +67,8 @@ class Screen
|
|
64
67
|
counter++
|
65
68
|
monthWheel.tapWithOptions({tapOffset:{x:0.5, y:0.33}})
|
66
69
|
target.delay(0.4)
|
67
|
-
raise "
|
70
|
+
raise "Couldn't find the month #{dateParts[2]}" unless counter < 12
|
68
71
|
# Set Year
|
69
72
|
view.pickers()[0].wheels()[2].selectValue(dateParts[3])
|
70
73
|
|
71
|
-
'
|
72
|
-
view.logElementTree()
|
73
|
-
|
74
|
-
'Rotate device to "([^"]*)"$': (orientation) ->
|
75
|
-
orientation = if orientation == "landscape" then UIA_DEVICE_ORIENTATION_LANDSCAPERIGHT else UIA_DEVICE_ORIENTATION_PORTRAIT
|
76
|
-
target.setDeviceOrientation(orientation)
|
74
|
+
'Rotate device to "([^"]*)"$': (orientation) -> rotateTo(orientation)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Run a Zucchini feature
|
2
|
+
Zucchini = (featureText, orientation) ->
|
3
|
+
rotateTo(orientation)
|
4
|
+
|
5
|
+
sections = featureText.trim().split(/\n\s*\n/)
|
6
|
+
|
7
|
+
for section in sections
|
8
|
+
lines = section.split(/\n/)
|
9
|
+
|
10
|
+
screenMatch = lines[0].match(/.+ on the "([^"]*)" screen:$/)
|
11
|
+
raise "Line '#{lines[0]}' doesn't define a screen context" unless screenMatch
|
12
|
+
|
13
|
+
screenName = screenMatch[1]
|
14
|
+
try
|
15
|
+
screen = eval("new #{screenName.camelCase()}Screen")
|
16
|
+
catch e
|
17
|
+
raise "Screen '#{screenName}' not defined"
|
18
|
+
|
19
|
+
if screen.anchor
|
20
|
+
if wait(screen.anchor)
|
21
|
+
$.log "Found anchor for screen '#{screenName}'"
|
22
|
+
else
|
23
|
+
raise "Could not find anchor for screen '#{screenName}'"
|
24
|
+
|
25
|
+
for line in lines.slice(1)
|
26
|
+
functionFound = false
|
27
|
+
for regExpText, func of screen.actions
|
28
|
+
match = line.trim().match(new RegExp(regExpText))
|
29
|
+
if match
|
30
|
+
functionFound = true
|
31
|
+
func.bind(screen)(match[1],match[2])
|
32
|
+
raise "Action for line '#{line}' not defined" unless functionFound
|
data/lib/zucchini/version.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zucchini::Compiler do
|
4
|
+
let(:path) { './spec/sample_setup/feature_one' }
|
5
|
+
let(:feature) { Zucchini::Feature.new(path) }
|
6
|
+
|
7
|
+
after(:all) { FileUtils.rm_rf Dir.glob("#{path}/run_data/feature.*") }
|
8
|
+
|
9
|
+
describe "#compile_js" do
|
10
|
+
before { feature.compile_js 'landscape' }
|
11
|
+
|
12
|
+
it "should strip comments from the feature file" do
|
13
|
+
File.read("#{feature.run_data_path}/feature.coffee").index('#').should be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "feature.js output" do
|
17
|
+
subject { File.read("#{feature.run_data_path}/feature.js") }
|
18
|
+
|
19
|
+
it "should include mechanic.js" do
|
20
|
+
should match /mechanic\.js UIAutomation Library/
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should include screen definitions" do
|
24
|
+
should match /SplashScreen = \(function/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should include Zucchini runtime" do
|
28
|
+
should match /Zucchini = function/
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should include custom libraries from support/lib" do
|
32
|
+
should match /Helpers.example = /
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should include screen orientation" do
|
36
|
+
should match /Zucchini\(.+\'landscape\'\)/
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -16,25 +16,25 @@ describe Zucchini::Config do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
describe "device" do
|
21
21
|
before(:all) { Zucchini::Config.base_path = "spec/sample_setup" }
|
22
22
|
|
23
23
|
context "device present in config.yml" do
|
24
24
|
it "should return the device hash" do
|
25
|
-
Zucchini::Config.device("My iDevice").should eq({:name =>"My iDevice", :udid =>"lolffb28d74a6fraj2156090784avasc50725dd0", :screen =>"ipad_ios5"})
|
25
|
+
Zucchini::Config.device("My iDevice").should eq({:name =>"My iDevice", :udid =>"lolffb28d74a6fraj2156090784avasc50725dd0", :screen =>"ipad_ios5", :simulator=>nil, :orientation=> 'portrait'})
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
context "device not present in config.yml" do
|
30
30
|
it "should raise an error" do
|
31
|
-
expect { Zucchini::Config.device("My Android Phone")}.to raise_error "Device not listed in config.yml"
|
31
|
+
expect { Zucchini::Config.device("My Android Phone")}.to raise_error "Device 'My Android Phone' not listed in config.yml"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
context "default device" do
|
36
36
|
it "should use default device if device name argument is nil" do
|
37
|
-
Zucchini::Config.device(nil).should eq({:name =>"Default Device", :screen =>"low_ios5", :udid => nil})
|
37
|
+
Zucchini::Config.device(nil).should eq({:name =>"Default Device", :screen =>"low_ios5", :udid => nil, :simulator=>nil, :orientation=> 'portrait'})
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should raise error if no default device provided" do
|
@@ -43,12 +43,4 @@ describe Zucchini::Config do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
47
|
-
describe "url" do
|
48
|
-
before(:all) { Zucchini::Config.base_path = "spec/sample_setup" }
|
49
|
-
|
50
|
-
it "should return a full URL string for a given server name" do
|
51
|
-
Zucchini::Config.url('backend', '/api').should eq "http://192.168.1.2:8080/api"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
46
|
+
end
|
@@ -18,7 +18,7 @@ describe Zucchini::Detector do
|
|
18
18
|
|
19
19
|
context "device hasn't been found" do
|
20
20
|
before { ENV['ZUCCHINI_DEVICE'] = 'My Android Phone' }
|
21
|
-
it { should raise_error "Device not listed in config.yml" }
|
21
|
+
it { should raise_error "Device 'My Android Phone' not listed in config.yml" }
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -3,32 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe Zucchini::Feature do
|
4
4
|
let(:path) { './spec/sample_setup/feature_one' }
|
5
5
|
let(:feature) { Zucchini::Feature.new(path) }
|
6
|
-
|
6
|
+
|
7
7
|
after(:all) { FileUtils.rm_rf Dir.glob("#{path}/run_data/feature.*") }
|
8
|
-
|
9
|
-
describe "#compile_js" do
|
10
|
-
before { feature.compile_js }
|
11
|
-
|
12
|
-
it "should strip comments from the feature file" do
|
13
|
-
File.read("#{feature.run_data_path}/feature.coffee").index('#').should be_nil
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "feature.js output" do
|
17
|
-
subject { File.read("#{feature.run_data_path}/feature.js") }
|
18
|
-
|
19
|
-
it "should include screen definitions" do
|
20
|
-
should match /SplashScreen = \(function/
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should include Zucchini runtime" do
|
24
|
-
should match /Zucchini.run = /
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should include custom libraries from support/lib" do
|
28
|
-
should match /Helpers.example = /
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
8
|
|
33
9
|
describe "approve" do
|
34
10
|
subject { lambda { feature.approve "reference" } }
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require 'coveralls'
|
2
2
|
require 'simplecov'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
else
|
7
|
-
SimpleCov.start do
|
8
|
-
add_filter "/spec/"
|
9
|
-
end
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter "/spec/"
|
10
6
|
end
|
7
|
+
Coveralls.wear! if ENV['COVERAGE'] == 'coveralls'
|
11
8
|
|
12
9
|
require 'clamp'
|
13
10
|
require 'fileutils'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zucchini-ios
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-08-
|
14
|
+
date: 2013-08-11 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: clamp
|
@@ -96,8 +96,10 @@ files:
|
|
96
96
|
- bin/zucchini
|
97
97
|
- lib/zucchini.rb
|
98
98
|
- lib/zucchini/approver.rb
|
99
|
+
- lib/zucchini/compiler.rb
|
99
100
|
- lib/zucchini/config.rb
|
100
101
|
- lib/zucchini/detector.rb
|
102
|
+
- lib/zucchini/device.rb
|
101
103
|
- lib/zucchini/feature.rb
|
102
104
|
- lib/zucchini/generator.rb
|
103
105
|
- lib/zucchini/report.rb
|
@@ -110,9 +112,14 @@ files:
|
|
110
112
|
- lib/zucchini/report/view.rb
|
111
113
|
- lib/zucchini/runner.rb
|
112
114
|
- lib/zucchini/screenshot.rb
|
113
|
-
- lib/zucchini/uia/
|
115
|
+
- lib/zucchini/uia/lib/compat.coffee
|
116
|
+
- lib/zucchini/uia/lib/mechanic.js
|
117
|
+
- lib/zucchini/uia/lib/uia.coffee
|
118
|
+
- lib/zucchini/uia/lib/util.coffee
|
114
119
|
- lib/zucchini/uia/screen.coffee
|
120
|
+
- lib/zucchini/uia/zucchini.coffee
|
115
121
|
- lib/zucchini/version.rb
|
122
|
+
- spec/lib/zucchini/compiler_spec.rb
|
116
123
|
- spec/lib/zucchini/config_spec.rb
|
117
124
|
- spec/lib/zucchini/detector_spec.rb
|
118
125
|
- spec/lib/zucchini/feature_spec.rb
|
@@ -176,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
183
|
version: '0'
|
177
184
|
segments:
|
178
185
|
- 0
|
179
|
-
hash: -
|
186
|
+
hash: -3527198499352191037
|
180
187
|
requirements: []
|
181
188
|
rubyforge_project:
|
182
189
|
rubygems_version: 1.8.23
|
@@ -184,6 +191,7 @@ signing_key:
|
|
184
191
|
specification_version: 3
|
185
192
|
summary: Functional testing framework for iOS-powered devices
|
186
193
|
test_files:
|
194
|
+
- spec/lib/zucchini/compiler_spec.rb
|
187
195
|
- spec/lib/zucchini/config_spec.rb
|
188
196
|
- spec/lib/zucchini/detector_spec.rb
|
189
197
|
- spec/lib/zucchini/feature_spec.rb
|
@@ -1,89 +0,0 @@
|
|
1
|
-
Function::bind = (context) ->
|
2
|
-
return this unless context
|
3
|
-
fun = this
|
4
|
-
->
|
5
|
-
fun.apply context, arguments
|
6
|
-
|
7
|
-
String::camelCase = ->
|
8
|
-
@replace /([\-\ ][A-Za-z])/g, ($1) ->
|
9
|
-
$1.toUpperCase().replace /[\-\ ]/g, ""
|
10
|
-
|
11
|
-
extend = (obj, mixin) ->
|
12
|
-
obj[name] = method for name, method of mixin
|
13
|
-
obj
|
14
|
-
|
15
|
-
puts = (text) -> UIALogger.logMessage text
|
16
|
-
|
17
|
-
# Instruments 4.5 crash when a JS primitive is thrown
|
18
|
-
# http://apple.stackexchange.com/questions/69484/unknown-xcode-instruments-crash
|
19
|
-
raise = (message) -> throw new Error(message)
|
20
|
-
|
21
|
-
# Prevent UIA from auto handling alerts
|
22
|
-
UIATarget.onAlert = (alert) -> return true
|
23
|
-
|
24
|
-
target = UIATarget.localTarget()
|
25
|
-
app = target.frontMostApp()
|
26
|
-
view = app.mainWindow()
|
27
|
-
|
28
|
-
UIAElement.prototype.$ = (name) ->
|
29
|
-
target.pushTimeout(0)
|
30
|
-
elem = null
|
31
|
-
for el in this.elements()
|
32
|
-
elem = if el.name() == name then el else el.$(name)
|
33
|
-
break if elem
|
34
|
-
target.popTimeout()
|
35
|
-
elem
|
36
|
-
|
37
|
-
target.waitForElement = (element) ->
|
38
|
-
return false unless element
|
39
|
-
found = false
|
40
|
-
counter = 0
|
41
|
-
while not found and (counter < 10)
|
42
|
-
if element.isValid() and element.isVisible()
|
43
|
-
found = true
|
44
|
-
else
|
45
|
-
@delay 0.5
|
46
|
-
counter++
|
47
|
-
return found
|
48
|
-
|
49
|
-
isNullElement = (elem) -> elem.toString() == "[object UIAElementNil]"
|
50
|
-
|
51
|
-
screensCount = 0
|
52
|
-
target.captureScreenWithName_ = target.captureScreenWithName
|
53
|
-
target.captureScreenWithName = (screenName) ->
|
54
|
-
screensCountText = (if (++screensCount < 10) then "0" + screensCount else screensCount)
|
55
|
-
@captureScreenWithName_ screensCountText + "_" + screenName
|
56
|
-
|
57
|
-
class Zucchini
|
58
|
-
@run: (featureText) ->
|
59
|
-
sections = featureText.trim().split(/\n\s*\n/)
|
60
|
-
|
61
|
-
for section in sections
|
62
|
-
lines = section.split(/\n/)
|
63
|
-
|
64
|
-
screenMatch = lines[0].match(/.+ on the "([^"]*)" screen:$/)
|
65
|
-
raise "Line '#{lines[0]}' doesn't define a screen context" unless screenMatch
|
66
|
-
|
67
|
-
screenName = screenMatch[1]
|
68
|
-
try
|
69
|
-
screen = eval("new #{screenName.camelCase()}Screen")
|
70
|
-
catch e
|
71
|
-
raise "Screen '#{screenName}' not defined"
|
72
|
-
|
73
|
-
if screen.anchor
|
74
|
-
element = screen.anchor()
|
75
|
-
found = target.waitForElement(element)
|
76
|
-
|
77
|
-
if found
|
78
|
-
puts "Found anchor for screen '#{screenName}'"
|
79
|
-
else
|
80
|
-
raise "Could not find anchor for screen '#{screenName}'"
|
81
|
-
|
82
|
-
for line in lines.slice(1)
|
83
|
-
functionFound = false
|
84
|
-
for regExpText, func of screen.actions
|
85
|
-
match = line.trim().match(new RegExp(regExpText))
|
86
|
-
if match
|
87
|
-
functionFound = true
|
88
|
-
func.bind(screen)(match[1],match[2])
|
89
|
-
raise "Action for line '#{line}' not defined" unless functionFound
|