Unable to find a ReactModal as a section - ArgumentError: wrong number of arguments - capybara

SitePrism has been working great for my automation project until I needed to get a handle on a particular ReactModal object that works with straight capybara find command but not in SitePrism. I would really appreciate any help with this issue.
calling find in pry debugger with would work
pry(#RSpec::Core::ExampleGroup::Nested_1)>
find "div:nth-child(18) > div > div > div"
=> # "div:nth-child(18) > div > div >
div"
pry(#RSpec::Core::ExampleGroup::Nested_1)>
find find "div:nth-child(18) > div > div > div"
=> # "div:nth-child(18) > div > div >
div"
however calling SitePrism object #videos_page.clipping would result in error
pry(#RSpec::Core::ExampleGroup::Nested_1)>#videos_page.clipper
ArgumentError: wrong number of arguments (given 2, expected 0)
from /Users/kpham/.rvm/gems/ruby-2.3.0#social/gems/site_prism-2.9/lib/site_prism/element_container.rb:28:in initialize'
pry(#RSpec::Core::ExampleGroup::Nested_1)>#videos_page.clipping
ArgumentError: wrong number of arguments (given 2, expected 0) from /Users/kpham/.rvm/gems/ruby-2.3.0#social/gems/site_prism-2.9/lib/site_prism/element_container.rb:28:ininitialize'
class ClippingDialog <SitePrism::Page
element :header, ".bc-modal-header h3"
element :close, ".bc-close"
section :body, ClippingDialogBody, ".bc-modal-body"
section :footer, ClippingDialogFooter, ".bc-modal-footer"
end
class VideosPage <SitePrism::Page
set_url "/videos"
section :clipper, ClippingDialog, ".bc-dialog.bc-dialog-clipping"
section :clipping, ClippingDialog, "div:nth-child(18) > div > div > div"
end
<div class="ReactModalPortal">
<div class="ReactModal__Overlay ReactModal__Overlay--after-open bc-modal bc-modal-clipping" data-reactid=".2">
<div class="ReactModal__Content ReactModal__Content--after-open bc-modal-content bc-modal-content-clipping" tabindex="-1" data-reactid=".2.0">
<div role="dialog" class="bc-dialog bc-dialog-clipping" data-reactid=".2.0.0">

Found the issue with my section definition, cut and paste error.
class ClippingDialog <SitePrism::Page
should be:
class ClippingDialog <SitePrism::Section
My issue is resolved.

Related

Rspec capybara Selenium::WebDriver::Error::ElementNotInteractableError could not be scrolled into view

I have this test spec:
Scenario "preview offer", js: true do
...
When "I click onto the contact details tab" do
within_frame "preview-iframe" do
click_link "Enter details"
end
end
...
end
But it throws an exception:
Failures:
1) Preview Offer preview coaching offer booking with Journeyman enabled
Failure/Error: button.click
Selenium::WebDriver::Error::ElementNotInteractableError:
Element <a href="/offers/details"> could not be scrolled into view
The actual html is:
<iframe frameborder="0" id="preview-iframe" name="preview-iframe" scrolling="no" src="/offer">
...
<ul class="list-steps">
...
<li data-page="enter-details">
Enter details
</li>
...
</ul>
...
</iframe>
I have try to be more specific for the test case as:
When "I click onto the contact details tab" do
sleep 5
execute_script "window.scrollBy(0,500)"
within_frame "preview-iframe" do
button = find("#body > div > header > div > div.header__bar > ul > li:nth-child(2) > a")
button.click
end
end
I added sleep 5 because to give times to iframe content to be fully loaded
added scroll to ensure the page is scrollable to the view?
specified the button to be click
But still got the same error, I use selenium as the web driver, anyone has this issue?
thank you

Capybara unable to pick up hidden element

Pretty simple spec is failing after upgrade (Rails 4.2 -> 5.2) and Capybara (2.x to 3.10.1).
I think it might have something to do with the way .hover is being used to make a hidden element appear on mouseover, but I could be wrong?!?
The "1" bubble appears when driver is manually paused right before "expect(…)" . However, I'm not sure Capybara's .hover is working in the spec. Is there any other way to do do this?
RSpec:
scenario 'changes counter' do
close_modal type: :image
find('editable-section:nth-child(1) li.photo:nth-child(1)').hover
save_and_open_page # <- `1` is visible on the page (see HTML below)
within 'editable-section:nth-child(1) li.photo:nth-child(1)' do
expect(page).to have_css '.comment-count', text: '1'
end
end
Failure:
1) Comment creation for image changes counter
Failure/Error: expect(page).to have_css '.comment-count', text: '1'
expected to find visible css ".comment-count" with text "1" within #<Capybara::Node::Element tag="li" path="/HTML/BODY/DIV[2]/SECTION/DIV/EDITABLE-SECTION[1]/DIV/DIV/DIV/SECTION/UL/LI"> but there were no matches. Also found "", which matched the selector but not all filters.
It doesn't even respond to:
pry> expect(page).to have_css('.comment-count')
RSpec::Expectations::ExpectationNotMetError: expected to find visible css ".comment-count" but there were no matches. Also found "", "", "", which matched the selector but not all filters.
HTML from Chrome paused right before expect shows that .comment-count is clearly there:
<ul attachments="section.attachments" class="collage ng-scope ng-isolate-scope" image-collage="" ng-if="isDisplaying">
<!-- ngRepeat: attachment in section.attachments -->
<li class="photo ng-scope" ng-repeat="attachment in section.attachments" style="width: 299px; height: 300px; margin-bottom: 9.6px; margin-right: 0px; display: inline-block; vertical-align: bottom; overflow: hidden; opacity: 1;">
<div class="meta-indicator">
<div class="comment-count">
<i class="fa fa-comment"></i>
<span ng-bind="attachment.commentsCount" class="ng-binding">1</span>
</div>
</div>
<a class="image-wrapper" href="">
<img ng-click="openModal(attachment)" ng-src="https://d545dpp7432ym.cloudfront.net/images/medium/test-image.jpg" role="button" tabindex="0" src="https://d545dpp7432ym.cloudfront.net/images/medium/test-image.jpg" style="width: 299px; height: 300px;">
</a>
</li>
<!-- end ngRepeat: attachment in section.attachments -->
</ul>
CSS (slim):
ul.collage(image-collage attachments="section.attachments" ng-if="isDisabled")
li.photo ng-repeat="attachment in section.attachments"
.meta-indicator
.comment-count
i.fa.fa-comment
span ng-bind="attachment.commentsCount"
a.image-wrapper href=""
img(
ng-src="{{ attachment.mediaFile.previewUrl('medium') }}"
)
ul.collage(image-collage attachments="section.attachments" ng-if="isDisplaying")
li.photo ng-repeat="attachment in section.attachments"
.meta-indicator
.comment-count
i.fa.fa-comment
span ng-bind="attachment.commentsCount"
a.image-wrapper href=""
img(
ng-src="{{ attachment.mediaFile.previewUrl('medium') }}"
ng-click="openModal(attachment)"
)
Edit: Add Chrome dev inspection
What's happening if I stop the test after find('...').hover the element is visible but the element is not revealed. If i manually hover the mouse at this point or force a :hover (as seen in image) then the test proceeds immediately and passes.
It is finding the element, as replacing .hover with .click opens the modal. Something about .hover is not working. Is that any other way to automate a :hover event?

Capybara doesn't want to select an input node

My HTML/ERB looks like this
<fieldset class="row notifications">
<legend>
<hr class="dash blue inline">
<%= t :my_notifications %>
</legend>
<label>
<%= f.check_box(:subscribed_to_news) %>
<span></span>
<span class="checkbox-text"><%= t :accepts_to_receive_news %></span>
<br>
</label>
</fieldset>
When I debug my Cucumber test with Capybara, I do find the notification checkbox f.check_box(:subscribed_to_news) in this mess
page.find('.notifications label')['innerHTML']
# => "\n\t\t<input name=\"user[subscribed_to_news]\" type=\"hidden\" value=\"0\"><input type=\"checkbox\" value=\"1\" checked=\"checked\" name=\"user[subscribed_to_news]\" id=\"user_subscribed_to_news\">\n\t\t<span></span>\n\t\t<span class=\"checkbox-text\">blahblahblah</span>\n\t\t<br>\n\t"
But for some reason I cannot find the nested inputs nor find them by ID
page.find('.notifications label input')
# => Capybara::ElementNotFound Exception: Unable to find css ".notifications label input"
page.find('.notifications label #user_subscribed_to_news') # => Capybara::ElementNotFound Exception: Unable to find css ".notifications label #user_subscribed_to_news"
Selecting the label does work though
page.find('.notifications label')
# => #<Capybara::Node::Element tag="label" path="//HTML[1]/BODY[1]/DIV[1]/MAIN[1]/SECTION[1]/FORM[1]/FIELDSET[3]/LABEL[1]">
What am I doing wrong ? I just want to check the damn checkbox :'(
Most likely reason is the checkbox is actually hidden by CSS and then replaced with images to enable identical styling of checkboxes across different browsers. If you're using the latest Capybara you can have it click it the label when the checkbox is hidden by calling
page.check('user_subscribed_to_news', allow_label_click: true) # you can also set Capybara.automatic_label_click = true to default to this behavior
or if using an older capybara you would need to click the label yourself
page.find(:label, "blahblahblah").click #match on labels text
or
page.find(:label, for: 'user_subscribed_to_news').click #match on labels for attribute if set
It would seem that the checkbox is unreachable via normal css /xpath...
I got away using some javascript
page.execute_script(%Q{document.querySelector('#{area} input##{selector}').click()})

Get a value of element in ruby cucumber

i am making my first steps in writing cucumber features in Ruby On Rails application and am struggling with getting a value of an element.
The structure is something like this:
<div class="selectize-dropdown-content">
<div data-value="test1" data-selectable="" class="option">TEST 1</div>
<div data-value="test2" data-selectable="" class="option">TEST 2</div>
</div>
I would like to get the value of the div element when the data-value is "test1" ... so, TEST 1
Currently I am doing it this way:
within(:xpath, '//div[#class="selectize-dropdown-content"]') do
find(:xpath, '//div[#data-value="' + value + '"]')
end
But it fails for not finding the "within" div.
So, I guess I am doing it wrong.
How does one go about it?
Thx
You need to call text method on the desired element
within('.selectize-dropdown-content') do
find(:xpath, "//div[#data-value='#{value}']").native.text
end
if there's a parent element for your block of code with ID you can do it like:
text = page.find('#parentID div:nth-child(1) div:first-child', visible: true).text
if you don't try it with javascript
text=page.evaluate_script('document.getElementsByClassName("selectize-dropdown-content")[0].getElementsByTagNam("div")[0].value')

Capybara: page_find doesn't seem to be working with double slash (//)

Trying to validate the 2nd link in the following HTML:
<div id="navigation">
<ul>
<li>
TV
</li>
<li>
Radio
</li>
with the following expression:
page.find(:xpath, "//div[#id='navigation']//a").should have_content('Radio')
and I'm getting the following error:
expected there to be content "Radio" in "TV"
Should'nt the find method research in all the A elements inside the DIV node as I'm using a double slash? Could this be a bug or am I doing something wrong?
And is there any other way to be able to validate the 2nd link?
Thanks for the help guys!
In your case find will find first a in Capybara < 2.0 and will raise an Ambiguous Match exception in Capybara 2.0 as there are more than one elements with such locator.
I suggest you to do the following:
page.should have_selector('#navigation a', text: 'Radio')

Resources