diff --git a/lib/puppeteer/events.rb b/lib/puppeteer/events.rb index 0a74a9c6..2ef0a400 100644 --- a/lib/puppeteer/events.rb +++ b/lib/puppeteer/events.rb @@ -96,6 +96,7 @@ module FrameManagerEmittedEvents ; end FrameAttached: EventsDefinitionUtils.symbol('FrameManager.FrameAttached'), FrameNavigated: EventsDefinitionUtils.symbol('FrameManager.FrameNavigated'), FrameDetached: EventsDefinitionUtils.symbol('FrameManager.FrameDetached'), + FrameSwapped: EventsDefinitionUtils.symbol('FrameManager.FrameSwapped'), LifecycleEvent: EventsDefinitionUtils.symbol('FrameManager.LifecycleEvent'), FrameNavigatedWithinDocument: EventsDefinitionUtils.symbol('FrameManager.FrameNavigatedWithinDocument'), ExecutionContextCreated: EventsDefinitionUtils.symbol('FrameManager.ExecutionContextCreated'), diff --git a/lib/puppeteer/frame_manager.rb b/lib/puppeteer/frame_manager.rb index f693f01a..8257aba4 100644 --- a/lib/puppeteer/frame_manager.rb +++ b/lib/puppeteer/frame_manager.rb @@ -353,6 +353,8 @@ def handle_frame_detached(frame_id, reason) if frame remove_frame_recursively(frame) end + elsif reason == 'swap' + emit_event(FrameManagerEmittedEvents::FrameSwapped, frame) end end diff --git a/lib/puppeteer/lifecycle_watcher.rb b/lib/puppeteer/lifecycle_watcher.rb index 7084f2fd..c43a3654 100644 --- a/lib/puppeteer/lifecycle_watcher.rb +++ b/lib/puppeteer/lifecycle_watcher.rb @@ -77,6 +77,7 @@ def initialize(frame_manager, frame, wait_until, timeout) check_lifecycle_complete end, @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigatedWithinDocument, &method(:navigated_within_document)), + @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameSwapped, &method(:handle_frame_swapped)), @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameDetached, &method(:handle_frame_detached)), ] @listener_ids['network_manager'] = @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Request, &method(:handle_request)) @@ -142,11 +143,21 @@ def timeout_or_termination_promise check_lifecycle_complete end + private def handle_frame_swapped(frame) + return if frame != @frame + @swapped = true + check_lifecycle_complete + end + private def check_lifecycle_complete # We expect navigation to commit. return unless @expected_lifecycle.completed?(@frame) @lifecycle_promise.fulfill(true) if @lifecycle_promise.pending? if @frame.loader_id == @initial_loader_id && !@has_same_document_navigation + if @swapped + @swapped = false + @new_document_navigation_promise.fulfill(true) + end return end if @has_same_document_navigation && @same_document_navigation_promise.pending? diff --git a/lib/puppeteer/page.rb b/lib/puppeteer/page.rb index 2eb3bf81..18cf8ebc 100644 --- a/lib/puppeteer/page.rb +++ b/lib/puppeteer/page.rb @@ -508,7 +508,6 @@ class PageError < StandardError ; end end private def handle_console_api(event) - puts "~~~~~~~~~~~~~~#{event}" if event['executionContextId'] == 0 # DevTools protocol stores the last 1000 console messages. These # messages are always reported even for removed execution contexts. In diff --git a/spec/integration/oopif_spec.rb b/spec/integration/oopif_spec.rb index 601910df..0ef265d9 100644 --- a/spec/integration/oopif_spec.rb +++ b/spec/integration/oopif_spec.rb @@ -80,6 +80,22 @@ def oopifs(context) expect(page.frames.size).to eq(1) end + it 'should support wait for navigation for transitions from local to OOPIF' do + page.goto(server_empty_page) + predicate = -> (frame) { page.frames.index { |_frame| _frame == frame } == 1 } + frame = page.wait_for_frame(predicate: predicate) do + attach_frame(page, 'frame1', server_empty_page) + end + expect(frame).not_to be_oop_frame + + frame.wait_for_navigation do + navigate_frame(page, 'frame1', "#{server_cross_process_prefix}/empty.html") + end + expect(frame).to be_oop_frame + detach_frame(page, 'frame1') + expect(page.frames.count).to eq(1) + end + it 'should keep track of a frames OOP state' do page.goto(server_empty_page) predicate = -> (frame) { page.frames.index { |_frame| _frame == frame } == 1 }