I'm using the following Capybara query:
all(:xpath, '//table[#class="myClass"]//tr)
My table contains two entries:
<tr class="class1" style="visibility: hidden;">
<tr class="class2">
The code above is a bit simplified compared to the original, but It serves the example. When running Capybara against Chrome or Firefox, the query results one element (class2). When running the same code against Poltergeist, I'm getting both elements. I tried to play around with explicitly telling Capybara to ignore hidden elements, but I'm still getting the hidden one. Am I'm missing here something?
This has been fixed by the Poltergeist team:
https://github.com/teampoltergeist/poltergeist/issues/618#issuecomment-150139228
Related
In a Capybara feature spec, I am attempting to do the following:
within_frame("element_content_content_ifr") do
# do stuff
end
Where element_content_content_ifr is the CSS ID of my tinymce iframe.
I get the error:
Capybara::ElementNotFound:
Unable to find visible frame "element_content_content_ifr"
I've set a pause during the test and inspected element. The iframe with the specified ID is definitely there, but Capybara can't find it. I am not having issues with Capybara finding iframes in other parts of my application, only the TinyMCE iframe.
I have also attempted sleep 5 before executing the within_frame line, but I get the same error. Is there something I'm doing wrong? Is there a proper way to do Capybara tests when TinyMCE is on the page?
Attached is a screenshot of the iframe's visibility on the page, as well as its DOM ancestors:
From the HTML/CSS shown it's confusing how the iframe is shown at all since its ancestor <div role="application" ...> has visibility: "hidden" as a style and there isn't a visible override of that anywhere below. First thing would be to make sure you're running a recent version of Capybara and whatever driver you're using (I assume selenium). If you already are, or that doesn't fix the issue you can try working around it with
within_frame("element_content_content_ifr", visible: false) do
and see if that works.
Beyond that if you can figure out what CSS is making the frame actually visible while inside the hidden element, I would appreciate it if you could file an issue on the Capybara project with enough info to replicate the issue.
I'm running Rails 5.x, with, Cucumber, Siteprism and Capybara through chromedriver. Most things work except..
I have a tiny bit of javascript that changes the class on an element in response to an event. But Capybara never sees the change. It only ever sees the class the element has when the page initially loaded.
Using Chrome, and debugging my Cucumber steps, I can see the element has the new class, but Capybara doesn't see it.
This must be an issue other people have encountered and solved, though I can't find the right subject title.
example coffeescript
$(document).on('focus', 'tbody#item-entry > tr > td > input', (e) ->
$(#).closest('tr').addClass('focused-row')
$(#).closest('td').addClass('focused-cell')
)
example html after the focus event has been triggered
<tr class="focused-row">
<td>ignore this </td>
</tr>
The purpose is to change the background colour of the row containing an input element that has focus. It works.
But Capybara, can't see the class, but it can see any classes added when the page is loaded. e.g.
expect(siteprism_stuff.root_element['class']).to match(/focused-row/)
Ignore the SitePrism stuff, that just gets the right element. root_element is the Capybara class for the dom node.
Now I know it's getting the right Capybara element because if I change my view to put stuff in the class for each row, then it sees that perfectly OK. What it can't see is the any new class added via Coffeescript. Although it's visible in the Chrome inspector, and changes the background color of the focused row as required.
You're specifying an "ends with" CSS attribute selector ($=)
input[class$='form-control']
which since the class attribute for the element you're interested in
<input type="search" class="form-control form-control-sm" placeholder="" aria-controls="universitiesTable">
doesn't end with 'form-control' is correctly not matching. You probably just want to use a normal CSS class selector input.form-control if continuing to do it the way you are. Any of the following options should find the search field and fill in the data you are trying to fill in.
fill_in 'Search:', with: string
fill_in type: 'search', with: string
find(:field, type: 'search').set(string)
find('input.form-control').set(string)
Note: Your question is still unclear as to whether you are seeing the class added in the inspector in test mode, and whether the line color is changing while the tests are running (or whether you're only seeing that in dev mode) - This answer assumes the JS is actually running in test mode and you're seeing the line color change while the tests are running.
You don't show how you're actually triggering the focus event but I'll assume you're clicking the element. The thing to understand when working with Capybara is that the browser works asynchronously, so when something like click has been done, the actions triggered by that click have not necessarily been done yet. Because of that, whenever doing any type of expectation with page elements you should always be using the matchers provided by Capybara rather than the basic matchers provided by RSpec. The Capybara provided matchers include waiting/retrying behavior to handle the asynchronous nature of dealing with the browser. In this case, assuming siteprism_stuff.root_element is the row element then you could be doing something like
expect(siteprism_stuff.root_element).to match_css('.focused-row')
or depending on exactly how your siteprism page objects are setup you could pass the class option to the siteprism existence checker
# `page_section` and `have_row` would need to be replaced with whatever is correct for your site prism page object
expect(page_section).to have_row(class: ['.focused-row'])
grails v 3.3.9, fields plugin
fighting with fields plgin and theres a problem when rendering domain objects and using bootstrap
i've got a sample here from a simple standalone page to show the problem
<p>f:display category </p>
<f:display bean="maintenanceAgreement" >
</f:display>
<hr />
<p>f:field category</p>
<f:field bean="${this.pageScope.maintenanceAgreement}" property="category">
<g:render template="/_fields/map/displayWidget" ></g:render>
</f:field>
<hr />
in essenence i have added a template in "/_fields/map/displayWidget" that renders a drop right table on a button
when you render a map field directly from your Domain object the sample table opens and you get all of the table
however when you
you can see the differences between using f.display (has clipping problem), f.field ( which seems to work) and f.all that ignores my _fields/map/_displayWidget.gsp
I dont want to have not use the fields plugin but its not working with bootstrap templating
has any one come up with a fix for this problem?
the project demo page is here
github standalone page to show rendering problem
the attached shows the output as you try each and select category property
well goldarn it another 2 days down the pan - but i have it !
I thought at first it was something to do with fields plugin processing. so i hacked a clone of plugin project locally and added some bits so i could watch it/debug step through it
in doing so i noted that my dummy web domain class page i'd cut across to the plugin didnt have the clipping problem. but the styles were not the same so i copied main.css and grails.css from ordinary project back into the plugin, then re rendered in the browser - and the clipping happened again.
so its in the css!. some very careful watching of browser and looking at the browser 'inspect' indicated that the clipping seemed to be enabled very early on in the journey.
so in my dummy page i just used
I then spent a day wandering round the various bits of fields plugin as its not that well explained anywhere.
if you look at the plugins taglib display method, by default that triggers the /templates/fields/_list.gsp. naming is a little odd but its the gsp that renders the domains persistent attributes as an ordered list - the plugins default _list.gsp looks like this
<ol class="property-list ${domainClass.decapitalizedName}">
<g:each in="${domainProperties}" var="p">
<li class="fieldcontain">
<span id="${p.name}-label" class="property-label"><g:message code="${domainClass.decapitalizedName}.${p.name}.label" default="${p.defaultLabel}" /></span>
<div class="property-value" aria-labelledby="${p.name}-label">${body(p)}</div>
</li>
</g:each>
</ol>
so after much exploration coming up through templates, from the bottom I ended up right at the top with the '
so nearly there now. back into main.css that i'd copied in. if you edit that, down around line 215 you get this style. If you comment out the overflow property - its all fixed !
.property-list .fieldcontain {
list-style: none;
/*overflow: hidden; */
zoom: 1;
}
I tried auto, scroll, and visible but that seems to much about with too much of the page so best to just comment it out.
once you do that - the rest of the rendering of your forms starts to work !! blimey one line of css for all that pain. Attached is the page using
Lastly through out all this, id ended up digging through /tracing fields plugin. What a nest that is. Not really finished here, but basically
with no body just renders a label and no content. So you either need to provide provide a body tag, say to get the value field displayed.
as
if no widget template has been defined then the renderDefaultDisplay is called which again has very limited options for controlling the rendering by falling through a 'switch (prop.type)' and basically calls either g.format (bool), g.formatDate (but no LocalDateTime/LocalDate Support) or g.fieldValue, non of which are bootstrap enabled.
if you call
these two diagrams are not beautiful but just high level pseudo code walk through for what the core tags are trying to do. One day i'll try and pretty that up but it might help you if you get stuck
I'll raise a bug for the main.css clipping directly to the grails team and see what happens, but you can comment the line out yourself if you fall foul of it.
I'm converting some existing HTML files to Slim (https://github.com/stonean/slim) and using it for the first time but I'm having problems getting lists to work in compact form (meaning all on one line rather than indented below). The docs say:
Inline tags
Sometimes you may want to be a little more compact and inline the
tags.
ul
li.first: a href="/a" A link
li: a href="/b" B link
But when I try that I get this output in the browser:
a href="/b" B
With the rendered HTML looking like this in the source:
<li:>a href="/b" B link</li:>
Any ideas why this isn't working and how to fix it?
Your syntax is correct and the output for me (slim 1.3.0) is, as expected:
<ul><li class="first">A link</li><li>B link</li></ul>
You should check your slim version and update appropriately.
I am using jquery ui sortable to sort TD's in a TR. In chrome this seems to be indenting the TDs to the right. From a similar question found on SO, I reckon this is because of chrome adding an extra TD which is not even visible under console, and is only being rendered.
How do make this work?
I have found this snippet that tries to force chrome to render again, but this does not seem to work.
var n = document.createTextNode(' ');
$('TD:eq(0)').parent().get(0).appendChild(n);
n.parentNode.removeChild(n);
The similar question found on SO says that he was able to solve the issue by calling a function .render() on his view item, I presume this is a custom function for a library the asker was using.
Any ideas on how to force refresh the DOM?
To those who are facing a similar issue, I found that hiding the parent element and showing it after a small delay(10ms works), keeps things working.