win_gui 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/book_code/early_success/bundle.rb +34 -0
- data/book_code/early_success/english.txt +1 -0
- data/book_code/early_success/jruby_basics.rb +47 -0
- data/book_code/early_success/windows_basics.rb +97 -0
- data/book_code/guessing/locknote.rb +379 -0
- data/book_code/guessing/monkeyshines.rb +14 -0
- data/book_code/guessing/note.rb +120 -0
- data/book_code/guessing/note_spec.rb +175 -0
- data/book_code/guessing/replay.rb +21 -0
- data/book_code/guessing/seed.rb +9 -0
- data/book_code/guessing/spec_helper.rb +69 -0
- data/book_code/guessing/windows_gui.rb +247 -0
- data/book_code/home_stretch/junquenote.rb +151 -0
- data/book_code/home_stretch/locknote.rb +180 -0
- data/book_code/home_stretch/note.rb +144 -0
- data/book_code/home_stretch/note_spec.rb +191 -0
- data/book_code/home_stretch/spec_helper.rb +55 -0
- data/book_code/home_stretch/swing_gui.rb +50 -0
- data/book_code/home_stretch/windows_gui.rb +232 -0
- data/book_code/junquenote/exports.sh +10 -0
- data/book_code/junquenote/jruby_mac.sh +10 -0
- data/book_code/junquenote/junquenote_app.rb +262 -0
- data/book_code/novite/Rakefile +10 -0
- data/book_code/novite/app/controllers/application.rb +18 -0
- data/book_code/novite/app/controllers/guests_controller.rb +28 -0
- data/book_code/novite/app/controllers/parties_controller.rb +77 -0
- data/book_code/novite/app/helpers/application_helper.rb +11 -0
- data/book_code/novite/app/helpers/guests_helper.rb +10 -0
- data/book_code/novite/app/helpers/parties_helper.rb +10 -0
- data/book_code/novite/app/models/guest.rb +11 -0
- data/book_code/novite/app/models/party.rb +32 -0
- data/book_code/novite/app/models/party_mailer.rb +19 -0
- data/book_code/novite/app/views/layouts/application.rhtml +44 -0
- data/book_code/novite/app/views/parties/new.html.erb +42 -0
- data/book_code/novite/app/views/parties/show.html.erb +43 -0
- data/book_code/novite/app/views/party_mailer/invite.erb +17 -0
- data/book_code/novite/config/boot.rb +117 -0
- data/book_code/novite/config/database.yml +19 -0
- data/book_code/novite/config/environment.rb +67 -0
- data/book_code/novite/config/environments/development.rb +29 -0
- data/book_code/novite/config/environments/production.rb +27 -0
- data/book_code/novite/config/environments/test.rb +30 -0
- data/book_code/novite/config/initializers/inflections.rb +18 -0
- data/book_code/novite/config/initializers/mime_types.rb +13 -0
- data/book_code/novite/config/routes.rb +47 -0
- data/book_code/novite/db/migrate/001_create_parties.rb +26 -0
- data/book_code/novite/db/migrate/002_create_guests.rb +23 -0
- data/book_code/novite/db/schema.rb +41 -0
- data/book_code/novite/log/empty.txt +0 -0
- data/book_code/novite/public/.htaccess +40 -0
- data/book_code/novite/public/404.html +38 -0
- data/book_code/novite/public/422.html +38 -0
- data/book_code/novite/public/500.html +38 -0
- data/book_code/novite/public/dispatch.cgi +10 -0
- data/book_code/novite/public/dispatch.fcgi +24 -0
- data/book_code/novite/public/dispatch.rb +18 -0
- data/book_code/novite/public/favicon.ico +0 -0
- data/book_code/novite/public/images/rails.png +0 -0
- data/book_code/novite/public/index.html +285 -0
- data/book_code/novite/public/javascripts/application.js +10 -0
- data/book_code/novite/public/javascripts/controls.js +971 -0
- data/book_code/novite/public/javascripts/dragdrop.js +980 -0
- data/book_code/novite/public/javascripts/effects.js +1128 -0
- data/book_code/novite/public/javascripts/prototype.js +4233 -0
- data/book_code/novite/public/robots.txt +5 -0
- data/book_code/novite/script/about +3 -0
- data/book_code/novite/script/console +3 -0
- data/book_code/novite/script/destroy +3 -0
- data/book_code/novite/script/generate +3 -0
- data/book_code/novite/script/performance/benchmarker +3 -0
- data/book_code/novite/script/performance/profiler +3 -0
- data/book_code/novite/script/performance/request +3 -0
- data/book_code/novite/script/plugin +3 -0
- data/book_code/novite/script/process/inspector +3 -0
- data/book_code/novite/script/process/reaper +3 -0
- data/book_code/novite/script/process/spawner +3 -0
- data/book_code/novite/script/runner +3 -0
- data/book_code/novite/script/server +3 -0
- data/book_code/novite/test/test_helper.rb +46 -0
- data/book_code/one_more_thing/applescript.rb +68 -0
- data/book_code/one_more_thing/note_spec.rb +50 -0
- data/book_code/one_more_thing/spec_helper.rb +17 -0
- data/book_code/one_more_thing/textedit-pure.rb +28 -0
- data/book_code/one_more_thing/textedit.applescript +26 -0
- data/book_code/one_more_thing/textedit.rb +32 -0
- data/book_code/one_more_thing/textnote.rb +87 -0
- data/book_code/simplify/junquenote.rb +48 -0
- data/book_code/simplify/locknote.rb +46 -0
- data/book_code/simplify/note.rb +35 -0
- data/book_code/simplify/note_spec.rb +28 -0
- data/book_code/simplify/swing_gui.rb +45 -0
- data/book_code/simplify/windows_gui.rb +232 -0
- data/book_code/simplify/windows_gui_spec.rb +35 -0
- data/book_code/story/invite.story +19 -0
- data/book_code/story/journal.txt +29 -0
- data/book_code/story/novite_stories.rb +156 -0
- data/book_code/story/party.rb +149 -0
- data/book_code/story/password.rb +61 -0
- data/book_code/story/password.story +26 -0
- data/book_code/story/rsvp.story +29 -0
- data/book_code/tables/TestTime.html +93 -0
- data/book_code/tables/TestTimeSample.html +63 -0
- data/book_code/tables/calculate_time.rb +39 -0
- data/book_code/tables/calculator.rb +108 -0
- data/book_code/tables/calculator_actions.rb +27 -0
- data/book_code/tables/calculator_spec.rb +47 -0
- data/book_code/tables/fit.rb +32 -0
- data/book_code/tables/matrix.rb +109 -0
- data/book_code/tables/pseudocode.rb +17 -0
- data/book_code/tubes/book_selenium.rb +67 -0
- data/book_code/tubes/book_watir.rb +60 -0
- data/book_code/tubes/dragdrop.html +81 -0
- data/book_code/tubes/html_capture.rb +33 -0
- data/book_code/tubes/joke_list.rb +67 -0
- data/book_code/tubes/list_spec.rb +41 -0
- data/book_code/tubes/search_spec.rb +32 -0
- data/book_code/tubes/selenium_example.rb +66 -0
- data/book_code/tubes/selenium_link.rb +23 -0
- data/book_code/tubes/web_server.rb +14 -0
- data/book_code/windows/wgui.rb +29 -0
- data/book_code/windows/wobj.rb +25 -0
- data/book_code/windows/wsh.rb +25 -0
- data/book_code/with_rspec/empty_spec.rb +13 -0
- data/book_code/with_rspec/junquenote.rb +60 -0
- data/book_code/with_rspec/locknote.rb +129 -0
- data/book_code/with_rspec/note_spec.rb +32 -0
- data/book_code/with_rspec/should_examples.rb +18 -0
- data/exp/exp.rb +6 -0
- data/exp/exp_encodings.rb +40 -0
- data/exp/exp_enum_windows.rb +60 -0
- data/exp/exp_quik.rb +38 -0
- data/exp/exp_wsh.rb +115 -0
- data/exp/old/windows_basics.rb +80 -0
- data/exp/old/wnote.rb +80 -0
- data/exp/old/wnote_spec.rb +20 -0
- data/features/step_definitions/win_gui_steps.rb +0 -0
- data/features/support/env.rb +4 -0
- data/features/win_gui.feature +9 -0
- data/lib/note/java/jemmy.jar +0 -0
- data/lib/note/java/jnote.rb +48 -0
- data/lib/note/java/jruby_basics.rb +37 -0
- data/lib/note/java/junquenote_app.rb +262 -0
- data/lib/note/java/note_spec.rb +20 -0
- data/lib/note/win/locknote.rb +19 -0
- data/lib/note.rb +15 -0
- data/lib/win_gui/constants.rb +66 -0
- data/lib/win_gui/string_extensions.rb +24 -0
- data/lib/win_gui/win_gui.rb +274 -0
- data/lib/win_gui/window.rb +70 -0
- data/lib/win_gui.rb +3 -0
- data/spec/note/win/locknote_spec.rb +7 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/test_apps/locknote/LockNote.exe +0 -0
- data/spec/win_gui/string_extensions_spec.rb +61 -0
- data/spec/win_gui/win_gui_spec.rb +733 -0
- data/spec/win_gui/window_spec.rb +124 -0
- metadata +251 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
|
3
|
+
<!--
|
|
4
|
+
! Excerpted from "Scripted GUI Testing With Ruby",
|
|
5
|
+
! published by The Pragmatic Bookshelf.
|
|
6
|
+
! Copyrights apply to this code. It may not be used to create training material,
|
|
7
|
+
! courses, books, articles, and the like. Contact us if you are in doubt.
|
|
8
|
+
! We make no guarantees that this code is fit for any purpose.
|
|
9
|
+
! Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<head>
|
|
14
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
15
|
+
<title>Drag and Drop</title>
|
|
16
|
+
<script src="prototype.js" type="text/javascript"></script>
|
|
17
|
+
<script src="scriptaculous.js?load=effects,dragdrop" type="text/javascript"></script>
|
|
18
|
+
<style type="text/css">
|
|
19
|
+
body {
|
|
20
|
+
font-family: "Frutiger", "Univers", "Helvetica Neue", arial, helvetica, sans-serif;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
ul {
|
|
24
|
+
list-style-image: none;
|
|
25
|
+
list-style-type: none;
|
|
26
|
+
margin-left: 0px;
|
|
27
|
+
padding-left: 0px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ul li {
|
|
31
|
+
margin-bottom: 5px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
span.drag {
|
|
35
|
+
background-color: black;
|
|
36
|
+
color: white;
|
|
37
|
+
cursor: move;
|
|
38
|
+
padding: 1px;
|
|
39
|
+
font-size: small;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
42
|
+
</head>
|
|
43
|
+
<body>
|
|
44
|
+
<h3>Jokes to use in the book</h3>
|
|
45
|
+
<p>
|
|
46
|
+
<a href="#" id="reorder" onclick="setTimeout('$$(\'.drag\').invoke(\'toggle\');', 1000);">Reorder</a>
|
|
47
|
+
</p>
|
|
48
|
+
<ul class="sortabledemo" id="jokelist">
|
|
49
|
+
<li id="bar">
|
|
50
|
+
<span class="drag" style="display: none;">DRAG</span>
|
|
51
|
+
<span class="joke">The one about the guy who walks into a bar</span>
|
|
52
|
+
</li>
|
|
53
|
+
<li id="doctor">
|
|
54
|
+
<span class="drag" style="display: none;">DRAG</span>
|
|
55
|
+
<span class="joke">The one about the doctor, lawyer, and programmer</span>
|
|
56
|
+
</li>
|
|
57
|
+
<li id="heaven">
|
|
58
|
+
<span class="drag" style="display: none;">DRAG</span>
|
|
59
|
+
<span class="joke">The one about the people lined up to get into Heaven</span>
|
|
60
|
+
</li>
|
|
61
|
+
<li id="dangerous">
|
|
62
|
+
<span class="drag" style="display: none;">DRAG</span>
|
|
63
|
+
<span class="joke">The one that's so funny I have to hire a separate typist for each word</span>
|
|
64
|
+
</li>
|
|
65
|
+
<li id="offensive">
|
|
66
|
+
<span class="drag" style="display: none;">DRAG</span>
|
|
67
|
+
<span class="joke">The really offensive one that's going to get me in a lot of trouble</span>
|
|
68
|
+
</li>
|
|
69
|
+
</ul>
|
|
70
|
+
|
|
71
|
+
<script type="text/javascript">
|
|
72
|
+
// <![CDATA[
|
|
73
|
+
Sortable.create("jokelist",
|
|
74
|
+
{dropOnEmpty: true,
|
|
75
|
+
handle: 'drag',
|
|
76
|
+
containment: ["jokelist"],
|
|
77
|
+
constraint: false});
|
|
78
|
+
// ]]>
|
|
79
|
+
</script>
|
|
80
|
+
</body>
|
|
81
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
|
|
10
|
+
require 'spec/runner/formatter/html_formatter'
|
|
11
|
+
|
|
12
|
+
Spec::Runner.configure do |config|
|
|
13
|
+
config.before :all do
|
|
14
|
+
$example_num = 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
config.after do
|
|
18
|
+
`screencapture #{$example_num}.png` #(1)
|
|
19
|
+
$example_num += 1
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HtmlCapture < Spec::Runner::Formatter::HtmlFormatter
|
|
27
|
+
def extra_failure_content(failure)
|
|
28
|
+
img = %Q(<img src="#{example_number}.png"
|
|
29
|
+
alt="" width="25%" height="25%" />)
|
|
30
|
+
super(failure) + img
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
require 'selenium'
|
|
12
|
+
|
|
13
|
+
class JokeList
|
|
14
|
+
def initialize
|
|
15
|
+
@browser = Selenium::SeleniumDriver.new \
|
|
16
|
+
'localhost', 4444, '*firefox', "http://localhost:8000", 10000
|
|
17
|
+
|
|
18
|
+
@browser.start
|
|
19
|
+
@browser.open 'http://localhost:8000/dragdrop.html'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def close
|
|
23
|
+
@browser.stop
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class JokeList
|
|
31
|
+
Reorder = '//a[@id="reorder"]'
|
|
32
|
+
Draggable = 'selenium.browserbot.findElement("css=.drag").visible()' #(1)
|
|
33
|
+
Locked = '!' + Draggable
|
|
34
|
+
|
|
35
|
+
def move(from_order, to_order)
|
|
36
|
+
from_element = "//li[#{from_order}]/span[@class='drag']"
|
|
37
|
+
to_element = "//li[#{to_order}]/span[@class='drag']"
|
|
38
|
+
|
|
39
|
+
@browser.click Reorder
|
|
40
|
+
@browser.wait_for_condition Draggable, 2000 #(2)
|
|
41
|
+
|
|
42
|
+
@browser.drag_and_drop_to_object from_element, to_element
|
|
43
|
+
|
|
44
|
+
@browser.click Reorder
|
|
45
|
+
@browser.wait_for_condition Locked, 2000 #(3)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class JokeList
|
|
53
|
+
def order(item)
|
|
54
|
+
@browser.get_element_index(item).to_i + 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class JokeList
|
|
62
|
+
def items
|
|
63
|
+
num_items = @browser.get_xpath_count('//li').to_i
|
|
64
|
+
(1..num_items).map {|i| @browser.get_text "//li[#{i}]/span[2]"}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'joke_list'
|
|
10
|
+
|
|
11
|
+
describe JokeList do
|
|
12
|
+
before do
|
|
13
|
+
@list = JokeList.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after do
|
|
17
|
+
@list.close
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
it 'lets me drag an item to the end' do
|
|
22
|
+
@list.order('doctor').should == 2
|
|
23
|
+
@list.move 2, 5
|
|
24
|
+
@list.order('doctor').should == 5
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
it 'lets me drag multiple items to sort' do
|
|
30
|
+
original = @list.items
|
|
31
|
+
|
|
32
|
+
original.length.downto(1) do |last_pos|
|
|
33
|
+
subset = @list.items[0..last_pos - 1]
|
|
34
|
+
max_pos = subset.index(subset.max) + 1
|
|
35
|
+
@list.move max_pos, last_pos
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@list.items.should == original.sort
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
describe 'Searching for Ruby' do
|
|
10
|
+
before :all do
|
|
11
|
+
@search = BookSearch.new
|
|
12
|
+
@results = @search.find 'Ruby'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
after :all do
|
|
16
|
+
@search.close
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should find the Pickaxe book' do
|
|
20
|
+
book = @results['Programming Ruby']
|
|
21
|
+
book.should_not be_nil
|
|
22
|
+
book[:authors].should include('Dave Thomas')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should not find the Ajax book' do
|
|
26
|
+
@results.should_not have_key('Pragmatic Ajax')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should fail (on purpose) to find Gilgamesh' do
|
|
30
|
+
@results.should have_key('Gilgamesh') #(1)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
require 'selenium'
|
|
12
|
+
|
|
13
|
+
browser = Selenium::SeleniumDriver.new \
|
|
14
|
+
'localhost', 4444, '*firefox', 'http://www.pragprog.com', 10000 #(1)
|
|
15
|
+
|
|
16
|
+
browser.start
|
|
17
|
+
browser.open 'http://www.pragprog.com'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
browser.type '//input[@id="q"]', 'Ruby' #(2)
|
|
23
|
+
browser.click '//button[@class="go"]' #(3)
|
|
24
|
+
browser.wait_for_page_to_load 5000
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
num_results = browser.get_xpath_count('//table[@id="bookshelf"]//tr').to_i
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
results = (1..num_results).map do |n|
|
|
35
|
+
element = "xpath=/descendant::td[@class='description'][#{n}]/h4/a" #(4)
|
|
36
|
+
title = browser.get_text(element)
|
|
37
|
+
url = browser.get_attribute(element + '@href') #(5)
|
|
38
|
+
|
|
39
|
+
{:title => title, :url => url, :element => element}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
results.each do |r|
|
|
43
|
+
puts 'Title: ' + r[:title]
|
|
44
|
+
puts 'Link: ' + r[:url]
|
|
45
|
+
puts
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
pickaxe = results.find {|r| r[:title].include? 'Programming Ruby 3'}
|
|
52
|
+
browser.click pickaxe[:element]
|
|
53
|
+
browser.wait_for_page_to_load 5000
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# The next part will fail unless we change
|
|
58
|
+
# the browser type above to '*chrome'.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
browser.click '//button[@class="add-to-cart"]'
|
|
62
|
+
browser.wait_for_page_to_load 5000
|
|
63
|
+
|
|
64
|
+
browser.open 'https://secure.pragprog.com/login'
|
|
65
|
+
browser.wait_for_page_to_load 5000
|
|
66
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'selenium'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
browser = Selenium::SeleniumDriver.new \
|
|
14
|
+
'localhost', 4444, '*chrome', 'http://www.pragprog.com', 10000
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
browser.start
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
browser.open 'http://www.pragprog.com/community'
|
|
21
|
+
browser.click '//div[text()="Dojo Foundation"]/following-sibling::ul/li/a'
|
|
22
|
+
browser.wait_for_page_to_load 5000
|
|
23
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'webrick'
|
|
10
|
+
include WEBrick
|
|
11
|
+
|
|
12
|
+
s = HTTPServer.new :Port => 8000, :DocumentRoot => Dir.pwd
|
|
13
|
+
trap('INT') {s.shutdown}
|
|
14
|
+
s.start
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'win32/guitest'
|
|
10
|
+
require 'win32/guitest_svn' #(1)
|
|
11
|
+
|
|
12
|
+
include Win32::GuiTest
|
|
13
|
+
|
|
14
|
+
system 'start "" "C:/Windows/System32/notepad.exe"'
|
|
15
|
+
sleep 1
|
|
16
|
+
|
|
17
|
+
w = findWindowLike(nil, /^Untitled - Notepad$/).first
|
|
18
|
+
w.sendkeys 'This is some text'
|
|
19
|
+
w.sendkeys ctrl('a')
|
|
20
|
+
w.sendkeys 'And this is its replacement'
|
|
21
|
+
|
|
22
|
+
e = w.children.find {|c| c.classname == 'Edit'}
|
|
23
|
+
puts e.windowText #(2)
|
|
24
|
+
|
|
25
|
+
w.sendkeys alt(key('F4'))
|
|
26
|
+
sleep 0.5
|
|
27
|
+
|
|
28
|
+
d = findWindowLike(nil, /^Notepad$/).first
|
|
29
|
+
d.sendkeys 'n'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'wet-winobj'
|
|
10
|
+
require 'winobjects/WinLabel'
|
|
11
|
+
require 'winobjects/WinCheckbox'
|
|
12
|
+
require 'winobjects/WinRadio'
|
|
13
|
+
|
|
14
|
+
include Wet::WinUtils
|
|
15
|
+
include Wet::Winobjects
|
|
16
|
+
|
|
17
|
+
system 'start "" "C:/Windows/System32/notepad.exe"'
|
|
18
|
+
sleep 1
|
|
19
|
+
|
|
20
|
+
w = app_window 'title' => 'Untitled - Notepad'
|
|
21
|
+
|
|
22
|
+
e = w.child_objects.first
|
|
23
|
+
e.set 'This is some text'
|
|
24
|
+
e.set 'And this is its replacement'
|
|
25
|
+
puts e.text
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'win32ole'
|
|
10
|
+
|
|
11
|
+
wsh = WIN32OLE.new 'Wscript.Shell'
|
|
12
|
+
|
|
13
|
+
wsh.Exec 'notepad'
|
|
14
|
+
sleep 1
|
|
15
|
+
wsh.AppActivate 'Untitled - Notepad'
|
|
16
|
+
|
|
17
|
+
wsh.SendKeys 'This is some text'
|
|
18
|
+
|
|
19
|
+
wsh.SendKeys '%EA'
|
|
20
|
+
wsh.SendKeys 'And this is its replacement'
|
|
21
|
+
wsh.SendKeys '%{F4}'
|
|
22
|
+
|
|
23
|
+
if wsh.AppActivate 'Notepad'
|
|
24
|
+
wsh.SendKeys 'n'
|
|
25
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
describe 'The main window' do
|
|
10
|
+
it 'launches with a welcome message'
|
|
11
|
+
it 'exits without a prompt if nothing has changed'
|
|
12
|
+
it 'prompts before exiting if the document has changed'
|
|
13
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
require 'java'
|
|
10
|
+
require 'jemmy.jar'
|
|
11
|
+
require 'junquenote_app'
|
|
12
|
+
|
|
13
|
+
include_class 'org.netbeans.jemmy.JemmyProperties'
|
|
14
|
+
include_class 'org.netbeans.jemmy.TestOut'
|
|
15
|
+
|
|
16
|
+
%w(Frame TextArea MenuBar Dialog Button).each do |o|
|
|
17
|
+
include_class "org.netbeans.jemmy.operators.J#{o}Operator"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
JemmyProperties.set_current_output TestOut.get_null_output
|
|
21
|
+
JemmyProperties.set_current_timeout 'DialogWaiter.WaitDialogTimeout', 3000
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Note
|
|
25
|
+
def initialize
|
|
26
|
+
JunqueNoteApp.new
|
|
27
|
+
@main_window = JFrameOperator.new 'JunqueNote'
|
|
28
|
+
|
|
29
|
+
puts "The main window's object ID is #{@main_window.object_id}."
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def type_in(message)
|
|
33
|
+
edit = JTextAreaOperator.new @main_window
|
|
34
|
+
edit.type_text "this is some text"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def text
|
|
39
|
+
edit = JTextAreaOperator.new @main_window #(1)
|
|
40
|
+
edit.text
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def exit!
|
|
45
|
+
menu = JMenuBarOperator.new @main_window
|
|
46
|
+
menu.push_menu_no_block 'File|Exit', '|'
|
|
47
|
+
|
|
48
|
+
dialog = JDialogOperator.new "Quittin' time"
|
|
49
|
+
button = JButtonOperator.new dialog, "No"
|
|
50
|
+
button.push
|
|
51
|
+
|
|
52
|
+
@prompted = true
|
|
53
|
+
rescue Exception => e
|
|
54
|
+
puts e.inspect
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def has_prompted?
|
|
58
|
+
@prompted
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
# Ruby supports the notion of "open classes;" that is, classes that can be
|
|
10
|
+
# defined in one place and modified later. We'll use this technique to
|
|
11
|
+
# build up the LockNote class piece by piece for the examples. In the real
|
|
12
|
+
# world, LockNote would be defined in one piece.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Note
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
require 'Win32API' #(1)
|
|
23
|
+
|
|
24
|
+
def user32(name, param_types, return_value) #(2)
|
|
25
|
+
Win32API.new 'user32', name, param_types, return_value
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
KEYEVENTF_KEYDOWN = 0
|
|
29
|
+
KEYEVENTF_KEYUP = 2
|
|
30
|
+
|
|
31
|
+
WM_SYSCOMMAND = 0x0112
|
|
32
|
+
SC_CLOSE = 0xF060
|
|
33
|
+
|
|
34
|
+
IDNO = 7
|
|
35
|
+
|
|
36
|
+
MOUSEEVENTF_LEFTDOWN = 0x0002
|
|
37
|
+
MOUSEEVENTF_LEFTUP = 0x0004
|
|
38
|
+
|
|
39
|
+
WM_GETTEXT = 0x000D
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Note
|
|
43
|
+
def initialize
|
|
44
|
+
find_window = user32 'FindWindow', ['P', 'P'], 'L'
|
|
45
|
+
|
|
46
|
+
system 'start "" "C:/LockNote/LockNote.exe"'
|
|
47
|
+
|
|
48
|
+
sleep 0.2 while (@main_window = find_window.call \
|
|
49
|
+
nil, 'LockNote - Steganos LockNote') <= 0
|
|
50
|
+
|
|
51
|
+
puts "The main window's handle is #{@main_window}."
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def type_in(message)
|
|
55
|
+
keybd_event = user32 'keybd_event', ['I', 'I', 'L', 'L'], 'V'
|
|
56
|
+
|
|
57
|
+
message.upcase.each_byte do |b| #(3)
|
|
58
|
+
keybd_event.call b, 0, KEYEVENTF_KEYDOWN, 0
|
|
59
|
+
sleep 0.05
|
|
60
|
+
keybd_event.call b, 0, KEYEVENTF_KEYUP, 0
|
|
61
|
+
sleep 0.05
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def text
|
|
67
|
+
find_window_ex = user32 'FindWindowEx', ['L', 'L', 'P', 'P'], 'L'
|
|
68
|
+
|
|
69
|
+
send_message = user32 'SendMessage', ['L', 'L', 'L', 'P'], 'L'
|
|
70
|
+
|
|
71
|
+
edit = find_window_ex.call @main_window, 0, 'ATL:00434310', nil
|
|
72
|
+
|
|
73
|
+
buffer = '\0' * 2048 #(4)
|
|
74
|
+
send_message.call edit, WM_GETTEXT, buffer.length, buffer
|
|
75
|
+
|
|
76
|
+
return buffer
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def exit!
|
|
81
|
+
begin
|
|
82
|
+
find_window = user32 'FindWindow', ['P', 'P'], 'L'
|
|
83
|
+
|
|
84
|
+
post_message = user32 'PostMessage', ['L', 'L', 'L', 'L'], 'L'
|
|
85
|
+
|
|
86
|
+
post_message.call @main_window, WM_SYSCOMMAND, SC_CLOSE, 0
|
|
87
|
+
|
|
88
|
+
# You might need a slight delay here.
|
|
89
|
+
sleep 0.5
|
|
90
|
+
|
|
91
|
+
get_dlg_item = user32 'GetDlgItem', ['L', 'L'], 'L'
|
|
92
|
+
|
|
93
|
+
dialog = timeout(3) do
|
|
94
|
+
sleep 0.2 while (h = find_window.call \
|
|
95
|
+
nil, 'Steganos LockNote') <= 0; h
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
button = get_dlg_item.call dialog, IDNO
|
|
99
|
+
|
|
100
|
+
get_window_rect = user32 'GetWindowRect', ['L', 'P'], 'I'
|
|
101
|
+
|
|
102
|
+
rectangle = [0, 0, 0, 0].pack 'LLLL'
|
|
103
|
+
get_window_rect.call button, rectangle
|
|
104
|
+
left, top, right, bottom = rectangle.unpack 'LLLL'
|
|
105
|
+
|
|
106
|
+
puts "The No button is #{right - left} pixels wide."
|
|
107
|
+
|
|
108
|
+
set_cursor_pos = user32 'SetCursorPos', ['L', 'L'], 'I'
|
|
109
|
+
|
|
110
|
+
mouse_event = user32 'mouse_event', ['L', 'L', 'L', 'L', 'L'], 'V'
|
|
111
|
+
|
|
112
|
+
center = [(left + right) / 2, (top + bottom) / 2]
|
|
113
|
+
|
|
114
|
+
set_cursor_pos.call *center #(5)
|
|
115
|
+
|
|
116
|
+
mouse_event.call MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
|
|
117
|
+
mouse_event.call MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
|
|
118
|
+
|
|
119
|
+
@prompted = true
|
|
120
|
+
rescue TimeoutError
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def has_prompted?
|
|
126
|
+
@prompted
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#---
|
|
2
|
+
# Excerpted from "Scripted GUI Testing With Ruby",
|
|
3
|
+
# published by The Pragmatic Bookshelf.
|
|
4
|
+
# Copyrights apply to this code. It may not be used to create training material,
|
|
5
|
+
# courses, books, articles, and the like. Contact us if you are in doubt.
|
|
6
|
+
# We make no guarantees that this code is fit for any purpose.
|
|
7
|
+
# Visit http://www.pragmaticprogrammer.com/titles/idgtr for more book information.
|
|
8
|
+
#---
|
|
9
|
+
describe 'The main window' do
|
|
10
|
+
|
|
11
|
+
it 'launches with a welcome message' do
|
|
12
|
+
note = Note.new #(1)
|
|
13
|
+
note.text.should include('Welcome') #(2)
|
|
14
|
+
note.exit! #(3)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
it 'exits without a prompt if nothing has changed' do
|
|
20
|
+
note = Note.new
|
|
21
|
+
note.exit!
|
|
22
|
+
note.should_not have_prompted
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'prompts before exiting if the document has changed' do
|
|
26
|
+
note = Note.new
|
|
27
|
+
note.type_in "changed"
|
|
28
|
+
note.exit!
|
|
29
|
+
note.should have_prompted
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|