WebDriver Dropdown Menu Won't Stay Open - javascript

I'm working with Selenium / Java and having an interesting issue with a DropDown Box that fires an event... I can't use Select because the dropdown is using an organized list, not select and option (when the box is closed):
<section id="..." class="ember-view">
<ol id="...">
<li id="...">
I successfully click on the dropdown box: element.click();
and the dropdown box opens! But then it closes right back up again when the next line executes (which is just a System.out.println("...");).
I'm baffled. I've tried
JavascriptExecutor jse = (JavascriptExecutor)driver
jse.executeScript("$(arguments[0]).change()", element);
and
jse.executeScript("$(arguments[0]).focus()", element);
and even
jse.executeScript("$(arguments[0]).blur()", element);
both before and after I click on the dropdown box, but that little sucker just won't stay open! When I print the value of arguments to the console System.out.println(jse.executeScript("$(arguments[0]));, arguments is null... I'm not sure what that means.

If you're not changing the classes when you click the dropdown then you're going to click it and it's going to just disappear after you click it pretty much. Try making it so the dropdown always shows and add a class that disappears on click called "hide" or "removeDisplay" like so
hide { display:none }
and then put it in the html element.
<htmlElement class="alwaysShowThis hide"></htmlElement>
make sure that on clicking it you remove the hide class, then you can just put a timer on it or just detect for when you are hovered over it.
the javascript might look like this:
display(event) {
if(/*checkfor hide class existing*/){
//remove hide class
}
}
hide() {
if(alwaysShowThis or its id is not being hovered over){
//add hide class to its classes
}
}
I mean these are just some 5 min suggestions, obviously there is a way to write these better but I don't have them off the top of my head, but you can find how to do all of these things quite easily.

I do appreciate everyone for contributing, but I never actually found the reason this was happening. So, I tried a cheat instead...
I put it all in a try / catch block, and that seems to slow it down enough to process the event. Of course, the catch is useless because it will never be reached but it works.
It's a total hack, I know. I'd still be interested in finding a reason for this behavior, but until then, we carry on!

Had similar problem and solved it with moving the cursor to the dropdown.
public void hover(WebElement element) {
Actions builder = new Actions(driver());
builder.moveToElement(element).perform();
}
After that it stayed open and I could click my selection.

Related

Removing an Onclick Event From a Menu Link

I am using a AJAX search plugin for Wordpress that displays in my mobile menu by targeting a specific menu ID (menu-item-6101). Everything works great, but when I click on it the menu is dismissed (which prevents you from doing any searches, the expected behaviour is for the menu to stay visible while typing).
I have spent a number of hours researching, and it seems that there is an onclick event attached to the <a> of that menu item that is likely causing the menu to be dismissed (note that none of the other parent -> child toggles cause this, only this menu item that the search plugin is using to display a search box).
I have tried every single variation of event.preventDefault();, event.stopImmediatePropagation(); & event.stopPropagation();, as well as trying to remove the listener, send it to null, etc. but unfortunately I am having issues with either the targeting (e.g. fetching the ID, and then targeting the <a>, or it is being overridden due to the javascript load order.
I have also tried to make an onclick event for that menu item div that forces the mobile menu to stay visible (the menu gets style="display:none;" added to when when focus is changed), so I thought perhaps that would be a different approach:
jQuery('div.proinput').click(function(){
var element = document.getElementById('#mobile_menu');
element.style.removeProperty("display");
jQuery('.et_mobile_menu').css({
display: inline-block !important;
});
});
I would really appreciate it if someone could help me.
Thanks!
I think the menu toggle is actually being fired by the div#ajaxsearchpro3_2 inside de anchor. Try with this (assuming the div will allways have the same ID):
FIXED
document.getElementById('ajaxsearchpro3_2')
.addEventListener('click', function(e) {
e.stopPropagation();
});
The final solution is:
jQuery(".et_mobile_menu .menu-item a").not(".toggle-menu").off("click");
Hope that this helps someone :)

Selenium WebDriver: clicking a visible button inside a row of a table

My apology as this question is quite long.
To be more specific, I am trying to click on the Pencil icon (Edit button) that is shown on the 4th row
Here's the code I tried to execute:
WebElement ele = driver.findElement(By.xpath("//a[contains(#title, 'Edit Row')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
Executor1.executeScript("arguments[0].click();", ele);
And here's the HTML code
After I ran the selenium code, the driver actually clicked on the Edit button of the 1st row (Administration | NA) instead of the 4th. I found out that not only the 1st but other rows also have the same HTML code, only difference was that the Pencil/Edit button is hidden because I wasn't the one that created the values of that row.
I did try with the following code as well:
driver.findElement(By.xpath("//a[contains(#title, 'Edit Row')]")).click();
I then received the error
element is not currently visible and so may not be interacted with
It seems the driver was still looking at the hidden Edit button in the first row, instead of the obvious visible one in 4th.
Is there anyway that I could click on the Edit button based on the value instead of the row number? The reason is that in the future, the value I enter for testing may not end up in 4th but 1st or 10th row.
Last but not least, my Safari can't seem to run the JS Executor code, everytime I gave it a go, the following error returned:
org.openqa.selenium.WebDriverException: 'undefined' is not a function (WARNING: The server did not provide any stacktrace information)
Can someone shed some light on this for me as well?
Cheers
Since there is only one edit icon displayed, the code below should work.
driver.findElement(By.cssSelector("a[title='Edit Row']")).click();
I think the reason you were running into the hidden element issue is that you were using JSE to click on it. Selenium is designed to only interact with elements that are visible... the way a user would. JSE allows you to interact with elements that are NOT visible. There are reasons to use JSE but I don't believe this is one of them. Using JSE you were finding an element that matched your XPath that was not visible and then trying to click on it... thus the error.
I suggest you to go once in firefox and then try same xpath in firebug with firepath add-on.
Try to inspect xpath of the pencil icon. Only one maching element with no dynamic values in that, then you can and use it. Else evaluate this xapth
//a[contains(#title, 'Edit Row')]
You can find one or more matching elements. Then try to find difference in one of attribute for required element. If you are able to create xpath by using that odd attribute then its on else go for List and in loop cross theck for that, then work on it.
Thanks murali and JeffC for the suggestions, I have managed to get the driver to click on the displayed Pencil with this:
List<WebElement> EditButtons = driver.findElements(By.cssSelector("a[title='Edit Row']"));
for(WebElement button : EditButtons) {
if(button.isDisplayed()) {
button.click();
}
}
Although it only solved half of the issue, I am trying to click on the displayed Edit button based on the value next to it. If I create another row with the value of 'Test234' and if the row is placed under the 4th row, the Edit button of 'Test234' won't be clicked. Any suggestion? I tried this but it doesn't seem to work, driver still clicked on the first visible edit button it saw:
List<WebElement> EditButtons = driver.findElements(By.cssSelector("a[title='Edit Row']"));
String textvalue = driver.findElement(By.xpath("//span[contains(text(),'test456')]")).getText();
for(WebElement button : EditButtons) {
if(button.isDisplayed() && textvalue.equalsIgnoreCase("test456")) {
button.click();
}
}
UPDATE: Alright, issue resolved, I switched back to use xpath instead of cssSelector, then modified Vagnesh's suggestion (Thanks Vagnesh !!) a bit and now the driver is clicking on the visible edit button next to the text I search for without going through the loop
driver.findElement(By.xpath("//span[contains(text(), 'Enter my desired Text here')]/following::div//a[contains(#title,'Edit Row')]")).click();
You should find the element based on the field text, so that it can find its corresponding edit link.
functional_area = "Business Development / Innovation"
WebElement ele = driver.findElement(By.xpath("//span[#class='xspTextComputedField'][contains(#text, '" + functional_area + "')]/following-sibling::div/a[contains(#title, 'Edit Row')]"));
You can make it more dynamic by parameterizing the text ex. Financial.

JQuery Add/Remove Class Issue

Building a simple Multilevel push menu based on CSS classes, It has no javascript animations and runs on CSS transform/transitions. It works fine on every part other than toggling the is-open classes.
When a user clicks on a link, it should first remove the .is-open class. Then add it so the animation activates.
If i say change the .is-open class in the second stage to .addClass("foo"); it has no problem removing the .is-open class and adding the .foo class. So i'm wondering what the problem is with this section of the code.
You can find the code here http://jsbin.com/EjUQ/2/
On the demo you'll find that menus without a submenu load nothing. This is the correct behavior. The problem I'm having is that I would like the Menu to close before opening a new one. So removing the .is-open class then applying it again.
e.g
Link 1, 4,7 don't have submenu's so nothing with open on click/touch, clicking the menu button will prompt nothing to happen. This is the correct behaviour.
Link 2,3,5,6 have submenu's, so it opens on click/touch and the menu button will toggle the menu to open/close.
Hopefully someone can point me the direction of what i'm doing wrong. Thanks.
You should utilize the transitionend event. So that you listen for the animation to complete before adding the 'is-open' class back to the sidebar and content. Ex:
sidebar.one('transitionend', function() {
sidebar.addClass("is-open");
content.addClass("is-open");
});
Now, what I have here isn't perfect, but I believe it conveys the concept: http://jsbin.com/EjUQ/9

Bootstrap: accordion strips ui-droppable class on expand

New to Bootstrap and having some issues with accordion. Hoping someone would help me resolve it.
Basically I have an empty accordion and a drop down menu. Every time a selection made in the drop down menu, it is added to the accordion, with full .accordion-group mark up, but with empty .accordion-body div. After that this accordion-group set as droppable and .ui-droppable class is automatically added.
After that I am able to drag and drop a bunch of other divs into the .accordion-group and those divs are appended to .accordion-body of this particular group. This part works fine, however, as soon as i click to expand any given .accordion-group, .ui-droppable class gets stripped from ALL of them.
How do I stop it from removing .ui-droppable class??
Steps to reproduce:
Use html markup from Bootstrap page:
(For some reason I am unable to format HTML as code here by indenting it with 4 spaces,so im just pasting the link to it)
http://twitter.github.com/bootstrap/javascript.html#collapse
Add JS, which makes groups droppable
$('#accordion2').find('.accordion-group').each(function() {
$(this).droppable();
});
Inspect elements to make sure .ui-droppable class is set
Click to expand a group. Any group.
Inspect elements. .ui-droppable has been stipped from ALL of them
Resolved this, but I think it is a very stupid way to achieve the result, so I am not happy with how Bootstrap handles toggles. I really don't think there is a need to loop though every .accordion-group to re-apply droppable attributes every single time someone opens OR closes a section.
Going to re-do it with just a button and a div for each section.
Here is the solution:
$('#host-groups').on('shown', function() {
$('#host-groups').find('.accordion-group').each(function() {
$(this).attr('id').droppable();
});
});
$('#host-groups').on('hidden', function() {
$('#host-groups').find('.accordion-group').each(function() {
$(this).attr('id').droppable();
});
});
/facepalm

How to I hide or disable a choice in the context menu in javascript after clicking it?

I have a context menu with 4 option, I want to hide or disable 1 option after clicking it. these are my script fragments. After I click the save option, whenever I right click again on the div I want only the Move option available in the context menu. drag is the div class. is it possible?
var menu = [
{'Move':function(menuItem,menuObject){
$(this).css({'backgroundColor':'red'});
return true;
}
},
{'Save':function(menuItem,menuObject){
$(this).css({'backgroundColor':'blue'});
return true;
}
}
];
$(function() {
$('.drag').contextMenu(menu,{
showSpeed:500,
hideSpeed:500,
showTransition:'fadeIn',
hideTransition:'fadeOut'
});
});
Thanks in advance
First of all the class drag is the class of the parent element.
So you have to find the class of the "save" element. Lets suppose the class is .save, then on click remove it. This is done with this code:
$(".save").click(function{
$(this).remove();
})
If you right click again, the element will be created again and the above function loses its purpose. So as I can see it, this is your problem.
But why do you need to hide the save button after something is "saved"? Maybe the user wants to save again.
It would be helpful if we could see a demo in order to understand the app you are trying to implement.
If you try to apply a rule only on changed (dragged) element you have to flag the changed ones in the class or in your db which holds the positions of the elements.
Then you can manipulate only the flagged (changed) through the jquery selector.
if ((.drag).hasClass('.changed')){
$(".save").css({"visibility: visible"});
}
Dont forget to hide by default the element in css
.save{visibility: none}

Categories

Resources