pickles 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +196 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/cucumber/pickles.rb +6 -0
- data/lib/cucumber/pickles/check_in.rb +10 -0
- data/lib/cucumber/pickles/config.rb +61 -0
- data/lib/cucumber/pickles/errors/ambigious.rb +27 -0
- data/lib/cucumber/pickles/errors/node_find_error.rb +37 -0
- data/lib/cucumber/pickles/fill_in.rb +10 -0
- data/lib/cucumber/pickles/helpers.rb +40 -0
- data/lib/cucumber/pickles/helpers/extensions/chrome/.DS_Store +0 -0
- data/lib/cucumber/pickles/helpers/extensions/chrome/compiled.crx.base64 +1 -0
- data/lib/cucumber/pickles/helpers/extensions/chrome/manifest.json +15 -0
- data/lib/cucumber/pickles/helpers/extensions/chrome/src/.DS_Store +0 -0
- data/lib/cucumber/pickles/helpers/extensions/chrome/src/inject/inject.js +35 -0
- data/lib/cucumber/pickles/helpers/main.rb +88 -0
- data/lib/cucumber/pickles/helpers/node_finders.rb +125 -0
- data/lib/cucumber/pickles/helpers/regex.rb +6 -0
- data/lib/cucumber/pickles/helpers/waiter.rb +152 -0
- data/lib/cucumber/pickles/locator/equal.rb +26 -0
- data/lib/cucumber/pickles/locator/index.rb +20 -0
- data/lib/cucumber/pickles/refinements.rb +49 -0
- data/lib/cucumber/pickles/steps.rb +73 -0
- data/lib/cucumber/pickles/steps/can_see.rb +70 -0
- data/lib/cucumber/pickles/steps/check.rb +55 -0
- data/lib/cucumber/pickles/steps/check_in/complex_input.rb +17 -0
- data/lib/cucumber/pickles/steps/check_in/factory.rb +26 -0
- data/lib/cucumber/pickles/steps/check_in/input.rb +36 -0
- data/lib/cucumber/pickles/steps/check_in/text.rb +17 -0
- data/lib/cucumber/pickles/steps/click.rb +91 -0
- data/lib/cucumber/pickles/steps/fill.rb +72 -0
- data/lib/cucumber/pickles/steps/fill_in/complex_input.rb +19 -0
- data/lib/cucumber/pickles/steps/fill_in/factory.rb +25 -0
- data/lib/cucumber/pickles/steps/fill_in/input.rb +29 -0
- data/lib/cucumber/pickles/steps/fill_in/select.rb +30 -0
- data/lib/cucumber/pickles/steps/redirect.rb +3 -0
- data/lib/cucumber/pickles/transform.rb +13 -0
- data/lib/cucumber/pickles/version.rb +3 -0
- data/lib/pickles.rb +3 -0
- data/pickles.gemspec +36 -0
- data/spec/helpers/node_finders_spec.rb +155 -0
- data/spec/helpers/waiter_spec.rb +41 -0
- data/spec/locator_spec.rb +31 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/step_def_spec.rb +0 -0
- data/spec/steps/check_in/factory_spec.rb +52 -0
- data/spec/steps/fill_in/factory_spec.rb +51 -0
- metadata +153 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
unless defined?(SUPPORT_DIR)
|
2
|
+
in_features_dir = caller.select { |path| path =~ /features/ }.first
|
3
|
+
|
4
|
+
if in_features_dir
|
5
|
+
features_dir = in_features_dir.split('/')
|
6
|
+
|
7
|
+
2.times { features_dir.pop }
|
8
|
+
|
9
|
+
SUPPORT_DIR = File.join(features_dir,'support')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative 'refinements'
|
14
|
+
require_relative 'config'
|
15
|
+
require_relative 'errors/ambigious'
|
16
|
+
|
17
|
+
module Locator
|
18
|
+
|
19
|
+
_dir = 'cucumber/pickles/locator/'
|
20
|
+
|
21
|
+
autoload :Index, _dir + 'index'
|
22
|
+
autoload :Equal, _dir + 'equal'
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
module Helpers
|
27
|
+
|
28
|
+
_dir = 'cucumber/pickles/helpers/'
|
29
|
+
|
30
|
+
autoload :Main, _dir + 'main'
|
31
|
+
autoload :Regex, _dir + 'regex'
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
module Pickles
|
36
|
+
|
37
|
+
extend Helpers::Main
|
38
|
+
include Helpers::Main
|
39
|
+
|
40
|
+
end
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
Q3IyNAIAAAAmAQAAAAEAADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtp8JSC/8xIo1YhrOEu3w08MRVZAtGRzRRig4Xkq+QfRjT52PFlqwuD6Y+tLPaL350aTk4o1ExFb0ycnth/oHkwywjf8V45YA2wo9itWyA4qE77NpYHyO6kpPxe/nOs2580MkVMc/2Cu4xQAoyOZsTmnstZlilow0sNyig4ww8PI0sVIuvtYOdd3r0WNMKRz9gcizYiYAHu+e00Wz5WFZRxKffZyro1M5XfYT1h3ZkIPY+YqFkQME12uk29YE5sNR/nLSd91DuZCOpHmM67Umlcui71omJp29zrPAIAJc+AjVFBiqQt4vnLzoLz5wkSkjgV0/L67aOiqsGrMT0/Ff0CAwEAAU0TBhDaJCyO6hi7PWmA3KFgBRQ0t3tJRypcZwt8V2uIS6dgY6a4O+/L6g8KdxwK5NaIpIpU/fkor68fseCerp82rt2pvSCWyEU9NSXDBJKlkMINaJf8b1EhX7T3yxFwTXQWFldA6UkCMhxYQTCe5KxCp0IRTqfSQ4YZ2Qpy6q6aH7HRLXoulpsrxWQx0W/buDeGicj7ToQdl85gxrqealjdP9Ro8K4yBHwQCqcj0OoM2HQk1HpLAxQRcMe7wVEoPA393PdrNtMpmqrTiiDfjiJsFqSCK8cLWhLn4WtpBrXh95jaaDFrHYsK2bXxVOUYuVAgazjpNMGgnZmnD1MwAylQSwMEFAAACAgAhQMDS9OaFCfEAAAATgEAAA0AAABtYW5pZmVzdC5qc29uVY7RasMwDEXf+xXCzyVr+1jKYOwzRgjG0RqH2G4lORRK/72KnRH2IqF7z5X03AGYaAOaM5jvgVJA6MnPSPA12gfw4IPZL5BK7FNcuENzaI5VDTb6X2TpNvtUjB7Zkb/JGvm/WjTh4xVmSwyS4EbISDPWm4T3rAADYxRgsZK5XnMpimpdXc26+EdlgGep5R1xAxbDXOw0dZkm/jTt/g8Yt1CZmdyHjyM6WVujxGpvKcqxs6LJZeiTy6F8IZakwi+t7e71BlBLAwQUAAAICAAQoQJLAAAAAAIAAAAAAAAABAAAAHNyYy8DAFBLAwQUAAAICABQAwNLAAAAAAIAAAAAAAAACwAAAHNyYy9pbmplY3QvAwBQSwMEFAAACAgAUAMDS5pHPma7AQAAdwUAABQAAABzcmMvaW5qZWN0L2luamVjdC5qc52TMW/bMBCFd/8KRkMk2RTdAJkiaAoCZLBRoO7QIQsjXSKiEqmSZ7uu4P/eo2zIduE6crQR773T3XdkXlpTg4DfCNopo4UDXczBOfkOUbvl7G2pcyQhsuAaox3ErB2NGFtJy6BClrHC5MsaNIrcgkR4qsCfosDlVjUYxKm3k1UorcE+f5/PKBT4vKmKrw3o7Md89ozYfINfS3AoGmvQ4KYBYUhN10oXZi0ktbGCvcdlX/jFVNb3Lfkrz3nBIW7PVppMOJbKCVkUTytqfKYcsQAbvQQ0T7FxSEPlpdTv8BLwvmzc3mdZF+xcC++6vT37hyTZ8pu7mO/HFbmsqshH+aG3bRoQJwLV0yyprJANBYrHUlVFRAh3LP3n8TncVPD/BYSdHlJmF+mOwhOiTIi08mnuXHgqH+8oHLM2ZJO9Hk7Hj4sFQyvpongEbjw9UllikoOW0DYasLh5YNpoYDeqboxFqTE9ydTmz2dS7hOhNbz+VHh9kF2bOOL0Zmz9D6aek9eG0vnYyw5UBphPYAwpPtS4m11qVcszV+Tw497x8VTEYLjbXFPZDTdfMG7D/lGyS8+3e1/+AY+2cfoXUEsBAgAAFAAACAgAhQMDS9OaFCfEAAAATgEAAA0AAAAAAAAAAQAAAAAAAAAAAG1hbmlmZXN0Lmpzb25QSwECAAAUAAAICAAQoQJLAAAAAAIAAAAAAAAABAAAAAAAAAAAAAAAAADvAAAAc3JjL1BLAQIAABQAAAgIAFADA0sAAAAAAgAAAAAAAAALAAAAAAAAAAAAAAAAABMBAABzcmMvaW5qZWN0L1BLAQIAABQAAAgIAFADA0uaRz5muwEAAHcFAAAUAAAAAAAAAAEAAAAAAD4BAABzcmMvaW5qZWN0L2luamVjdC5qc1BLBQYAAAAABAAEAOgAAAArAwAAAAA=
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"name": "Chrome driver Ajax shim",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"manifest_version": 2,
|
5
|
+
"description": "Chrome driver testing vars to preserve Ajax requests sent status",
|
6
|
+
"content_scripts": [
|
7
|
+
{
|
8
|
+
"matches": ["<all_urls>"],
|
9
|
+
"js": [
|
10
|
+
"src/inject/inject.js"
|
11
|
+
],
|
12
|
+
"run_at": "document_start"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
}
|
Binary file
|
@@ -0,0 +1,35 @@
|
|
1
|
+
chrome.extension.sendMessage({}, function(response) {
|
2
|
+
|
3
|
+
var elt = document.createElement("script");
|
4
|
+
|
5
|
+
elt.innerHTML = "var oldOpen=XMLHttpRequest.prototype.open;window.activeRequests=0,XMLHttpRequest.prototype.open=function(a,b,c,d,e){window.activeRequests++,this.addEventListener(\"readystatechange\",function(){4==this.readyState&&window.activeRequests--},!1),oldOpen.call(this,a,b,c,d,e)};";
|
6
|
+
|
7
|
+
|
8
|
+
document.head.appendChild(elt);
|
9
|
+
|
10
|
+
var style = document.createElement('style');
|
11
|
+
style.type = 'text/css';
|
12
|
+
style.innerHTML = '* {' +
|
13
|
+
'/*CSS transitions*/' +
|
14
|
+
' -o-transition-property: none !important;' +
|
15
|
+
' -moz-transition-property: none !important;' +
|
16
|
+
' -ms-transition-property: none !important;' +
|
17
|
+
' -webkit-transition-property: none !important;' +
|
18
|
+
' transition-property: none !important;' +
|
19
|
+
// '/*CSS transforms*/' +
|
20
|
+
// ' -o-transform: none !important;' +
|
21
|
+
// ' -moz-transform: none !important;' +
|
22
|
+
// ' -ms-transform: none !important;' +
|
23
|
+
// ' -webkit-transform: none !important;' +
|
24
|
+
// ' transform: none !important;' +
|
25
|
+
' /*CSS animations*/' +
|
26
|
+
' -webkit-animation: none !important;' +
|
27
|
+
' -moz-animation: none !important;' +
|
28
|
+
' -o-animation: none !important;' +
|
29
|
+
' -ms-animation: none !important;' +
|
30
|
+
' animation: none !important;}';
|
31
|
+
|
32
|
+
document.head.appendChild(style);
|
33
|
+
|
34
|
+
|
35
|
+
});
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require_relative 'node_finders'
|
2
|
+
require_relative 'waiter'
|
3
|
+
|
4
|
+
module Helpers::Main
|
5
|
+
|
6
|
+
include NodeFinders
|
7
|
+
include Waiter
|
8
|
+
|
9
|
+
#
|
10
|
+
# parent node of given
|
11
|
+
#
|
12
|
+
# @node - Capybara node
|
13
|
+
#
|
14
|
+
# returns Capybara node
|
15
|
+
#
|
16
|
+
def parent_node(node)
|
17
|
+
node.find(:xpath, '..', wait: 0, visible: false)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# trigger blur event on given node
|
22
|
+
#
|
23
|
+
# @node - Capybara node
|
24
|
+
#
|
25
|
+
def blur(node)
|
26
|
+
trigger(node, 'blur')
|
27
|
+
|
28
|
+
Capybara.current_session.execute_script("document.body.click()")
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Select checkbox | radio input
|
33
|
+
#
|
34
|
+
# @input - Capybara node with <input type="checkbox|radio">
|
35
|
+
# @value - optional - value to set to input, Defaults to input state switch
|
36
|
+
#
|
37
|
+
# returns: [void]
|
38
|
+
#
|
39
|
+
def select_input(input, value = nil)
|
40
|
+
case value
|
41
|
+
when "true", true
|
42
|
+
value = true
|
43
|
+
when "false", false
|
44
|
+
value = false
|
45
|
+
else
|
46
|
+
value = !input.checked?
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Hack:
|
51
|
+
# cant use input.set(#{value})
|
52
|
+
# because element can be hidden or covered by other eement
|
53
|
+
# in which case Selenium raises error
|
54
|
+
#
|
55
|
+
trigger(parent_node(input), 'click')
|
56
|
+
|
57
|
+
Capybara.current_session.execute_script("arguments[0].checked = #{value}", input)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Attach file from features/support/attachments/* to given file input
|
62
|
+
#
|
63
|
+
# @input - Capybara node with <input type="file">
|
64
|
+
# @file - file path relative to features/support/attachments/*
|
65
|
+
#
|
66
|
+
# returns [void]
|
67
|
+
#
|
68
|
+
def attach_file(input, file)
|
69
|
+
path = File.expand_path(File.join(SUPPORT_DIR,"attachments/#{file}"))
|
70
|
+
|
71
|
+
raise RuntimeError, "file '#{path}' does not exists" unless File.exists?(path)
|
72
|
+
|
73
|
+
input.set(path)
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Triggers event on node
|
78
|
+
# Usefull when Capybara raises error about element being covered by another
|
79
|
+
#
|
80
|
+
# @node - Capybara node
|
81
|
+
# @event - event to trigger
|
82
|
+
#
|
83
|
+
# returns: [void]
|
84
|
+
def trigger(node, event)
|
85
|
+
Capybara.current_session.execute_script("arguments[0].#{event}()", node)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module NodeFinders
|
2
|
+
|
3
|
+
using BlankMethod
|
4
|
+
|
5
|
+
#
|
6
|
+
# Finds text node by text locator
|
7
|
+
#
|
8
|
+
# @text - locator ( see locator docs in #Artifact )
|
9
|
+
# @within: - within block to limit search to
|
10
|
+
#
|
11
|
+
# returns Capybara node
|
12
|
+
#
|
13
|
+
def find_node(locator, within: nil)
|
14
|
+
within ||= Capybara.current_session
|
15
|
+
|
16
|
+
locator, index = Locator::Index.execute(locator)
|
17
|
+
locator, xpath = Locator::Equal.execute(locator)
|
18
|
+
|
19
|
+
if index
|
20
|
+
xpath = "(#{xpath})[#{index}]"
|
21
|
+
end
|
22
|
+
|
23
|
+
_rescued_find([:xpath, xpath, wait: 0, visible: false], locator, within: within, message: "find_node") do
|
24
|
+
raise Capybara::ElementNotFound,
|
25
|
+
"Unable to find node by locator #{locator}",
|
26
|
+
caller
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Does lookup based on provided in config maps
|
32
|
+
#
|
33
|
+
def detect_node(el_alias, locator = nil, within: nil)
|
34
|
+
return find_node(locator, within: within) if el_alias.blank?
|
35
|
+
|
36
|
+
within ||= Capybara.current_session
|
37
|
+
|
38
|
+
locator, index = Locator::Index.execute(locator)
|
39
|
+
|
40
|
+
if index.nil?
|
41
|
+
el_alias, index = Locator::Index.execute(el_alias.to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
el_alias = el_alias.to_sym
|
45
|
+
|
46
|
+
if xpath = Pickles.config.xpath_node_map[el_alias]
|
47
|
+
xpath = xpath.respond_to?(:call) ? xpath.call(locator) : xpath
|
48
|
+
|
49
|
+
search_params = [:xpath, xpath, wait: 0]
|
50
|
+
elsif css = Pickles.config.css_node_map[el_alias] || el_alias
|
51
|
+
css = css.respond_to?(:call) ? css.call(locator) : css
|
52
|
+
|
53
|
+
search_params = [:css, css, text: locator, wait: 0]
|
54
|
+
end
|
55
|
+
|
56
|
+
if index
|
57
|
+
within.all(*search_params)[index - 1]
|
58
|
+
else
|
59
|
+
_rescued_find(search_params, locator || el_alias, within: within, message: "Detecting by #{xpath || css}") do
|
60
|
+
raise Capybara::ElementNotFound,
|
61
|
+
"Unable to detect node by locator #{locator}",
|
62
|
+
caller
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Similar to find_node, but looking for fillable fields for this cases:
|
69
|
+
# 1. label or span(as label) with input hint for input || textarea || @contenteditable
|
70
|
+
# 2. capybara lookup by label || plcaeholder || id || name || etc
|
71
|
+
# 3. @contenteditable with @placeholder = @locator
|
72
|
+
#
|
73
|
+
# @input_locator - string to identify input field by
|
74
|
+
#
|
75
|
+
# returns: Capybara node
|
76
|
+
#
|
77
|
+
def find_input(input_locator, within: nil, options: {})
|
78
|
+
within ||= Capybara.current_session
|
79
|
+
options[:wait] = 0
|
80
|
+
options[:visible] = false
|
81
|
+
|
82
|
+
locator, index = Locator::Index.execute(input_locator)
|
83
|
+
|
84
|
+
if index
|
85
|
+
index_xpath = "[#{index}]"
|
86
|
+
end
|
87
|
+
|
88
|
+
xpath = ".//*[@contenteditable and (@placeholder='#{locator}' or name='#{locator}')]#{index_xpath}"
|
89
|
+
|
90
|
+
# case 3
|
91
|
+
_rescued_find([:xpath, xpath, options], locator, within: within, message: "@contenteditable with placeholder = #{locator}") do
|
92
|
+
|
93
|
+
locator, label_xpath = Locator::Equal.execute(input_locator)
|
94
|
+
|
95
|
+
inputtable_field_xpath = "*[self::input or self::textarea or @contenteditable]"
|
96
|
+
|
97
|
+
xpath = "(#{label_xpath})#{index_xpath}/ancestor::*[.//#{inputtable_field_xpath}][position()=1]//#{inputtable_field_xpath}"
|
98
|
+
|
99
|
+
# case 1
|
100
|
+
_rescued_find([:xpath, xpath, options], locator, within: within, message: "find_node(#{locator}) => look for closest fillable field") do
|
101
|
+
|
102
|
+
# case 2
|
103
|
+
_rescued_find([:fillable_field, locator, options], locator, within: within, message: 'Capybara#fillable_input') do
|
104
|
+
|
105
|
+
# all cases failed => raise
|
106
|
+
raise Capybara::ElementNotFound,
|
107
|
+
"Unable to find fillable field by locator #{locator}",
|
108
|
+
caller
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def _rescued_find(params, locator, within:, message:)
|
118
|
+
within.find(*params)
|
119
|
+
rescue Capybara::Ambiguous => err # Capybara::Ambiguous < Capybara::ElementNotFound == true
|
120
|
+
raise Pickles::Ambiguous.new(locator, within, params, message), nil, caller
|
121
|
+
rescue Capybara::ElementNotFound
|
122
|
+
yield
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# original code:
|
2
|
+
#
|
3
|
+
# (function() {
|
4
|
+
# var oldOpen = XMLHttpRequest.prototype.open;
|
5
|
+
# window.openHTTPs = 0;
|
6
|
+
# XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
7
|
+
# window.openHTTPs++;
|
8
|
+
# this.addEventListener("readystatechange", function() {
|
9
|
+
# if(this.readyState == 4) {
|
10
|
+
# window.openHTTPs--;
|
11
|
+
# }
|
12
|
+
# }, false);
|
13
|
+
# oldOpen.call(this, method, url, async, user, pass);
|
14
|
+
# }
|
15
|
+
# })(XMLHttpRequest);
|
16
|
+
#
|
17
|
+
# module Capybara
|
18
|
+
# module Selenium
|
19
|
+
# class Driver
|
20
|
+
#
|
21
|
+
# class << self
|
22
|
+
# alias __pickles_redefined__new new
|
23
|
+
#
|
24
|
+
# #
|
25
|
+
# # Monkey patch initializer to load custom chrome extension in extensions/chrome
|
26
|
+
# #
|
27
|
+
# # It will add window.activeRequests to keep track of active AJAX requests in tests
|
28
|
+
# #
|
29
|
+
# # For source code of extension see extensions/chrome/src/inject/inject.js
|
30
|
+
# #
|
31
|
+
# # TODO: support all major browser drivers
|
32
|
+
# #
|
33
|
+
# def new(app, options={})
|
34
|
+
# if options[:browser].to_s == "chrome"
|
35
|
+
# options[:desired_capabilities] ||= {}
|
36
|
+
# options[:desired_capabilities]["chromeOptions"] ||= {}
|
37
|
+
# options[:desired_capabilities]["chromeOptions"]["extensions"] ||= []
|
38
|
+
#
|
39
|
+
# extension_path = File.expand_path('extensions/chrome/compiled.crx.base64', __dir__)
|
40
|
+
#
|
41
|
+
# options[:desired_capabilities]["chromeOptions"]["extensions"].unshift(File.read(extension_path))
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# __pickles_redefined__new(app, options)
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
|
53
|
+
def stub_xml_http_request(page)
|
54
|
+
page.evaluate_script <<-JAVASCRIPT
|
55
|
+
(function() {
|
56
|
+
|
57
|
+
if (window.ajaxRequestIsSet) { return; };
|
58
|
+
window.ajaxRequestIsSet = true;
|
59
|
+
|
60
|
+
var oldOpen = XMLHttpRequest.prototype.open;
|
61
|
+
window.activeRequests = 0;
|
62
|
+
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
63
|
+
window.activeRequests++;
|
64
|
+
this.addEventListener("readystatechange", function() {
|
65
|
+
if (this.readyState == 4) {
|
66
|
+
window.activeRequests--;
|
67
|
+
|
68
|
+
#{
|
69
|
+
if Pickles.config.log_xhr_response
|
70
|
+
<<-LOG
|
71
|
+
if (parseInt(this.status, 10) >= 400) {
|
72
|
+
console.error("############## ERRRO RESPONSE START ################");
|
73
|
+
console.error(this.response);
|
74
|
+
console.error("############## ERRRO RESPONSE END ################");
|
75
|
+
}
|
76
|
+
LOG
|
77
|
+
end
|
78
|
+
}
|
79
|
+
|
80
|
+
}
|
81
|
+
}, false);
|
82
|
+
oldOpen.call(this, method, url, async, user, pass);
|
83
|
+
};
|
84
|
+
|
85
|
+
|
86
|
+
var style = document.createElement('style');
|
87
|
+
style.type = 'text/css';
|
88
|
+
style.innerHTML = '* {' +
|
89
|
+
'/*CSS transitions*/' +
|
90
|
+
' -o-transition-property: none !important;' +
|
91
|
+
' -moz-transition-property: none !important;' +
|
92
|
+
' -ms-transition-property: none !important;' +
|
93
|
+
' -webkit-transition-property: none !important;' +
|
94
|
+
' transition-property: none !important;' +
|
95
|
+
' /*CSS animations*/' +
|
96
|
+
' -webkit-animation: none !important;' +
|
97
|
+
' -moz-animation: none !important;' +
|
98
|
+
' -o-animation: none !important;' +
|
99
|
+
' -ms-animation: none !important;' +
|
100
|
+
' animation: none !important;}';
|
101
|
+
document.getElementsByTagName('head')[0].appendChild(style);
|
102
|
+
|
103
|
+
})();
|
104
|
+
JAVASCRIPT
|
105
|
+
end
|
106
|
+
|
107
|
+
module Capybara
|
108
|
+
class Session
|
109
|
+
|
110
|
+
alias __pickles_redefined__old_visit visit
|
111
|
+
|
112
|
+
def visit(*args)
|
113
|
+
__pickles_redefined__old_visit(*args)
|
114
|
+
|
115
|
+
stub_xml_http_request(Capybara.current_session)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
module Waiter
|
122
|
+
|
123
|
+
module_function
|
124
|
+
|
125
|
+
def wait
|
126
|
+
wait_for_ajax
|
127
|
+
|
128
|
+
return unless block_given?
|
129
|
+
|
130
|
+
page.document.synchronize do
|
131
|
+
yield
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def page
|
136
|
+
Capybara.current_session
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# waits for all Ajax requests to finish
|
141
|
+
#
|
142
|
+
def wait_for_ajax
|
143
|
+
page.document.synchronize do
|
144
|
+
pending_ajax_requests_num.zero? || raise(Capybara::ElementNotFound)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def pending_ajax_requests_num
|
149
|
+
page.evaluate_script("window.activeRequests")
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|