使用selenium在jupyterlab中写入并运行代码单元

2024-09-29 00:15:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我想测试juptyerlab的补丁实现。我希望使用selenium在代码单元中执行"hello world"。到目前为止,我可以登录并创建新笔记本:

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()

这创建了一个新的笔记本,但现在我只能在单元格中输入一些代码并运行它。如果我查看页面源代码,我看不到单元格的任何html元素。但是如果我在单元格中输入print("test"),那么driver.page_source包含以下内容(它嵌套在我省略的其他内容中):

^{pr2}$

我可以看到print("text")的文本在哪里(即,上面html片段中最深的嵌套元素),但我无法确定在这里可以向哪个元素发送文本或向哪个元素发送键。在

我遇到了robotframework-jupyterlibrary,它有一些线索,比如this和{a3}。从那些环节我看到了

${JLAB CSS ACTIVE INPUT} ${JLAB CSS ACTIVE CELL} .CodeMirror

以及

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}

这让我想到如果我选择.CodeMirror元素,那么我只需要弄清楚Get WebElement在这种奇怪的语言中做了什么,以及如何在selenium中实现它。在

有什么想法吗?在


我也尝试过(基于https://stackoverflow.com/a/48723135/1011724https://stackoverflow.com/a/50279295/1011724):

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()

但我一直在犯错

selenium.common.exceptions.WebDriverException: Message: TypeError: rect is undefined


Tags: and元素bydriverseleniumcellelementfind
2条回答

打开Jupyter笔记本:

打开一个命令窗口并导航到存储库文件夹,或者打开anaconda-command-prompt窗口并简单地执行

  • jupyter notebook NotebookApp.token='' NotebookApp.password=''

使用driver.get("http://localhost:8888")加载笔记本后,最棘手的部分是如何选择Dynamically changing object。访问参考号:Dynamically Changing IDs。在

  • By using find_element_by_xpath
  • By using find_element_by_css_selector

这两种方法都会给您相同的选择点,但最好使用Xpath,这是一种更方便的技术。你可以这样向前走

import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome('chromedriver.exe')
wait = WebDriverWait(driver, 20)

driver.maximize_window()
website_url = "http://localhost:8888/"
driver.get(website_url)

# Using Xpath
# I prefer using xpath, because it is simple to understand
# and if you want to dynamically enter data into fields, it would be an awesome approach
driver.find_element_by_xpath("//div[@id='new-buttons']").click()

if len(driver.find_elements_by_xpath("//div[@id='new-buttons']//li[@id='kernel-python3']")) > 0:

   time.sleep(3)
   driver.find_element_by_xpath("//div[@id='new-buttons']//li[@id='kernel-python3']").click()

driver.find_element_by_xpath('//div[@class="cell code_cell rendered selected"]').click()

# Using css_selector
#driver.find_element_by_css_selector("#notebook-container > div").click()

command = 'print("Hello World!")'

#a = driver.find_element_by_css_selector("#notebook-container > div > div.input > div.inner_cell >"
#                                         "div.input_area > div > div:nth-child(1) > textarea")

time.sleep(3)
# To select Note-Book text-area and place command in it.
a = driver.find_element_by_xpath('//div[@class="input_area"]//textarea').click().send_keys(command)

# To run the Code in Selected Cell
time.sleep(3)
driver.find_element_by_xpath("//button[@title='Run']").click()

print("Test is done.")

以下代码在Chrome、Firefox和jupyterlab的最新版本中进行了测试:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get("http://localhost:8888")
token = "0107216930d05db8a7c36ad6a73573dd5349c3dd56fee852"

wait.until(EC.element_to_be_clickable((By.ID, "password_input"))).send_keys(token, Keys.ENTER)

# wait for "Python 3" Notebook menu or CodeMirror element if already launched.
wait.until(EC.presence_of_element_located(
    (By.CSS_SELECTOR, "[title='Python 3'][data-category='Notebook'], .jp-Notebook .CodeMirror")))
# if "Python 3" Notebook menu found click to open new Notebook
if len(driver.find_elements_by_css_selector("[title='Python 3'][data-category='Notebook']")) > 0:
    driver.find_element_by_css_selector("[title='Python 3'][data-category='Notebook']").click()

# wait for CodeMirror and click to focus
code_mirror = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".jp-Notebook .CodeMirror")))
code_mirror.click()
code_mirror.find_element_by_tag_name("textarea").send_keys("print('Hello World!')")
driver.find_element_by_css_selector("[data-icon='run']").click()

output = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".jp-OutputArea-output")))
print(output.text)
assert output.text.strip() == "Hello World!"

driver.quit()

相关问题 更多 >