
    tj8v                     8   d Z dadaddlmZ 	 ddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZ	 	 ddlmZ ddlZddlZ	 ddlZddlmZ 	 ddlZg dZ G d d      Z G d de      Z G d de      Zd'dZd Zd Zd Z d Z!d Z"d Z#d(dZ$d)dZ% G d de&      Z' G d de'      Z( G d d e(      Z)d! Z*d" Z+d# Z,d$ Z-d% Z.d& Z/y#  t        dz  aY xY w# e$ r ddlZY   xY w#  t        dz  aY xY w#  t        d	z  aY xY w#  t        d
z  aY xY w)*a  
    This module provides some testing functionality for paraview and
    vtk web applications.  It provides the ability to run an arbitrary
    test script in a separate thread and communicate the results back
    to the service so that the CTest framework can be notified of the
    success or failure of the test.

    This test harness will notice when the test script has finished
    running and will notify the service to stop.  At this point, the
    test results will be checked in the main thread which ran the
    service, and in the case of failure an exception will be raised
    to notify CTest of the failure.

    Test scripts need to follow some simple rules in order to work
    within the test harness framework:

    1) implement a function called "runTest(args)", where the args
    parameter contains all the arguments given to the web application
    upon starting.  Among other important items, args will contain the
    port number where the web application is listening.

    2) import the testing module so that the script has access to
    the functions which indicate success and failure.  Also the
    testing module contains convenience functions that might be of
    use to the test scripts.

       from vtk.web import testing

    3) Call the "testPass(testName)" or "testFail(testName)" functions
    from within the runTest(args) function to indicate to the framework
    whether the test passed or failed.

 N    )
vtkTestingz0
Unable to load at least one basic Python module)ImagezC
Unable to load at least one modules necessary for image comparison)	webdriverz?
Unable to load at least one module necessary for browser testsz<
Unable to load at least one module necessary for HTTP tests)firefoxchromeinternet_explorersafari	nobrowserc                   (    e Zd Z ed      \  ZZZZZy)TestModuleBrowsers   N)	__name__
__module____qualname__ranger   r   r	   r
   r        C/DATA/.local/lib/python3.12/site-packages/vtkmodules/web/testing.pyr   r   S   s    <A!H9GV&	r   r   c                       e Zd Zd Zd Zy)DependencyErrorc                     || _         y N)value)selfr   s     r   __init__zDependencyError.__init__]   s	    
r   c                 ,    t        | j                        S r   )reprr   r   s    r   __str__zDependencyError.__str__`   s    DJJr   N)r   r   r   r   r    r   r   r   r   r   \   s     r   r   c                       e Zd Zd Zd Zy)
Dictionaryc                     | |   S r   r   )r   attrNames     r   __getattribute__zDictionary.__getattribute__i   s    H~r   c                     || |<   y r   r   )r   r$   	attrValues      r   __setattr__zDictionary.__setattr__l   s    "Xr   N)r   r   r   r%   r(   r   r   r   r"   r"   h   s    #r   r"   c                 L   t               at        |       D ]  }t        | |      }|t        |<    |r	|t        d<   t        j                  dk7  rWt        j                  Ft
        dk7  rt        d       t        t
               ||j                  t               yt                yyy)a  
    This function should be called to initialize the testing module.  The first
    important thing it does is to store the options for later, since the
    startTestThread function will need them.  Then it checks the arguments that
    were passed into the server to see if a test was actually requested, making
    a note of this fact.  Then, if a test was required, this function then
    checks if all the necessary testing modules were safely imported, printing
    a warning if not.  If tests were requested and all modules were present,
    then this function sets "test_module_do_testing" to True and sets up the
    startTestThread function to be called after the reactor is running.

        opts: Parsed arguments from the server

        reactor: This argument is optional, but is used by server.py to
        cause the test thread to be started only after the server itself
        has started.  If it is not provided, the test thread is launched
        immediately.

        cleanupMethod: A callback method you would like the test thread
        to execute when the test has finished.  This is used by server.py
        as a way to have the server terminated after the test has finished,
        but could be used for other cleanup purposes.  This argument is
        also optional.
    cleanupMethodr   Nz/WARNING: Some tests may have unmet dependencies)	r"   testModuleOptionsvarsgetattrtestScriptPathimport_warning_infoprintcallWhenRunning_start_test_thread)optsreactorr*   argoptValues        r   
initializer7   s   s    : # Dz4%!)# 
 -:/* 	((B.,,8 "$CD%& ##$67   9 	/r   c                     | j                  dddd       | j                  dddd       | j                  d	d
dd       | j                  dddd       | j                  dddd       y)aO  
    This function retrieves any command-line arguments that the client-side
    tester needs.  In order to run a test, you will typically just need the
    following:

      --run-test-script => This should be the full path to the test script to
      be run.

      --baseline-img-dir => This should be the 'Baseline' directory where the
      baseline images for this test are located.

      --test-use-browser => This should be one of the supported browser types,
      or else 'nobrowser'.  The choices are 'chrome', 'firefox', 'internet_explorer',
      'safari', or 'nobrowser'.
    z--run-test-scriptr   z The path to a test script to runr.   )defaulthelpdestz--baseline-img-dirzAThe path to the directory containing the web test baseline imagesbaselineImgDirz--test-use-browserr   zJOne of 'chrome', 'firefox', 'internet_explorer', 'safari', or 'nobrowser'.
useBrowserz--temporary-directory.z7A temporary directory for storing test images and diffstmpDirectoryz--test-image-file-namez3Name of file in which to store generated test imagetestImgFileN)add_argument)parsers    r   add_argumentsrC      s    " /	   P	   Y	   F	    B	  r   c                      t        j                          at        j                  t        g t
        t        t
        j                  d      } | j                          y)z
    This function checks whether testing is required and if so, sets up a Queue
    for the purpose of communicating with the thread.  then it starts the
    after waiting 5 seconds for the server to have a chance to start up.
    )
serverOpts	commQueue
testScript)targetargskwargsN)Queuetest_module_comm_queue	threadingThreadlaunch_web_testr+   r.   start)ts    r   r2   r2      sE     #[[]+/+::
	A GGIr   c                 6    | di}t         j                  |       y)z
    Test scripts should call this function to indicate that the test passed.  A
    note is recorded that the test succeeded, and is checked later on from the
    main thread so that CTest can be notified of this result.
    passNrL   puttestName	resultObjs     r   	test_passrY     s     6"Iy)r   c                 6    | di}t         j                  |       y)a  
    Test scripts should call this function to indicate that the test failed.  A
    note is recorded that the test did not succeed, and this note is checked
    later from the main thread so that CTest can be notified of the result.

    The main thread is the only one that can signal test failure in
    CTest framework, and the main thread won't have a chance to check for
    passage or failure of the test until the main loop has terminated.  So
    here we just record the failure result, then we check this result in the
    processTestResults() function, throwing an exception at that point to
    indicate to CTest that the test failed.
    failNrT   rV   s     r   	test_failr\     s     6"Iy)r   c                  :    t        j                  j                  |  S )a*  
    A very simple convenience function so that test scripts can build platform
    independent paths out of a list of elements, without having to import the
    os module.

        pathElts: Any number of strings which should be concatenated together
        in a platform independent manner.
    )ospathjoin)pathEltss    r   concat_pathsrb   *  s     77<<""r   c                  \    t         j                   j                         j                  d      S )zT
    This function returns the current time as a string, using ISO 8601 format.
     )datetimenow	isoformatr   r   r   get_current_time_stringrh   ;  s$    
   ",,S11r   c                     t               }|j                  d       |j                  |       |j                  d       |j                  |       |j                  | d      S )a  
    This function creates a vtkTesting object, and specifies the name of the
    baseline image file, using a fully qualified path (baseline_img must be
    fully qualified).  Then it calls the vtkTesting method which compares the
    image (test_img, specified only with a relative path) against the baseline
    image as well as any other images in the same directory as the baseline
    image which follow the naming pattern: 'img.png', 'img_1.png', ... , 'img_N.png'

        test_img: File name of output image to be compared against baseline.

        baseline_img: Fully qualified path to first of the baseline images.

        tmp_dir: Fully qualified path to a temporary directory for storing images.
    z-Tz-Vg        )r   AddArgumentRegressionTest)test_imgbaseline_imgtmp_dirrQ   s       r   compare_imagesro   J  sP    " 	AMM$MM'MM$MM, Hc**r   c                     t        j                         D ],  }|	 |       r y| |z  |kD  r yt        j                  |        . y)z
    This function provides the ability to wait for a certain number of seconds,
    or else to wait for a specific criterion to be met.
    NTF)	itertoolscounttimesleep)delaylimit	criterionis       r   wait_with_timeoutry   h  s=    
 __ Y[QYJJu r   c                   V    e Zd ZdZ G d d      ZddZd Zd Zd Zd	 Z	d
 Z
d Zd Zy)WebTesta  
    This is the base class for all automated web-based tests.  It defines five
    stages that any test must run through, and allows any or all of these
    stages to be overridden by subclasses.  This class defines the run_test
    method to invoke the five stages overridden by subclasses, one at a time:
    1) initialize, 2) setup, 3) capture, 4) postprocess, and 5) cleanup.
    c                       e Zd Zy)WebTest.AbortN)r   r   r   r   r   r   Abortr}     s    r   r~   Nc                      || _         || _        y r   )urltestname)r   r   r   rJ   s       r   r   zWebTest.__init__  s     r   c                    	 | j                          | j                          | j                          | j                          | j	                          | j                          y # t
        j                  $ r Y & | j                           xY wr   )checkdependenciesr7   setupcapturepostprocessr{   r~   cleanupr   s    r   run_testzWebTest.run_test  sj    	""$OOJJLLLN 	 }} 		LLNs   AA# #B
8B
c                      y r   r   r   s    r   r   zWebTest.checkdependencies      r   c                      y r   r   r   s    r   r7   zWebTest.initialize  r   r   c                      y r   r   r   s    r   r   zWebTest.setup  r   r   c                      y r   r   r   s    r   r   zWebTest.capture  r   r   c                      y r   r   r   s    r   r   zWebTest.postprocess  r   r   c                      y r   r   r   s    r   r   zWebTest.cleanup  r   r   NN)r   r   r   __doc__r~   r   r   r   r7   r   r   r   r   r   r   r   r{   r{   z  s9     ! r   r{   c                   $    e Zd ZdZddZd Zd Zy)BrowserBasedWebTesta  
    This class can be used as a base for any browser-based web tests.  It
    introduces the notion of a selenium browser and overrides phases (1) and
    (3), initialization and cleanup, of the test phases introduced in the base
    class.  Initialization involves selecting the browser type, setting the
    browser window size, and asking the browser to load the url.  Cleanup
    involves closing the browser window.
    Nc                 Z    || _         || _        d | _        t        j                  | fi | y r   )sizebrowserwindowr{   r   )r   r   r   rJ   s       r   r   zBrowserBasedWebTest.__init__  s*    	((r   c                    	 | j                   | j                   t        j                  k(  rt        j                         | _        n| j                   t        j                  k(  rt        j                         | _        nO| j                   t        j                  k(  rt        j                         | _        nt        d| j                   z        | j                  6| j
                  j                  | j                  d   | j                  d          | j                  &| j
                  j                  | j                         y y # t        $ r} d }~wt        $ r}t        |      d }~ww xY w)Nz*self.browser argument has illegal value %rr      )r   r   r   r   Chromer   r   Firefoxr	   Ier   	Exceptionr   set_window_sizer   get)r   dErrinsts      r   r7   zBrowserBasedWebTest.initialize  s   	(||#t||7I7P7P'P'..0!3!;!;;'//1!3!E!EE'lln%@DLLQ  99 KK''		!diilC88KKOODHH%    	 	(!$''	(s$   C	E   	E&	E

E&E!!E&c                 ^    	 | j                   j                          y #  t        d       Y y xY w)NzYUnable to call window.quit, perhaps this is expected because of unmet browser dependency.)r   quitr0   r   s    r   r   zBrowserBasedWebTest.cleanup  s)    	KK	ks    ,r   )r   r   r   r   r   r7   r   r   r   r   r   r     s    )&.r   r   c                   $    e Zd ZdZddZd Zd Zy)ImageComparatorWebTestaY  
    This class extends browser based web tests to include image comparison.  It
    overrides the capture phase of testing with some functionality to simply
    grab a screenshot of the entire browser window.  It overrides the
    postprocess phase with a call to vtk image comparison functionality.
    Derived classes can then simply override the setup function with a series
    of selenium-based browser interactions to create a complete test.  Derived
    classes may also prefer to override the capture phase to capture only
    certain portions of the browser window for image comparison.
    Nc                     |t        d      |t        d      t        j                  | fi | || _        || _        || _        y )Nzmissing argument 'filename'zmissing argument 'baseline')	TypeErrorr   r   filenamebaselinetmpDir)r   r   r   temporaryDirrJ   s        r   r   zImageComparatorWebTest.__init__  sN    9::9::$$T4V4  "r   c                 N    | j                   j                  | j                         y r   )r   save_screenshotr   r   s    r   r   zImageComparatorWebTest.capture  s    ##DMM2r   c                     t        | j                  | j                  | j                        }|dk(  rt	        | j
                         y t        | j
                         y )Nr   )ro   r   r   r   rY   r   r\   )r   results     r   r   z"ImageComparatorWebTest.postprocess  s;    t}}dkkJQ;dmm$dmm$r   )NNN)r   r   r   r   r   r   r   r   r   r   r   r     s    		#3%r   r   c                     | j                  |      }|j                  d      }t        j                  d      }|j	                  |      }t        j                  |j                  d            }|S )a#  
    This function takes a selenium browser and a css selector string and uses
    them to find the target HTML image element.  The desired image element
    should contain it's image data as a Base64 encoded JPEG image string.
    The 'src' attribute of the image is read, Base64-decoded, and then
    returned.

        browser: A selenium browser instance, as created by webdriver.Chrome(),
        for example.

        cssSelector: A string containing a CSS selector which will be used to
        find the HTML image element of interest.
    srcdata:image/jpeg;base64,(.+)r   )find_element_by_css_selectorget_attributerecompilematchbase64	b64decodegroup)r   cssSelectorimageEltbase64Stringb64RegEx
b64Matcherimgdatas          r   get_image_datar     sc      33K@H ))%0Lzz89H-Jz//23GNr   c           	      J   | j                  |      }|j                  d      }t        j                  d      }|j	                  |      }t        j                  t        j                  t        j                  |j                  d                        }|j                  |       y)a  
    This function takes a selenium browser instance, a css selector string,
    and a file name.  It uses the css selector string to finds the target HTML
    Image element, which should contain a Base64 encoded JPEG image string,
    it decodes the string to image data, and then saves the data to the file.
    The image type of the written file is determined from the extension of the
    provided filename.

        browser: A selenium browser instance as created by webdriver.Chrome(),
        for example.

        cssSelector: A string containing a CSS selector which will be used to
        find the HTML image element of interest.

        imgFilename: The filename to which to save the image. The extension is
        used to determine the type of image which should be saved.
    r   r   r   N)r   r   r   r   r   r   openioBytesIOr   r   r   save)r   r   imgfilenamer   r   r   r   imgs           r   save_image_data_as_pngr   *  sz    $ 33K@H))%0Lzz89H-J
**RZZ 0 01A1A!1D EF
GCHH[r   c                 h    t        |d      5 }|j                  |        ddd       y# 1 sw Y   yxY w)aQ  
    This function takes an image data, as returned by this module's
    get_image_data() function for example, and writes it out to the file given by
    the filePath parameter.

        imgData: An image data object
        filePath: The full path, including the file name and extension, where
        the image should be written.
    wbN)r   write)imgDatafilePathfs      r   write_image_to_diskr   H  s(     
h		 
		s   (1c           
         t        j                  d|       }d}t        j                  |      D ]Q  \  }}t        j                  |      s|j                  |      }|j                  dk(  s=	  |j                  di |  |S  |S # t        $ r1}t        dt        t        |            z          t        |        d}~ww xY w)a'  
    This function takes the fully qualified path to a test file, along with
    any needed keyword arguments, then dynamically loads the file as a module
    and finds the test class defined inside of it via inspection.  It then
    uses the keyword arguments to instantiate the test class and return the
    instance.

        pathToScript: Fully qualified path to python file containing defined
        subclass of one of the test base classes.
        kwargs: Keyword arguments to be passed to the constructor of the
        testing subclass.
    dynamicTestModuleNzCaught exception: r   )impload_sourceinspect
getmembersisclass__new__r   r   r   r0   strtype)pathToScriptrJ   
moduleNameinstancenameobjr   s          r   instantiate_test_subclassr   \  s     !4lCJH ''
3	c??3{{3'H""&99%H%%// O 4 O ! .T$Z@A$Ks   ,B	B>,B99B>c            
      R   d}d}d|v r|d   }d|v r|d   }d}|t        d       t        |       t        j                  d      }t        j                  ||      }|r|j                  d      }n)t        dt        t              z   d	z          t        |       |dk7  r|d
z   }t        |j                  |      }|j                  }	|j                  }
t        j                  |j                        }	 t        |||j                   |j"                  ||
||	      }|	 |j%                          nt        d       t        |       yd|v r |d           yy# t&        $ r }t        d       t)        |       Y d}~4d}~ww xY w# t*        $ r}ddl}ddl}|j1                         d   }t        d       t        dt        t3        |            z          t        dt        |      z          t        ddj5                  |j7                  |            z          t        |       Y d}~d}~ww xY w)a  
    This function loads a python file as a module (with no package), and then
    instantiates the class it must contain, and finally executes the run_test()
    method of the class (which the class may override, but which is defined in
    both of the testing base classes, WebTest and ImageComparatorBaseClass).
    After the run_test() method finishes, this function will stop the web
    server if required.  This function expects some keyword arguments will be
    present in order for it to complete it's task:

        kwargs['serverOpts']: An object containing all the parameters used
        to start the web service.  Some of them will be used in the test script
        in order perform the test.  For example, the port on which the server
        was started will be required in order to connect to the server.

        kwargs['testScript']: The full path to the python file containing the
        testing subclass.
    NrE   rG   unknownz6No test script file found, no test script will be run.z([^\.\/\\]+)\.pyr   z Unable to parse testScriptFile (z), no test will be runz.png)r   hostportr   r   r   r   z=Some dependency of this test was not met, allowing it to passz1Unable to instantiate test instance, failing testr      z.Caught an exception while running test script:z  r   r*   )r0   r\   r   r   searchr   r   testScriptfilerb   r<   r?   r@   test_module_browsersindexr=   r   r   r   r   r   rY   r   sys	tracebackexc_infor   r`   	format_tb)rI   rJ   rE   testScriptFilerW   fnamePatternfmatchimgFileNameknownGoodFileNametempDirtestImgFileNametestBrowsertestInstancederrr   r   r   tbs                     r   rO   rO     s'   & JN vL)

 v-H FG(
 ::12LYY|^4F<<?..!"&'	

 	( 9 '()B)BKP))$00*001F1FG$	 4!____#(*$	L '( ))+ IJ(# *$#
?#% %- ' (W h''(  	 !"BBC$T$Z()$T"#$!4!4R!899:h	 sC   1)E? E +E? 	E<E72E? 7E<<E? ?	H&BH!!H&c                      t         Nt         j                         } d}| D ]#  }| |   }|dk(  st        d|z   dz   |z          d}% |du rt        d      yy)a  
    This function checks the module's global test_module_comm_queue variable for a
    test result.  If one is found and the result is 'fail', then this function
    raises an exception to communicate the failure to the CTest framework.

    In order for a test result to be found in the test_module_comm_queue variable,
    the test script must have called either the testPass or testFail functions
    provided by this test module before returning.
    NFr[   z
  Test -> z: Tz]At least one of the requested tests failed.  See detailed output, above, for more information)rL   r   r0   r   )resultObjectfailedATestrW   
testResults       r   finalizer     s|     )-113$H%h/JV#lX-4zAB"	 % $E   *r   r   )r>   )Nr   N)0r   r/   rL   vtkmodules.vtkTestingRenderingr   r^   r   rs   re   rM   r   r   rK   typesr   PILr   ImportErrorr   rq   seleniumr   requestsr   r   r   r   dictr"   r7   rC   r2   rY   r\   rb   rh   ro   ry   objectr{   r   r   r   r   r   r   rO   r   r   r   r   <module>r     se   D    5OLLLLL

 " Y E E i  # #:!@2p4	**,
#"2+<$0f 0l.' .h %0  %N><(!Pk&h[ONN  NJGsK   (C C C, 
C< D C	C)%C, 'C))C, ,C9<D	D