如果我们没有选择使用 ID,类或名称来查找元素的方法,该怎么办? 袖子上有东西吗? 好吧,我有一个cssSelector。 这是一种先进而有效的策略。
- CSS (级联样式表)。 根据维基百科的说法,“CSS 是一种样式表语言,用于描述以标记语言编写的文档的表示形式”。 它通过添加样式来更改 HTML 元素的外观,并定义应如何在网页上显示它们。
- 选择器 是使用 HTML 标记,属性及其值构造的模式。 然后将它们用于匹配所需的 Web 元素。
使用cssSelector定位器优于 XPath 定位器的优点
- 速度更快,尤其是在 Internet Explorer 中
- 更简单
- 更具可读性
- 首选使用方式
通过cssSelector定位
有多种使用cssSelector
定位器的方式,这取决于可用的标签,属性,关键字等。要列出它们,
- 使用标签和 ID 属性
- 使用标签和类属性
- 使用标签和名称属性
- 使用标签和多个属性
- 定位子元素
- 按子字符串匹配
在这篇文章中,我们将介绍前四种方法。 是时候一步一步地完成这些工作了。
1.使用标签和 ID 属性
借助cssSelector
定位策略,可以使用元素的 HTML 标记及其 ID 属性及其值来对其进行访问。
有两种方法可以实现此目的:
- 语法 :
driver.findElement(By.cssSelector("tag_name#value_of_id"));
或driver.findElement(By.cssSelector("tag_name[id='value_of_id']"));;
- 说明 :使用匹配的 CSS 选择器定位元素。 在第一种方法中,
#
符号代表“id
”属性。 - 示例 :让我们在 Gmail 帐户登录页面上找到“电子邮件”文本框。
右键单击“输入电子邮件”文本框,然后选择检查元素以获取相应的 HTML 代码。 我们可以看到“input
”标签的“id
”属性为“email
”。driver.findElement(By.cssSelector("input#Email"));
或者 driver.findElement(By.cssSelector("input[id='Email']"));
2.使用标签和类属性
元素的 HTML 标签及其类属性及其值可用于访问它。 也有两种方法可以实现此目的,
- 语法 :
driver.findElement(By.cssSelector("tag_name.value_of_class"));
或driver.findElement(By.cssSelector("tag_name[class='value_of_class']”));
- 说明 :使用匹配的 CSS 选择器定位元素。 在第一种方法中,“
.
”符号代表“class
”属性。 - 示例 :让我们在使用类属性的 Gmail 帐户“注册”页面上找到“手机”文本框。
右键点击“手机”文本框,然后选择检查元素,以获取相应的 HTML 代码,如下所示,
<input tabindex="0" name="RecoveryPhoneNumber"
id="RecoveryPhoneNumber" value=""
class="i18n_phone_number_input-inner_input" type="tel">
我们可以看到“input
”标签具有“class
”属性,名称为“i18n_phone_number_input-inner_input
”。
-
driver.findElement(By.cssSelector("input.i18n_phone_number_input-inner_input "));
- 或
-
driver.findElement(By.cssSelector("input[class='i18n_phone_number_input-inner_input']"));
3.使用标签和名称属性
元素的 HTML 标记及其名称属性及其值可用于访问它。
- 语法 :
driver.findElement(By.cssSelector("tag_name[name='value_of_name']"))
- 说明 :使用匹配的 CSS 选择器定位元素。
- 示例 :让我们在 Gmail 帐户注册页面上找到名字文本框。
右键点击“名字”文本框,然后选择检查元素,以获取相应的 HTML 代码,如下所示:
<input value="" name="FirstName"
id="FirstName" spellcheck="false" class="
form-error" aria-invalid="true" type="text">
我们可以看到,“input
”标签的“name
”属性为“FirstName
”。
driver.findElement(By.cssSelector("input[name='FirstName']"));
4.使用标签和多个属性
元素的 HTML 标签和一个以上的属性及其值可用于访问它。
- 语法 :
driver.findElement(By.cssSelector("tag_name[attribute1='value_of_attribute1'][attribute2='value_of_attribute2']"))
- 说明 :使用匹配的 CSS 选择器定位元素。 以这种方式可以提到许多属性。
- 示例 :让我们使用 ID,类型和名称属性在 Gmail 帐户注册页面上找到“创建密码”文本框。
右键点击“创建密码”文本框,然后选择检查元素以获取相应的 HTML 代码,如下所示:
<input name="Passwd" id="Passwd" type="password">
我们可以看到,“input
”标签具有“name
”和“id
”属性,它们的值均为“Passwd
”,“type
”属性为password
。
-
driver.findElement(By.cssSelector("input#Passwd[name='Passwd']"));
- 或
-
driver.findElement(By.cssSelector("input[type='Password'][name='Passwd'"));
如果使用 id,则可以用“#
”符号表示,而可以用“.
”符号表示类。
定位子元素
也可以使用cssSelectors
来定位子元素。让我们考虑一下 HTML 代码,锚标记是“div
”的子元素。 要访问子元素:
- 使用 ID:
driver.findElement(By.cssSelector("div#child a"));
#
代表“ID”,子元素标签写在空格后面。 - 使用类别:
driver.findElement(By.cssSelector("div.bg_main a"));
.
代表“类”
示例 :让我们在 Gmail 帐户注册页面上找到名字文本框。右键点击“名字”文本框,然后选择检查元素,以获取相应的 HTML 代码,如下所示,
<label id="recovery-email-label">
<strong>Your current email address</strong>
<input name="RecoveryEmailAddress" id="RecoveryEmailAddress" value=""
spellcheck="false" type="text">
</label>
“标签”标签的子元素可以通过其input
标签和name
属性进行访问。
driver.findElement(By.cssSelector("label#recovery-email-label input[name='RecoveryEmailAddress']"));
如果父元素具有多个子元素 (例如下拉列表),并且它们没有“id
”或“class
”或此类属性来标识,则“nth-of-type
”用于定位特定的子元素。
- 考虑一下 HTML 代码:
<li>Cat</li> <li>Dog</li> <li>Birds</li>
- 要标识子元素“狗”:
driver.findElement(By.cssSelector("ul#pets li:nth-of-type(2)"));
按子字符串匹配
cssSelectors
也帮助我们使用子字符串来定位元素。
匹配前缀(或)开头
为了匹配具有已知前缀的元素,
- 语法 :
driver.findElement(By.cssSelector(")tag_name[attribute^='prefix_value_of_attribute']"))
- 解释 :找到以给定前缀开头的元素。 用“
^
”符号表示。
考虑以下代码:
-
<input value="" name="LastName" id="LastName" spellcheck="false" type="text">
- 我们可以看到
input
标签具有一个名为“LastName
”的“id
”属性。 要找到此元素,我们可以指定查找以“Last
”开头的“id
”属性值。driver.findElement(By.cssSelector("input[id^='Last']"));
匹配后缀(或)结尾
为了匹配具有已知后缀的元素,
- 语法 :
driver.findElement(By.cssSelector("tag_name[attribute$='suffix_value_of_attribute']"))
- 说明 :找到以给定后缀结尾的元素。 用“
$
”符号表示。
考虑以下代码:
-
<input name="PasswdAgain" id="PasswdAgain" type="password">
- 我们可以看到“
input
”标签的“name
”属性为“PasswdAgain
”。 要找到此元素,我们可以指定查找以“Again
”结尾的“name
”属性值。 - 代码:
-
driver.findElement(By.cssSelector("input[name$='Again']"));
匹配一个子字符串
为了使元素与子字符串匹配:
- 语法 :
driver.findElement(By.cssSelector("tag_name[attribute*='substring_of_attribute_value']"))
- 说明 :找到包含给定子字符串的元素。 用“
*
”符号表示。
考虑以下代码:
-
<input name="PasswdAgain" id="PasswdAgain" type="password">
- 我们可以看到“
input
”标签的“name
”属性为“PasswdAgain
”。 要找到此元素,我们可以指定查找包含“wdAg
”的“name
”属性值。 - 代码:
-
driver.findElement(By.cssSelector("input[name*='wdAg']"));
概览
让我们看一个测试用例,它实现了使用本方法和上一篇文章中介绍的cssSelector
定位器的不同方法。
- 打开 Firefox 浏览器。
- 导航到 Google 帐户创建页面
- 找到带有 HTML 标签和名称属性的“名字”文本框
- 输入“
testFirst
”作为名字 - 在“姓氏”文本框中找到一个以子字符串开头的值
- 输入“
testLast
”作为姓氏 - 找到带有 HTML 标签,类型和名称属性的“创建密码”文本框
- 输入“
Pass1234!
”作为密码 - 在“确认您的密码”文本框中找到包含子字符串的值
- 输入“
Pass1234!
”作为确认密码 - 找到带有 HTML 标签和类别属性的“手机”文本框
- 输入“
9496543210
”作为电话号码 - 使用子元素方法找到“当前电子邮件地址”文本框
- 输入“
...
” - 验证“JUnit”窗格是否成功,并确认 Eclipse IDE 控制台输出屏幕
此方案的 JUnit 代码是:
package com.blog.junitTests;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class ElementLocatorTest3 {
//Declaring variables
private WebDriver driver;
private String baseUrl;
@Before
public void setUp() throws Exception{
// Selenium version 3 beta releases require system property set up
System.setProperty("webdriver.gecko.driver", "E:\\Softwares\\"
+ "Selenium\\geckodriver-v0.10.0-win64\\geckodriver.exe");
// Create a new instance for the class FirefoxDriver
// that implements WebDriver interface
driver = new FirefoxDriver();
// Implicit wait for 5 seconds
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
// Assign the URL to be invoked to a String variable
baseUrl = "https://accounts.google.com/SignUp";
}
@Test
public void testPageTitle() throws Exception{
// Open baseUrl in Firefox browser window
driver.get(baseUrl);
// Locate 'First Name' text box by cssSelector: tag and name attribute
// assign it to a variable of type WebElement
WebElement firstName = driver.findElement(By.cssSelector("input[name='FirstName']"));
// Clear the default placeholder or any value present
firstName.clear();
// Enter/type the value to the text box
firstName.sendKeys("testFirst");
//Locate 'Last Name' text box by cssSelector: begins with sub-string
WebElement lastName = driver.findElement(By.cssSelector("input[id^='Last']"));
lastName.clear();
lastName.sendKeys("testLast");
//Locate password text box by cssSelector: tag and type, name attributes
WebElement pwd = driver.findElement(By.cssSelector("input[type='Password'][name='Passwd']"));
pwd.clear();
pwd.sendKeys("Pass1234!");
//Locate 'Confirm your password' text box by cssSelector: contains sub-string
WebElement confirmPwd = driver.findElement(By.cssSelector("input[name*='wdAg']"));
confirmPwd.clear();
confirmPwd.sendKeys("Pass1234!");
// Locate Mobile phone text box by cssSelector: tag and class
WebElement mobileNum = driver.findElement(By.cssSelector("input.i18n_phone_number_input-inner_input"));
mobileNum.clear();
mobileNum.sendKeys("9496543210");
//Locate "current email address" text box by cssSelector: child element method
WebElement recoveryEmail = driver.findElement(By.cssSelector("label#recovery-email-label input[name='RecoveryEmailAddress']"));
recoveryEmail.clear();
recoveryEmail.sendKeys("[[email protected]](/cdn-cgi/l/email-protection)");
}
@After
public void tearDown() throws Exception{
// Close the Firefox browser
driver.close();
}
}
执行结果(注释清楚地提供给每行代码,因此是不言自明的。):
在 JUnit 窗格中,绿色条显示测试用例已成功执行。 另外,控制台窗口中不会记录任何错误。下图显示了在 Firefox 浏览器中执行的最终输出。
下一节:我们今天将讨论 XPath 策略。 这也是一种先进且有效的定位策略(cssSelectors也是!)。 虽然有效,但有时可能会造成混淆。 因此,让我们深入研究如何理解我们经常被误解的朋友,并一劳永逸地提出好的代码。