High-level testing advice for PayPal integration tests

Hey all,

I’m currently working on a set of integration tests for a project I inherited that works with Paypal’s Payflow Hosted Payment Pages. I’m open to any form of tests that will help ensure that our payment process is well-covered, so any advice would be appreciated, but currently am focusing on integration tests.

I’m using PayPal’s Hosted Payment pages to host the page where credit card information is entered. This payment page is loaded via an iframe, which has order/user information passed to it via hidden form fields in a POST request.

The flow looks like this:

User Information Page ->
Confirmation Page (has an iframe with hidden form fields that submit to PayPal after confirmation) ->
Payment Page (iframe: PayPal Credit Card Page) ->

Eventually the goal is to stub the request that is sent to PayPal (likely via VCR, though there may be issues with it+capybara-webkit) so I can simulate the full stack of a user entering information and simulate acceptance/declines of credit cards appropriately.

Unfortunately, I’m unable to even get interaction working using within_frame to simulate clicks in the tests. While the code executes correctly in development mode, the tests give an error of Capybara::ElementNotFound and fail.

When I puts page.body to the screen in the test, it shows the <iframe> tag, but without any content. Even if I try to add something like sleep(5) to ensure there’s enough time to load the iframe, it still doesn’t work. The iframe is local, so I’m not certain of what could be causing the issues. Here’s an example of results from puts page.body in the test:

<iframe id="payflow-checkout" src="/payments/payflow/checkout/3" width="490px" height="660px" frameborder="0" scrolling="yes" style="background-color: white;" target="_top"></iframe>

And the test:

feature "Donor submits valid payment information", js: true do
  it "should show as a successful payment" do
    visit "/projects/#{project.id}/home"
    click_on "Give to this Project"
    click_on "Continue"
    within_frame "payflow-checkout" do
      click_on "submit"
    # expect(page).to have_content("Successful payment")

When I debug the output using save_and_open_page or save_screenshot, I see the confirmation page is loading, but the iframe content isn’t. This is using capybara-webkit 1.4.1 on Rails 3.2.21, if it helps.

Any ideas? Beyond any specific ideas for helping with this test, I’m also open to any discussion about how you’d approach testing this – at the end of the day, all I want to ensure is that each step of the payment process is working properly, and the sheer number of problems I’m encountering testing this way is making me reconsider if I’m even taking the right approach.


Hi @robcole,

Consider taking a look at puffing-billy - its like VCR for 3rd party browser content. Puffing-billy is a proxy that all of your test browser traffic flows through, and it can stub all of that traffic.

If I’m understanding correctly, I think your aim would be to make it so your PayPal dependent test can run successfully without an Internet connection. Puffing-billy can record your PayPal request/responses and serve them during latter test runs.

Regarding the iframe timeout, this issue may go away once you’ve got puffing-billy setup. However, in the meantime, I’d recommend removing sleep (its not needed with Capybara) and instead setting Capybara’s default wait time:

Capybara.default_wait_time = 5 # in seconds, may want to increase

Then this wait time will be the max timeout used by within_frame "payflow-checkout" do ... end.

For some puffing-billy examples, see https://github.com/eliotsykes/rspec-rails-examples#puffing-billy-examples


Thanks for the response. Eventually I figured out that it looks like the error I’m having is, for some reason, related to capybara-webkit. Switching to Poltergeist helped me around the iframe not loading errors. http://stackoverflow.com/questions/24081305/how-to-write-integration-tests-for-stripe-checkout-on-rails helped turn me on to that as a possible solution.

I’ve managed to progress to the point that I can load the iframe and enter the credit card information remotely on PayPal’s form. Unfortunately, running into yet another problem there where the Payment button responds to click_on, but simply doesn’t submit. Trying to debug that now… but running into some more complexities.

Once I can get it submitting, I’ll look into recording and playing back the full interactions using puffing-billy. You guessed at my end goal, which is to have recording/playback of interactions with external sites so I don’t have any dependencies on them in the tests; unfortunately, in order to do that (AFAIK) I have to get the test working without mocking the interactions first.