55import os
66import socket
77import threading
8- import time
98import traceback
10- import uuid
119from urllib .parse import urljoin
1210
1311from .base import (AsyncCallbackHandler ,
@@ -82,6 +80,9 @@ def set_timeout(self, timeout):
8280 body = {"type" : "script" , "ms" : timeout * 1000 }
8381 self .webdriver .send_session_command ("POST" , "timeouts" , body )
8482
83+ def create_window (self , type = "tab" , ** kwargs ):
84+ return self .webdriver .new_window (type_hint = type )
85+
8586 @property
8687 def current_window (self ):
8788 return self .webdriver .window_handle
@@ -226,10 +227,9 @@ class WebDriverTestharnessProtocolPart(TestharnessProtocolPart):
226227 def setup (self ):
227228 self .webdriver = self .parent .webdriver
228229 self .runner_handle = None
230+ self .persistent_test_window = None
229231 with open (os .path .join (here , "runner.js" )) as f :
230232 self .runner_script = f .read ()
231- with open (os .path .join (here , "window-loaded.js" )) as f :
232- self .window_loaded_script = f .read ()
233233
234234 def load_runner (self , url_protocol ):
235235 if self .runner_handle :
@@ -245,10 +245,11 @@ def load_runner(self, url_protocol):
245245
246246 def close_old_windows (self ):
247247 self .webdriver .actions .release ()
248- handles = [ item for item in self .webdriver .handles if item != self . runner_handle ]
249- for handle in handles :
250- self ._close_window (handle )
248+ for handle in self .webdriver .handles :
249+ if handle not in { self . runner_handle , self . persistent_test_window } :
250+ self ._close_window (handle )
251251 self .webdriver .window_handle = self .runner_handle
252+ self .reset_browser_state ()
252253 return self .runner_handle
253254
254255 def _close_window (self , window_handle ):
@@ -258,65 +259,8 @@ def _close_window(self, window_handle):
258259 except webdriver_error .NoSuchWindowException :
259260 pass
260261
261- def open_test_window (self , window_id ):
262- self .webdriver .execute_script (
263- "window.open('about:blank', '%s', 'noopener')" % window_id )
264-
265- def get_test_window (self , window_id , parent , timeout = 5 ):
266- """Find the test window amongst all the open windows.
267- This is assumed to be either the named window or the one after the parent in the list of
268- window handles
269-
270- :param window_id: The DOM name of the Window
271- :param parent: The handle of the runner window
272- :param timeout: The time in seconds to wait for the window to appear. This is because in
273- some implementations there's a race between calling window.open and the
274- window being added to the list of WebDriver accessible windows."""
275- test_window = None
276- end_time = time .time () + timeout
277- while time .time () < end_time :
278- try :
279- # Try using the JSON serialization of the WindowProxy object,
280- # it's in Level 1 but nothing supports it yet
281- win_s = self .webdriver .execute_script ("return window['%s'];" % window_id )
282- win_obj = json .loads (win_s )
283- test_window = win_obj ["window-fcc6-11e5-b4f8-330a88ab9d7f" ]
284- except Exception :
285- pass
286-
287- if test_window is None :
288- test_window = self ._poll_handles_for_test_window (parent )
289-
290- if test_window is not None :
291- assert test_window != parent
292- return test_window
293-
294- time .sleep (0.1 )
295-
296- raise Exception ("unable to find test window" )
297-
298- def _poll_handles_for_test_window (self , parent ):
299- test_window = None
300- after = self .webdriver .handles
301- if len (after ) == 2 :
302- test_window = next (iter (set (after ) - {parent }))
303- elif after [0 ] == parent and len (after ) > 2 :
304- # Hope the first one here is the test window
305- test_window = after [1 ]
306- return test_window
307-
308- def test_window_loaded (self ):
309- """Wait until the page in the new window has been loaded.
310-
311- Hereby ignore Javascript execptions that are thrown when
312- the document has been unloaded due to a process change.
313- """
314- while True :
315- try :
316- self .webdriver .execute_script (self .window_loaded_script , asynchronous = True )
317- break
318- except webdriver_error .JavascriptErrorException :
319- pass
262+ def reset_browser_state (self ):
263+ """Reset browser-wide state that normally persists between tests."""
320264
321265
322266class WebDriverPrintProtocolPart (PrintProtocolPart ):
@@ -828,7 +772,6 @@ def __init__(self, logger, browser, server_config, timeout_multiplier=1,
828772 self ._get_next_message = self ._get_next_message_classic
829773
830774 self .close_after_done = close_after_done
831- self .window_id = str (uuid .uuid4 ())
832775 self .cleanup_after_test = cleanup_after_test
833776
834777 def is_alive (self ):
@@ -857,20 +800,16 @@ def do_test(self, test):
857800 def do_testharness (self , protocol , url , timeout ):
858801 # The previous test may not have closed its old windows (if something
859802 # went wrong or if cleanup_after_test was False), so clean up here.
860- parent_window = protocol .testharness .close_old_windows ()
803+ protocol .testharness .close_old_windows ()
861804
862805 # If protocol implements `bidi_events`, remove all the existing subscriptions.
863806 if hasattr (protocol , 'bidi_events' ):
864807 # Use protocol loop to run the async cleanup.
865808 protocol .loop .run_until_complete (protocol .bidi_events .unsubscribe_all ())
866809
867810 # Now start the test harness
868- protocol .testharness .open_test_window (self .window_id )
869- test_window = protocol .testharness .get_test_window (self .window_id ,
870- parent_window ,
871- timeout = 5 * self .timeout_multiplier )
811+ test_window = self .get_or_create_test_window (protocol )
872812 self .protocol .base .set_window (test_window )
873-
874813 # Wait until about:blank has been loaded
875814 protocol .base .execute_script (self .window_loaded_script , asynchronous = True )
876815
@@ -975,6 +914,9 @@ async def process_bidi_event(method, params):
975914
976915 return rv , extra
977916
917+ def get_or_create_test_window (self , protocol ):
918+ return protocol .base .create_window ()
919+
978920 def _get_next_message_classic (self , protocol , url , _ ):
979921 """
980922 Get the next message from the test_driver using the classic WebDriver async script execution. This will block
0 commit comments