twalpole / apparition

Capybara driver for Chrome using CDP
MIT License
363 stars 46 forks source link

'within_frame' working in headless but not when using Chrome driver #35

Open TimCannady opened 4 years ago

TimCannady commented 4 years ago

We use Braintree's Drop-in UI to handle credit card payments. They use hosted fields to render some of the sensitive inputs in an iframe.

Our feature tests run successfully when using headless: true, but we receive the following error when using headless: false:

Screen Shot 2019-11-19 at 2 25 17 PM

This occurs at the point in the code where we invoke within_frame('braintree-hosted-field-number')

We did some digging in Capybara::Apparition::Page.push_frame, and this led us to some logic for @session.on 'Page.frameNavigated' in the same class (being the place where @frames.add() is called).

We could be seeing things incorrectly, but it appears that the iframe in question is successfully added to the @frames object when using headless mode, but not when using Chrome driver.

Here's some GitGists showing how we landed there:

Perhaps we're seeing things incorrectly while debugging. In any case, we've never been able to get within_frame to properly switch to an iframe which is clearly in the DOM (including after adding a sleep 20 for good measure).

For reference, here's how we're registering the driver:

Capybara.register_driver :apparition do |app|
  Capybara::Apparition::Driver.new(app,
    browser_options: {
      'no-sandbox' => nil,
      'disable-web-security' => nil,
      'disable-features' => 'VizDisplayCompositor'
    },
    headless: headless,
    js_errors: false,
    window_size: [1440, 900]
  )
end

Thanks in advance for any guidance!

twalpole commented 4 years ago

Sorry about the delay on this, been really busy. I’ll be looking at it this weekend

TimCannady commented 4 years ago

Hello! Just circling back on this for when convenient. Thanks @twalpole! 🙏

TimCannady commented 4 years ago

Greetings! Circling back on the item above if time permits. Thanks @twalpole.

twalpole commented 4 years ago

I finally have some time to refocus on apparition -- any chance of a self contained example of the issue you're having?

glaucocustodio commented 3 years ago

I am having a similar issue with within_iframe:

browser.within_frame('foo') do
end

I just receive Timed out waiting for frame to be ready, debugging the code, in method push_frame(frame_el) I see frame_id is set with the right iframe (id foo like above) but @frames[frame_id] always return nil, I tried increasing the timer (ex: Capybara::Helpers.timer(expire_in: 30)) but didn't work. The same thing happens regardless of the headless option in my case. Just for reference: the same code works with selenium_chrome / chromedriver.

When running with DEBUG=1 I see the following logs before the time out (47C7E13B290B2AF5E64F0952F04C6C6C is the frameId of the foo iframe):

**** frameAttached called with {:frame_id=>"47C7E13B290B2AF5E64F0952F04C6C6C", :parent_frame_id=>"C4B0B1540854982B7EECAC6432FAB6D0"}
Setting loading for 47C7E13B290B2AF5E64F0952F04C6C6C
unknown frame for context 47C7E13B290B2AF5E64F0952F04C6C6C
Setting loaded for 47C7E13B290B2AF5E64F0952F04C6C6C
Setting loading for 47C7E13B290B2AF5E64F0952F04C6C6C
unknown frame for context 47C7E13B290B2AF5E64F0952F04C6C6C
Setting loaded for 47C7E13B290B2AF5E64F0952F04C6C6C

Any tips?

infernalmaster commented 1 year ago

I see that ferrum has similar issue https://github.com/rubycdp/ferrum/issues/235