From a47ed8c0915f45e3607fb033d41700ee3a445f56 Mon Sep 17 00:00:00 2001 From: YusukeIwaki Date: Mon, 13 Jun 2022 23:47:02 +0900 Subject: [PATCH 1/5] fix: make sure inner OOPIFs can be attached to --- lib/puppeteer/frame_manager.rb | 7 +++++++ spec/assets/inner-frame1.html | 10 ++++++++++ spec/assets/inner-frame2.html | 1 + spec/assets/main-frame.html | 10 ++++++++++ spec/integration/oopif_spec.rb | 10 ++++++++++ spec/spec_helper.rb | 8 +++++--- 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 spec/assets/inner-frame1.html create mode 100644 spec/assets/inner-frame2.html create mode 100644 spec/assets/main-frame.html diff --git a/lib/puppeteer/frame_manager.rb b/lib/puppeteer/frame_manager.rb index 8257aba4..0201e062 100644 --- a/lib/puppeteer/frame_manager.rb +++ b/lib/puppeteer/frame_manager.rb @@ -75,6 +75,13 @@ def initialize(client, page, ignore_https_errors, timeout_settings) client.async_send_message('Page.enable'), client.async_send_message('Page.getFrameTree'), ) + if cdp_session + cdp_session.send_message('Target.setAutoAttach', { + autoAttach: true, + waitForDebuggerOnStart: false, + flatten: true, + }) + end frame_tree = results.last['frameTree'] handle_frame_tree(client, frame_tree) await_all( diff --git a/spec/assets/inner-frame1.html b/spec/assets/inner-frame1.html new file mode 100644 index 00000000..00f19ec1 --- /dev/null +++ b/spec/assets/inner-frame1.html @@ -0,0 +1,10 @@ + diff --git a/spec/assets/inner-frame2.html b/spec/assets/inner-frame2.html new file mode 100644 index 00000000..9a236cc4 --- /dev/null +++ b/spec/assets/inner-frame2.html @@ -0,0 +1 @@ + diff --git a/spec/assets/main-frame.html b/spec/assets/main-frame.html new file mode 100644 index 00000000..0c50feff --- /dev/null +++ b/spec/assets/main-frame.html @@ -0,0 +1,10 @@ + diff --git a/spec/integration/oopif_spec.rb b/spec/integration/oopif_spec.rb index 0ef265d9..ac5d7d36 100644 --- a/spec/integration/oopif_spec.rb +++ b/spec/integration/oopif_spec.rb @@ -145,6 +145,16 @@ def oopifs(context) expect(page.frames.size).to eq(2) end + it 'should wait for inner OOPIFs' do + predicate = -> (frame) { frame.url&.end_with?('/inner-frame2.html') } + frame2 = page.wait_for_frame(predicate: predicate) do + page.goto("http://mainframe:#{server_port}/main-frame.html") + end + expect(oopifs(browser_context).size).to eq(2) + expect(page.frames.count { |frame| frame.oop_frame? }).to eq(2) + expect(frame2.evaluate('() => document.querySelectorAll("button").length')).to eq(1) + end + it 'should load oopif iframes with subresources and request interception' do predicate = -> (frame) { frame.url&.end_with?('/oopif.html') } frame_promise = page.async_wait_for_frame(predicate: predicate) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 098e5bac..99c27f20 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -78,6 +78,7 @@ def firefox? if example.metadata[:enable_site_per_process_flag] args = launch_options[:args] || [] args << '--site-per-process' + args << '--host-rules=MAP * 127.0.0.1' launch_options[:args] = args end @@ -150,7 +151,7 @@ def default_launch_options config.include PuppeteerMethods, type: :puppeteer test_with_sinatra = Module.new do - attr_reader :server_prefix, :server_cross_process_prefix, :server_empty_page, :sinatra + attr_reader :server_port, :server_prefix, :server_cross_process_prefix, :server_empty_page, :sinatra end config.include(test_with_sinatra, sinatra: true) config.around(sinatra: true) do |example| @@ -163,8 +164,9 @@ def default_launch_options sinatra_app.set(:quiet, true) sinatra_app.set(:public_folder, File.join(__dir__, 'assets')) sinatra_app.set(:logging, false) - @server_prefix = "http://localhost:4567" - @server_cross_process_prefix = "http://127.0.0.1:4567" + @server_port = 4567 + @server_prefix = "http://localhost:#{@server_port}" + @server_cross_process_prefix = "http://127.0.0.1:#{@server_port}" @server_empty_page = "#{@server_prefix}/empty.html" sinatra_app.get('/_ping') { '_pong' } From 7f419cf5144cd30b1e9084a3614866849c1331bf Mon Sep 17 00:00:00 2001 From: YusukeIwaki Date: Tue, 21 Jun 2022 01:12:05 +0900 Subject: [PATCH 2/5] fix race-condition --- lib/puppeteer/frame_manager.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/puppeteer/frame_manager.rb b/lib/puppeteer/frame_manager.rb index 0201e062..cfae75e8 100644 --- a/lib/puppeteer/frame_manager.rb +++ b/lib/puppeteer/frame_manager.rb @@ -71,18 +71,17 @@ def initialize(client, page, ignore_https_errors, timeout_settings) private def init(cdp_session = nil) client = cdp_session || @client - results = await_all( + promises = [ client.async_send_message('Page.enable'), client.async_send_message('Page.getFrameTree'), - ) - if cdp_session - cdp_session.send_message('Target.setAutoAttach', { + cdp_session&.async_send_message('Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: false, flatten: true, }) - end - frame_tree = results.last['frameTree'] + ].compact + results = await_all(*promises) + frame_tree = results[1]['frameTree'] handle_frame_tree(client, frame_tree) await_all( client.async_send_message('Page.setLifecycleEventsEnabled', enabled: true), From c5d4e416e9509bbb9456cd136944fe598ed8a85b Mon Sep 17 00:00:00 2001 From: YusukeIwaki Date: Tue, 21 Jun 2022 01:12:27 +0900 Subject: [PATCH 3/5] feat: use absolute URL for EVALUATION_SCRIPT_URL https://github.com/puppeteer/puppeteer/pull/8481 --- lib/puppeteer/execution_context.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppeteer/execution_context.rb b/lib/puppeteer/execution_context.rb index dcb8a737..9cdee1cf 100644 --- a/lib/puppeteer/execution_context.rb +++ b/lib/puppeteer/execution_context.rb @@ -2,7 +2,7 @@ class Puppeteer::ExecutionContext include Puppeteer::IfPresent using Puppeteer::DefineAsyncMethod - EVALUATION_SCRIPT_URL = '__puppeteer_evaluation_script__' + EVALUATION_SCRIPT_URL = 'pprt://__puppeteer_evaluation_script__' SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m # @param client [Puppeteer::CDPSession] From 42f24f354c4fee905d94fe457557f85974e3a481 Mon Sep 17 00:00:00 2001 From: YusukeIwaki Date: Tue, 21 Jun 2022 01:14:16 +0900 Subject: [PATCH 4/5] fix: consider existing frames when waiting for a frame https://github.com/puppeteer/puppeteer/pull/8200 --- lib/puppeteer/page.rb | 4 ++++ spec/integration/oopif_spec.rb | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/puppeteer/page.rb b/lib/puppeteer/page.rb index 68d1e83d..979bd89b 100644 --- a/lib/puppeteer/page.rb +++ b/lib/puppeteer/page.rb @@ -814,6 +814,10 @@ def wait_for_frame(url: nil, predicate: nil, timeout: nil) predicate end + frames.each do |frame| + return frame if frame_predicate.call(frame) + end + wait_for_frame_manager_event( FrameManagerEmittedEvents::FrameAttached, FrameManagerEmittedEvents::FrameNavigated, diff --git a/spec/integration/oopif_spec.rb b/spec/integration/oopif_spec.rb index ac5d7d36..a32f4d4c 100644 --- a/spec/integration/oopif_spec.rb +++ b/spec/integration/oopif_spec.rb @@ -221,4 +221,12 @@ def oopifs(context) expect(result_bounding_box.x).to be > 150 # padding + margin + border left expect(result_bounding_box.y).to be > 150 # padding + margin + border top end + + it 'should resolve immediately if the frame already exists' do + page.goto(server_empty_page) + attach_frame(page, 'frame2', "#{server_cross_process_prefix}/empty.html") + predicate = ->(frame) { frame.url&.end_with?('/empty.html') } + frame = page.wait_for_frame(predicate: predicate) + expect(frame.url).to end_with("/empty.html") + end end From 83cfc5f7404008d9ef9ee5737440b9c5321e93c1 Mon Sep 17 00:00:00 2001 From: YusukeIwaki Date: Tue, 21 Jun 2022 01:22:30 +0900 Subject: [PATCH 5/5] fix Style/TrailingCommaInArrayLiteral --- lib/puppeteer/frame_manager.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/puppeteer/frame_manager.rb b/lib/puppeteer/frame_manager.rb index cfae75e8..63edcbf5 100644 --- a/lib/puppeteer/frame_manager.rb +++ b/lib/puppeteer/frame_manager.rb @@ -78,7 +78,7 @@ def initialize(client, page, ignore_https_errors, timeout_settings) autoAttach: true, waitForDebuggerOnStart: false, flatten: true, - }) + }), ].compact results = await_all(*promises) frame_tree = results[1]['frameTree']