I have a floating menu that pops up when a user clicks on a menu button (button is hidden behind the floating menu in the image below).
The functionality works fine in a live browser (tried it on Firefox, Safari, and Chrome).
However it doesn't seem to work when testing with Capybara-Webkit - the menu never becomes visible on click
Here's the basic implementation:
The menu is a <ul>
that sits inside a <div>
<div class="location-card">
...
<div class="location-card__menu-btn">
<%= inline_svg("icons/menu-btn-icon.svg", height: "20px", width: "20px") %>
<ul class="location-card__menu">
<li>Delete</li>
<li>Open</li>
<li>Share</li>
...
</ul>
</div>
</div>
Simple javascript/jquery sets a toggle class (location-card--menu-open
) on the top-level <div>
whenever the button is clicked.
$(".location-card").on("click", ".location-card__menu-btn", function(e) {
// Find the card element top-level div
var card = $(e.currentTarget).parents(".location-card");
// Set the toggle class
$(card).addClass("location-card--menu-open");
});
Finally, the CSS for the menu defaults to display: none
, but is changed to display: flex
when the toggle class is present on the parent.
.location-card__menu {
display: none;
...
}
.location-card--menu-open .location-card__menu {
display: flex;
...
}
When testing I do the following:
// Click the menu button
find(".location-card__menu-btn").click
// Verify that the menu opened and is visible
expect(page).to have_selector(".location-card__menu", visible: true)
to which Capybara throws the errror:
expected to find visible css ".location-card__menu" within #<Capybara::Node::Element ... > but there were no matches. Also found "", which matched the selector but not all filters.
As the error says, the element is found but is not visible even though the toggle class is added correctly. The CSS rule that adds the display: flex
is not being applied even though the toggle class exists on the parent.
I can verify this is the issue by removing the display: none
to have the menu displayed by default and then everything works great and the test passes.
Any idea why Capybara or the underlying browser might be failing to re-apply the CSS logic once the DOM changes?
I'm using:
Thanks!
capybara-webkit
is basically equivalent to a 7 year old version of Safari (due to QtWebkit, which it is built on, not having been updated in a long time). As such it doesn't support a lot of modern JS/CSS, which happens to include flex box. Because of this display: flex
will be considered invalid and ignored.
You're going to have a much easier time testing your app if you swap from using capybara-webkit
to selenium with headless chrome or firefox for your headless testing.