Capybara 'drag & drop' does not work - ruby-on-rails

I am using cucumber/capybara/selenium/firefox on Mac. All working great except for d&d. Drag and drop is available via drag_node.drag_to(drop_node). When called, it does not raise any errors but the actual drag and drop just never happens.
Now rather than copy pasting bits and pieces, I've found this sample app (written by a guy who apparently had similar problems) that demonstrates the issue.
Google however isn't aware of drag_to() being broken. As far as I could see. That gives a hope that it is me missing something rather than a bug. So what is it? What am I missing? A bug?

For me, #drag_to did work, however, its powers seem to be limited.
In order to move a UI-sortable table row down, I had to create a table with three rows, then run this code (in a Cucumber step):
element = find('tbody tr:nth-child(1)')
target = find('tbody tr:nth-child(3)')
element.drag_to target
This would swap the first with the second row. My interpretation is that Capybara does not drag far enough, so I gave it a target beyond my actual target.
Note: I have configured UI-sortable with tolerance: 'pointer'.

I have had the same proble and solved it by going directly to the selenium-webdriver.
I an using selenium-webdriver 2.20.0 and Capybara 1.1.2
this works with this HTML
<!DOCTYPE html>
<html>
<head>
<title>Cabybara Drag And Drop</title>
</style>
<style type="text/css" media="screen">
#list_1 { background:#2C4999; }
#list_2 { background:#99752A; }
.list { padding:10px; width:200px; }
.item { background:#FFF; margin:10px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script type="text/javascript">
$().ready(function(){
$( "#list_1" ).sortable({ connectWith:"#list_2" });
$( "#list_2" ).sortable({ connectWith:"#list_1" });
});
</script>
</head>
<body>
<ol id='list_1' class='list'>
<li id='item_1' class='item'>Item 1</li>
<li id='item_2' class='item'>Item 2</li>
<li id='item_3' class='item'>Item 3</li>
<li id='item_4' class='item'>Item 4</li>
<li id='item_5' class='item'>Item 5</li>
</ol>
<ol id='list_2' class='list'>
<li id='item_6' class='item'>Item 6</li>
<li id='item_7' class='item'>Item 7</li>
<li id='item_8' class='item'>Item 8</li>
<li id='item_9' class='item'>Item 9</li>
<li id='item_10' class='item'>Item 10</li>
</ol>
</body>
</html>
Now fore the Ruby code.
Getting at the selenium-webdriver from capybara call page.driver.browser
require 'test_helper'
class DragDropTest < ActionDispatch::IntegrationTest
setup do
Capybara.current_driver = Capybara.javascript_driver # :selenium by default
end
def test_drag_item_1_to_list_2
visit '/drag_drop'
element = page.find(:id, 'item_1')
target = page.find(:id, 'list_2')
selenium_webdriver = page.driver.browser
selenium_webdriver.mouse.down(element.native)
selenium_webdriver.mouse.move_to(target.native, 0, 10)
selenium_webdriver.mouse.up
sleep 2
end
end

It is selenium-webdriver having problem with sortable lists. This post covers the workaround: http://www.dixis.com/?p=626

#drag_to does not work on sortable lists, presumably since you aren't dragging "to" an element as much as dragging a set distance and direction. Selenium's #drag_by is what you're looking for but is not currently supported by Capybara.
See also:
https://github.com/jnicklas/capybara/issues/222
https://github.com/jnicklas/capybara/issues/119

Related

Error: link is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`

I keep getting this error mess while doing this tutorial I think I'm putting the code in right?
I'm using vs as my editor.
import React from 'react';
import { NavLink, Link } from 'react-router-dom';
const Topbar = () => {
return(
<nav className='navbar navbar-light'>
<div className='container'>
<link to='/' className='navbar-brand'>
Medium
</link>
<ul className='nav navbar-nav pull-xs-right'>
<li>
<NavLink to='/' className='nav-link'>
Home
</NavLink>
</li>
<li>
<NavLink to='/login' className='nav-link'>
Sign in
</NavLink>
</li>
<li>
<NavLink to='/register' className='nav-link'>
Sign up
</NavLink></li>
</ul>
</div>
</nav>
)
}
export default Topbar;
i cant understand why i keep catching this error mess
Error: link is a void element tag and must neither have children nor use dangerouslySetInnerHTML.
You are using link-tag instead of Link. Fix this and error should disappear.
Use capitalized Link instead of link
import Link from 'next/link'
<Link href="/"><a>Medium</a></Link>
**Use Capitalized Link Tag **
HOME

Ajax loaded nested list Can't get event from inner

We have this nested list:
<ul id="AllTopics" data-role="listview" data-inset="true" data-filter="true" data-filter-placeholder="Search topic...">
<li>Polite Phrases<span class="ui-li-count">101</span>
<ul data-role="listview" data-inset="true" >
<li >Polite Phrases<span class="ui-li-count">101</span></li>
<li >At The End Of A Letter/Email<span class="ui-li-count">101</span></li>
</ul>
</li>
</ul>
The first <ul> with the id="AllTopics" is in the html documnet itself,
The inner <li><ul><li>... are loaded from Ajax call like:
on('pageinit'... event
... $("ul").append(...
I can get the event from the first new born <li> , like:
$('#AllTopics').on('click','li',function (event){...
But the inner <li> or <a> do not seem to fire events :-(
Ani ideas ?
Thank's in advance
The problem would be that the new content is loaded using an Ajax call, and you just setup the events before, so the new elements won't have them.
Try using delegate JQuery function:
$('#AllTopics').delegate('li a','click',function(){
alert('How you dare to click on my links?!');
});
EDIT
Other solution is to assign the events once elements are added via Ajax call.
// This is an example, retrieve the data on your own form
$.get('mypage.php',function(data){
// Add content to your DOM elements
$('#AllTopics').append(data);
// Assign events
$('#AllTopics').on('click','li',function (event){
alert('Holy moly, you keep clicking on my links!');
});
});
Note: I just realized that your HTML elements have this composition:
<ul>
<li>
<a/>
</li>
<span/>
<ul>
<li>
</a>
</li>
</ul>
</ul>
So, OF COURSE that is only affecting the first one because there are two levels of li - a (you have an ul element inside another one). You can define an ID for your second group of li - a elements to trigger events successfully or keep doing it in this way:
$('#AllTopics').delegate('li a','click',function(){
alert('How you dare to click on the first link?!');
});
$('#AllTopics').delegate('ul li a','click',function(){
alert('Stop clicking my children links!');
});

Simple multi tier accordion list with jquery

I am trying to simplify a navigation tree with a jquery accordion style menu. With some help from other posts i feel like im missing something simple. What is getting me is that one category has a second sub list. I cant get it to to open.close correctly. the sample code I have here just does not expand "T1 sub b" item. What am I missing?
http://jsfiddle.net/9uvgs/203/
html:
<ul class='menu'>
<li>Tier1</li>
<ul>
<li>T1 sub a</li>
<li>T1 sub b</li>
<ul>
<li>T1 sub i</li>
</ul>
</ul>
<li>Tier 2</li>
<ul>
<li>T2 sub a</li>
<li>T2 sub a</li>
<li>T2 sub a</li>
</ul>
</ul>
Jquery
$(document).ready(function(){
$('ul.menu ul').hide();
$('ul.menu>li').click(function(){
$(this).next('ul').slideToggle();
});
});
$(document).ready(function(){
$('ul.menu ul').hide();
$('ul.menu li').click(function(){
$(this).next('ul').slideToggle();
});
});
I've done this and it looks like working just fine.
You are only applying the click event to the direct children of ul.menu a simple solution would be to change you selector to ul.menu li instead of ul.menu>li
$(document).ready(function(){
$('ul.menu ul').hide();
$('ul.menu li').click(function(){
$(this).next('ul').slideToggle();
});
});

jquerymobile pages and Phonegap deviceready event onLoad

I know this has been discussed before, but with no results for me.
The problem is that deviceready() is only fired once, the first time on "list" page. I canĀ“t get it to work on article pages. And when I go back from a "article" page to "articlelist" the event is still out of work. I need the menubutton operative in every data-role="page".
The js:
<script type='text/javascript'>
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
document.addEventListener("menubutton", onMenuKeyDown, false);
}
function onMenuKeyDown() {
alert('Menu pressed');
}
</script>
The HTML:
<body onload="onLoad()">
<div id="list" data-role="page">
<ul id="articleList" data-role="listview">
<li id="list1"><a id="link1" href="#article1"></li>
<li id="list2"><a id="link1" href="#article2"></li>
</ul>
</div>
<div id="article1" data-role="page">Content</div>
<div id="article2" data-role="page">Content</div>
I'm with: cordova-1.5.0 /jquery.mobile-1.1.0-rc.2 /jquery-1.7.1 /Android
Any help please?
I just quickly tested this in the app I'm working on right now and it works. Phonegap-1.6.1 and jquery.mobile-1.1.0 final
Perhaps you should try upgrading your phonegap and jquery.mobile

jQuery Mobile - How to mobile-ize a checkbox rendered via jQuery Templates

On a jQuery Mobile site I have elements of a <ul> being populated by jQuery Templates, filling out <li> items so something like this:
<ul>
</ul>
<button>Fill</button>
<script type="text/x-jquery-tmpl" id="tmpl-items">
<li><input type="checkbox" name="guys" /> ${FirstName} ${LastName}</li>
</script>
<script type="text/javascipt">
$('this-page-id').live('pageinit', function() {
$('button').click(function() {
$('#tmpl-items').tmpl(MyApp.Model)
.appendTo('ul')
});
})
</script>
Everything works, except the checkbox renders as a normal checkbox, not a cool jquery-mobilized checkbox. I know that the trick is to call "refresh" on the widget but I have no idea what widget I should be using - there is no data-role here. Does anybody know?
Can you triggering a create on the ul,like this $('ul').trigger('create');

Resources