capybara-webkit 1.14.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +8 -9
- data/Appraisals +3 -9
- data/Gemfile +0 -1
- data/Gemfile.lock +41 -41
- data/NEWS.md +14 -0
- data/README.md +2 -2
- data/capybara-webkit.gemspec +2 -2
- data/gemfiles/2.15.gemfile +10 -0
- data/gemfiles/master.gemfile +3 -4
- data/lib/capybara/webkit/browser.rb +14 -5
- data/lib/capybara/webkit/driver.rb +14 -1
- data/lib/capybara/webkit/node.rb +39 -24
- data/lib/capybara/webkit/server.rb +38 -5
- data/lib/capybara/webkit/version.rb +1 -1
- data/lib/capybara_webkit_builder.rb +3 -1
- data/spec/driver_spec.rb +110 -21
- data/spec/fixtures/exit_text.rb +9 -0
- data/spec/integration/session_spec.rb +69 -0
- data/spec/node_spec.rb +90 -0
- data/spec/server_spec.rb +9 -2
- data/spec/spec_helper.rb +4 -1
- data/spec/support/matchers/include_response.rb +5 -1
- data/src/CommandFactory.cpp +2 -0
- data/src/Connection.cpp +2 -2
- data/src/Evaluate.cpp +2 -2
- data/src/EvaluateAsync.cpp +54 -0
- data/src/EvaluateAsync.h +14 -0
- data/src/JavascriptInvocation.cpp +37 -13
- data/src/JavascriptInvocation.h +6 -3
- data/src/Node.cpp +9 -1
- data/src/PageLoadingCommand.cpp +4 -4
- data/src/Refresh.cpp +12 -0
- data/src/Refresh.h +10 -0
- data/src/TimeoutCommand.cpp +1 -1
- data/src/WebPage.cpp +8 -7
- data/src/WebPage.h +1 -1
- data/src/WebPageManager.cpp +8 -8
- data/src/WebPageManager.h +1 -1
- data/src/capybara.js +71 -44
- data/src/find_command.h +2 -0
- data/src/webkit_server.pro +4 -0
- metadata +39 -14
- data/gemfiles/2.13.gemfile +0 -11
- data/gemfiles/2.7.gemfile +0 -12
@@ -26,15 +26,23 @@ module Capybara
|
|
26
26
|
discover_port
|
27
27
|
discover_pid
|
28
28
|
forward_output_in_background_thread
|
29
|
+
register_shutdown_hook
|
29
30
|
end
|
30
31
|
|
31
32
|
private
|
32
33
|
|
33
34
|
def open_pipe
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
35
|
+
if IO.respond_to?(:popen4)
|
36
|
+
@pid,
|
37
|
+
@pipe_stdin,
|
38
|
+
@pipe_stdout,
|
39
|
+
@pipe_stderr = IO.popen4(SERVER_PATH)
|
40
|
+
else
|
41
|
+
@pipe_stdin,
|
42
|
+
@pipe_stdout,
|
43
|
+
@pipe_stderr,
|
44
|
+
@wait_thr = Open3.popen3(SERVER_PATH)
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def discover_port
|
@@ -58,7 +66,7 @@ module Capybara
|
|
58
66
|
end
|
59
67
|
|
60
68
|
def discover_pid
|
61
|
-
@pid
|
69
|
+
@pid ||= @wait_thr[:pid]
|
62
70
|
end
|
63
71
|
|
64
72
|
def forward_output_in_background_thread
|
@@ -67,6 +75,31 @@ module Capybara
|
|
67
75
|
IO.copy_stream(@pipe_stderr, @output_target) if @output_target
|
68
76
|
end
|
69
77
|
end
|
78
|
+
|
79
|
+
def register_shutdown_hook
|
80
|
+
@owner_pid = Process.pid
|
81
|
+
at_exit do
|
82
|
+
if Process.pid == @owner_pid
|
83
|
+
kill_process
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def kill_process
|
89
|
+
if @pid
|
90
|
+
if RUBY_PLATFORM =~ /mingw32/
|
91
|
+
Process.kill(9, @pid)
|
92
|
+
else
|
93
|
+
Process.kill("INT", @pid)
|
94
|
+
end
|
95
|
+
Process.wait(@pid)
|
96
|
+
@wait_thr.join if @wait_thr
|
97
|
+
end
|
98
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
99
|
+
# This just means that the webkit_server process has already ended
|
100
|
+
ensure
|
101
|
+
@pid = @wait_thr = nil
|
102
|
+
end
|
70
103
|
end
|
71
104
|
end
|
72
105
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'etc'
|
1
2
|
require "fileutils"
|
2
3
|
require "rbconfig"
|
3
4
|
require "shellwords"
|
@@ -90,7 +91,8 @@ module CapybaraWebkitBuilder
|
|
90
91
|
end
|
91
92
|
|
92
93
|
def make(target = "")
|
93
|
-
|
94
|
+
job_count = Etc.respond_to?(:nprocessors) ? Etc.nprocessors : 1
|
95
|
+
env_hide('CDPATH') { sh("#{make_bin} #{target} --jobs=#{job_count}") }
|
94
96
|
end
|
95
97
|
|
96
98
|
def env_hide(name)
|
data/spec/driver_spec.rb
CHANGED
@@ -554,7 +554,13 @@ describe Capybara::Webkit::Driver do
|
|
554
554
|
|
555
555
|
it "evaluates Javascript and returns an object" do
|
556
556
|
result = driver.evaluate_script(%<({ 'one' : 1 })>)
|
557
|
-
expect(result).to eq
|
557
|
+
expect(result).to eq "one" => 1
|
558
|
+
end
|
559
|
+
|
560
|
+
it "evaluate Javascript and returns an object when the original was readonly" do
|
561
|
+
result = driver.evaluate_script(%<window.getComputedStyle(document.getElementById('greeting'))>)
|
562
|
+
expect(result).to be_a Hash
|
563
|
+
expect(result["zIndex"]).to eq "auto"
|
558
564
|
end
|
559
565
|
|
560
566
|
it "evaluates Javascript and returns true" do
|
@@ -577,6 +583,27 @@ describe Capybara::Webkit::Driver do
|
|
577
583
|
expect(result).to eq [1, 2]
|
578
584
|
end
|
579
585
|
|
586
|
+
it "evaluates asynchronous JS which isn't" do
|
587
|
+
result = driver.evaluate_async_script("arguments[0](4)")
|
588
|
+
expect(result).to eq 4
|
589
|
+
end
|
590
|
+
|
591
|
+
it "evaluates asynchronous JS" do
|
592
|
+
result = driver.evaluate_async_script("setTimeout(function(callback){ callback('jaguar') }, 100, arguments[0])")
|
593
|
+
expect(result).to eq "jaguar"
|
594
|
+
end
|
595
|
+
|
596
|
+
it "evaluates asynchronous JS and returns an object" do
|
597
|
+
result = driver.evaluate_async_script(%<setTimeout(function(callback){ callback({ 'one' : 1 }) }, 100, arguments[0])>)
|
598
|
+
expect(result).to eq "one" => 1
|
599
|
+
end
|
600
|
+
|
601
|
+
it "evaluates asynchronous JS and returns an object when the original was readonly" do
|
602
|
+
result = driver.evaluate_async_script(%<setTimeout(function(callback){ callback(window.getComputedStyle(document.getElementById('greeting'))) }, 100, arguments[0])>)
|
603
|
+
expect(result).to be_a Hash
|
604
|
+
expect(result["zIndex"]).to eq "auto"
|
605
|
+
end
|
606
|
+
|
580
607
|
it "executes Javascript" do
|
581
608
|
driver.execute_script(%<document.getElementById('greeting').innerHTML = 'yo'>)
|
582
609
|
expect(driver.find_xpath("//p[contains(., 'yo')]")).not_to be_empty
|
@@ -605,6 +632,12 @@ describe Capybara::Webkit::Driver do
|
|
605
632
|
expect(driver.find_xpath("//p[@id='greeting'][contains(., 'new content')]")).not_to be_empty
|
606
633
|
end
|
607
634
|
|
635
|
+
it "passes elements as arguments to asynchronous script" do
|
636
|
+
greeting = driver.find_xpath("//p[@id='greeting']").first
|
637
|
+
result = driver.evaluate_async_script(%<arguments[2]([arguments[1], arguments[0]])>, greeting, "a string")
|
638
|
+
expect(result).to eq ["a string", greeting]
|
639
|
+
end
|
640
|
+
|
608
641
|
it "passes arguments to evaaluated Javascript" do
|
609
642
|
expect(driver.evaluate_script(%<arguments[0]>, 3)).to eq 3
|
610
643
|
end
|
@@ -1406,7 +1439,7 @@ describe Capybara::Webkit::Driver do
|
|
1406
1439
|
end
|
1407
1440
|
|
1408
1441
|
it "does not modify the selected attribute of a new selection" do
|
1409
|
-
expect(
|
1442
|
+
expect(driver.evaluate_script("arguments[0].getAttribute('selected')", monkey_option)).to be_nil
|
1410
1443
|
end
|
1411
1444
|
|
1412
1445
|
it "returns the old value when a reset button is clicked" do
|
@@ -1586,35 +1619,49 @@ describe Capybara::Webkit::Driver do
|
|
1586
1619
|
<textarea class="watch"></textarea>
|
1587
1620
|
<input class="watch" type="checkbox"/>
|
1588
1621
|
<input class="watch" type="radio"/>
|
1622
|
+
<select id="single" class="watch">
|
1623
|
+
<option>Single Option 1</option>
|
1624
|
+
<option>Single Option 2</option>
|
1625
|
+
</select>
|
1626
|
+
<select id="multiple" class="watch" multiple="multiple">
|
1627
|
+
<option class="watch" selected="selected">Multiple Option 1</option>
|
1628
|
+
<option class="watch" selected="selected">Multiple Option 2</option>
|
1629
|
+
<option class="watch">Multiple Option 3</option>
|
1630
|
+
<optgroup>
|
1631
|
+
<option class="watch">Multiple Option 4</option>
|
1632
|
+
</optgroup>
|
1633
|
+
</select>
|
1589
1634
|
</form>
|
1590
1635
|
<ul id="events"></ul>
|
1591
1636
|
<script type="text/javascript">
|
1592
1637
|
var events = document.getElementById("events");
|
1593
1638
|
var recordEvent = function (event) {
|
1594
1639
|
var element = document.createElement("li");
|
1595
|
-
|
1640
|
+
var event_description = "";
|
1641
|
+
if (event.target.id)
|
1642
|
+
event_description += event.target.id + '.';
|
1643
|
+
event_description += event.type;
|
1644
|
+
element.innerHTML = event_description;
|
1596
1645
|
events.appendChild(element);
|
1597
1646
|
};
|
1598
1647
|
|
1599
1648
|
var elements = document.getElementsByClassName("watch");
|
1649
|
+
var watched_events = ["focus", "keydown", "keypress", "keyup", "input", "change",
|
1650
|
+
"blur", "mousedown", "mouseup", "click"];
|
1600
1651
|
for (var i = 0; i < elements.length; i++) {
|
1601
|
-
var
|
1602
|
-
|
1603
|
-
|
1604
|
-
element.addEventListener("keypress", recordEvent);
|
1605
|
-
element.addEventListener("keyup", recordEvent);
|
1606
|
-
element.addEventListener("input", recordEvent);
|
1607
|
-
element.addEventListener("change", recordEvent);
|
1608
|
-
element.addEventListener("blur", recordEvent);
|
1609
|
-
element.addEventListener("mousedown", recordEvent);
|
1610
|
-
element.addEventListener("mouseup", recordEvent);
|
1611
|
-
element.addEventListener("click", recordEvent);
|
1652
|
+
for (var j = 0; j < watched_events.length; j++) {
|
1653
|
+
elements[i].addEventListener(watched_events[j], recordEvent);
|
1654
|
+
}
|
1612
1655
|
}
|
1613
1656
|
</script>
|
1614
1657
|
</body></html>
|
1615
1658
|
HTML
|
1616
1659
|
end
|
1617
1660
|
|
1661
|
+
def logged_events
|
1662
|
+
driver.find_xpath("//li").map(&:visible_text)
|
1663
|
+
end
|
1664
|
+
|
1618
1665
|
before { visit("/") }
|
1619
1666
|
|
1620
1667
|
let(:newtext) { '12345' }
|
@@ -1631,29 +1678,49 @@ describe Capybara::Webkit::Driver do
|
|
1631
1678
|
it "triggers text input events on inputs of type #{field_type}" do
|
1632
1679
|
driver.find_xpath("//input[@type='#{field_type}']").first.set(newtext)
|
1633
1680
|
driver.find_xpath("//body").first.click
|
1634
|
-
expect(
|
1681
|
+
expect(logged_events).to eq textevents
|
1635
1682
|
end
|
1636
1683
|
end
|
1637
1684
|
|
1638
1685
|
it "triggers events for cleared inputs" do
|
1639
1686
|
driver.find_xpath("//input[@type='text']").first.set('')
|
1640
1687
|
driver.find_xpath("//body").first.click
|
1641
|
-
expect(
|
1688
|
+
expect(logged_events).to include("change")
|
1642
1689
|
end
|
1643
1690
|
|
1644
1691
|
it "triggers textarea input events" do
|
1645
1692
|
driver.find_xpath("//textarea").first.set(newtext)
|
1646
|
-
expect(
|
1693
|
+
expect(logged_events).to eq keyevents
|
1647
1694
|
end
|
1648
1695
|
|
1649
1696
|
it "triggers radio input events" do
|
1650
1697
|
driver.find_xpath("//input[@type='radio']").first.set(true)
|
1651
|
-
expect(
|
1698
|
+
expect(logged_events).to eq %w(mousedown focus mouseup change click)
|
1652
1699
|
end
|
1653
1700
|
|
1654
1701
|
it "triggers checkbox events" do
|
1655
1702
|
driver.find_xpath("//input[@type='checkbox']").first.set(true)
|
1656
|
-
expect(
|
1703
|
+
expect(logged_events).to eq %w(mousedown focus mouseup change click)
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
it "triggers select events" do
|
1707
|
+
driver.find_xpath("//option[text() = 'Single Option 2']").first.select_option
|
1708
|
+
expect(logged_events).to eq %w[single.mousedown single.focus single.input single.change single.mouseup single.click]
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
it "triggers correct unselect events for multiple selects" do
|
1712
|
+
driver.find_xpath("//option[text() = 'Multiple Option 2']").first.unselect_option
|
1713
|
+
expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.change multiple.mouseup multiple.click]
|
1714
|
+
end
|
1715
|
+
|
1716
|
+
it "triggers correct unselect events for multiple selects when already unselected" do
|
1717
|
+
driver.find_xpath("//option[text() = 'Multiple Option 3']").first.unselect_option
|
1718
|
+
expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.mouseup multiple.click]
|
1719
|
+
end
|
1720
|
+
|
1721
|
+
it "triggers correct select events for multiple selects when additional option is selected" do
|
1722
|
+
driver.find_xpath("//option[text() = 'Multiple Option 4']").first.select_option
|
1723
|
+
expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.change multiple.mouseup multiple.click]
|
1657
1724
|
end
|
1658
1725
|
end
|
1659
1726
|
|
@@ -1687,12 +1754,22 @@ describe Capybara::Webkit::Driver do
|
|
1687
1754
|
<option value="1" id="option-1" selected="selected">one</option>
|
1688
1755
|
<option value="2" id="option-2">two</option>
|
1689
1756
|
</select>
|
1757
|
+
<select id="change_select_in_optgroup" name="change_select_in_optgroup">
|
1758
|
+
<optgroup>
|
1759
|
+
<option value="1" id="option-in-optgroup-1" selected="selected">one</option>
|
1760
|
+
<option value="2" id="option-in-optgroup-2">two</option>
|
1761
|
+
</optgroup>
|
1762
|
+
</select>
|
1690
1763
|
</form>
|
1691
1764
|
<script type="text/javascript">
|
1692
1765
|
document.getElementById("change_select").
|
1693
1766
|
addEventListener("change", function () {
|
1694
1767
|
this.className = "triggered";
|
1695
1768
|
});
|
1769
|
+
document.getElementById("change_select_in_optgroup").
|
1770
|
+
addEventListener("change", function () {
|
1771
|
+
this.className = "triggered";
|
1772
|
+
});
|
1696
1773
|
document.getElementById("change").
|
1697
1774
|
addEventListener("change", function () {
|
1698
1775
|
this.className = "triggered";
|
@@ -1754,12 +1831,21 @@ describe Capybara::Webkit::Driver do
|
|
1754
1831
|
end
|
1755
1832
|
|
1756
1833
|
it "fires a change on select" do
|
1757
|
-
select = driver.find_xpath("//select").first
|
1834
|
+
select = driver.find_xpath("//select[@id='change_select']").first
|
1758
1835
|
expect(select.value).to eq "1"
|
1759
1836
|
option = driver.find_xpath("//option[@id='option-2']").first
|
1760
1837
|
option.select_option
|
1761
1838
|
expect(select.value).to eq "2"
|
1762
|
-
expect(driver.find_xpath("//select[@class='triggered']")).not_to be_empty
|
1839
|
+
expect(driver.find_xpath("//select[@id='change_select'][@class='triggered']")).not_to be_empty
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
it "fires a change on select when using an optgroup" do
|
1843
|
+
select = driver.find_xpath("//select[@id='change_select_in_optgroup']").first
|
1844
|
+
expect(select.value).to eq "1"
|
1845
|
+
option = driver.find_xpath("//option[@id='option-in-optgroup-2']").first
|
1846
|
+
option.select_option
|
1847
|
+
expect(select.value).to eq "2"
|
1848
|
+
expect(driver.find_xpath("//select[@id='change_select_in_optgroup'][@class='triggered']")).not_to be_empty
|
1763
1849
|
end
|
1764
1850
|
|
1765
1851
|
it "fires drag events" do
|
@@ -2017,14 +2103,17 @@ describe Capybara::Webkit::Driver do
|
|
2017
2103
|
end
|
2018
2104
|
|
2019
2105
|
it "ignores custom fonts" do
|
2106
|
+
skip "font replacement not needed for QT >= 5" unless driver.version =~ /Qt: 4/
|
2020
2107
|
expect(font_family).to eq "Arial"
|
2021
2108
|
end
|
2022
2109
|
|
2023
2110
|
it "ignores custom fonts before an element" do
|
2111
|
+
skip "font replacement not needed for QT >= 5" unless driver.version =~ /Qt: 4/
|
2024
2112
|
expect(font_family).to eq "Arial"
|
2025
2113
|
end
|
2026
2114
|
|
2027
2115
|
it "ignores custom fonts after an element" do
|
2116
|
+
skip "font replacement not needed for QT >= 5" unless driver.version =~ /Qt: 4/
|
2028
2117
|
expect(font_family).to eq "Arial"
|
2029
2118
|
end
|
2030
2119
|
end
|
@@ -337,6 +337,33 @@ describe Capybara::Session do
|
|
337
337
|
end
|
338
338
|
end
|
339
339
|
|
340
|
+
context "text" do
|
341
|
+
before(:all) do
|
342
|
+
@app = Class.new(ExampleApp) do
|
343
|
+
get "/" do
|
344
|
+
<<-HTML
|
345
|
+
<!DOCTYPE html>
|
346
|
+
<html>
|
347
|
+
<head></head>
|
348
|
+
<body>
|
349
|
+
<form>
|
350
|
+
This is my form
|
351
|
+
<input name="type"/>
|
352
|
+
<input name="tagName"/>
|
353
|
+
</form>
|
354
|
+
</body>
|
355
|
+
</html>
|
356
|
+
HTML
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
it "gets a forms text when inputs have conflicting names" do
|
362
|
+
subject.visit("/")
|
363
|
+
expect(subject.find(:css, "form").text).to eq("This is my form")
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
340
367
|
context 'click tests' do
|
341
368
|
before(:all) do
|
342
369
|
@app = Class.new(ExampleApp) do
|
@@ -551,4 +578,46 @@ describe Capybara::Session do
|
|
551
578
|
expect(session).to have_text('Hello')
|
552
579
|
end
|
553
580
|
end
|
581
|
+
|
582
|
+
if Capybara.respond_to?(:threadsafe)
|
583
|
+
context "threadsafe/per-session config mode" do
|
584
|
+
before do
|
585
|
+
Capybara::SpecHelper.reset_threadsafe(true, subject)
|
586
|
+
end
|
587
|
+
|
588
|
+
after do
|
589
|
+
Capybara::SpecHelper.reset_threadsafe(false, subject)
|
590
|
+
end
|
591
|
+
|
592
|
+
it "can allow reload in one session but not in another" do
|
593
|
+
session1, session2 = 2.times.collect do
|
594
|
+
session_for_app do
|
595
|
+
get '/' do
|
596
|
+
<<-HTML
|
597
|
+
<html>
|
598
|
+
<div id="parent">
|
599
|
+
<p id="removeMe">Hello</p>
|
600
|
+
</div>
|
601
|
+
</html>
|
602
|
+
HTML
|
603
|
+
end
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
607
|
+
session1.config.automatic_reload = false
|
608
|
+
session2.config.automatic_reload = true
|
609
|
+
|
610
|
+
node1, node2 = [session1, session2].map do |session|
|
611
|
+
session.visit('/')
|
612
|
+
|
613
|
+
node = session.find(:xpath, "//p[@id='removeMe']")
|
614
|
+
session.execute_script("document.getElementById('parent').innerHTML = 'Magic'")
|
615
|
+
node
|
616
|
+
end
|
617
|
+
|
618
|
+
expect(node1.text).to eq 'Hello'
|
619
|
+
expect{ node2.text }.to raise_error(Capybara::Webkit::NodeNotAttachedError)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
554
623
|
end
|
data/spec/node_spec.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "capybara/webkit/driver"
|
5
|
+
require "base64"
|
6
|
+
require "self_signed_ssl_cert"
|
7
|
+
|
8
|
+
describe Capybara::Webkit::Node do
|
9
|
+
include AppRunner
|
10
|
+
|
11
|
+
def visit(path, driver = self.driver)
|
12
|
+
driver.visit(url(path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def url(path)
|
16
|
+
"#{AppRunner.app_host}#{path}"
|
17
|
+
end
|
18
|
+
|
19
|
+
context "html app" do
|
20
|
+
let(:driver) do
|
21
|
+
driver_for_html(<<-HTML)
|
22
|
+
<html>
|
23
|
+
<head>
|
24
|
+
<title>Hello HTML</title>
|
25
|
+
</head>
|
26
|
+
<body>
|
27
|
+
<form action="/" method="GET">
|
28
|
+
<input type="text" name="foo" value="bar"/>
|
29
|
+
<input type="checkbox" name="checkedbox" value="1" checked="checked"/>
|
30
|
+
<input type="checkbox" name="uncheckedbox" value="2"/>
|
31
|
+
<input type="checkbox" name="falsecheckedbox" value="3" checked="false"/>
|
32
|
+
<input type="text" name="styled" style="font-size: 150%;"/>
|
33
|
+
</form>
|
34
|
+
|
35
|
+
<div id="visibility_wrapper" style="visibility: hidden">
|
36
|
+
<div id="hidden">Hidden</div>
|
37
|
+
<div id="visible" style="visibility: visible">Visibile</div>
|
38
|
+
<div style="visibility: visible">
|
39
|
+
<div id="nested_visible">Nested Visibile</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div id="display_none" style="display: none">
|
44
|
+
<div id="not_displayed" style="visibility: visible; display: block;">Should not be displayed</div>
|
45
|
+
</div>
|
46
|
+
</body>
|
47
|
+
</html>
|
48
|
+
HTML
|
49
|
+
end
|
50
|
+
|
51
|
+
before { visit("/") }
|
52
|
+
|
53
|
+
context "Node#[]" do
|
54
|
+
it "gets boolean properties" do
|
55
|
+
box1 = driver.find_css('input[name="checkedbox"]').first
|
56
|
+
box2 = driver.find_css('input[name="uncheckedbox"]').first
|
57
|
+
box3 = driver.find_css('input[name="falsecheckedbox"]').first
|
58
|
+
expect(box1["checked"]).to eq true
|
59
|
+
expect(box2["checked"]).to eq false
|
60
|
+
expect(box3["checked"]).to eq true
|
61
|
+
box1.set(false)
|
62
|
+
expect(box1["checked"]).to eq false
|
63
|
+
end
|
64
|
+
|
65
|
+
it "prefers property over attribute" do
|
66
|
+
input = driver.find_css('input[name="foo"]').first
|
67
|
+
expect(input["value"]).to eq "bar"
|
68
|
+
input.set("new value")
|
69
|
+
expect(input["value"]).to eq "new value"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns attribute when property is an object" do
|
73
|
+
input = driver.find_css('input[name="styled"]').first
|
74
|
+
expect(input["style"]).to eq "font-size: 150%;"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "Node#visible" do
|
79
|
+
it "correctly analyzes visibility CSS" do
|
80
|
+
expect(driver.find_css('#hidden').first.visible?).to be false
|
81
|
+
expect(driver.find_css('#visible').first.visible?).to be true
|
82
|
+
expect(driver.find_css('#nested_visible').first.visible?).to be true
|
83
|
+
end
|
84
|
+
|
85
|
+
it "correctly analyzes display: none CSS" do
|
86
|
+
expect(driver.find_css('#not_displayed').first.visible?).to be false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|