Permalink
Newer
Older
100644 656 lines (462 sloc) 22.9 KB
1
= Capybara
Nov 4, 2009
2
Nov 16, 2009
3
* http://github.com/jnicklas/capybara
Nov 4, 2009
4
5
== Description:
Nov 4, 2009
6
7
Capybara aims to simplify the process of integration testing Rack applications,
8
such as Rails, Sinatra or Merb. Capybara simulates how a real user would
9
interact with a web application. It is agnostic about the driver running your
10
tests and currently comes with Rack::Test and Selenium support built in.
11
HtmlUnit and env.js are supported through external gems.
Nov 4, 2009
12
Feb 4, 2011
13
A complete reference is available at
14
{at rubydoc.info}[http://rubydoc.info/github/jnicklas/capybara/master].
16
== Install:
17
18
Install as a gem:
19
20
sudo gem install capybara
21
22
On OSX you may have to install libffi, you can install it via MacPorts with:
23
24
sudo port install libffi
25
26
== Development:
27
28
* Source hosted at {GitHub}[http://github.com/jnicklas/capybara].
29
* Please direct questions, discussions at the {mailing list}[http://groups.google.com/group/ruby-capybara].
Nov 24, 2009
30
* Report issues on {GitHub Issues}[http://github.com/jnicklas/capybara/issues]
31
32
Pull requests are very welcome! Make sure your patches are well tested, Capybara is
33
a testing tool after all. Please create a topic branch for every separate change
34
you make.
36
Capybara uses bundler in development. To set up a development environment, simply do:
37
Feb 4, 2011
38
git submodule update --init
39
gem install bundler --pre
40
bundle install
41
42
== Using Capybara with Cucumber
Nov 4, 2009
43
44
Capybara is built to work nicely with Cucumber. Support for Capybara is built into
45
cucumber-rails. In your Rails app, just run:
Nov 4, 2009
46
47
rails generate cucumber:install --capybara
Nov 4, 2009
48
49
And everything should be set up and ready to go.
50
51
If you want to use Capybara with Cucumber outside Rails (for example with Merb
52
or Sinatra), you'll need to require Capybara and set the Rack app manually:
53
54
require 'capybara/cucumber'
55
Capybara.app = MyRackApp
56
57
Now you can use it in your steps:
58
59
When /I sign in/ do
60
within("#session") do
61
fill_in 'Login', :with => 'user@example.com'
62
fill_in 'Password', :with => 'password'
63
end
64
click_link 'Sign in'
65
end
Nov 4, 2009
66
67
Capybara sets up some {tags}[http://wiki.github.com/aslakhellesoy/cucumber/tags]
68
for you to use in Cucumber. Often you'll want to run only some scenarios with a
69
driver that supports JavaScript, Capybara makes this easy: simply tag the
70
scenario (or feature) with <tt>@javascript</tt>:
71
72
@javascript
73
Scenario: do something Ajaxy
74
When I click the Ajax link
75
...
76
77
You can change which driver Capybara uses for JavaScript:
78
79
Capybara.javascript_driver = :culerity
80
81
There are also explicit <tt>@selenium</tt>, <tt>@culerity</tt> and
82
<tt>@rack_test</tt> tags set up for you.
83
84
== Using Capybara with RSpec
85
86
If you prefer RSpec to using Cucumber, you can use the built in RSpec support
87
by adding the following line (typically to your <tt>spec_helper.rb</tt> file):
88
89
require 'capybara/rspec'
90
91
You can now use it in your examples:
92
93
describe "the signup process", :type => :request do
94
it "signs me in" do
95
within("#session") do
96
fill_in 'Login', :with => 'user@example.com'
97
fill_in 'Password', :with => 'password'
98
end
99
click_link 'Sign in'
100
end
101
end
102
103
Capybara is only included for examples with <tt>:type => :request</tt> (or
104
<tt>:acceptance</tt> for compatibility).
105
106
If you use the <tt>rspec-rails</tt> gem, <tt>:type => :request</tt>
107
is automatically set on all files under <tt>spec/requests</tt> (and,
108
synonymously, <tt>spec/integration</tt> and <tt>spec/acceptance</tt>), so
109
that's a good directory to place your Capybara specs in. <tt>rspec-rails</tt>
110
will also automatically include Capybara in <tt>:controller</tt> and
111
<tt>:mailer</tt> examples.
112
113
RSpec's metadata feature can be used to switch to a different driver. Use
114
<tt>:js => true</tt> to switch to the javascript driver, or provide a
115
<tt>:driver</tt> option to switch to one specific driver. For example:
116
117
describe 'some stuff which requires js', :js => true do
118
it 'will use the default js driver'
119
it 'will switch to one specific driver', :driver => :celerity
120
end
121
122
Capybara also comes with a built in DSL for creating descriptive acceptance tests:
123
124
feature "signing up" do
125
background do
126
User.make(:email => 'user@example.com', :password => 'caplin')
127
end
128
129
scenario "signing in with correct credentials" do
130
within("#session") do
131
fill_in 'Login', :with => 'user@example.com'
132
fill_in 'Password', :with => 'caplin'
133
end
134
click_link 'Sign in'
135
end
136
end
137
138
Note that Capybara's built in RSpec support only works with RSpec 2.0 or later.
139
You'll need to roll your own for earlier versions of RSpec.
140
141
== Using Capybara with Test::Unit
142
143
To use Capybara with Test::Unit, include the DSL (<tt>include Capybara</tt> up
144
until version 0.4.x, <tt>include Capybara::DSL</tt> for newer versions) in
145
whatever test class you are using. For example, if your classes derive from
146
<tt>ActionDispatch::IntegrationTest</tt>, use
147
148
class ActionDispatch::IntegrationTest
149
include Capybara::DSL
150
end
151
152
Test::Unit does not support selecting the driver through test metadata, but you
153
can switch the driver for specific classes using the <tt>setup</tt> and
154
<tt>teardown</tt> methods. See the section "Selecting the Driver".
155
156
== Using Capybara with Ruby on Rails
157
158
If you are using the Rails framework, add this line to automatically configure
159
Capybara to test against your Rails application:
Feb 4, 2011
161
require 'capybara/rails'
162
163
== Using Capybara with Rack
164
165
If you're using Capybara with a non-Rails Rack application, set
166
<tt>Capybara.app</tt> to your application class:
167
168
Capybara.app = MyRackApp
169
170
== Drivers
171
172
Capybara uses the same DSL to drive a variety of browser and headless drivers.
173
174
=== Selecting the Driver
175
176
By default, Capybara uses the <tt>:rack_test</tt> driver, which is fast but does not
177
support JavaScript. You can set up a different default driver for your
178
features. For example if you'd prefer to run everything in Selenium, you could
179
do:
180
181
Capybara.default_driver = :selenium
182
183
However, if you are using RSpec or Cucumber, you may instead want to consider
184
leaving the faster <tt>:rack_test</tt> as the +default_driver+, and marking only those
185
tests that require a JavaScript-capable driver using <tt>:js => true</tt> or
186
<tt>@javascript</tt>, respectively. By default, JavaScript tests are run using the
187
<tt>:selenium</tt> driver. You can change this by setting
188
<tt>Capybara.javascript_driver</tt>.
190
You can also change the driver temporarily (typically in the Before/setup and
191
After/teardown blocks):
192
193
Capybara.current_driver = :culerity # temporarily select different driver
194
... tests ...
195
Capybara.use_default_driver # switch back to default driver
196
197
Note that switching the driver creates a new session, so you may not be able to
198
switch in the middle of a test.
200
=== Selenium
201
202
At the moment, Capybara supports {Selenium 2.0
203
(Webdriver)}[http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver],
204
*not* Selenium RC. Provided Firefox is installed, everything is set up for you,
205
and you should be able to start using Selenium right away.
206
207
By default Capybara tries to synchronize Ajax requests, so it will wait for
208
Ajax requests to finish after you've interacted with the page. You can switch
209
off this behaviour by setting the driver option <tt>:resynchronize</tt> to
210
<tt>false</tt>. See the section on configuring drivers.
211
212
Note: Selenium does not support transactional fixtures; see the section
213
"Transactional Fixtures" below.
214
215
=== HtmlUnit
217
There are three different drivers, maintained as external gems, that you can
218
use to drive {HtmlUnit}[http://htmlunit.sourceforge.net/]:
220
* {Akephalos}[https://github.com/bernerdschaefer/akephalos] might be the best
221
HtmlUnit driver right now.
222
223
* {Celerity}[https://github.com/sobrinho/capybara-celerity] only runs on JRuby,
224
so you'll need to install the celerity gem under JRuby: <tt>jruby -S gem
225
install celerity</tt>
226
227
* {Culerity}[https://github.com/sobrinho/capybara-culerity]: Install celerity
228
as noted above, and make sure that JRuby is in your path. Note that Culerity
229
does not seem to be working under Ruby 1.9 at the moment.
230
231
Note: HtmlUnit does not support transactional fixtures; see the section
232
"Transactional Fixtures" below.
233
234
=== env.js
May 19, 2010
235
236
The {capybara-envjs driver}[http://github.com/smparkes/capybara-envjs]
237
uses the envjs gem ({GitHub}[http://github.com/smparkes/env-js],
238
{rubygems.org}[http://rubygems.org/gems/envjs]) to interpret
239
JavaScript outside the browser. The driver is installed by installing the capybara-envjs gem:
May 19, 2010
241
gem install capybara-envjs
May 19, 2010
243
More info about the driver and env.js are available through the links above. The envjs gem only supports
244
Ruby 1.8.7 at this time.
245
246
Note: Envjs does not support transactional fixtures; see the section
247
"Transactional Fixtures" below.
248
250
Feb 4, 2011
251
Capybara's DSL (domain-specific language) is inspired by Webrat. While
252
backwards compatibility is retained in a lot of cases, there are certain
253
important differences. Unlike in Webrat, all searches in Capybara are *case
254
sensitive*. This is because Capybara heavily uses XPath, which doesn't support
255
case insensitivity.
Dec 25, 2009
257
=== Navigating
258
Feb 4, 2011
259
You can use the
260
<tt>{visit}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method]</tt>
Feb 4, 2011
261
method to navigate to other pages:
Dec 25, 2009
262
263
visit('/projects')
264
visit(post_comments_path(post))
265
266
The visit method only takes a single parameter, the request method is *always*
267
GET.
268
Feb 4, 2011
269
You can get the {current
270
path}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#current_path-instance_method]
271
of the browsing session for test assertions:
272
273
current_path.should == post_comments_path(post)
274
Dec 25, 2009
275
=== Clicking links and buttons
276
277
<em>Full reference: {Capybara::Node::Actions}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions]</em>
278
Dec 25, 2009
279
You can interact with the webapp by following links and buttons. Capybara
280
automatically follows any redirects, and submits forms associated with buttons.
281
282
click_link('id-of-link')
283
click_link('Link Text')
284
click_button('Save')
Feb 4, 2011
285
click_on('Link Text') # clicks on either links or buttons
286
click_on('Button Value')
Dec 25, 2009
287
288
=== Interacting with forms
289
290
<em>Full reference: {Capybara::Node::Actions}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions]</em>
291
292
There are a number of tools for interacting with form elements:
Dec 25, 2009
293
294
fill_in('First Name', :with => 'John')
295
fill_in('Password', :with => 'Seekrit')
296
fill_in('Description', :with => 'Really Long Text...')
297
choose('A Radio Button')
Dec 25, 2009
298
check('A Checkbox')
299
uncheck('A Checkbox')
300
attach_file('Image', '/path/to/image.jpg')
301
select('Option', :from => 'Select Box')
302
303
=== Querying
304
305
<em>Full reference: {Capybara::Node::Matchers}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers]</em>
306
Dec 25, 2009
307
Capybara has a rich set of options for querying the page for the existence of
308
certain elements, and working with and manipulating those elements.
Dec 25, 2009
309
310
page.has_selector?('table tr')
311
page.has_selector?(:xpath, '//table/tr')
312
page.has_no_selector?(:content)
313
Dec 25, 2009
314
page.has_xpath?('//table/tr')
315
page.has_css?('table tr.foo')
316
page.has_content?('foo')
318
You can use these with RSpec's magic matchers:
Dec 25, 2009
319
320
page.should have_selector('table tr')
321
page.should have_selector(:xpath, '//table/tr')
322
page.should have_no_selector(:content)
323
Dec 25, 2009
324
page.should have_xpath('//table/tr')
325
page.should have_css('table tr.foo')
326
page.should have_content('foo')
327
page.should have_no_content('foo')
328
329
Note that <tt>page.should have_no_xpath</tt> is preferred over
330
<tt>page.should_not have_xpath</tt>. Read the section on asynchronous JavaScript
331
for an explanation.
Dec 25, 2009
332
333
If all else fails, you can also use the
334
<tt>{page.html}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#html-instance_method]</tt>
335
method to test against the raw HTML:
336
337
page.html.should match /<span>.../i
338
339
=== Finding
340
341
<em>Full reference: {Capybara::Node::Finders}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders]</em>
342
343
You can also find specific elements, in order to manipulate them:
Dec 25, 2009
344
345
find_field('First Name').value
346
find_link('Hello').visible?
347
find_button('Send').click
349
find(:xpath, "//table/tr").click
350
find("#overlay").find("h1").click
Dec 25, 2009
351
all('a').each { |a| a[:href] }
352
353
Note that <tt>find</tt> will wait for an element to appear on the page, as explained in the
354
Ajax section. If the element does not appear it will raise an error.
356
These elements all have all the Capybara DSL methods available, so you can restrict them
357
to specific parts of the page:
358
359
find('#navigation').click_link('Home')
360
find('#navigation').should have_button('Sign out')
361
362
=== Scoping
363
364
Capybara makes it possible to restrict certain actions, such as interacting with
365
forms or clicking links and buttons, to within a specific area of the page. For
Feb 4, 2011
366
this purpose you can use the generic
367
<tt>{within}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#within-instance_method]</tt>
Feb 4, 2011
368
method. Optionally you can specify which kind of selector to use.
370
within("li#employee") do
371
fill_in 'Name', :with => 'Jimmy'
372
end
373
374
within(:xpath, "//li[@id='employee']") do
375
fill_in 'Name', :with => 'Jimmy'
376
end
377
378
There are special methods for restricting the scope to a specific fieldset,
379
identified by either an id or the text of the fieldet's legend tag, and to a
380
specific table, identified by either id or text of the table's caption tag.
381
382
within_fieldset('Employee') do
383
fill_in 'Name', :with => 'Jimmy'
384
end
385
386
within_table('Employee') do
387
fill_in 'Name', :with => 'Jimmy'
388
end
389
Dec 25, 2009
390
=== Scripting
391
392
In drivers which support it, you can easily execute JavaScript:
393
394
page.execute_script("$('body').empty()")
395
396
For simple expressions, you can return the result of the script. Note
397
that this may break with more complicated expressions:
Dec 25, 2009
398
399
result = page.evaluate_script('4 + 4');
400
401
=== Debugging
402
403
It can be useful to take a snapshot of the page as it currently is and take a
404
look at it:
405
406
save_and_open_page
407
408
== Transactional fixtures
409
410
Transactional fixtures only work in the default Rack::Test driver, but not for
411
other drivers like Selenium. Cucumber takes care of this automatically, but
412
with Test::Unit or RSpec, you may have to use the
413
{database_cleaner}[https://github.com/bmabey/database_cleaner] gem. See {this
414
explanation}[https://groups.google.com/d/msg/ruby-capybara/JI6JrirL9gM/R6YiXj4gi_UJ]
415
(and code for {solution
416
2}[http://opinionated-programmer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#comment-220]
417
and {solution 3}[http://pastie.org/1745020]) for details.
418
419
== Asynchronous JavaScript (Ajax and friends)
420
421
When working with asynchronous JavaScript, you might come across situations
422
where you are attempting to interact with an element which is not yet present
423
on the page. Capybara automatically deals with this by waiting for elements
424
to appear on the page.
425
426
When issuing instructions to the DSL such as:
427
428
click_link('foo')
429
click_link('bar')
430
page.should have_content('baz')
431
432
If clicking on the *foo* link causes triggers an asynchronous process, such as
433
an Ajax request, which, when complete will add the *bar* link to the page,
434
clicking on the *bar* link would be expeced to fail, since that link doesn't
435
exist yet. However Capybara is smart enought to retry finding the link for a
436
brief period of time before giving up and throwing an error. The same is true of
437
the next line, which looks for the content *baz* on the page; it will retry
438
looking for that content for a brief time. You can adjust how long this period
439
is (the default is 2 seconds):
440
441
Capybara.default_wait_time = 5
442
443
Be aware that because of this behaviour, the following two statements are *not*
444
equivalent, and you should *always* use the latter!
446
page.should_not have_xpath('a')
447
page.should have_no_xpath('a')
448
449
The former would incorrectly wait for the content to appear, since the
450
asynchronous process has not yet removed the element from the page, it would
451
therefore fail, even though the code might be working correctly. The latter
452
correctly waits for the element to disappear from the page.
454
== Using the DSL in unsupported testing frameworks
455
456
You can mix the DSL into any context by including +Capybara::DSL+:
457
Nov 4, 2009
458
Nov 16, 2009
459
require 'capybara'
460
require 'capybara/dsl'
461
Nov 16, 2009
462
Capybara.default_driver = :culerity
465
include Capybara::DSL
466
467
def login!
468
within("//form[@id='session']") do
469
fill_in 'Login', :with => 'user@example.com'
470
fill_in 'Password', :with => 'password'
471
end
472
click_link 'Sign in'
473
end
474
end
475
478
Normally Capybara expects to be testing an in-process Rack application, but you
479
can also use it to talk to a web server running anywhere on the internets, by
480
setting app_host:
481
482
Capybara.current_driver = :selenium
483
Capybara.app_host = 'http://www.google.com'
487
Note that the default driver (<tt>:rack_test</tt>) does not support running
488
against a remote server. With drivers that support it, you can also visit any
489
URL directly:
490
491
visit('http://www.google.com')
492
493
By default Capybara will try to boot a rack application automatically. You
494
might want to switch off Capybara's rack server if you are running against a
495
remote application:
496
497
Capybara.run_server = false
498
499
== Using the sessions manually
501
For ultimate control, you can instantiate and use a
502
{Session}[http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session]
503
manually.
505
require 'capybara'
507
session = Capybara::Session.new(:culerity, my_rack_app)
508
session.within("//form[@id='session']") do
509
session.fill_in 'Login', :with => 'user@example.com'
510
session.fill_in 'Password', :with => 'password'
511
end
512
session.click_link 'Sign in'
514
== XPath, CSS and selectors
515
516
Capybara does not try to guess what kind of selector you are going to give it,
Feb 4, 2011
517
and will always use CSS by default. If you want to use XPath, you'll need to
518
do:
520
within(:xpath, '//ul/li') { ... }
521
find(:xpath, '//ul/li').text
522
find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value
524
Alternatively you can set the default selector to XPath:
526
Capybara.default_selector = :xpath
527
find('//ul/li').text
529
Capybara allows you to add custom selectors, which can be very useful if you
530
find yourself using the same kinds of selectors very often:
531
532
Capybara.add_selector(:id) do
533
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
534
end
535
536
Capybara.add_selector(:row) do
537
xpath { |num| ".//tbody/tr[#{num}]" }
538
end
540
The block given to xpath must always return an XPath expression as a String, or
541
an XPath expression generated through the XPath gem. You can now use these
542
selectors like this:
543
544
find(:id, 'post_123')
545
find(:row, 3)
546
547
You can specify an optional match option which will automatically use the
548
selector if it matches the argument:
550
Capybara.add_selector(:id) do
551
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
552
match { |value| value.is_a?(Symbol) }
553
end
554
555
Now use it like this:
556
557
find(:post_123)
558
559
This :id selector is already built into Capybara by default, so you don't
560
need to add it yourself.
561
562
== Beware the XPath // trap
563
564
In XPath the expression // means something very specific, and it might not be what
565
you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
566
in the current context". As an example:
567
568
page.find(:xpath, '//body').all(:xpath, '//script')
569
570
You might expect this to find all script tags in the body, but actually, it finds all
571
script tags in the entire document, not only those in the body! What you're looking
572
for is the .// expression which means "any descendant of the current node":
573
574
page.find(:xpath, '//body').all(:xpath, './/script')
576
The same thing goes for within:
577
578
within(:xpath, '//body') do
579
page.find(:xpath, './/script')
580
within(:xpath, './/table/tbody') do
581
...
582
end
585
== Configuring and adding drivers
586
587
Capybara makes it convenient to switch between different drivers. It also exposes
588
an API to tweak those drivers with whatever settings you want, or to add your own
589
drivers. This is how to switch the selenium driver to use chrome:
590
591
Capybara.register_driver :selenium do |app|
592
Capybara::Driver::Selenium.new(app, :browser => :chrome)
593
end
594
595
However, it's also possible to give this a different name, so tests can switch
596
between using different browsers effortlessly:
597
598
Capybara.register_driver :selenium_chrome do |app|
599
Capybara::Driver::Selenium.new(app, :browser => :chrome)
600
end
601
602
Whatever is returned from the block should conform to the API described by
603
Capybara::Driver::Base, it does not however have to inherit from this class.
604
Gems can use this API to add their own drivers to Capybara.
605
606
The {Selenium wiki}[http://code.google.com/p/selenium/wiki/RubyBindings] has
607
additional info about how the underlying driver can be configured.
608
609
== Gotchas:
611
* Access to session and request is not possible from the test, Access to
612
response is limited. Some drivers allow access to response headers and HTTP
613
status code, but this kind of functionality is not provided by some drivers,
614
such as Selenium.
Nov 4, 2009
615
616
* Access to Rails specific stuff (such as <tt>controller</tt>) is unavailable,
617
since we're not using Rails' integration testing.
619
* Freezing time: It's common practice to mock out the Time so that features
620
that depend on the current Date work as expected. This can be problematic,
621
since Capybara's Ajax timing uses the system time, resulting in Capybara
622
never timing out and just hanging when a failure occurs. It's still possible to
623
use plugins which allow you to travel in time, rather than freeze time.
624
One such plugin is {Timecop}[http://github.com/jtrupiano/timecop].
625
626
* When using Rack::Test, beware if attempting to visit absolute URLs. For
627
example, a session might not be shared between visits to <tt>posts_path</tt>
628
and <tt>posts_url</tt>. If testing an absolute URL in an Action Mailer email,
629
set <tt>default_url_options</tt> to match the Rails default of
630
<tt>www.example.com</tt>.
631
632
== License:
Nov 4, 2009
633
634
(The MIT License)
635
636
Copyright (c) 2009 Jonas Nicklas
637
638
Permission is hereby granted, free of charge, to any person obtaining
639
a copy of this software and associated documentation files (the
640
'Software'), to deal in the Software without restriction, including
641
without limitation the rights to use, copy, modify, merge, publish,
642
distribute, sublicense, and/or sell copies of the Software, and to
643
permit persons to whom the Software is furnished to do so, subject to
644
the following conditions:
645
646
The above copyright notice and this permission notice shall be
647
included in all copies or substantial portions of the Software.
648
649
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
650
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
651
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
652
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
653
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
654
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
655
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.