1
1
import base64
2
2
import functools
3
3
import io
4
+ import json
4
5
import logging
5
6
import multiprocessing
6
7
import os
@@ -230,6 +231,31 @@ def set_screen_resolution(self, width=None, height=None):
230
231
""" , width , height )
231
232
self ._driver .set_window_size (* window_size )
232
233
234
+ def _webdriver_command (self , command , params = None , req_type = "POST" ):
235
+ """
236
+ Execute a webdriver command.
237
+
238
+ Args:
239
+ command (str): The command URL after the session part
240
+ params (dict): The payload to be serialized and sent to the webdriver. Defaults to None.
241
+ req_type (str, optional): The type of request to be made. Defaults to "POST".
242
+
243
+ Returns:
244
+ str: The value of the response
245
+ """
246
+ if not params :
247
+ params = {}
248
+
249
+ resource = f"/session/{ self .driver .session_id } /{ command } "
250
+ url = self .driver .command_executor ._url + resource
251
+ body = json .dumps (params )
252
+ response = self .driver .command_executor ._request (req_type , url , body )
253
+
254
+ if not response :
255
+ raise Exception (response .get ('value' ))
256
+
257
+ return response .get ('value' )
258
+
233
259
##########
234
260
# Display
235
261
##########
@@ -747,7 +773,6 @@ def create_tab(self, url):
747
773
self .navigate_to (url )
748
774
749
775
def create_window (self , url ):
750
-
751
776
try :
752
777
# Refactor this when Selenium 4 is released
753
778
self .execute_javascript (f"window.open('{ url } ', '_blank', 'location=0');" )
@@ -769,10 +794,47 @@ def close_page(self):
769
794
def activate_tab (self , handle ):
770
795
self ._driver .switch_to .window (handle )
771
796
797
+ def print_pdf (self , path = None , print_options = None ):
798
+ """Print the current page as a PDF file.
799
+
800
+ Args:
801
+ path (str, optional): The path for the file to be saved. Defaults to None.
802
+ print_options (dict, optional): Print options as defined at. Defaults to None.
803
+
804
+ Returns:
805
+ str: the saved file path
806
+ """
807
+ title = self .page_title () or "document"
808
+ default_path = os .path .expanduser (os .path .join ("~" , "Desktop" , f"{ title } .pdf" ))
809
+
810
+ if self .browser in [Browser .CHROME , Browser .EDGE ] and not self .headless :
811
+ # Chrome still does not support headless webdriver print
812
+ # but Firefox does.
813
+ self .execute_javascript ("window.print();" )
814
+ # We need to wait for the file to be available in this case.
815
+ self .wait_for_file (default_path )
816
+ return default_path
817
+
818
+ if print_options is None :
819
+ print_options = {
820
+ 'landscape' : False ,
821
+ 'displayHeaderFooter' : False ,
822
+ 'printBackground' : True ,
823
+ 'preferCSSPageSize' : True ,
824
+ 'marginTop' : 0 ,
825
+ 'marginBottom' : 0
826
+ }
827
+ data = self ._webdriver_command ("print" , print_options )
828
+ bytes_file = base64 .b64decode (data )
829
+ if not path :
830
+ path = default_path
831
+ with open (path , "wb" ) as f :
832
+ f .write (bytes_file )
833
+ return path
834
+
772
835
#######
773
836
# Mouse
774
837
#######
775
-
776
838
@only_if_element
777
839
def click_on (self , label ):
778
840
"""
@@ -1491,14 +1553,14 @@ def sleep(self, interval):
1491
1553
"""
1492
1554
self .wait (interval )
1493
1555
1494
- def wait_for_file (self , path , timeout = 10000 ):
1556
+ def wait_for_file (self , path , timeout = 60000 ):
1495
1557
"""
1496
- Invoke the system handler to open the given file .
1558
+ Wait for a file to be available on disk .
1497
1559
1498
1560
Args:
1499
1561
path (str): The path for the file to be executed
1500
1562
timeout (int, optional): Maximum wait time (ms) to search for a hit.
1501
- Defaults to 10000ms (10s ).
1563
+ Defaults to 60000ms (60s ).
1502
1564
1503
1565
Returns:
1504
1566
status (bool): Whether or not the file was available before the timeout
0 commit comments