title: Use selenium to write in and run a code cell in jupyterlab
body: <p>I would like to test a patched implementation of juptyerlab. I was hoping to use selenium to execute <code>"hello world"</code> in a code cell. So far I can log in and create a new notebook:</p>
  
  <pre><code>from selenium import webdriver
  
  driver = webdriver.Firefox()
  # assume jupyterlab is running and serving on localhost at port 8888
  driver.get("http://localhost:8888")
  elem = driver.find_element_by_id("password_input")
  password = ""
  elem.send_keys(password)
  elem = driver.find_element_by_id("login_submit")
  elem.click()
  elem = driver.find_element_by_css_selector(".jp-Launcher-cwd+ .jp-Launcher-section .jp-LauncherCard")
  elem.click()
  </code></pre>
  
  <p>This creates a new notebook, but now I'm stuck at the point of entering some code in a cell and running it. If I view the page source I don't see any html elements for the cells. But if I enter <code>print("test")</code> in a cell, then <code>driver.page_source</code> contains this (it's pretty nested in other stuff I've omitted too):</p>
  
  <pre><code>                                &lt;div class="CodeMirror cm-s-jupyter CodeMirror-wrap jp-mod-readOnly"&gt;
                                      &lt;div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 0px;"&gt;
                                          &lt;textarea
                                                  style="position: absolute; bottom: -1em; padding: 0px; width: 1px; height: 1em; outline: currentcolor none medium;"
                                                  autocorrect="off" autocapitalize="off"
                                                  spellcheck="false" tabindex="0"
                                                  wrap="off"&gt;&lt;/textarea&gt;&lt;/div&gt;
                                      &lt;div class="CodeMirror-vscrollbar" tabindex="-1"
                                           cm-not-content="true"
                                           style="display: block; bottom: 0px;"&gt;
                                          &lt;div style="min-width: 1px; height: 33px;"&gt;&lt;/div&gt;
                                      &lt;/div&gt;
                                      &lt;div class="CodeMirror-hscrollbar" tabindex="-1"
                                           cm-not-content="true"&gt;
                                          &lt;div style="height: 100%; min-height: 1px; width: 0px;"&gt;&lt;/div&gt;
                                      &lt;/div&gt;
                                      &lt;div class="CodeMirror-scrollbar-filler"
                                           cm-not-content="true"&gt;&lt;/div&gt;
                                      &lt;div class="CodeMirror-gutter-filler"
                                           cm-not-content="true"&gt;&lt;/div&gt;
                                      &lt;div class="CodeMirror-scroll" tabindex="-1" draggable="true"&gt;
                                          &lt;div class="CodeMirror-sizer"
                                               style="margin-left: 0px; padding-right: 0px; padding-bottom: 0px;"&gt;
                                              &lt;div style="position: relative;"&gt;
                                                  &lt;div class="CodeMirror-lines" role="presentation"&gt;
                                                      &lt;div style="position: relative; outline: currentcolor none medium;"
                                                           role="presentation"&gt;
                                                          &lt;div class="CodeMirror-measure"&gt;
                                                              &lt;pre&gt;&lt;span&gt;xxxxxxxxxx&lt;/span&gt;&lt;/pre&gt;
                                                          &lt;/div&gt;
                                                          &lt;div class="CodeMirror-measure"&gt;
                                                              &lt;pre class="CodeMirror-line"
                                                                   role="presentation"&gt;&lt;span
                                                                      role="presentation"&gt;&lt;span
                                                                      class="cm-builtin"&gt;print&lt;/span&gt;(&lt;span
                                                                      class="cm-string"&gt;"test"&lt;/span&gt;)&lt;/span&gt;&lt;/pre&gt;
                                                          &lt;/div&gt;
                                                          &lt;div style="position: relative; z-index: 1;"&gt;&lt;/div&gt;
                                                          &lt;div class="CodeMirror-cursors"&gt;&lt;/div&gt;
                                                          &lt;div class="CodeMirror-code"
                                                               role="presentation"&gt;&lt;/div&gt;
                                                      &lt;/div&gt;
                                                  &lt;/div&gt;
                                              &lt;/div&gt;
                                          &lt;/div&gt;
                                          &lt;div style="position: absolute; height: 30px; width: 1px; border-bottom: 0px solid transparent;"&gt;&lt;/div&gt;
                                          &lt;div class="CodeMirror-gutters"
                                               style="display: none;"&gt;&lt;/div&gt;
                                      &lt;/div&gt;
                                  &lt;/div&gt;
  </code></pre>
  
  <p>I can see where the text for <code>print("text")</code> is (i.e. the deepest nested elements in the above html snippet), but I can't figure out which element here I would be able to send text to or send keys to.</p>
  
  <p>I came across <a href="https://github.com/robots-from-jupyter/robotframework-jupyterlibrary" rel="nofollow noreferrer">robotframework-jupyterlibrary</a> and it has some clues such as <a href="https://github.com/robots-from-jupyter/robotframework-jupyterlibrary/blob/master/src/JupyterLibrary/clients/jupyterlab/Selectors.robot" rel="nofollow noreferrer">this</a> and <a href="https://github.com/robots-from-jupyter/robotframework-jupyterlibrary/blob/master/src/JupyterLibrary/clients/jupyterlab/Notebook.robot" rel="nofollow noreferrer">this </a>. From those links I see</p>
  
  <pre><code>${JLAB CSS ACTIVE INPUT} ${JLAB CSS ACTIVE CELL} .CodeMirror
  </code></pre>
  
  <p>and </p>
  
  <pre><code>Add and Run JupyterLab Code Cell
      [Arguments]    ${code}=print("hello world")
      [Documentation]    Add a ``code`` cell to the currently active notebook and run it.
      Click Element    css:${JLAB CSS NB TOOLBAR} ${JLAB CSS ICON ADD}
      Sleep    0.1s
      ${cell} =   Get WebElement  css:${JLAB CSS ACTIVE INPUT}
      Click Element    ${cell}
      Set CodeMirror Value    ${JLAB CSS ACTIVE INPUT}  ${code}
      Run Current JupyterLab Code Cell
  Click Element ${cell}
  </code></pre>
  
  <p>which makes me think if I select the <code>.CodeMirror</code> element, then I just need to figure out what <code>Get WebElement</code> does in that weird language and how to do it in selenium. </p>
  
  <p>Any ideas?</p>
  
  <hr>
  
  <p>I've also tried (based on <a href="https://stackoverflow.com/a/48723135/1011724">https://stackoverflow.com/a/48723135/1011724</a> and <a href="https://stackoverflow.com/a/50279295/1011724">https://stackoverflow.com/a/50279295/1011724</a>):</p>
  
  <pre><code>from selenium.webdriver.common.action_chains import ActionChains
  
  actions = action_chains.ActionChains(driver)
  textarea = driver.find_elements_by_css_selector('.CodeMirror textarea')[0]  # tried for [0], [1] ,[2] and [3] which is all of them.
  actions.move_to_element(textarea).click().send_keys("testing...").perform()
  </code></pre>
  
  <p>but I keep getting the error</p>
  
  <blockquote>
    <p>selenium.common.exceptions.WebDriverException: Message: TypeError: rect is undefined</p>
  </blockquote>