-
学习中心
[
博客
为创始人和工程经理提供关于扩展、管理和产品开发的见解。
社区帖子
阅读编程教程,分享你的知识,并一起成为更好的开发者。
](www.codementor.io/community/t…)
热门话题
写一篇文章
注册
寻找开发者和导师社区帖子博客注册登录
[
](www.codementor.io/projects?re…)
关注
如何使用Python处理Selenium WebDriver中的下拉菜单?
发表于 5月10日, 2021
下拉框是现代网站的一个组成部分。像其他的HTML元素一样,这些元素也需要被测试,特别是当你执行自动化浏览器测试的时候。UI/UX设计师喜欢下拉元素,但自动化测试工程师才会去玩它。因此,当你处理访问表单或测试网站时,知道如何在Selenium WebDriver中处理下拉元素变得很重要。
设计师喜欢使用美观的下拉菜单或盒子。主要是因为下拉菜单倾向于节俭地利用可用的屏幕空间。当你只想从用户那里得到特定的输入而不是一些垃圾数据时,它是很有用的。然而,下拉式设计的漏洞可能是用户的一个严重障碍。
我曾经遇到过一些网站的导航下拉菜单实现得很差,在那里我没有办法在不点击某个选项的情况下退出菜单。这是一种错误的刺激性体验!在移动浏览器中,它变得更加棘手,在理想情况下,下拉选项必须为拇指界面进行优化。为了确保整个应用程序或网站的无缝用户体验,测试自动化工程师往往需要彻底调查下拉菜单的任何可能缺陷。
这个见解旨在成为你处理如何使用Python在Selenium WebDriver中处理下拉菜单的首选目的地。你可以考虑把这个页面收藏起来,并订阅我们的博客(如果你还没有),以获得未来的自动化测试教程和LambdaTest的报价更新。
自动化测试工程师必须知道的不同类型的下拉菜单
在HTML中,我们会遇到四种类型的下拉实现。
- 下拉式导航选项。
这些通常是在网站的导航栏中遇到的,下拉链接到其他网页。
- 下拉命令选项。
和导航下拉选项一样,这些也是在顶部发现的,但这些是为了对活动页面本身执行一些操作。例如--Google Docs菜单栏。
- 属性选择下拉选项。
这些通常用于实现搜索过滤功能和自定义选项,如改变网站的颜色-模板或语言。
- 表格填充下拉选项。
这些下拉选项用于注册表格或产品/服务预订表格。
如何在Selenium Webdriver中处理下拉菜单
在SeleniumPython中,测试各种下拉元素可以使用CSS和/或XPATH选择器来处理。但作为一个额外的功能,我们在Selenium WebDriver中拥有SELECT类。我们可以用它来实现与使用html标签实现的下拉选项的自动交互。 什么是Selenium WebDriver中的 "选择 "类? Selenium提供Select类来实现HTML选择元素。Selenium中的Select类是一个普通的Java类,你可以使用关键字New来创建一个新的对象,并指定一个Web元素的位置。在这个关于如何在Selenium WebDriver中处理下拉菜单的教程中,我们将看到不同的SELECT类功能。 class selenium.webdriver.support.select.Select(webelement) 在引擎盖下,Selenium选择类会检查我们使用的HTML网页元素是否是一个<选择>标签。如果不是,Selenium WebDriver会抛出UnexpectedTagNameException 。 **注意:**Selenium'Select'只能用于html 标签,而不能用于其他。"
Selenium SELECT类由以下子函数组成。
options(self)
这个函数在目标标签中找到所有标签。 all_selected_options(self) 这个函数在所有选项上循环,使用is_selected()方法检查是否被选中,并返回一个被选中的 "选项 "列表。 first_selected_option(self) 这与上面的函数类似,在标签下的所有可用选项中循环,但一旦发现第一个is_selected() ,就会返回。
select_by_value(self, value)
这个函数利用CSS选择器来评估网页元素的值属性。它返回所有具有匹配值的。
select_by_index(self, index)
Selenium的这个SELECT类函数通过使用get_attribute("index")来评估标签的索引并返回匹配的选项。
select_by_visible_text(self, text)
这个函数是用XPATH和多个if-else实现的。选择在选项标签的开头和结尾之间含有与文本属性相等的字符串的选项元素,即dummy_text_attribute。
同样,也有一些函数可以取消对所选选项的选择。
deselect_by_index(self, index)deselect_by_value(self, value)deselect_all(self)deselect_by_visible_text(self, text)
Selenium WebDriver的SELECT类内部使用了两个函数来实现上述 "选择或取消选择 "选项的功能。
def _setSelected(self, option):
if not option.is_selected():
option.click()
def _unsetSelected(self, option):
if option.is_selected():
option.click()
在下面的所有演示中,我们将使用一个有三个不同下拉元素的网页作为演示页面,如下所示。
在Selenium WebDriver中选择带有匹配文本的下拉选项
为了自动测试<选项>的选择,根据它是否与一个特定的文本字符串相匹配的标准,我们使用Selenium中SELECT类的select_by_visible_text(self, text) 方法。
例子
在上述网页的 "单独选择的演示 "部分,我们有四个选项 - "Python, Java, C#, PHP"。使用字符串匹配来选择 "Java"。
dropdown1 = Select(driver.find_element_by_id('lang1'))
dropdown1.select_by_visible_text('Java')
Selecting a Dropdown option in Selenium WebDriver using the value attribute
通常情况下,和标签在表单中的使用是通过给选项分配一个 "value "属性来实现的。用户可以看到标签的开头和结尾之间的文本,但它是在表单提交时发送到服务器的分配给 "value "属性的值。如前所述,Selenium WebDriver为自动化测试工程师提供了一个API,也可以根据选项的值来选择选项,即select_by_value(self, value) 。 在我们的演示页面上,第一个 "选择你的语言:"部分是一个使用带有值属性的选择和选项实现的表单元素。要使用select_by_value 方法选择python - dropdown = Select(driver.find_element_by_id('lang')) dropdown.select_by_value('python') 在Selenium WebDriver中使用索引选择一个下拉选项 document.getElementById("myCourses").selectedIndex = "3"; 同样地,Selenium Python也提供了一种方法,即select_by_index(self, index) ,以自动选择选项。在我们的测试网页上的 "单独选择的演示 "部分,我们可以通过传递索引'3'来选择C#。 dropdown = Select(driver.find_element_by_id('lang1')) dropdown.select_by_index(3) 使用Selenium WebDriver来处理启用了多选的下拉菜单 通过在元素中添加一个名为 "multiple "的属性,可以启用多选项选择。为了检查下拉菜单是否允许多选,我们可以使用xpath或get属性或两者。在内部,Selenium在其__init__()构造函数中使用以下方法来评估下拉列表是否允许多选 self._el = webelement multi = self._el.get_attribute("multiple") self.is_multiple = multi and multi != "false" 我们首先使用xpath或CSS选择器识别一个 web元素,然后使用get_attribute()方法评估它是否包含一个 "multiple "属性。
dropdown = driver.find_element_by_tag_name('select')
if dropdown.get_attribute("multiple"):
print("multiple select options can be chosen")
else:
print("only one select option can be selected")
在Selenium WebDriver中选择多个下拉选项
一旦你知道可以在下拉菜单中选择多个选项,我们就可以使用Selenium WebDriver的 "select "类方法对选项进行迭代并选择它们。另外,我们也可以使用Selenium WebDriver的 "actionchains "类来选择多个选择。其策略是首先获得网页元素,然后在按下 "ctrl "键的情况下对其进行连锁点击操作。对于我们的演示测试页面,我们演示了在Selenium Python中选择多个选项的两种方法。 对于 "动作链 "的演示,我们首先评估id为 "lang2 "的元素是否有 "multiple "属性。如果是,那么我们就分别选择带有 "PHP "和 "C#"选项的webelements --
myOption = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'C#')]")
myOption1 = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'PHP')]")
然后我们就可以用下面的代码对其执行连锁动作------。
ActionChains(driver).key_down(Keys.CONTROL).click(myOption).key_up(Keys.CONTROL).perform()
ActionChains(driver).key_down(Keys.CONTROL).click(myOption1).key_up(Keys.CONTROL).perform()
对于Selenium SELECT类的演示,我们首先找到具有 "multiple "属性的id为 "lang2 "的元素。如果是,那么我们就用select_by_index, select_by_value, select_by_visible_text ,分别选择带有 "Java"、"PHP "和 "Python "的选项。 dropdown = Select(driver.find_element_by_id('lang2')) dropdown.select_by_index(3) dropdown.select_by_value('php') dropdown.select_by_visible_text('Python') 在Selenium WebDriver中选择所有的下拉选项 为了选择所有的选项,我们可以在可用的选项上循环,并使用Selenium WebDriver的SELECT APIs进行选择。对于我们的示例演示,要选择id为 "lang2 "的webelement的所有选项。 dropdown = Select(driver.find_element_by_id('lang2')) for opt in dropdown.options: dropdown.select_by_visible_text(opt.get_attribute("innerText")) 在Selenium WebDriver中取消选择或清除已经选择的下拉选项 要取消对一个选项的选择,我们可以使用任何一个.NET接口。 deselect_by_index(self, index) deselect_by_value(self, value) deselect_by_visible_text(self, text) 而要取消对所有选项的选择,我们有以下方法deselect_all(self) 在我们的例子中,我们可以使用-来取消对多个选项中的python的选择。 dropdown = Select(driver.find_element_by_id('lang2')) dropdown.deselect_by_visible_text('Python') 现在,我们将使用LambdaTest Selenium Grid和Python在云端运行一个自动化测试,看看如何使用Selenium SELECT类来处理Selenium中的下拉菜单。如果你是LambdaTest的新手,它是一个经济、高效、可扩展的测试平台,与所有主要的测试框架、CI/CD工具和语言兼容。直观的文档、深入的见解和测试教程使初学者也能很容易地在2000多个浏览器上进行无缝测试,操作系统和设备组合。 请阅读以下测试脚本的评论,以了解程序流程。 # import the packages we would be using to automate this test from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys import time # Username, Access Token and grid URL can be obtained through automation dashboard - username = "user_name" accessToken = "access_key" gridUrl = "hub.lambdatest.com/wd/hub" # environment configs, for simplicity we have only two configs. You can have more than 2000 if required browsers = [ { "browser":"Chrome", "version":"88.0", "OS" : "windows 10", "resolution" : "1024x768" }, { "browser":"Firefox", "OS" : "windows 10", "version":"71.0", "resolution" : "1024x768" } ] # looping over environment to perform cross-browser testing for cap in browsers: desired_cap = { # operating system 'platform' : cap["OS"], # Browser 'browserName' : cap["browser"], 'version' : cap["version"], # Resolution of machine "resolution": cap["resolution"], "name": "Select Option in selenium webdriver", "build": "Select Option in selenium webdriver", "network": True, "video": True, "visual": True, "console": True, } url = "https://"+username+":"+accessToken+"@"+gridUrl print("Initiating remote driver on platform: "+desired_cap["platform"]+" browser: "+desired_cap["browserName"]+" version: "+desired_cap["version"]) # driver instance creation driver = webdriver.Remote( desired_capabilities=desired_cap, command_executor= url ) # maximizing the browser window to fit the screen resolution driver.maximize_window() # loading the passed url into browser driver.get('https://pynishant.github.io/dropdown-selenium-python-select.html') # identifying select element with id="lang2" using selectors and checking if attribute "multiple" is present in it. dropdown = driver.find_element_by_id('lang2') if dropdown.get_attribute("multiple"): # xpath selector to find the element with text "C#" and "PHP" respectively myOption = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'C#')]") myOption1 = driver.find_element_by_xpath("//select[@multiple]/option[contains(text(), 'PHP')]") # using actionchains to select multiple options ActionChains(driver).key_down(Keys.CONTROL).click(myOption).key_up(Keys.CONTROL).perform() # pausing program execution for few seconds time.sleep(2) ActionChains(driver).key_down(Keys.CONTROL).click(myOption1).key_up(Keys.CONTROL).perform() try: # creating a selenium Select webelement of html <select> tag dropdown = Select(driver.find_element_by_id('lang2')) # using selenium webdriver's select class methods to find all selected options and printing it's text. Ideally, here output should be "PHP, C#" print("All selected options using ActionChains : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) # clearing the php selection we performed in last step dropdown.deselect_by_visible_text('PHP') # Again printing the active selections, this time output should be only c# print("Remaining selected options after deselecting PHP : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) time.sleep(2) # Using selenium select class method to deselect all options dropdown.deselect_all() time.sleep(2) # Using different select class methods, to select multiple options # selecting by index, Java dropdown.select_by_index(3) time.sleep(2) # selecting by value - php dropdown.select_by_value('php') time.sleep(2) # selecting by text - python dropdown.select_by_visible_text('Python') # printing active selections - output should include all three php, python, java print("All selected options after selecting using different select class methods : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) dropdown.deselect_all() # to select all possible options dropdown = Select(driver.find_element_by_id('lang2')) for opt in dropdown.options: dropdown.select_by_visible_text(opt.get_attribute("innerText")) # all four selected options should be output print("Selected option lists after selecting all of them : \n") for opt in dropdown.all_selected_options: print(opt.get_attribute('innerText')) driver.quit() except Exception as e: print(e) print("error") else: print("get_attribute didn't work!") 输出。 你可以在LambdaTest自动化仪表板上检查你的成功测试运行或构建的状态。对于上述程序,这里是仪表板的截图。 使用下拉菜单时的常见错误。处理 ElementNotInteractable 异常 当你与下拉菜单互动时,要确保。 该元素是可点击的。 该元素是可见的。 该元素被启用。 在Python中使用try-except-finally方法。 ElementNotInteractable 异常发生在元素不能被访问(被另一个元素阻碍)或不活跃的时候。某些元素是不可点击的。如果你尝试对它们进行点击操作,会导致错误。 如果你的目标元素是AJAX渲染的,或者依赖于其他事件来实现可点击,那么下面的方法可能会有帮助。 rom selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome(path_to_your_chrome_driver) driver.maximize_window() # some code... element = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "id_of_your_target_element")) ) # some code... 在这里,你明确地在你的目标元素变成可点击之前等待一个时间。 你也可以用以下方法检查目标元素是否被启用。 element.is_enabled() 或者,如果目标元素是可见的 element.is_displayed() 让我们来演示一下为什么在与一个元素进行交互之前检查它的可见性是很重要的。 这一次,我们使用一个稍微不同的版本的上述演示网址:pynishant.github.io/dropdown-visibility-demo.html from selenium import webdriver from selenium.webdriver.support.ui import Select from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys import time from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.maximize_window() driver.get('pynishant.github.io/dropdown-visibility-demo.html') try: # try clicking invisible element langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]') ActionChains(driver).click(langDropdown).perform() except Exception as e: print(e) # try clicking visible element langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]') ActionChains(driver).click(langDropdown).perform() # try clicking an element with another element overflowing it myOption = driver.find_element_by_xpath('//select[@id="lang"]/option[@value="python"]') ActionChains(driver).click(myOption).perform() time.sleep(3) # Get the selected value of element under target and element hovering target selectedOption = Select(driver.find_element_by_xpath('//select[@id="lang"]')) selectedOption1 = Select(driver.find_element_by_xpath('//select[@id="lang1"]')) try: selected_option = selectedOption.first_selected_option.text except Exception as e: print(e) selected_option = "None" try: selected_option1 = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]').text except Exception as e: print(e) selected_option1 = "None" print("Selection output for id='lang' element with lang1 expanded : " +str(selected_option)) print("Selection output for id='lang1' element with lang1 expanded : " +str(selected_option1)) time.sleep(3) # try clicking 'lang select' elements with car dropdown elements hovering over it. Notice Car elements are not clickable. carDropdown = driver.find_element_by_xpath('//select[@id="cars"]') ActionChains(driver).click(carDropdown).perform() time.sleep(3) myOption = driver.find_element_by_xpath('//select[@id="lang"]/option[@value="python"]') ActionChains(driver).click(myOption).perform() # get selected value of target and car elements selectedOption = Select(driver.find_element_by_xpath('//select[@id="lang"]')) selectedOption2 = Select(driver.find_element_by_xpath('//select[@id="cars"]')) try: selected_option = selectedOption.first_selected_option.text except Exception as e: print(e) selected_option = "None" try: selected_option2 = selectedOption2.first_selected_option.text except Exception as e: print(e) selected_option2 = "None" print("Selection output for id='cars' element with lang1 expanded : " +str(selected_option2)) print("Selection output for id='lang' element with car dropdown expanded : " +str(selected_option)) time.sleep(5) driver.quit() 在命令行中使用输出来执行这个。 python demo-visibility.py 在上面的代码中,我们尝试与一个不可见的元素进行交互,但它抛出了JS错误。 try: # try clicking invisible element langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]') ActionChains(driver).click(langDropdown).perform() except Exception as e: print(e) 接下来,我们尝试在标签中选择一个元素,并展开标签,将鼠标悬停在上。
# try clicking visible element
langDropdown = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]')
ActionChains(driver).click(langDropdown).perform()
# try clicking an element with another element overflowing it
myOption = driver.find_element_by_xpath('//select[@id="lang"]/option[@value="python"]')
ActionChains(driver).click(myOption).perform()
time.sleep(3)
# Get the selected value of element under target and element hovering target
selectedOption = Select(driver.find_element_by_xpath('//select[@id="lang"]'))
try:
selected_option = selectedOption.first_selected_option.text
except Exception as e:
print(e)
selected_option = "None"
try:
selected_option1 = driver.find_element_by_xpath('//select[@id="lang1"]/following-sibling::div[1]').text
except Exception as e:
print(e)
selected_option1 = "None"
从输出结果可以看出,我们最终选择了中的一个元素 "Java"。这有时会导致不正确的测试。所以,要观察元素的行为。 总结 在这个Selenium WebDriver教程中,我们演示了如何使用Selenium WebDriver的selenium.webdriver.support.select.Select(webelement)类提供的方法在Selenium WebDriver中处理下拉菜单。我们探讨了从下拉菜单中选择/不选择一个选项的方法。我们还详细介绍了 "检查是否允许多选,并在需要时选择多个选项"。文章还分享了自动化测试人员在与下拉元素进行自动化交互时避免ElementNotInteractable错误的技巧。对于可扩展的自动化需求,坚持最佳测试自动化实践,并考虑在云中测试以降低成本。 这就是所有的人,我希望你喜欢这个用于Selenium测试自动化的Selenium WebDriver教程。如有任何疑问,请发表评论。如果你觉得这篇文章有帮助,请在你的圈子和社交媒体上分享。 测试愉快!!!? SeleniumPython自动化Seleniumwebdriver测试 报道 喜欢这篇文章吗?如果有帮助,请给harshitpaul一个赞。 2 分享 harshitpaul 关注 发现并阅读更多来自harshitpaul的帖子 开始吧 喜欢这个帖子吗? 给harshitpaul留个赞和评论吧 2 成为第一个分享您意见的人 支持GitHub口味的markdown 提交 显示更多回复