[跟着官方文档学Selenium][学习笔记][六][WebDriver的元素]

举报
John2021 发表于 2022/04/03 14:55:22 2022/04/03
【摘要】 交互用于操纵表单的高级指令集。仅有五种基本命令可用于元素的操作:点击(适用于任何元素)发送键位(仅适用于文本字段和内容可编辑元素)清除(仅适用于文本字段和内容可编辑元素)提交(仅适用于表单元素)选择(参见选择列表元素) 附加验证这些方法的设计目的是尽量模拟用户体验,所以,与Actions接口不同,在指定制定操作之前,会尝试执行两件事。1,如果它确定元素在视图之外,则会将元素滚动到视图中,特...

交互

用于操纵表单的高级指令集。
仅有五种基本命令可用于元素的操作:

  • 点击(适用于任何元素)
  • 发送键位(仅适用于文本字段和内容可编辑元素)
  • 清除(仅适用于文本字段和内容可编辑元素)
  • 提交(仅适用于表单元素)
  • 选择(参见选择列表元素)

附加验证

这些方法的设计目的是尽量模拟用户体验,所以,与Actions接口不同,在指定制定操作之前,会尝试执行两件事。
1,如果它确定元素在视图之外,则会将元素滚动到视图中,特别是将元素底部与视图底部对齐。
2, 确保元素在执行操作之前是可交互的。这可能意味着滚动不成功,或者该元素没有以其他方式显示。确定某个元素是否显示在页面上太难了无法直接在webdriver规范中定义,因此Selenium发送一个带有JavaScript原子的执行命令,检查是否有可能阻止该元素显示。如果确定某个元素不在视图中,不显示,不可键盘交互,或不可指针交互,则返回一个元素不可交互错误。

点击

元素点击命令执行在元素中央。如果元素中央由于某些元素被遮挡,Selenium将返回一个元素点击中断错误。

发送键位

元素发送键位命令将录入提供的键位到可编辑的元素。通常,这意味着元素是具有文本类型的表单的输入元素或具有内容可编辑属性的元素。如果不可编辑,则返回无效元素状态错误。以下是WebDriver支持的按键列表。

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class HelloSelenium
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        try
        {
            //输入URL
            webDriver.get("https://www.baidu.com");
            //输入Selenium按下回车键
            webDriver.findElement(By.id("kw")).sendKeys("Selenium" + Keys.ENTER);
        }
        finally
        {
            webDriver.quit();
        }
    }
}

清除

元素清除命令重置元素的内容。这要求元素可编辑,且可重置。通常,这意味着元素是具有文本类型的表单的输入元素或具有内容可编辑属性的元素。如果不满足这些条件,将返回无效元素状态错误。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

public class clear
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        try
        {
            //导航URL
            webDriver.get("https://www.baidu.com");
            //存储SearchInput元素
            WebElement searchInput = webDriver.findElement(By.id("kw"));
            searchInput.sendKeys("Selenium");
            //清除输入的文本
            searchInput.clear();
        }
        finally
        {
            //webDriver.quit();
        }
    }
}

提交

在Selenium4中,不再通过单独的端点以及脚本执行的方法来实现。因此,建议不要使用此方法,而是单击相应的表单提交按钮。

查询器

根据提供的定位值定位元素。
使用Selenium的最基本方面之一是获得要使用的元素引用。Selenium提供了许多内置的定位器策略来唯一地识别元素。在高级方法中,可以通过许多方式使用这些定位器。出于本文档的目的,让我们考虑一下这段HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DemoPage</title>
</head>
<body>
<div>
    <ol id="vegetables">
        <li class="patatoes">patatoes</li>
        <li class="onions">onions</li>
        <li class="tomatoes"><span>Tomato is a vegetable</span></li>
    </ol>
    <ul id="fruits">
        <li class="bananas">bananas</li>
        <li class="apples">apples</li>
        <li class="tomatoes"><span>Tomato is a fruit</span></li>
    </ul>
</div>
</body>
</html>

第一个匹配的元素

很多定位器会匹配页面的多个元素。查找单个元素方法将返回给给定上下文中找到的第一个元素的引用。

评估整个DOM

当find element方法被驱动实例调用时,它将返回在DOM中与提供的定位器相匹配的第一个元素。这个值可以被存储或元素操作所使用。在上面的HTML例子中,有两个元素,其中一个叫tomatoes,所以这个方法将返回vegetables列表中的元素。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo1
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo1.html");

        WebElement vegetable = webDriver.findElement(By.className("tomatoes"));
        System.out.println(vegetable.getText());//Tomato is a vegetable
    }
}

评估DOM的子集

相比在整个DOM中查找唯一定位器,经常会用到查找的是定位另一个元素。在上面例子中,两个元素的类名都为"tomatoes",要找到第二个的引用有点挑战性。
一种解决方案是查找具有唯一属性的元素,该元素是所需元素的祖先,而不是不需要的元素的祖先,然后在该对象上调用find element。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo2
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo1.html");

        WebElement fruits = webDriver.findElement(By.id("fruits"));
        WebElement tomatoes = fruits.findElement(By.className("tomatoes"));
        String text = tomatoes.getText();
        System.out.println(text);//Tomato is a fruit
    }
}

优化定位器

如上例所示,嵌套查找可能不是最有效的位置策略,因为这需要向浏览器发出两个单独的指令。
为了稍微提高性能,我们可以使用CSS或者XPath在单条指令中查找元素。可以观看我们鼓励测试实践部分中的定位器策略建议
在这个例子中我们将使用CSS Selector

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo3
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo1.html");

        WebElement fruit = webDriver.findElement(By.cssSelector("#fruits .tomatoes"));
        System.out.println(fruit.getText());//Tomato is a fruit
    }
}

匹配所有元素

需要获取与定位器匹配的所有元素(而不仅仅是第一个元素)的引用有几种用例。复数查找元素方法返回元素引用的集合。如果没有匹配项,则返回空列表。在这种情况下,所有水果和蔬菜列表项的引用将在集合中返回。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.util.List;

public class Demo4
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo1.html");

        List<WebElement> plants = webDriver.findElements(By.tagName("li"));
        for (int i = 0; i < plants.size(); i++)
        {
            System.out.println("第" + (i + 1) + "个元素为:" + plants.get(i).getText());
        }
        /*
        *   第1个元素为:potatoes
            第2个元素为:onions
            第3个元素为:Tomato is a vegetable
            第4个元素为:bananas
            第5个元素为:apples
            第6个元素为:Tomato is a fruit
        * */
    }
}

获取元素

通常,你会获得一个元素集合,但希望使用特定元素,这意味着你需要循环访问该集合并确定所需的元素。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.util.List;

public class Demo5
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo1.html");

        List<WebElement> elements = webDriver.findElements(By.tagName("li"));
        for (WebElement element : elements)
        {
            System.out.println("Paragraph text: " + element.getText());
        }
        /*
        *   Paragraph text: potatoes
            Paragraph text: onions
            Paragraph text: Tomato is a vegetable
            Paragraph text: bananas
            Paragraph text: apples
            Paragraph text: Tomato is a fruit
        * */
    }
}

从元素中找元素

用于在父元素的上下文中查找匹配的子WebElements的列表。为了实现这一点,父WebElement使用"findElements"链接来访问子元素。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;

import java.util.List;

public class findElementsFromElement
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        try
        {
            webDriver.get("XXX\\example.html");
            //通过tagName 'div' 获取元素
            WebElement element = webDriver.findElement(By.tagName("div"));
            //通过tagName 'p' 获取所有可用元素
            List<WebElement> elements = element.findElements(By.tagName("p"));
            for (WebElement e : elements)
            {
                System.out.println(e.getText());
            }
        }
        finally
        {
            webDriver.quit();
        }
    }
}

获取激活元素

它用于追踪或查找在当前浏览上下文中具有焦点的DOM元素

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class activeElementTest
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        try
        {
            webDriver.get("https://www.baidu.com");
            webDriver.findElement(By.cssSelector("#kw")).sendKeys("Selenium");

            //获取当前激活元素的属性
            String attr = webDriver.switchTo().activeElement().getAttribute("name");
            System.out.println(attr);//wd
        }
        finally
        {
            webDriver.quit();
        }
    }
}

信息

你可以查询有关特定元素的许多详细信息

Is Displayed

此方法用于检查链接的元素是否显示在网页上。返回一个布尔值,如果链接的元素显示在当前浏览上下文中就是True,否则为False。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo1
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("https://www.baidu.com");

        boolean kwDisplayed = webDriver.findElement(By.id("kw")).isDisplayed();
        if (kwDisplayed)
        {
            System.out.println("搜索框已显示");
        }
        else
        {
            System.out.println("搜索框没有显示");
        }
    }
}

Is Element Selected

此方法确定是否已选择引用的元素。广泛用于复选框,单选按钮,输入元素和选项元素。
返回一个布尔值,如果在当前浏览上下文中已选择引用的元素返回True,否则返回False。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo2</title>
</head>
<body>
<form>
    <input type="checkbox" name="tomato" value="tomato" checked>Tomato<br>
    <input type="checkbox" name="apple" value="apple">Apple<br>
</form>
</body>
</html>
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo2
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\Demo2.html");

        //如果选中元素返回True
        boolean tomatoSelected = webDriver.findElement(By.name("tomato")).isSelected();
        if (tomatoSelected)
        {
            System.out.println("西红柿被选中");
        }
        else
        {
            System.out.println("西红柿没被选中");
        }
        boolean appleSelected = webDriver.findElement(By.name("apple")).isSelected();
        if (appleSelected)
        {
            System.out.println("苹果被选中");
        }
        else
        {
            System.out.println("苹果没被选中");
        }
    }
}

Get Element TagName

此方法用于获取在当前浏览上下文中具有焦点的被引用的元素TagName

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo3
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("https://www.example.com");

        String h1Value = webDriver.findElement(By.cssSelector("h1")).getTagName();
        System.out.println(h1Value);
    }
}

Get Element Rect

用于获取参考元素的尺寸和坐标
提取的数据主体包含以下详细信息:

  • 元素左上角的X轴位置
  • 元素左上角的Y轴位置
  • 元素高度
  • 元素宽度
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo4
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("https://www.example.com");

        //返回高宽xy四个元素
        Rectangle res = webDriver.findElement(By.cssSelector("h1")).getRect();
        //Rectangle类提供了获取xy高宽方法
        System.out.println(res.getX());
        System.out.println(res.getY());
        System.out.println(res.getWidth());
        System.out.println(res.getHeight());
    }
}

获取元素CSS值

获取当前浏览上下文中元素的特定计算样式属性的值

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo5
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("https://www.example.com");

        String color = webDriver.findElement(By.linkText("More information...")).getCssValue("color");
        System.out.println(color);//rgba(56, 72, 143, 1)
    }
}

获取元素文本

获取特定元素渲染后的文本

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class Demo6
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("https://www.example.com");

        String text = webDriver.findElement(By.cssSelector("h1")).getText();
        System.out.println(text);//Example Domain
    }
}

定位器

在DOM中标识一个或多个特定元素的方法。定位器是一种标识页面上元素的方法。它是传递给查找元素方法的参数。

元素选择策略

在WebDriver中有8种不同的内置元素定位策略:

定位器Locator 描述
class name 定位class属性与搜索值匹配的元素(不允许使用复合类名)
css selector 定位CSS选择器匹配的元素
id 定位id属性与搜索值匹配的元素
name 定位name属性与搜索值匹配的元素
link text 定位link text可视文本与搜索值完全匹配的锚元素
partial link text 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。
tag name 定位标签名称与搜索值匹配的元素
xpath 定位与XPath表达式匹配的元素

相对定位器

Selenium 4引入了相对定位器(以前称为友好定位器)。当为所需元素构建定位器并不容易,但很容易在空间上描述元素相对于具有易于构建的定位器的元素位置时,这些定位器非常有用。

相对定位器如何工作的

Selenium使用JavaScript函数getBoundingClientRect()定义页面元素的大小和位置,并且可以用这些信息定位旁边的元素。
相对定位器方法可以将原点(先前定位的元素参考或者其他定位器)用作原点的参数。
让我们以下面的页面为例来理解相对定位器。

可用的相对定位器

Above

如果email的文本域不容易获取,但是密码文本域容易获取,我们可以定位"input"元素在密码元素"上方"

By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));

Below

如果密码文本域不容易获取,但是email的文本域容易获取,我们可以定位"input"元素在email元素"下方"

By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));

Left of

如果cancel按钮不容易获取,但是submit按钮容易获取,我们可以通过定位submit元素的左边来找到cancel元素

By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));

Right of

如果submit按钮不容易获取,但是cancel按钮容易获取,我们可以通过定位cancel元素的右边来找到submit元素

By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));

Near

如果相对定位不明显,或者因窗口大小而已,则可以使用near方法识别距离,提供的定位器范围最多50px.一个很好的用例是使用一个表单元素,该元素没有易于构建的定位器,但其关联的输入标签元素具有

By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));

链式相对定位器

需要的话你还可以链接定位器。有时,该元素最容易被识别为一个元素的上/下以及另一个元素的左/右。

By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email").toRightOf(By.id("cancel"));

选择列表

与其他元素相比,选择列表具有特俗的行为。
选择元素可能需要大量样板代码才能自动化。为了减少这种情况并使你的测试更干净,在Selenium的support包中有一个Select类。要使用它需要导入以下语句:

import org.openqa.selenium.support.ui.Select;

然后,能够参考<select>元素,基于WebElement创建一个Select对象

WebElement selectElement = driver.findElement(By.id("selectElementID"));
Select selectObject = new Select(selectElement);

Select对象现在将为你提供一系列命令,使你可以与<select>元素进行交互。首先,有多种方法可以从<select>元素中选择一个选项。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<select>
    <option value="value1">Bread</option>
    <option value="value2" selected>Milk</option>
    <option value="value3">Cheese</option>
</select>
</body>
</html>

有三种方法可以从上述元素中选择第一个选项:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.Select;

public class Demo1
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo.html");

        WebElement selectElement = webDriver.findElement(By.id("selectElementID"));
        Select selectObject = new Select(selectElement);

        //根据下标选择
        //selectObject.selectByIndex(1);
        //根据值的属性选择
        //selectObject.selectByValue("value1");
        //根据text选择
        selectObject.selectByVisibleText("Bread");
    }
}

然后,可以检视所有被选择的选项:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.Select;

import java.util.List;

public class Demo2
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo.html");

        WebElement selectElement = webDriver.findElement(By.id("selectElementID"));
        Select selectObject = new Select(selectElement);

        //将选项返回到List集合
        List<WebElement> allSelectedOptions = selectObject.getAllSelectedOptions();
        System.out.println(allSelectedOptions);//tag name: option

        //返回DOM遍历时找到的第一个option
        WebElement firstSelectedOption = selectObject.getFirstSelectedOption();
        System.out.println("=======\n"+firstSelectedOption.getText());//Milk
    }
}

或者你可能只对<select>元素包含哪些<option>元素感兴趣

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.Select;

import java.util.List;

public class Demo3
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo.html");

        WebElement selectElement = webDriver.findElement(By.id("selectElementID"));
        Select selectObject = new Select(selectElement);

        List<WebElement> allAvailableOptions = selectObject.getOptions();
        System.out.println(allAvailableOptions.size());//3
        for (WebElement all : allAvailableOptions)
        {
            System.out.println(all.getText());
            /*
            *   Bread
                Milk
                Cheese
            * */
        }
    }
}

如果要取消选择任何元素,现在有四个选项:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.Select;

public class Demo4
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo.html");

        WebElement selectElement = webDriver.findElement(By.id("selectElementID"));
        Select selectObject = new Select(selectElement);
        
        //1,根据下标删除
        selectObject.deselectByIndex(1);
        //2,根据值属性删除
        selectObject.deselectByValue("value1");
        //3,根据text删除
        selectObject.deselectByVisibleText("Bread");
        //4,删除所有
        selectObject.deselectAll();
    }
}

最后,一些<select>元素允许你选择多个选项。可以通过使用以下命令确定你的<select>元素是否允许多选

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.Select;

public class Demo5
{
    public static void main(String[] args)
    {
        WebDriver webDriver = new EdgeDriver();
        webDriver.get("XXX\\demo.html");

        WebElement selectElement = webDriver.findElement(By.id("selectElementID"));
        Select selectObject = new Select(selectElement);

        boolean doesThisAllowMultipleSelections = selectObject.isMultiple();
        System.out.println(doesThisAllowMultipleSelections);//false
    }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。