capybara-webkit 1.14.0 → 1.15.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.
- 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
|