如何使SeleniumWebDriver能够在bokeh文档中使用Python远程对象(Pyro)?

如何使SeleniumWebDriver能够在bokeh文档中使用Python远程对象(Pyro)?,python,selenium-webdriver,bokeh,pyro,Python,Selenium Webdriver,Bokeh,Pyro,我在bokeh服务器上运行了一个python文档,其中包含bokeh服务器视图\u server\u so.py--show。该网页立即在浏览器选项卡中打开 出于测试目的,我使用Pyro允许远程访问bokeh服务器中运行的某些对象/方法 我的服务器测试脚本只创建一个按钮和一个方法(暴露于远程控制),bokeh在http://localhost:5006/view_server_so 该按钮是一个切换按钮,每次按下该按钮时,其活动状态在True和False之间交替,并且其颜色会发生变化 # vie

我在bokeh服务器上运行了一个python文档,其中包含
bokeh服务器视图\u server\u so.py--show
。该网页立即在浏览器选项卡中打开

出于测试目的,我使用Pyro允许远程访问bokeh服务器中运行的某些对象/方法

我的服务器测试脚本只创建一个按钮和一个方法(暴露于远程控制),bokeh在
http://localhost:5006/view_server_so

该按钮是一个切换按钮,每次按下该按钮时,其活动状态在
True
False
之间交替,并且其颜色会发生变化

# view_server_so.py
# This script shall be started from the command line with
# bokeh serve view_server_so.py --show

from bokeh.layouts import layout, row
bokeh.models import Toggle
from bokeh.io import curdoc
import os
import Pyro4
import socket
import subprocess
import threading

# The layout used in the html-page
class View():
    def __init__(self):
        self.document = curdoc()
        self.btn_task = Toggle(label="Press me",
                               button_type="success",
                               css_classes=["btn_task"])        
        self.layout = layout(row(self.btn_task))

    @Pyro4.expose
    def get_btn_task_active_state(self):
        # This method is enabled for remote control
        # The btn_task changes its active state each time it is pressed (bool)
        print('active state: {}'.format(self.btn_task.active))
        return self.btn_task.active

# As the script is started with 'bokeh serve', 
# bokeh has control of the main event loop.
# To enable Pyro to listen for client requests for the object view,
# and its exposed method,
# the Pyro event loop needs to run in its own thread.
class PyroDaemon(threading.Thread):
    def __init__(self, obj):
        threading.Thread.__init__(self)
        self.obj=obj
        self.started=threading.Event()
        print('PyroDaemon.__init__()')
    def run(self):
        daemon=Pyro4.Daemon()
        obj = self.obj
        self.uri=daemon.register(obj,"test")
        self.started.set()
        print('PyroDaemon.run()')
        daemon.requestLoop()

view = View()
print('view created')

# starting a Pyro name server
hostname = socket.gethostname()
print('hostname: {}'.format(hostname))
try:
    print('try Pyro4.locateNS()')
    name_server=Pyro4.locateNS()
except Pyro4.errors.NamingError:
    print('except Pyro4.errorsNamingError')
    args = ['python', '-m', 'Pyro4.naming', '-n', hostname]
    p = subprocess.Popen(args) 
    name_server=Pyro4.locateNS()
print('Nameserver is started')

# create a pyro daemon with object view, running in its own worker thread
pyro_thread=PyroDaemon(view)
pyro_thread.setDaemon(True)
pyro_thread.start()
pyro_thread.started.wait()
print('Daemon is started')

# The object view is registered at the Pyro name server
name_server.register('view', pyro_thread.uri, metadata = {'View'})
print('view is registered')

view.document.add_root(view.layout)
现在我有了第二个测试脚本。对远程对象进行一些设置后,它只需多次调用方法
get\u btn\u task\u active\u state()
,并打印结果。在两次通话之间单击浏览器中的按钮时,活动状态将切换并正确打印

import Pyro4
import time

# looking for the Pyro name server created in view_server_so.py
nameserver=Pyro4.locateNS(broadcast = True)
# get the URI (universal resource identifier)
uris = nameserver.list(metadata_all = {'View'})
# create a proxy object that interacts (remote control)
# with the remote object 'view'
view_rc = Pyro4.Proxy(uris['view'])

for i in range(3):
    time.sleep(3)
    # change the state manually: click on the button
    print('state: {}'.format(view_rc.get_btn_task_active_state()))
    # prints
    # state: False
    # state: True
    # state: False
由于手动测试变得单调乏味,我想自动手动点击按钮。因此,我正在添加webdriver支持,在网页中查找按钮,并像以前一样自动单击和调用
get\u btn\u task\u active\u state()

import Pyro4
from selenium import webdriver
import socket
import time

# looking for the Pyro name server created in view_server_so.py
nameserver=Pyro4.locateNS(broadcast = True)
# get the URI (universal resource identifier)
uris = nameserver.list(metadata_all = {'View'})
# create a proxy object that interacts (remote control)
# with the remote object 'view'
view_rc = Pyro4.Proxy(uris['view'])

# use the Chrome webdriver
driver = webdriver.Chrome()
# open a Chrome Browser and the given webpage
driver.get("http://localhost:5006/view_server_so")
time.sleep(1)
# Find the button
btn_task = driver.find_element_by_class_name("btn_task")

for i in range(3):
    time.sleep(1)
    print('state: {}'.format(view_rc.get_btn_task_active_state()))
    btn_task.click()
    # prints
    # state: False
    # state: False
    # state: False
    #
    # but should alternate between False and True
当webdriver控制的浏览器打开时,我可以看到按钮的颜色在自动单击时发生视觉变化,但按钮的活动状态似乎不再发生变化


需要进行哪些更改,以便自动脚本提供与手动测试相同的结果?

您的“视图”通过Pyro代理连接到远程进程,但是单击操作是在本地进程中直接在本地“驱动程序”上完成的。我认为bokeh服务器的远程进程无法检测来自另一个进程的更改?(虽然这并不能解释为什么手动单击浏览器中的按钮时它会工作…)也许可以调查bokeh库的限制?谢谢您的评论。我不认为webdriver是一个单一的进程。如果这是真的,那么我的方法就行不通了。也许一些webdriver开发者可以证实这些想法?