B
    3\`+                 @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ e jjZdddZG dd deZG dd dZdddZedddZdd Zdd Zdd ZdS )    N)ActionChains)By)Keys)WebDriverWait)expected_conditions)
WebElement)contextmanager
   Fc             C   sH   t | |}|r"|rtj}q4tj}n|r.tj}ntj}||tj|fS )N)	r   ECZvisibility_of_element_locatedZpresence_of_element_locatedZ"visibility_of_all_elements_locatedZ presence_of_all_elements_locateduntilr   ZCSS_SELECTOR)browserselectorZtimeoutZvisiblesinglewaitZconditional r   <lib/python3.7/site-packages/notebook/tests/selenium/utils.pywait_for_selector   s    
r   c               @   s   e Zd ZdddZdS )CellTypeError c             C   s
   || _ d S )N)message)selfr   r   r   r   __init__    s    zCellTypeError.__init__N)r   )__name__
__module____qualname__r   r   r   r   r   r      s   r   c               @   s&  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zedd Z	edd Z
edd Zdd Zdd Zdd ZdGddZdHddZdIddZd d! Zd"d# ZdJd%d&Zd'd( ZdKd)d*Zd+d, ZdLd/d0ZdMd1d2ZdNd4d5Zd6d7 ZdOd9d:Zdd;d<d=Zd>d? Zd@dA ZdBdC Z e!dPdEdFZ"d-S )QNotebookc             C   s   || _ |   d S )N)r   #disable_autosave_and_onbeforeunload)r   r   r   r   r   r   &   s    zNotebook.__init__c             C   s
   t | jS )N)lencells)r   r   r   r   __len__*   s    zNotebook.__len__c             C   s
   | j | S )N)r   )r   keyr   r   r   __getitem__-   s    zNotebook.__getitem__c             C   s   t |tr| j||dd d S )NF)indexcontentrender)
isinstanceint	edit_cell)r   r    itemr   r   r   __setitem__0   s    
zNotebook.__setitem__c             C   s   dd | j D S )Nc             s   s   | ]
}|V  qd S )Nr   ).0cellr   r   r   	<genexpr><   s    z$Notebook.__iter__.<locals>.<genexpr>)r   )r   r   r   r   __iter__;   s    zNotebook.__iter__c             C   s   | j dS )Nbody)r   Zfind_element_by_tag_name)r   r   r   r   r.   >   s    zNotebook.bodyc             C   s   | j dS )z7Gets all cells once they are visible.
        
        r+   )r   Zfind_elements_by_class_name)r   r   r   r   r   B   s    zNotebook.cellsc             C   s   |  | jS )N)r"   current_cell)r   r   r   r   current_indexI   s    zNotebook.current_indexc             C   s   | j |S )N)r   r"   )r   r+   r   r   r   r"   M   s    zNotebook.indexc             C   s   | j d | j d dS )zDisable request to save before closing window and autosave.
        
        This is most easily done by using js directly.
        zwindow.onbeforeunload = null;z)Jupyter.notebook.set_autosave_interval(0)N)r   execute_script)r   r   r   r   r   P   s    z,Notebook.disable_autosave_and_onbeforeunloadc             C   s   | j tj | jd dS )zHChanges us into command mode on currently focused cell
        
        zireturn Jupyter.notebook.handle_command_mode(Jupyter.notebook.get_cell(Jupyter.notebook.get_edit_index()))N)r.   	send_keysr   ZESCAPEr   r1   )r   r   r   r   to_command_modeX   s    zNotebook.to_command_moder   c             C   s$   | j | }|  |   || _d S )N)r   clickr3   r/   )r   r"   r+   r   r   r   
focus_cella   s    
zNotebook.focus_cellr   c             C   sv   |  | |   | jd t| jddd | jd  | jd| | jd| | jd  d S )	Nfz#find-and-replaceT)r   Zfindreplace_allcells_btnZfindreplace_find_inpZfindreplace_replace_inpZfindreplace_replaceall_btn)r5   r3   r.   r2   r   r   Zfind_element_by_idr4   )r   r"   Zfind_txtZreplace_txtr   r   r   find_and_replaceg   s    
zNotebook.find_and_replacecodec             C   s~   |  | | j| }|dkr*| jd n:|dkr@| jd n$|dkrV| jd ntd|| | |  | | jS )Nmarkdownmrawrr8   yz<{} is not a valid cell type,use 'code', 'markdown', or 'raw')r5   r   r/   r2   r   formatwait_for_stale_cell)r   r"   	cell_typer+   r   r   r   convert_cell_typeq   s    



zNotebook.convert_cell_typec             C   s    t | jd}|t|}dS )z This is needed to switch a cell's mode and refocus it, or to render it.

        Warning: there is currently no way to do this when changing between 
        markdown and raw cells.
        r	   N)r   r   r   r
   Zstaleness_of)r   r+   r   elementr   r   r   r?      s    zNotebook.wait_for_stale_cellc             C   s   d}| j |S )NzKreturn Jupyter.notebook.get_cells().map(function(c) {return c.get_text();}))r   r1   )r   JSr   r   r   get_cells_contents   s    zNotebook.get_cells_contentsdiv .CodeMirror-codec             C   s   | j | |jS )N)r   Zfind_element_by_css_selectortext)r   r"   r   r   r   r   get_cell_contents   s    zNotebook.get_cell_contentsc             C   s   d |||}| j|S )Nz.Jupyter.notebook.get_cell({}).metadata.{} = {})r>   r   r1   )r   r"   r    valuerC   r   r   r   set_cell_metadata   s    zNotebook.set_cell_metadatac             C   s   d |}| j|S )Nz.return Jupyter.notebook.get_cell({}).cell_type)r>   r   r1   )r   r"   rC   r   r   r   get_cell_type   s    
zNotebook.get_cell_typec             C   s   d ||}| j| d S )Nz2Jupyter.notebook.get_cell({}).set_input_prompt({}))r>   r   r1   )r   r"   Z	prmpt_valrC   r   r   r   set_cell_input_prompt   s    zNotebook.set_cell_input_promptNFc             C   s   |dk	r|  |}| | | jtj t| jd | jtj x@t	|
 D ]0\}}|dkrr| jtjd | jtj| qRW |r| | j dS )zLSet the contents of a cell to *content*, by cell object or by index
        Nar   
)r"   r5   r/   r2   r   ENTERctrlr   ZDELETE	enumerate
splitlinesexecute_cellr0   )r   r+   r"   r#   r$   Zline_noliner   r   r   r'      s    

zNotebook.edit_cellc             C   sN   t |tr|}nt |tr&| |}ntd| | | jtj	tj
 d S )Nz0execute_cell only accepts a WebElement or an int)r%   r&   r   r"   	TypeErrorr5   r/   r2   r   ZCONTROLrN   )r   Zcell_or_indexr"   r   r   r   rR      s    


zNotebook.execute_cellc             C   sV   |  | | jd |dkr&|d n|}|r<| j||d |dkrR| j||d d S )Nbr      )r"   r#   r8   )r"   r@   )r5   r/   r2   r'   rA   )r   r"   r@   r#   Z	new_indexr   r   r   add_cell   s    
zNotebook.add_cellc             C   s"   |  | |   | jd d S )NZdd)r5   r3   r/   r2   )r   r"   r   r   r   delete_cell   s    
zNotebook.delete_cellTc             C   s"   | j |dd | j|||d d S )Nr9   )r@   )r"   r#   r$   )rX   r'   )r   r"   r#   r$   r   r   r   add_markdown_cell   s    zNotebook.add_markdown_cell)r@   c            G   s@   x:t |D ].\}}t|tr,| j||d q
td| q
W d S )N)r@   r#   z"Don't know how to add cell from %r)rP   r%   strrX   rT   )r   r@   valuesirH   r   r   r   append   s
    

zNotebook.appendc             C   s   | j |  d S )N)r^   )r   r\   r   r   r   extend   s    zNotebook.extendc             C   s   x| D ]}|  | qW d S )N)rR   )r   r+   r   r   r   run_all   s    
zNotebook.run_allc             C   s   t | j| d S )N)trigger_keystrokesr.   )r   keysr   r   r   trigger_keydown   s    zNotebook.trigger_keydownkernel-python3c          	   C   s,   t |dd t||d W d Q R X | |S )Nz.cell)r   )kernel_name)
new_windowselect_kernel)clsr   re   r   r   r   new_notebook   s    zNotebook.new_notebook)r   )r   r   r   )r   r8   )r   rE   )r   )Nr   r   F)N)rU   r8   r   )rU   r   T)rd   )#r   r   r   r   r   r!   r)   r-   propertyr.   r   r0   r"   r   r3   r5   r7   rA   r?   rD   rG   rI   rJ   rK   r'   rR   rX   rY   rZ   r^   r_   r`   rc   classmethodri   r   r   r   r   r   $   s>   	



	





	
r   kernel-python3c             C   sL   t | d}|ttjdf}|  d|}t| |dd}|  dS )zCClicks the "new" button and selects a kernel from the options.
    r	   znew-dropdown-buttonz#{} aT)r   N)	r   r   r
   Zelement_to_be_clickabler   ZIDr4   r>   r   )r   re   r   Z
new_buttonZkernel_selectorZkernelr   r   r   rg      s    

rg   c             #   sD   | j  dV  t fdd| j D }| | |dk	r@t| | dS )u  Contextmanager for switching to & waiting for a window created. 
    
    This context manager gives you the ability to create a new window inside 
    the created context and it will switch you to that new window.
    
    If you know a CSS selector that can be expected to appear on the window, 
    then this utility can wait on that selector appearing on the page before
    releasing the context.
    
    Usage example:
    
        from notebook.tests.selenium.utils import new_window, Notebook
        
        ⋮ # something that creates a browser object
        
        with new_window(browser, selector=".cell"):
            select_kernel(browser, kernel_name=kernel_name)
        nb = Notebook(browser)

    Nc             3   s   | ]}| kr|V  qd S )Nr   )r*   Zwindow)initial_window_handlesr   r   r,   	  s    znew_window.<locals>.<genexpr>)Zwindow_handlesnextZswitch_to_windowr   )r   r   Znew_window_handler   )rm   r   rf      s    
rf   c             C   s   t | d|  dS )zSend key combination Shift+(k)zshift-%sN)ra   )r   kr   r   r   shift  s    rp   c             C   s   t | d|  dS )zSend key combination Ctrl+(k)z
control-%sN)ra   )r   ro   r   r   r   rO     s    rO   c             G   s   x|D ]}| d}t|dkrdd |dd D }t| }x|D ]}||}qDW ||d  x |ddd D ]}||}qtW |  q| tt|d 	 |d  qW dS )a@   Send the keys in sequence to the browser.
    Handles following key combinations
    1. with modifiers eg. 'control-alt-a', 'shift-c'
    2. just modifiers eg. 'alt', 'esc'
    3. non-modifiers eg. 'abc'
    Modifiers : http://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html
    -rW   c             S   s   g | ]}t t| qS r   )getattrr   upper)r*   xr   r   r   
<listcomp>"  s    z&trigger_keystrokes.<locals>.<listcomp>NrU   r   )
splitr   r   Zkey_downr2   Zkey_upZperformrr   r   rs   )r   rb   Zeach_key_combinationZmodifiers_keysZacr]   r   r   r   ra     s    


  
ra   )r	   FF)rl   )N)osZtimeZselenium.webdriverr   Zselenium.webdriver.common.byr   Zselenium.webdriver.common.keysr   Zselenium.webdriver.support.uir   Zselenium.webdriver.supportr   r
   Z$selenium.webdriver.remote.webelementr   
contextlibr   pathjoinZpjoinr   
ValueErrorr   r   rg   rf   rp   rO   ra   r   r   r   r   <module>   s&   
 D

