记录自己看selenium源码的一些收获

记录自己看selenium源码的一些收获,第1张

在第一篇文章中,成功用的Postman模拟了打开了一个百度地址,这章主要是记录Selenium中我们最常基础方法了 - 定位元素。


我们可以看到selenium-api下By这个类当中 包含了常用的寻元素内部静态类,这些内部类都满足

  1. 继承与By这个类,
  2. 实现序列化的接口(没有过多研究,可以查看更多信息)

1.首先把几个基础的概念放在前面:

  • SearchContext:WebElement和WebDriver都实现了接口中的两个方法 findElement / findElements。
  • WebElement和WebDriver都需要实现以下的接口,他们的寻找元素的方法会不一样,

  • WebElement中的寻元素方法命令的类型是 FIND_CHILD_ELEMENT 而不是FIND_ELEMENT,同时接口的地址也会不一样(需要带上element的id)

2.接下来我们debug WebElement e = c.findElement(By.id("kw")); 这行代码,可以看到它的调用的顺序

 以下是具体的调用顺序:

  
// 调用WebDriver中的findElement方法
public WebElement findElement(By by) {
    return by.findElement(this);
  }

// 调用ById.findElement的方法, context是Webdriver,那么调用
    @Override
    public WebElement findElement(SearchContext context) {
// 因为webDriver实现了FindsById接口,所以调用webDriver.findElementById方法
      if (context instanceof FindsById)
        return ((FindsById) context).findElementById(id);
      return ((FindsByXPath) context).findElementByXPath(".//*[@id = '" + id
          + "']");
    }

// 调用webDriver.findElementById
  public WebElement findElementById(String using) {
    return findElement("id", using);// 此处的字符串id 在后面的request封装时要用
  }

//调用webDriver中的findElement方法
  protected WebElement findElement(String by, String using) {
    if (using == null) {
      throw new IllegalArgumentException("Cannot find elements when the selector is null.");
    }
// 这行代码将command和附带的参数转换成httprequest 并返回一个WebElement对象
    Response response = execute(DriverCommand.FIND_ELEMENT,
        ImmutableMap.of("using", by, "value", using));
    Object value = response.getValue();
    WebElement element;
    try {
      element = (WebElement) value;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to WebElement: " + value, ex);
    }
    setFoundBy(this, element, by, using);
    return element;
  }


3.通过日志查询我们可以看到返回的内容

4.其他寻元素方法也是同理,只是在execute的时候封装了不同的json格式的数据 放在request里面。

至于RemoteWebElement中的findElement方法,其实只是在uri中加了一个元素的id(用于限制寻元素的范围。

  public WebElement findElement(By by) {
    return by.findElement(this);
  }

  protected WebElement findElement(String using, String value) {
// 需要加上id这个属性(也就是我们在找到一个元素时 他们返回的元素ID标识
    Response response = execute(DriverCommand.FIND_CHILD_ELEMENT,
                                ImmutableMap.of("id", id, "using", using, "value", value));

    Object responseValue = response.getValue();
    WebElement element;
    try {
      element = (WebElement) responseValue;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to WebElement: " + value, ex);
    }
    parent.setFoundBy(this, element, using, value);
    return element;
  }
总结: 
  • 所有的寻元素的 *** 作都是通过封装成request并且到这个接口。

  • 我们可以看到 locator 的策略只有5种,其中ById ByClassName ByName其实在实质上都是使用的css selectors 策略,只是selenium会帮我们转化成css 选择器的格式,比如用id kw找元素时,会变成#kw 
  •  FindElements 和FindElement的原理相同,只是接口不同,不再赘述

  • Command和接口地址对应除了看官方文档也可以查看包中这个类,里面定义了接口的方法,地址,占位符等信息。WebDriverhttps://www.w3.org/TR/webdriver1/

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/739451.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存