标签归档:webdriver

Selenium:FirefoxProfile异常无法加载配置文件

问题:Selenium:FirefoxProfile异常无法加载配置文件

对于这个先前的问题,我将Selenium更新到了2.0.1版本,但是现在我又遇到了另一个错误,即使配置文件位于以下位置/tmp/webdriver-py-profilecopy

  在执行中,文件“ /home/sultan/Repository/Django/monitor/app/request.py”,第236行
    浏览器= Firefox(配置文件)
  __init__中的文件“ /usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py”,第46行
    self.binary,超时),
  __init__中的文件“ /usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/extension_connection.py”,第46行
    self.binary.launch_browser(self.profile)
  在launch_browser中的第44行,文件“ /usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py”
    self._wait_until_connectable() 
  _wait_until_connectable中的文件“ /usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py”,第87行
    引发WebDriverException(“无法加载配置文件。配置文件目录:%s”%self.profile.path)
selenium.common.exceptions.WebDriverException:无法加载配置文件。个人档案目录:/ tmp / webdriver-py-profilecopy

怎么了?我该如何解决这个问题?

Per this previous question I updated Selenium to version 2.0.1 But now I have another error, even when the profile files exist under /tmp/webdriver-py-profilecopy:

  File "/home/sultan/Repository/Django/monitor/app/request.py", line 236, in perform
    browser = Firefox(profile)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py", line 46, in __init__
    self.binary, timeout),
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/extension_connection.py", line 46, in __init__
    self.binary.launch_browser(self.profile)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 44, in launch_browser
    self._wait_until_connectable() 
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 87, in _wait_until_connectable
    raise WebDriverException("Can't load the profile. Profile Dir : %s" % self.profile.path)
selenium.common.exceptions.WebDriverException: Can't load the profile. Profile Dir : /tmp/webdriver-py-profilecopy

What is wrong? How can I resolve this issue?


回答 0

更新:

硒团队已修复最新版本。对于几乎所有环境,修复程序都是:

点安装-U硒

尚不清楚它是在哪个版本上修复的(显然是r13122),但肯定是在2.26.0(更新时为最新)上已修复。


此错误意味着_wait_until_connectable超时,因为某些原因,代码无法连接到已加载到firefox中的webdriver扩展。

我刚刚向selenium报告了一个错误,在此我收到此错误,因为我正尝试使用代理,并且firefox接受了配置文件中4个配置的更改中的2个,因此未配置该代理与扩展名。不知道为什么会这样…

https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/2061

Update:

Selenium team fixed in latest version. For almost all environments the fix is:

pip install -U selenium

Unclear at which version it was fixed (apparently r13122), but certainly by 2.26.0 (current at time of update) it is fixed.


This error means that _wait_until_connectable is timing out, because for some reason, the code cannot connect to the webdriver extension that has been loaded into the firefox.

I have just reported an error to selenium where I am getting this error because I’m trying to use a proxy and only 2 of the 4 configured changes in the profile have been accepted by firefox, so the proxy isn’t configured to talk to the extension. Not sure why this is happening…

https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/2061


回答 1

将Ubuntu升级到12.04后,我遇到了同样的问题。

该问题在软件包方面,已在库的最新版本中修复。只需更新硒库。对于几乎所有的Python环境,这是:

pip install -U selenium

I had the same issue after upgrading Ubuntu to 12.04.

The issue was on the package side and has been fixed in the latest version of the library. Just update the selenium library. For almost all Python environments this is:

pip install -U selenium

回答 2

我遇到了FF 32.0和Selenium selenium-2.42.1-py2.7.egg相同的问题。试图更新硒,但是它已经是最新版本。解决方案是将Firefox降级到版本30。过程如下:

#Download version 30 for Linux (This is the 64 bit)
wget http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/30.0/linux-x86_64/en-US/firefox-30.0.tar.bz2

tar -xjvf firefox-30.0.tar.bz2
#Remove the old version
sudo rm -rf /opt/firefox*
sudo mv firefox /opt/firefox30.0
#Create a permanent link
sudo ln -sf /opt/firefox30.0/firefox /usr/bin/firefox

这样就解决了所有问题,并且这种组合效果更好!

I faced the same problem with FF 32.0 and Selenium selenium-2.42.1-py2.7.egg. Tried to update selenium, but it is already the latest version. The solution was to downgrade Firefox to version 30. Here is the process:

#Download version 30 for Linux (This is the 64 bit)
wget http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/30.0/linux-x86_64/en-US/firefox-30.0.tar.bz2

tar -xjvf firefox-30.0.tar.bz2
#Remove the old version
sudo rm -rf /opt/firefox*
sudo mv firefox /opt/firefox30.0
#Create a permanent link
sudo ln -sf /opt/firefox30.0/firefox /usr/bin/firefox

This solved all the problems, and this combination works better !


回答 3

作为对Jeff Hoye答案的扩展,一种更“ Pythonic”的方式将是webdriver.firefox.firefox_profile.FirefoxProfile如下子类化:

class CygwinFirefoxProfile(FirefoxProfile):
    @property
    def path(self):
        path = self.profile_dir
        # Do stuff to the path as described in Jeff Hoye's answer
        return path

然后,创建驱动程序:

driver = webdriver.Firefox(firefox_profile=CygwinFirefoxProfile())

As an extension to Jeff Hoye‘s answer, a more ‘Pythonic’ way would be to subclass webdriver.firefox.firefox_profile.FirefoxProfile as follows:

class CygwinFirefoxProfile(FirefoxProfile):
    @property
    def path(self):
        path = self.profile_dir
        # Do stuff to the path as described in Jeff Hoye's answer
        return path

Then, to create your driver:

driver = webdriver.Firefox(firefox_profile=CygwinFirefoxProfile())

回答 4

如果pip install -U selenium不起作用(就我而言,它不起作用),请尝试将Firefox降级到以前的版本。

我安装了Firefox 49.0,并降级到45.0,以确保selenium支持该版本。那时,它工作得很好。

这是降级到Firefox 45.0的快速方法:

sudo apt-get install firefox=45.0.2+build1-0ubuntu1

希望这可以帮助。

If pip install -U selenium doesn’t work (it didn’t, in my case), try downgrading your Firefox to a previous version.

I had Firefox 49.0 and downgraded to 45.0 to make sure the version is supported by selenium. It worked perfectly then.

Here’s a fast way to downgrade to Firefox 45.0:

sudo apt-get install firefox=45.0.2+build1-0ubuntu1

Hope this helps.


回答 5

如果您从cygwin运行webdriver,则问题在于配置文件的路径仍为POSIX格式,这会混淆Windows程序。我的解决方案使用cygpath将其转换为Windows格式。

在此文件/方法中:selenium.webdriver.firefox.firefox_binary.launch_browser():

更换:

    self._start_from_profile_path(self.profile.path)

与:

    from subprocess import Popen, PIPE
    proc = Popen(['cygpath','-d',self.profile.path], stdout=PIPE, stderr=PIPE)
    stdout, stderr = proc.communicate()
    path = stdout.split('\n', 1)[0]

    self._start_from_profile_path(path)
    #self._start_from_profile_path(self.profile.path)

由于Python甚至与我的主要编程语言都不接近,因此如果有人可以推荐一种更Python化的方法,也许我们可以将其推入发行版。如果它在开箱即用的Cygwin中工作肯定会很方便。

If you are running webdriver from cygwin, the problem is that the path to the profile is still in POSIX format which confuses windows programs. My solution uses cygpath to convert it into Windows format.

in this file/method: selenium.webdriver.firefox.firefox_binary.launch_browser():

replace:

    self._start_from_profile_path(self.profile.path)

with:

    from subprocess import Popen, PIPE
    proc = Popen(['cygpath','-d',self.profile.path], stdout=PIPE, stderr=PIPE)
    stdout, stderr = proc.communicate()
    path = stdout.split('\n', 1)[0]

    self._start_from_profile_path(path)
    #self._start_from_profile_path(self.profile.path)

Since Python is not even close to my primary programming language, if someone can recommend a more pythonic approach maybe we can push it into the distribution. It sure would be handy if it worked in cygwin right out of the box.


回答 6

我遇到了同样的问题,并认为这是硒/ Firefox的错误组合。原来,我的.mozilla /文件夹权限仅可由root用户访问。做的chmod 770 ~/.mozilla/did俩。我建议在进一步排除故障之前确保这不是问题。

I had the same problem and believed it was the wrong combo of selenium / Firefox. Turned out that my .mozilla/ folder permissions were only accessible to the root user. Doing chmod 770 ~/.mozilla/ did the trick. I would suggest making sure this is not the issue before troubleshooting further.


回答 7

pip install -U selenium

我遇到了相同的问题,Firefox 34.0.5 (Dec 1, 2014)并将Selenium从升级2.42.12.44.0解决了我的问题。

但是,此后我又看到了这个问题,我认为是2.44.0,并进行了另一次升级。因此,我想知道是否可以通过简单地卸载然后重新安装来解决该问题。如果是这样,我不确定那将表明潜在的问题是什么。

pip install -U selenium

I had this same issue with Firefox 34.0.5 (Dec 1, 2014) and upgrading Selenium from 2.42.1 to 2.44.0 resolved my issue.

However, I’ve have since seen this issue again, I think with 2.44.0, and another upgrade fixed it. So I’m wondering if it might be fixed by simply uninstalling and then re-installing. If so, I’m not sure what that would indicate the underlying problem is.


回答 8

我正在使用硒2.53和55.0版的Firefox。我安装了较旧版本的firefox(46.0.1)解决了此问题,因为硒2.53不适用于47.0及更高版本的firefox。

I was using selenium 2.53 and firefox version 55.0. I solved this issue by installing the older version of firefox (46.0.1) since selenium 2.53 will not work for firefox version 47.0 & above.


回答 9

这不是一个适当的解决方案,但对我有用,如果有人可以改善,我将很高兴知道。我只是以root用户身份运行脚本sudo python myscript.py。我想我可以通过更改配置文件默认文件或目录来解决。

This is not a proper solution but worked for me, if somebody can improve I would be glad to know. I just run my script as root: sudo python myscript.py. I guess I can solve by changing the profile default file or directory could work.


如何使用Python + Selenium WebDriver保存和加载Cookie

问题:如何使用Python + Selenium WebDriver保存和加载Cookie

如何将Python的Selenium WebDriver中的所有cookie保存到txt文件,然后稍后加载?该文档没有对getCookies函数做太多说明。

How can I save all cookies in Python’s Selenium WebDriver to a txt-file, then load them later? The documentation doesn’t say much of anything about the getCookies function.


回答 0

您可以使用pickle将当前cookie保存为python对象。例如:

import pickle
import selenium.webdriver 

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
pickle.dump( driver.get_cookies() , open("cookies.pkl","wb"))

然后再将它们添加回去:

import pickle
import selenium.webdriver 

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
    driver.add_cookie(cookie)

You can save the current cookies as a python object using pickle. For example:

import pickle
import selenium.webdriver 

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
pickle.dump( driver.get_cookies() , open("cookies.pkl","wb"))

and later to add them back:

import pickle
import selenium.webdriver 

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
    driver.add_cookie(cookie)

回答 1

当您需要从一个会话到另一个会话的cookie时,还有另一种方法可以使用Chrome选项user-data-dir,以便将文件夹用作配置文件,我运行:

chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com")

您可以在此处执行检查人机交互的登录,然后执行此操作,然后每次使用该文件夹启动Webdriver时都需要我现在需要的cookie。您还可以手动安装扩展,并在每个会话中使用它们。在我运行的第二个时间里,所有的cookie都在那里:

chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com") #Now you can see  the cookies, the settings, extensions, etc, and the logins done in the previous session are present here. 

好处是您可以使用具有不同设置和Cookie的多个文件夹,无需加载,卸载Cookie,安装和卸载扩展程序,更改设置,通过代码更改登录名的扩展程序,因此无法中断程序的逻辑,等等这比通过代码完成所有操作要快。

When you need cookies from session to session there is another way to do it, use the Chrome options user-data-dir in order to use folders as profiles, I run:

#you need to: from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com")

You can do here the logins that check for human interaction, I do this and then the cookies I need now every-time I start the Webdriver with that folder everything is in there. You can also manually install the Extensions and have them in every session. Secon time I run, all the cookies are there:

#you need to: from selenium.webdriver.chrome.options import Options    
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com") #Now you can see  the cookies, the settings, extensions, etc, and the logins done in the previous session are present here. 

The advantage is you can use multiple folders with different settings and cookies, Extensions without the need to load, unload cookies, install and uninstall Extensions, change settings, change logins via code, and thus no way to have the logic of the program break, etc Also this is faster than havin to do it all by code.


回答 2

请记住,您只能为当前域添加cookie。如果您想为您的Google帐户添加Cookie,请执行

browser.get('http://google.com')
for cookie in cookies:
    browser.add_cookie(cookie)

Remember, you can only a add cookie for the current domain. If you wanna add a cookie for your Google account, do

browser.get('http://google.com')
for cookie in cookies:
    browser.add_cookie(cookie)

回答 3

基于@Eduard Florinescu的回答,但添加了更新的代码和缺少的导入:

$ cat work-auth.py 
#!/usr/bin/python3

# Setup:
# sudo apt-get install chromium-chromedriver
# sudo -H python3 -m pip install selenium

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
chrome_options.add_argument("user-data-dir=chrome-data") 
driver.get('https://www.somedomainthatrequireslogin.com')
time.sleep(30)  # Time to enter credentials
driver.quit()

$ cat work.py 
#!/usr/bin/python3

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
driver.get('https://www.somedomainthatrequireslogin.com')  # Already authenticated
time.sleep(10)
driver.quit()

Based on answer by @Eduard Florinescu but with newer code and missing import added:

$ cat work-auth.py 
#!/usr/bin/python3

# Setup:
# sudo apt-get install chromium-chromedriver
# sudo -H python3 -m pip install selenium

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
chrome_options.add_argument("user-data-dir=chrome-data") 
driver.get('https://www.somedomainthatrequireslogin.com')
time.sleep(30)  # Time to enter credentials
driver.quit()

$ cat work.py 
#!/usr/bin/python3

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
driver.get('https://www.somedomainthatrequireslogin.com')  # Already authenticated
time.sleep(10)
driver.quit()

回答 4

@Roel Van de Paar编写的代码仅作了少许修改,所有功劳都归功于他。我在Windows中使用它,并且在设置和添加Cookie方面都运行良好:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('chromedriver.exe',options=chrome_options)
driver.get('https://web.whatsapp.com')  # Already authenticated
time.sleep(30)

Just a slight modification for the code written by @Roel Van de Paar, as all credit goes to him. I am using this in Windows and it is working perfectly, both for setting and adding cookies:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('chromedriver.exe',options=chrome_options)
driver.get('https://web.whatsapp.com')  # Already authenticated
time.sleep(30)

回答 5

这是我在Windows中使用的代码,它有效。

 for item in COOKIES.split(';'):
            name,value = item.split('=',1)
            name=name.replace(' ','').replace('\r','').replace('\n','')
            value = value.replace(' ','').replace('\r','').replace('\n','')
            cookie_dict={  
                    'name':name,
                    'value':value,
                    "domain": "",  # google chrome
                    "expires": "",
                    'path': '/',
                    'httpOnly': False,
                    'HostOnly': False,
                    'Secure': False
                    }
            self.driver_.add_cookie(cookie_dict)

this is code I used in windows, It works.

 for item in COOKIES.split(';'):
            name,value = item.split('=',1)
            name=name.replace(' ','').replace('\r','').replace('\n','')
            value = value.replace(' ','').replace('\r','').replace('\n','')
            cookie_dict={  
                    'name':name,
                    'value':value,
                    "domain": "",  # google chrome
                    "expires": "",
                    'path': '/',
                    'httpOnly': False,
                    'HostOnly': False,
                    'Secure': False
                    }
            self.driver_.add_cookie(cookie_dict)

回答 6

我的操作系统是Windows 10,Chrome版本是75.0.3770.100。我已经尝试过’user-data-dir’解决方案,但是没有用。尝试@ Eric Klien的解决方案也失败。最后,我将chrome设置设置为图片,它可以工作!但是在Windows Server 2012上却不起作用。

设置

my os is Windows 10, and the chrome version is 75.0.3770.100. I have tried the ‘user-data-dir’ solution, didn’t work. try the solution of @ Eric Klien fails too. finally, I make the chrome setting like the picture, it works!but it didn’t work on windows server 2012.

setting


如何使用Python使用Selenium选择下拉菜单值?

问题:如何使用Python使用Selenium选择下拉菜单值?

我需要从中选择一个元素 下拉菜单中。

例如:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

1)首先,我必须单击它。我这样做:

inputElementFruits = driver.find_element_by_xpath("//select[id='fruits']").click()

2)之后,我必须选择一个好的元素,让我们说Mango

我尝试这样做,inputElementFruits.send_keys(...)但是没有用。

I need to select an element from a drop-down menu.

For example:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

1) First I have to click on it. I do this:

inputElementFruits = driver.find_element_by_xpath("//select[id='fruits']").click()

2) After that I have to select the good element, lets say Mango.

I tried to do it with inputElementFruits.send_keys(...) but it did not work.


回答 0

除非您的点击触发了某种Ajax调用来填充列表,否则您实际上不需要执行该点击。

只需找到元素,然后枚举选项,然后选择所需的选项即可。

这是一个例子:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@name='element_name']/option[text()='option_text']").click()

您可以在以下网址中阅读更多内容:https :
//sqa.stackexchange.com/questions/1355/unable-to-select-an-option-using-seleniums-python-webdriver

Unless your click is firing some kind of ajax call to populate your list, you don’t actually need to execute the click.

Just find the element and then enumerate the options, selecting the option(s) you want.

Here is an example:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@name='element_name']/option[text()='option_text']").click()

You can read more in:
https://sqa.stackexchange.com/questions/1355/unable-to-select-an-option-using-seleniums-python-webdriver


回答 1

Selenium提供了一个方便的Select来使用select -> option构造:

from selenium import webdriver
from selenium.webdriver.support.ui import Select

driver = webdriver.Firefox()
driver.get('url')

select = Select(driver.find_element_by_id('fruits01'))

# select by visible text
select.select_by_visible_text('Banana')

# select by value 
select.select_by_value('1')

也可以看看:

Selenium provides a convenient Select class to work with select -> option constructs:

from selenium import webdriver
from selenium.webdriver.support.ui import Select

driver = webdriver.Firefox()
driver.get('url')

select = Select(driver.find_element_by_id('fruits01'))

# select by visible text
select.select_by_visible_text('Banana')

# select by value 
select.select_by_value('1')

See also:


回答 2

首先,您需要导入Select类,然后创建Select类的实例。创建Select类的实例后,您可以对该实例执行select方法以从下拉列表中选择选项。这是代码

from selenium.webdriver.support.select import Select

select_fr = Select(driver.find_element_by_id("fruits01"))
select_fr.select_by_index(0)

firstly you need to import the Select class and then you need to create the instance of Select class. After creating the instance of Select class, you can perform select methods on that instance to select the options from dropdown list. Here is the code

from selenium.webdriver.support.select import Select

select_fr = Select(driver.find_element_by_id("fruits01"))
select_fr.select_by_index(0)

回答 3

希望这段代码对您有所帮助。

from selenium.webdriver.support.ui import Select

ID为下拉列表的元素

ddelement= Select(driver.find_element_by_id('id_of_element'))

带xpath的下拉元素

ddelement= Select(driver.find_element_by_xpath('xpath_of_element'))

带CSS选择器的下拉元素

ddelement= Select(driver.find_element_by_css_selector('css_selector_of_element'))

从下拉列表中选择“香蕉”

  1. 使用下拉索引

ddelement.select_by_index(1)

  1. 使用下拉菜单的值

ddelement.select_by_value('1')

  1. 您可以使用匹配显示在下拉菜单中的文本。

ddelement.select_by_visible_text('Banana')

I hope this code will help you.

from selenium.webdriver.support.ui import Select

dropdown element with id

ddelement= Select(driver.find_element_by_id('id_of_element'))

dropdown element with xpath

ddelement= Select(driver.find_element_by_xpath('xpath_of_element'))

dropdown element with css selector

ddelement= Select(driver.find_element_by_css_selector('css_selector_of_element'))

Selecting ‘Banana’ from a dropdown

  1. Using the index of dropdown

ddelement.select_by_index(1)

  1. Using the value of dropdown

ddelement.select_by_value('1')

  1. You can use match the text which is displayed in the drop down.

ddelement.select_by_visible_text('Banana')


回答 4

我尝试了很多事情,但下拉菜单位于表内,因此我无法执行简单的选择操作。仅以下解决方案有效。在这里,我突出显示下拉元素并按下箭头,直到获得所需的值-

        #identify the drop down element
        elem = browser.find_element_by_name(objectVal)
        for option in elem.find_elements_by_tag_name('option'):
            if option.text == value:
                break

            else:
                ARROW_DOWN = u'\ue015'
                elem.send_keys(ARROW_DOWN)

I tried a lot many things, but my drop down was inside a table and I was not able to perform a simple select operation. Only the below solution worked. Here I am highlighting drop down elem and pressing down arrow until getting the desired value –

        #identify the drop down element
        elem = browser.find_element_by_name(objectVal)
        for option in elem.find_elements_by_tag_name('option'):
            if option.text == value:
                break

            else:
                ARROW_DOWN = u'\ue015'
                elem.send_keys(ARROW_DOWN)

回答 5

您无需单击任何内容。使用xpath或任何您选择的方式查找,然后使用发送键

例如:HTML:

<select id="fruits01" class="select" name="fruits">
    <option value="0">Choose your fruits:</option>
    <option value="1">Banana</option>
    <option value="2">Mango</option>
</select>

Python:

fruit_field = browser.find_element_by_xpath("//input[@name='fruits']")
fruit_field.send_keys("Mango")

而已。

You don’t have to click anything. Use find by xpath or whatever you choose and then use send keys

For your example: HTML:

<select id="fruits01" class="select" name="fruits">
    <option value="0">Choose your fruits:</option>
    <option value="1">Banana</option>
    <option value="2">Mango</option>
</select>

Python:

fruit_field = browser.find_element_by_xpath("//input[@name='fruits']")
fruit_field.send_keys("Mango")

That’s it.


回答 6

您可以很好地使用CSS选择器组合

driver.find_element_by_css_selector("#fruits01 [value='1']").click()

将attribute = value css选择器中的1更改为与所需水果对应的值。

You can use a css selector combination a well

driver.find_element_by_css_selector("#fruits01 [value='1']").click()

Change the 1 in the attribute = value css selector to the value corresponding with the desired fruit.


回答 7

from selenium.webdriver.support.ui import Select
driver = webdriver.Ie(".\\IEDriverServer.exe")
driver.get("https://test.com")
select = Select(driver.find_element_by_xpath("""//input[@name='n_name']"""))
select.select_by_index(2)

会很好的工作

from selenium.webdriver.support.ui import Select
driver = webdriver.Ie(".\\IEDriverServer.exe")
driver.get("https://test.com")
select = Select(driver.find_element_by_xpath("""//input[@name='n_name']"""))
select.select_by_index(2)

It will work fine


回答 8

它与选项值一起使用:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@class='class_name']/option[@value='option_value']").click()

It works with option value:

from selenium import webdriver
b = webdriver.Firefox()
b.find_element_by_xpath("//select[@class='class_name']/option[@value='option_value']").click()

回答 9

这样,您可以在任何下拉菜单中选择所有选项。

driver.get("https://www.spectrapremium.com/en/aftermarket/north-america")

print( "The title is  : " + driver.title)

inputs = Select(driver.find_element_by_css_selector('#year'))

input1 = len(inputs.options)

for items in range(input1):

    inputs.select_by_index(items)
    time.sleep(1)

In this way you can select all the options in any dropdowns.

driver.get("https://www.spectrapremium.com/en/aftermarket/north-america")

print( "The title is  : " + driver.title)

inputs = Select(driver.find_element_by_css_selector('#year'))

input1 = len(inputs.options)

for items in range(input1):

    inputs.select_by_index(items)
    time.sleep(1)

回答 10

使用selenium.webdriver.support.ui.Select类与下拉选择配合使用的最佳方法,但由于HTML的设计问题或其他问题,有时它无法按预期工作。

在这种情况下,您也可以使用execute_script()以下替代方法:

option_visible_text = "Banana"
select = driver.find_element_by_id("fruits01")

#now use this to select option from dropdown by visible text 
driver.execute_script("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } }", select, option_visible_text);

The best way to use selenium.webdriver.support.ui.Select class to work to with dropdown selection but some time it does not work as expected due to designing issue or other issues of the HTML.

In this type of situation you can also prefer as alternate solution using execute_script() as below :-

option_visible_text = "Banana"
select = driver.find_element_by_id("fruits01")

#now use this to select option from dropdown by visible text 
driver.execute_script("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } }", select, option_visible_text);

回答 11

按照提供的HTML:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

选择一个 <option>元素中元素菜单,您必须使用Select Class。此外,由于您必须与你有诱导WebDriverWaitelement_to_be_clickable()

选择<option>文本作为芒果您可以使用以下两种定位策略之一

  • 使用ID属性和select_by_visible_text()方法:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import Select
    
    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "fruits01"))))
    select.select_by_visible_text("Mango")
  • 使用CSS-SELECTORselect_by_value()方法:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
  • 使用XPATHselect_by_index()方法:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//select[@class='select' and @name='fruits']"))))
    select.select_by_index(2)

As per the HTML provided:

<select id="fruits01" class="select" name="fruits">
  <option value="0">Choose your fruits:</option>
  <option value="1">Banana</option>
  <option value="2">Mango</option>
</select>

To select an <option> element from a menu you have to use the Select Class. Moreover, as you have to interact with the you have to induce WebDriverWait for the element_to_be_clickable().

To select the <option> with text as Mango from the you can use you can use either of the following Locator Strategies:

  • Using ID attribute and select_by_visible_text() method:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import Select
    
    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "fruits01"))))
    select.select_by_visible_text("Mango")
    
  • Using CSS-SELECTOR and select_by_value() method:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.select[name='fruits']"))))
    select.select_by_value("2")
    
  • Using XPATH and select_by_index() method:

    select = Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//select[@class='select' and @name='fruits']"))))
    select.select_by_index(2)
    

回答 12

  1. 项目清单

公共类ListBoxMultiple {

public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
    WebDriver driver=new ChromeDriver();
    driver.get("file:///C:/Users/Amitabh/Desktop/hotel2.html");//open the website
    driver.manage().window().maximize();


    WebElement hotel = driver.findElement(By.id("maarya"));//get the element

    Select sel=new Select(hotel);//for handling list box
    //isMultiple
    if(sel.isMultiple()){
        System.out.println("it is multi select list");
    }
    else{
        System.out.println("it is single select list");
    }
    //select option
    sel.selectByIndex(1);// you can select by index values
    sel.selectByValue("p");//you can select by value
    sel.selectByVisibleText("Fish");// you can also select by visible text of the options
    //deselect option but this is possible only in case of multiple lists
    Thread.sleep(1000);
    sel.deselectByIndex(1);
    sel.deselectAll();

    //getOptions
    List<WebElement> options = sel.getOptions();

    int count=options.size();
    System.out.println("Total options: "+count);

    for(WebElement opt:options){ // getting text of every elements
        String text=opt.getText();
        System.out.println(text);
        }

    //select all options
    for(int i=0;i<count;i++){
        sel.selectByIndex(i);
        Thread.sleep(1000);
    }

    driver.quit();

}

}

  1. List item

public class ListBoxMultiple {

public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
    WebDriver driver=new ChromeDriver();
    driver.get("file:///C:/Users/Amitabh/Desktop/hotel2.html");//open the website
    driver.manage().window().maximize();


    WebElement hotel = driver.findElement(By.id("maarya"));//get the element

    Select sel=new Select(hotel);//for handling list box
    //isMultiple
    if(sel.isMultiple()){
        System.out.println("it is multi select list");
    }
    else{
        System.out.println("it is single select list");
    }
    //select option
    sel.selectByIndex(1);// you can select by index values
    sel.selectByValue("p");//you can select by value
    sel.selectByVisibleText("Fish");// you can also select by visible text of the options
    //deselect option but this is possible only in case of multiple lists
    Thread.sleep(1000);
    sel.deselectByIndex(1);
    sel.deselectAll();

    //getOptions
    List<WebElement> options = sel.getOptions();

    int count=options.size();
    System.out.println("Total options: "+count);

    for(WebElement opt:options){ // getting text of every elements
        String text=opt.getText();
        System.out.println(text);
        }

    //select all options
    for(int i=0;i<count;i++){
        sel.selectByIndex(i);
        Thread.sleep(1000);
    }

    driver.quit();

}

}


使用Python在Selenium WebDriver中获取WebElement的HTML源

问题:使用Python在Selenium WebDriver中获取WebElement的HTML源

我正在使用Python绑定来运行Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

我知道我可以像这样抓取网络元素:

elem = wd.find_element_by_css_selector('#my-id')

我知道我可以通过…

wd.page_source

但是无论如何,有没有获得“元素来源”?

elem.source   # <-- returns the HTML as a string

Python的Selenium Webdriver文档基本上不存在,我在代码中看不到任何能够启用该功能的东西。

对访问元素(及其子元素)的HTML的最佳方法有何想法?

I’m using the Python bindings to run Selenium WebDriver:

from selenium import webdriver
wd = webdriver.Firefox()

I know I can grab a webelement like so:

elem = wd.find_element_by_css_selector('#my-id')

And I know I can get the full page source with…

wd.page_source

But is there anyway to get the “element source”?

elem.source   # <-- returns the HTML as a string

The selenium webdriver docs for Python are basically non-existent and I don’t see anything in the code that seems to enable that functionality.

Any thoughts on the best way to access the HTML of an element (and its children)?


回答 0

您可以读取innerHTML属性以获取元素内容outerHTML来源或包含当前元素的来源。

Python:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

C#:

element.GetAttribute("innerHTML");

红宝石:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

经过测试并与ChromeDriver

You can read innerHTML attribute to get source of the content of the element or outerHTML for source with the current element.

Python:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

C#:

element.GetAttribute("innerHTML");

Ruby:

element.attribute("innerHTML")

JS:

element.getAttribute('innerHTML');

PHP:

$element->getAttribute('innerHTML');

Tested and works with the ChromeDriver.


回答 1

获取a的html源代码实际上并没有直接的方法webelement。您将不得不使用JS。我不太确定python绑定,但是您可以在Java中轻松地做到这一点。我确信一定有一些类似于JavascriptExecutorPython中的类。

 WebElement element = driver.findElement(By.id("foo"));
 String contents = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", element); 

There is not really a straight-forward way of getting the html source code of a webelement. You will have to use JS. I am not too sure about python bindings but you can easily do like this in Java. I am sure there must be something similar to JavascriptExecutor class in Python.

 WebElement element = driver.findElement(By.id("foo"));
 String contents = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", element); 

回答 2

当然,我们可以在下面的Selenium Python中使用此脚本获取所有HTML源代码:

elem = driver.find_element_by_xpath("//*")
source_code = elem.get_attribute("outerHTML")

如果要保存到文件:

with open('c:/html_source_code.html', 'w') as f:
    f.write(source_code.encode('utf-8'))

我建议保存到文件,因为源代码非常长。

Sure we can get all HTML source code with this script below in Selenium Python:

elem = driver.find_element_by_xpath("//*")
source_code = elem.get_attribute("outerHTML")

If you you want to save it to file:

with open('c:/html_source_code.html', 'w') as f:
    f.write(source_code.encode('utf-8'))

I suggest saving to a file because source code is very very long.


回答 3

在Ruby中,使用selenium-webdriver(2.32.1),存在一种page_source包含整个页面源的方法。

In Ruby, using selenium-webdriver (2.32.1), there is a page_source method that contains the entire page source.


回答 4

实际上,使用属性方法更容易,更直接。

将Ruby与Selenium和PageObject宝石一起使用,以获取与某个元素关联的类,该行将为element.attribute(Class)

如果您想将其他属性绑定到元素,则适用相同的概念。例如,如果我想要一个元素的String element.attribute(String)

Using the attribute method is, in fact, easier and more straight forward.

Using Ruby with the Selenium and PageObject gems, to get the class associated with a certain element, the line would be element.attribute(Class).

The same concept applies if you wanted to get other attributes tied to the element. For example, if I wanted the String of an element, element.attribute(String).


回答 5

看起来已经过时了,但无论如何还是要放在这里。在您的情况下,正确的做法是:

elem = wd.find_element_by_css_selector('#my-id')
html = wd.execute_script("return arguments[0].innerHTML;", elem)

要么

html = elem.get_attribute('innerHTML')

两者都为我工作(selenium-server-standalone-2.35.0)

Looks outdated, but let it be here anyway. The correct way to do it in your case:

elem = wd.find_element_by_css_selector('#my-id')
html = wd.execute_script("return arguments[0].innerHTML;", elem)

or

html = elem.get_attribute('innerHTML')

Both are working for me (selenium-server-standalone-2.35.0)


回答 6

Java与Selenium 2.53.0

driver.getPageSource();

Java with Selenium 2.53.0

driver.getPageSource();

回答 7

希望对您有所帮助:http : //selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html

这里介绍Java方法:

java.lang.String    getText() 

但不幸的是,它在Python中不可用。因此,您可以将方法名称从Java转换为Python,并使用当前方法尝试另一种逻辑,而无需获取整个页面的源代码…

例如

 my_id = elem[0].get_attribute('my-id')

I hope this could help: http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html

Here is described Java method:

java.lang.String    getText() 

But unfortunately it’s not available in Python. So you can translate the method names to Python from Java and try another logic using present methods without getting the whole page source…

E.g.

 my_id = elem[0].get_attribute('my-id')

回答 8

这对我来说是无缝的。

element.get_attribute('innerHTML')

This works seamlessly for me.

element.get_attribute('innerHTML')

回答 9

InnerHTML将返回所选元素内的元素,而outerHTML将连同所选元素一起返回HTML内

示例:-现在假设您的Element如下

<tr id="myRow"><td>A</td><td>B</td></tr>

innerHTML元素输出

<td>A</td><td>B</td>

outsideHTML元素输出

<tr id="myRow"><td>A</td><td>B</td></tr>

现场示例:-

http://www.java2s.com/Tutorials/JavascriptDemo/f/find_out_the_difference_between_innerhtml_and_outerhtml_in_javascript_example.htm

在下面,您将找到根据不同绑定要求的语法。根据需要将更innerHTML改为outerHTML

Python:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

如果您想使用整页HTML,请使用以下代码:-

driver.getPageSource();

InnerHTML will return element inside the selected element and outerHTML will return inside HTML along with the element you have selected

Example :- Now suppose your Element is as below

<tr id="myRow"><td>A</td><td>B</td></tr>

innerHTML element Output

<td>A</td><td>B</td>

outerHTML element Output

<tr id="myRow"><td>A</td><td>B</td></tr>

Live Example :-

http://www.java2s.com/Tutorials/JavascriptDemo/f/find_out_the_difference_between_innerhtml_and_outerhtml_in_javascript_example.htm

Below you will find the syntax which require as per different binding. Change the innerHTML to outerHTML as per required.

Python:

element.get_attribute('innerHTML')

Java:

elem.getAttribute("innerHTML");

If you want whole page HTML use below code :-

driver.getPageSource();

回答 10

WebElement element = driver.findElement(By.id("foo"));
String contents = (String)((JavascriptExecutor)driver).executeScript("return      arguments[0].innerHTML;", element); 

该代码也确实可以从源代码中获取JavaScript!

WebElement element = driver.findElement(By.id("foo"));
String contents = (String)((JavascriptExecutor)driver).executeScript("return      arguments[0].innerHTML;", element); 

This code really works to get JavaScript from source as well!


回答 11

在PHPUnit硒测试中,它是这样的:

$text = $this->byCssSelector('.some-class-nmae')->attribute('innerHTML');

And in PHPUnit selenium test it’s like this:

$text = $this->byCssSelector('.some-class-nmae')->attribute('innerHTML');

回答 12

如果您对Python中的远程控制解决方案感兴趣,请按照以下方法获取innerHTML:

innerHTML = sel.get_eval("window.document.getElementById('prodid').innerHTML")

If you are interested in a solution for Remote Control in Python, here is how to get innerHTML:

innerHTML = sel.get_eval("window.document.getElementById('prodid').innerHTML")

回答 13

我更喜欢获取呈现的HTML的方法如下:

driver.get("http://www.google.com")
body_html = driver.find_element_by_xpath("/html/body")
print body_html.text

但是,上述方法会删除所有标签(也是嵌套标签),并且仅返回文本内容。如果您也有兴趣获取HTML标记,请使用以下方法。

print body_html.getAttribute("innerHTML")

The method to get the rendered HTML I prefer is following:

driver.get("http://www.google.com")
body_html = driver.find_element_by_xpath("/html/body")
print body_html.text

However the above method removes all the tags( yes the nested tags as well ) and returns only text content. If you interested in getting the HTML markup as well, then use the method below.

print body_html.getAttribute("innerHTML")

Selenium-浏览器自动化框架和生态系统

Selenium是一个伞形项目,封装了支持Web浏览器自动化的各种工具和库。Selenium专门为W3C WebDriver specification-与所有主要Web浏览器兼容的平台和语言中立的编码接口

这个项目是由志愿贡献者慷慨捐赠数千小时进行代码开发和维护而实现的

Selenium的源代码位于Apache 2.0 license

文档

叙述性文档:

接口文档:

拉取请求

请阅读CONTRIBUTING.md在提交您的拉取请求之前

要求

  • Bazelisk中指定的Bazel版本自动下载的Bazel包装器.bazelversion文件,并透明地将所有命令行参数传递给真正的Bazel二进制文件
  • 最新版本的Java 11 OpenJDK
  • javajar在路径上(请确保使用java可从JDK执行,但不能从JRE执行)
    • 要测试这一点,请尝试运行以下命令javac如果您只安装了JRE,则此命令将不存在。如果您遇到一系列命令行选项,那么您引用的JDK是正确的
  • Python 3.7+
  • python在路上
  • The tox automation project对于Python:pip install tox
  • MacOS用户应该安装最新版本的Xcode,包括命令行工具。以下命令应该可以工作:
xcode-select --install
  • Apple Silicon Mac的用户应添加build --host_platform=//:rosetta致他们的.bazelrc.local文件。我们正在努力确保从长远来看这不是必需的
  • Windows用户应安装最新版本的Visual Studio命令行工具和生成工具
    • BAZEL_VS环境变量应该指向构建工具的位置,例如C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
    • BAZEL_VC环境变量应该指向命令行工具的位置,例如C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC
    • BAZEL_VC_FULL_VERSION环境变量应包含已安装的命令行工具的版本,例如14.27.29110

可选要求

  • Ruby 2.0

Internet Explorer驱动程序

如果您计划编译IE driver,您还需要:

构建可以在任何平台上运行,但如果您不是在Windows上构建,则会以静默方式跳过IE的测试

大楼

巴泽尔

Bazel是由谷歌的优秀员工建造的。Bazel管理依赖项下载、生成Selenium二进制文件、执行测试,并且完成所有这些工作的速度都相当快

下面是运行Bazel的更详细的说明,但是如果您可以成功构建java和javascript文件夹而不出错,那么您应该相信您的系统上有正确的二进制文件

在构建之前

确保您安装了Firefox并安装了最新版本geckodriver在您的$PATH您可能需要不时更新此信息

通用构建目标

要从源代码构建最常用的Selenium模块,请从根项目文件夹执行以下命令:

bazel build java/...

如果您手头有一些额外的时间,您可以运行此命令以获得构建成功的额外信心。这将做更多的工作来构建所有的javascript工件:

bazel build java/... javascript/...

如果您正在对此项目中的java/或javascript/文件夹进行更改,并且此命令执行时没有错误,那么您应该能够创建更改的PR。(另见CONTRIBUTING.md)

构建详细信息

  • Bazel文件名为BUILD.bazel
  • crazyfun生成文件被称为build.desc这是一个较旧的构建系统,大部分仍在用于Ruby绑定的项目中

模块的构建顺序由构建系统决定。如果要构建单个模块(假设所有依赖模块之前都已构建),请尝试以下操作:

bazel test javascript/atoms:test

在这种情况下,javascript/atoms是模块目录,test是该目录BUILD.bazel文件

如你所见构建目标在日志中滚动,您可能需要单独运行它们

常见任务(Bazel)

要从源代码构建大量Selenium二进制文件,请从根文件夹运行以下命令:

bazel build java/... javascript/...

要构建网格部署JAR,请运行以下命令:

bazel build grid

要在项目的特定区域内运行测试,请使用“test”命令,后跟文件夹或目标。测试用“小”、“中”或“大”标记,并且可以用--test_size_filters选项:

bazel test --test_size_filters=small,medium java/...

Bazel的“test”命令将运行包中的测试,包括集成测试。期待着test java/...启动浏览器并消耗大量时间和资源

编辑代码

大多数团队成员使用IntelliJ IDEA或VS.Code进行日常编辑。如果您在IntelliJ中工作,我们强烈建议您安装Bazel IJ
plugin
其文档记录在its own site

如果您使用的是IntelliJ和Bazel插件,则会有一个项目视图签入到中的树中scripts/ij.bazelproject这将使运行和编辑代码变得更容易:)

游览

代码库通常围绕用于编写组件的语言进行划分。Selenium广泛使用JavaScript,所以让我们从这里开始。使用JavaScript很容易。首先,启动开发服务器:

bazel run debug-server

现在,导航到http://localhost:2310/javascript您会发现javascript/正在显示目录。我们使用Closure
Library
来开发大部分JavaScript,所以现在导航到http://localhost:2310/javascript/atoms/test

此目录中的测试是名称以_test.html单击其中一个以加载页面并运行测试

Maven POM文件

这是public Selenium Maven
repository

生成输出

bazel属性创建顶级目录组。bazel-每个目录上的前缀

在以下方面提供帮助go

更一般但更基本的帮助go

./go --help

go只是个包装而已Rake,因此您可以使用标准命令,如rake -T要获取有关可用目标的详细信息,请执行以下操作

马文本身

如果还不清楚,那么Selenium不是用Maven构建的。它是用bazel,不过这是用go如上所述,您不必对此了解太多

也就是说,可以相对快速地构建供Maven使用的硒片。只有在针对您的应用程序测试尖端的Selenium开发(我们欢迎)时,您才会真正想要这样做。以下是构建和部署到本地maven存储库的最快方法(~/.m2/repository),同时跳过Selenium自己的测试

./go maven-install

Maven罐子现在应该在你当地了~/.m2/repository

有用资源

请参阅Build Instructions关于构建零碎的硒的最后一句话的维基页面

在Linux上运行浏览器测试

为了运行浏览器测试,您首先需要安装特定于浏览器的驱动程序,例如geckodriverchromedriver,或edgedriver这些需要放在你的PATH

默认情况下,Bazel在您当前的X-server UI中运行这些测试。如果您愿意,也可以在虚拟或嵌套的X服务器中运行它们

  1. 运行X服务器Xvfb :99Xnest :99
  2. 运行窗口管理器,例如,DISPLAY=:99 jwm
  3. 运行您感兴趣的测试:
bazel test --test_env=DISPLAY=:99 //java/... --test_tag_filters=chrome

在虚拟X服务器中运行测试的一种简单方法是使用Bazel的--run_under功能:

bazel test --run_under="xvfb-run -a" //java/... --test_tag_filters=chrome

Bazel安装/故障排除

MacOS

巴泽利克(BAZELLISK)

Bazelisk是Bazel的Mac友好启动器。要安装,请执行以下步骤:

brew tap bazelbuild/tap && \
brew uninstall bazel; \
brew install bazelbuild/tap/bazelisk

Xcode

如果您收到提到Xcode的错误,则需要安装命令行工具

Bazel for Mac需要一些额外的步骤才能正确配置。首先要做的是:使用Bazelisk项目(Philwo提供),它是Bazel的纯Golang实现。要安装Bazelisk,请首先验证您的Xcode是否会合作:执行以下命令:

xcode-select -p

如果值为/Applications/Xcode.app/Contents/Developer/,您可以继续安装bazelisk。但是,如果返回值为/Library/Developer/CommandLineTools/,您需要将Xcode系统重定向到正确的值

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/
sudo xcodebuild -license

第一个命令将提示您输入密码。第二步要求您阅读新的Xcode许可,然后通过键入“Agree”接受它。

(多亏了this thread对于这些步骤)