within_frame not working for stripe v3 widget

462 views
Skip to first unread message

Tiago Cardoso

unread,
Aug 13, 2019, 7:24:53 AM8/13/19
to Capybara
So, not sure if this is a bug or can be worked around, so I decided to post this one here:

I'm trying to use "within_frame" to populate the stripe input fields in the widget. Something like this:

frame = find("#stripe-card-element > div > iframe")
within_frame(frame) do
  fill_in name: "cardnumber", with: "4242" * 4
  fill_in name: "expdate", with: "1234"
  fill_in name: "cvc", with: "1233
end

this doesn't work. I can find the frame, however when within the frame, I can't find them. I tried also accessing the innerhtml property, but I got the empty iframe (no content inside):

> frame["innerHTML"]
#=> "<iframe autocomplete=......></frame>

Is there a way to work around this? Any reason why stripe widget isn't accessible otherwise? 

I'm using docker, with the selenium webdriver "selenium/standalone-chrome-debug:3.141.59-oxygen" image

Thomas Walpole

unread,
Aug 13, 2019, 12:53:34 PM8/13/19
to Capybara
You can't call `innerHTML` on the frame element to check it's content because it's not accessible for security reasons. To check the frames HTML content check `page.html` when inside the block passed to `within_frame`.  If that shows the frame content blank try sleeping for a few seconds before calling `within_frame` to see if it's an issue with the frame being replaced in the page when loading.  If that fixes your issue then you'll need to improve the selector you're using to find the frame to only find the frame once it's been replaced (attribute difference, etc). Another possibility is that the stripe JS is detecting the browser running in headless mode (I assume you're running in headless) and intentionally not building its widget.  Hopefully it's not that...

Chris Irish

unread,
Aug 13, 2019, 8:45:42 PM8/13/19
to Capybara
I did something like this about a year ago using Stripe Elements js library and found I had to use find_field and send_keys

Dunno why, but filling only worked this way for me, so I made a lil helper method for my specs.

Maybe it'll work in your case too?

def fill_stripe_elements(card: , expiry: '0120', cvc: '123', postal: '12345')
    using_wait_time(10) do
      frame = find('#card-element > div > iframe')
      within_frame(frame) do
        card.to_s.chars.each do |piece|
          find_field('cardnumber').send_keys(piece)
        end

        find_field('exp-date').send_keys expiry
        find_field('cvc').send_keys cvc
        find_field('postal').send_keys postal
      end
    end
  end

On Tuesday, August 13, 2019 at 4:24:53 AM UTC-7, Tiago Cardoso wrote:

Tiago Cardoso

unread,
Aug 14, 2019, 10:51:20 AM8/14/19
to ruby-c...@googlegroups.com
Sadly, your solution isn't working for me (I'd seen a variation of it somewhere when googling about the issue).

Does it have to do with the iframe being served from https while the page is served under http in test mode?

Also, did you test against https://js.stripe.com/v3/ ?

--
You received this message because you are subscribed to the Google Groups "Capybara" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-capybar...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-capybara/ca2c4cf0-6ad1-4d30-8872-f2d948f8f62a%40googlegroups.com.

Thomas Walpole

unread,
Aug 14, 2019, 12:22:26 PM8/14/19
to Capybara
Tiago - It very well could be an http/https issue if stripes library requires use of https even in test mode - you should be able to see that in the browser when running a test though.  https://gist.github.com/twalpole/ce436a537b2aedc0136eb6880c69a56c - is standalone code that will fill in the relevant info on one of the demos on Stripes site.  Are you using Stripe the same way as that demo? If not please provide details to which specific usage of Stripe you are implementing - a link to a demo in stripes docs would be best.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-capybara+unsubscribe@googlegroups.com.

Maximilian Schwenk

unread,
Mar 3, 2021, 5:46:58 PM3/3/21
to Capybara
Interestingly, @twal your snippet worked in headless chrome, but headful chrome basically refused to work with `within_frame`. Exact same expectations, `within_frame` just seemed to not recontextualize the 'find' queries. Unsure what would be the root cause of that.

capybara (3.35.3)
selenium-webdriver (3.142.7)
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-capybar...@googlegroups.com.

Thomas Walpole

unread,
Mar 3, 2021, 6:07:34 PM3/3/21
to Capybara
I believe the Stripe site has changed quite a bit since I wrote that snippet -- I'm a bit surprised it would work at all

Maximilian Schwenk

unread,
Mar 3, 2021, 10:18:01 PM3/3/21
to Capybara
I actually figured out it was because my custom headful driver did not have
`--disable-site-isolation-trials` set

Using the default driver you provide in capybara fixed the issue.

https://github.com/teamcapybara/capybara/blob/1480800582a2a5e635dfe68fc3d9bcdce3b90b1d/lib/capybara/registrations/drivers.rb#L38

Your snippet still works FWIW. Thanks as always for your responsiveness @twal
Reply all
Reply to author
Forward
0 new messages