I have a select2 v4 that loads options through AJAX.
I am running a Cucumber test where I need to select 2 options of the list, but I can't seem to make the list open up and load (which normally gets populated when I type 2 or characters).
I have tried:
As suggested here:
#session.execute_script("$('#publish_to').select2('open')")
and
#session.first(".input.publish_to .select2-container").click
and
#session.first("#publish_to").find(".select2-choice").click
which do not give me an error, but I am not getting the options to select, so I am assuming that the click is not really working. Things I have tried to select the options:
# This one cannot find the css:
#session.find(".select2-results__options", text: client.email).click
# This one gives me a Timeout error
#session.evaluate_script "$('#publish_to').val(#{client.id}).trigger('change')"
# This one gives me a Timeout error
#session.evaluate_script "$('.select2-search__field').trigger('keydown').val('#{client.email}').trigger('keyup')";
sleep 10
#session.find('.select2-search__option', text: client.email).click
Anything with trigger gives me a Timeout error, so I tried waiting for jQuery.active but I never got a true even waiting for 2 minutes:
counter = 0
timeout_in_sec = 120
while counter < timeout_in_sec && #session.evaluate_script('jQuery.active').zero?
sleep 1.second
counter+=1
end
I tried using the gem capybara-select2 running:
#session.select2 client.email, css: '#publish_to', search: true
but I get the error undefined methodselect2' for #and I haveWorld(CapybaraSelect2)in myenv.rb`
I am using Cucumber v3.1.2 with ruby gem 'cucumber-rails'
The poltergeist driver is roughly equivalent to a 7 year old version of Safari which means it doesn't support a lot of current JS/CSS. This means your issue could simply be that select2 is no longer compatible with Poltergeist (without a lot of polyfilling). You're going to be much better off updating to using a real browser (stable - chrome via selenium, etc) or one of the direct to Chrome drivers (highly beta) that have spun off Poltergeist (Apparition is one of them). Those will allow you to run with a visible browser (useful for debugging) or headless.
The following code uses Chrome via selenium and interacts with the select2 demo site to select an entry that is loaded via Ajax.
require "selenium/webdriver"
require "capybara/dsl"
sess = Capybara::Session.new(:selenium_chrome)
sess.visit("https://select2.org/data-sources/ajax")
sess.first('.select2-container', minimum: 1).click
sess.find('.select2-dropdown input.select2-search__field').send_keys("capy")
sleep 5 # just to watch the browser search
sess.find('.select2-results__option', text: 'teamcapybara/capybara').click
sess.assert_selector(:css, '.select2-selection__rendered', text: 'teamcapybara/capybara')
sleep 5 # just to see the effect
[7] pry(#<RSpec::Core::ExampleGroup::Nested_1>)> page.execute_script "window.close()"
Selenium::WebDriver::Error::NoSuchWindowError: Script execution failed. Script: window.close();
The window could not be found
[8] pry(#<RSpec::Core::ExampleGroup::Nested_1>)> page.driver.browser.window_handles
=> ["f1-2"]
I had a browser open with two tabs, the above command does close one but the last tab never closes. It is open but when I try to run page.execute_script "window.close()" it gives the above error.
page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.execute_script "window.close()"
end
The above code was working for me sometime back but doesnt work anymore. It gives the same error.
UPDATE:
When I use,
page.driver.browser.window_handles.each do |handle|
page.driver.browser.switch_to.window(handle)
page.driver.browser.close
end
it gives the following error Selenium::WebDriver::Error::UnknownError: 'auto_id' does not refer to an open tab
Two ways you can do it
In line with your technique using JS. You would first need to switch back to your first browser window (window_handle) and then perform "window.close()". (Not Preferred) (Not sure why its not working now for you, did you upgrade server version or different browser?)
Simply use #driver.quit (Preferred)
Update
Just write this once. This will close all windows.
after(:each) do
#driver.quit
end
If you want to close only one browser tab/window/popup, switch to that window_handle and then perform
#driver.close();
page.driver.browser.close closes current tab towards the end and the last (second) tab closes itself after each example.
in case if you are using cucumber, you can the use the BEFORE/AFTER hooks .please refer similar question on stackoverflow
for some more on cucumber,please refer this Cucumber Hooks
IE8 gives an error from jquery 1.5.1 minimized: Invalid argument, but firefox doesn't.
The error comes from this line:w
a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),d.expr&&d.expr.filters&&(d.expr.filters.animated=function(a){return d.grep(d.timers,function(b){return a===b.elem}).length});var ce=/^t(?:able|d|h)$/i,cf=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?d.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,g=f.documentElement;if(!c||!d.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=f.body,i=cg(f),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||d.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||d.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:d.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){d.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return d.offset.bodyOffset(b);d.offset.initialize();var c,e=b.offsetParent,f=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(d.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===e&&(l+=b.offsetTop,m+=b.offsetLeft,d.offset.doesNotAddBorder&&(!d.offset.doesAddBorderForTableAndCells||!ce.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),f=e,e=b.offsetParent),d.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;d.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},d.offset={initialize:function(){var a=c.body,b=c.createElement("div"),e,f,g,h,i=parseFloat(d.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),a=b=e=f=g=h=null,d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=e==="absolute"&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=cf.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!cf.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=cg(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=cg(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window)
My code doesn't have an error...
I suggest that you debug your code, as the min version of jquery works just fine. You have a problem with your code that is indirectly causing an error in internet explorer and you have to do a work around.
My favorite thing (and what I did for a similar problem that I just figured out) is to
cut out all your javascript and run it to make sure that it works
paste it back in, a chunk at a time, testing each time
once you find the offending chunk of javascript code, cut that out and put everything else back in to make sure that is the only problem
narrow it down in that chunk to see where internet explorer is being retarded. If you are using PHP, you might need to do something like this to have internet explorer skip the code that is causing it to fail
$('li[title]').qtip({
style: {
name: 'dark',
background: $('.ui-widget-header:first').css('background-color')
<?php
//internet explorer is retarded
if(!preg_match('/MSIE/i',$_SERVER["HTTP_USER_AGENT"]))
{
echo ", tip: true";
}
?>
},
position: {
target: 'mouse',
corner: {
target: 'topLeft',
tooltip: 'bottomLeft'
}
}
});
I hope that helps! (If it did, please mark as answer)
I used the "slideToggle" from jquery version "jquery-1.6.4.min.js" on one big DIV element.
The "DIV" element has inside more html elements.
In internet explorer 8 (maybe on FF too) when I try to load the slideToggle function on this big DIV I received an error. Not sure what was the real cause of error but during my investigation I found a bug into the jquery:
_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}})
There are situations when "a" variable is "NAN". Because of this I got some errors.
So I placed this check routine inside:
if(isNaN(a.now)){return;}
And all my problems gone.
_default:function(a){if(isNaN(a.now)){return;}a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}})
For me, this comes up when setting the padding or margins to a negative number. This has been discussed in a number of places online re: "IE negative padding". The following are the watch values from my IE console that prove this.
a.prop >> 'paddingTop'
a.prop==="width"||a.prop==="height" >> false
Math.max(0,a.now) >> 0
a.now >> -1.8277004484618357
(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit >> "-1.8277004484618357px"
a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit >> Invalid Argument
experimenting:
- a.elem.style[a.prop] = '1px' >> '1px'
- a.elem.style[a.prop] = '-1px' >> Invalid Argument
The thread over at: StackOverflow: jQuery, IE & Animate proposes the following:
a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now||0):a.now)+a.unit;
... which did nothing for me.
I don't really think this is a jQuery bug, and I haven't found it in their bug tracking system (I'll admit I haven't looked too hard), but rather an issue with IE not being able to handle negative padding/margins. It's a tough call whether jQuery should handle this or not ...
EDIT: This was opened as jQuery bug 4571, where they decided that the behavior was correct and that developers should be more careful in setting margins/padding values since a negative margin/pad really isn't valid. They went on to say that they wish FF would throw an error like IE. Wow! don't hear that often!