Capybara::Poltergeist::InvalidSelector on element with id and class - capybara

I have code like this:
<td class="activities" id="3">
<a id="3" class="btn add_activity" href="#">+</a>
</td>
And I want to click on the + link. The resulting form is opened with javascript, so I need Poltergeist to click on it. But it returns an error:
Capybara::Poltergeist::InvalidSelector:
The browser raised a syntax error while trying to evaluate css selector ".activities#28"
This is my test:
it "can open form", js: true do
within(".activities#28") do
click_link "+"
end
end
So why it can't find the element?

You have a few issues here
Your CSS selector ".activities#28" is technically illegal. This is because an id identifier in a CSS selector cannot start with a digit unless it is escaped. To fix that your CSS selector would need to become .activities#\32 8
Once fixed it won't match the HTML you've shown, because the HTML shown has an id of "3" not "28"
Your HTML shown has two elements with the same id ("3"). That's illegal HTML since ids are required to be unique on the page. Are you trying to store an id of a record that needs to be tied to that element on the page? If so it could be in a data attribute instead (which would change your CSS selector too) - although storing the same multiple times doesn't make a lot of sense either.
<td class="activities" data-id="3">
<a class="btn add_activity" href="#" data-id="3">+</a>
</td>

Related

Thymeleaf editing th:field before action

I have a simple pagination that looks like
<ul class="pagination justify-content-end" th:field="*{page}">
<li class="page-item page-item disabled">
<a class="page-link" href="action">1</a>
</li>
</ul>
I would get the following behaviour with Thymeleaf. Clicking on the page and before submitting the action, the value of the th:field associated with the pagination should be changed by setting it to the th:value of the selected page. In other words, clicking on the page number should change the value of "*{page}" and then call the method. Is there any way to do that, for example, combining th:onclick with th:action?
Thymeleaf is a rendering engine, as such it can do nothing once the page is served to the end user. At best u can fill variables into javascript when rendering to achieve the desired result.
As for your described functionality the given code is far to limited or faulty to give a suggestion for a javascript solution, for one th:field on a non-input element doesn't do much. Also the shown href is just a simple href that doesnt interact in any way with the encapsulating th:field.

adding tooltip to zendesk home_page.hbs

I want to add tooltips for some "Categories" box in Zendesk, so when the user hang over one box then I can show a tooltip with more information about the "Category".
Problem is that I'm trying to use IF statement like this:
{{#if href == '/hc/en-us/categories/360001117812-Cow-Traffic' }}
{{#each categories}}
{{#if ../has_multiple_categories}}
<li class="blocks-item">
<a href='{{url}}' class="blocks-item-link">
{{#if href == 'url_to_compare' }}
<a class="tooltiptext">tooltip_text</a>
{{/if}}
<span class="blocks-item-title">{{name}}</span>
<span class="blocks-item-description">{{excerpt description}}</span>
As this IF is inside of a {{#if}} of the categories I want to select in this example only one link using the href to see if the mouse is over or not the box.
I already tried to add a helper in the script.js file but looks like it's not working, I remember that there was a way to use this IF and IS to be able to solve it.
Thanks!
I get a lot of help on this, at the end I found that the better way to solve this is using a {{#is}} statement, So it's possible to use {{#is name "Category Name"}} {{/is}}
And this option will do a comparation between the name of the Category and the name you are looking for, if the value it's equal then you can do something inside, if not then you can use an {{else}} between and do another thing over there.
{{#is name "Category Name"}}
<div class="tooltip1">{{name}}<span class="tooltiptext">{{excerpt description}}</span></div>
{{else}}
<span class="blocks-item-title">{{name}}</span>
{{/is}}
I used the "Excerpt description" to add the value of the tooltip inside Zendesk, and no need to add it manually in the home_page.hbs code.
I added 3 different tooltips and working fine now. Thank you all!

Capybara: click on text within <span>

I had a bot that would apply on indeed.com jobs. It would collect jobs then apply to them one by one. However, indeed recently made things a lot harder. Used to be able to just locate the button's id and use that but now the id is dynamic: changes from different job positions.
Does anyone know how it is possible to link to the "Apply Now" button (not really a botton) if the code below is:
<a class="indeed-apply-button" href="javascript:void(0);" id="indeed-ia-1532137767182-0">
<span class="indeed-apply-button-inner" id="indeed-ia-1532137767182-0inner">
<span class="indeed-apply-button-label" id="indeed-ia-1532137767182-0label">Apply Now</span>
<span class="indeed-apply-button-cm">
<img src="https://d3fw5vlhllyvee.cloudfront.net/indeedapply/s/14096d1/check.png" style="border: 0px;">
</span>
</span>
</a>
Many ways to click that element, the 3 simplest would probably be
click_link('Apply Now') # find link by partial text and click it
click_link(class: 'indeed-apply-button') # find and click link by class
find('span', text: 'Apply Now').click # find span by text and click in it
in my case I had to select an option shown using js-chosen library inside an iframe. So, its not a regular select tag. So had to do following to select:-
within_frame(find("#cci_form")) do
find('#showing_listing_id_chosen').click
find('[data-option-array-index="2"]').click
end
But, no luck using
find('.active-result[data-option-array-index="2"]').click
or
find('li[data-option-array-index="2"]').click

including id in url map with submitToRemote tag

I'm building a list of results from a query, and for each result, I want them to be able to select one, and have that result come on the same page. I could use radio buttons and an additional submit button, but I don't like the way that looks with the results. My preferred solution would be to have a button or a link to each result and have that update the proper div on select. I'm trying to use submitToRemote for this:
<g:each in="${users}" var="user">
<tr>
<td>
<g:submitToRemote value="${user.firstName} ${user.lastName}"
url="[action: 'modifyUser', id:'${user.id}']" update ="adminSpace"
class="btn btn-primary"/>
...
The problem is that id field in the url, I'm sure I'm not accessing it correctly, but I cannot for the life of me find the proper syntax.
Currently I'm getting:
Message: named capturing group is missing trailing '}'
I've looked at the documentation (submitToRemote), Where it says:
url - The url to submit to, either a map containing keys for the action, controller and id or a string value
however it doesn't give any indication on how to specify the id. When I manually add a value for the id it does work (such as:
url="[action: 'modifyUser', id: '1']"
). That however isn't incredibly useful. So how do I get the id passed through to my action within the confines of the submitToRemote?
What if you try to use the createLink method? Something like:
<g:submitToRemote value="${user.firstName} ${user.lastName}"
url="${createLink(action: 'modifyUser', id: user.id)}" update ="adminSpace"
class="btn btn-primary"/>
Do not put user.id in ${} like:
<g:submitToRemote value="${user.firstName} ${user.lastName}"
url="[action: 'modifyUser', id: user.id]" update="adminSpace"
class="btn btn-primary"/>
and your code works fine.

How to fill in input field that is the child of an element that sits next to an element with given text

Inside a capybara test, I need to fill in a text field that doesn't have a unique id or class attribute.
The text field (the field called title in this case) can appear anywhere on the page. The only thing we know is that the text field is wrapped in a div and this div sits immediately after an h3 tag which has the content "Title"
<h3>Title</h3>
<div class="input-row clear">
<input id="ember5046" class="ember-view ember-text-field" type="text">
</div>
<h3>Work Location</h3>
<div class="input-row clear">
<input id="ember5048" class="ember-view ember-text-field" type="text">
</div>
How can I do it?
We are not allowed to use xpath (company policy)
We are not allowed to do index based selectors like all("input")[0]
I think it should be possible with the css adjacent siblings combinator selector. Something like:
h3[text=Title] + div
This gives you the next element matching the thing after the +. If you rather want everything that matches you could use the ~ operator instead. These siblings selector can only help you to find things after a certain node. Going backwards is not possible as far as I know.

Resources