文档帮助

术语、图标和标签

许多类在使用配置对象创建(实例化)类时都有快捷名称。快捷名称被称为 alias(如果类扩展了 Ext.Component,则称为 xtype)。别名/xtype 列在适用类的类名旁边,以便快速参考。

访问级别

框架类或其成员可以指定为 privateprotected。否则,类/成员为 publicPublicprotectedprivate 是访问描述符,用于传达应如何以及何时使用类或类成员。

成员类型

成员语法

下面是一个示例类成员,我们可以对其进行剖析,以展示类成员的语法(在本例中是从 Ext.button.Button 类查看的 lookupComponent 方法)。

让我们看一下成员行的每个部分

  • 展开/折叠 - 在成员行的左侧是一个控件,用于展开和折叠每个成员行以显示/隐藏成员详细信息。
  • 成员名称 - 类成员的名称(本例中为 lookupComponent
  • 方法参数 - 方法使用的任何必需或可选参数(或传递给事件处理程序方法的参数)将列在方法名称旁边的括号内(本例中为 ( item )
  • 返回类型 - 方法或属性返回的类实例或 javascript 对象(本例中为 Ext.Component)。对于不返回除 undefined 之外任何内容的方法,可以省略此项,或者可以显示为以斜杠 / 分隔的多个可能值,表示返回的内容可能取决于方法调用的结果(即,如果 get 方法调用成功,方法可能返回 Component,如果失败,则返回 false,这将显示为 Ext.Component/Boolean)。
  • 标志 - 适用于成员的任何标志都将显示在接下来(本例中为 PROTECTED - 请参阅下面的标志部分)
  • 成员来源 - 在成员行的右侧是最初描述成员的类(本例中为 Ext.container.Container)。如果成员源自当前类,则源类将显示为蓝色链接,如果它从祖先类或混合类继承,则显示为灰色。
  • 成员源代码 - 在成员来源类的右侧下方是一个链接,用于查看成员的源代码(示例中的 view source
  • 参数列表 - 类方法的每个参数都将使用与上面括号中找到的名称相同的名称、期望的类或对象类型以及参数的描述列出(示例中为 item : Object)。
  • 返回值 - 如果类返回除 undefined 之外的值,则“返回值”部分将注释返回的类或对象类型以及描述(示例中为 Ext.Component
  • Since示例中未显示) - 某些成员将显示该成员首次引入的产品版本(即 Available since 3.4.0 - 示例中未显示),紧跟在成员描述之后
  • Default示例中未显示) - Configs 通常显示要应用于类实例的默认配置值(如果未被覆盖)(即 Defaults to: false

成员标志

API 文档使用许多标志来进一步传达类成员的功能和意图。标签可以用文本标签、缩写或图标表示。

  • Required - 实例化类时必需的配置
  • Bindable - 配置有一个 setter,允许通过 ViewModel 绑定设置此配置
  • Read Only - 该属性可以读取,但不能用于在运行时配置/重新配置类实例
  • Singleton - Singleton 类在定义后立即实例化,不能手动实例化
  • Static - 静态方法或属性是属于类本身的方法或属性,而不是类的实例
  • Chainable - 指的是在调用时返回类实例的方法。
    这使得可以进行链式方法调用,如:classInstance.method1().method2().etc();
  • Deprecated - 计划在未来框架版本中删除的类或成员,并在当前版本中提供以实现向后兼容性。
    Deprecated 类和成员将有一条消息,指导您使用首选的类/方法。
  • Removed - 已删除的类或成员,仅在文档中作为在框架版本之间升级的用户的参考而存在
  • Template - 在基类中定义的方法,旨在被子类覆盖
  • Abstract - 类或成员可以定义为抽象的。抽象类和成员建立类结构并提供有限的(如果有)代码。特定于类的代码将通过子类中的覆盖来提供。
  • Preventable - 如果事件处理程序返回 false,则标记为可阻止的事件将不会触发

类图标

- 表示框架类

- Singleton 框架类。*有关更多信息,请参阅 singleton 标志

- 组件类型框架类(Ext JS 框架中扩展 Ext.Component 的任何类)

- 表示类、成员或指南在当前查看的版本中是新的

成员图标

- 表示 config 类型的类成员

- 表示 property 类型的类成员

- 表示 method 类型的类成员

- 表示 event 类型的类成员

- 表示 theme variable 类型的类成员

- 表示 theme mixin 类型的类成员

- 表示类、成员或指南在当前查看的版本中是新的

类成员快速导航菜单

在 API 文档页面上的类名正下方是一行按钮,对应于当前类拥有的成员类型。每个按钮显示按类型划分的成员计数(此计数在应用过滤器时更新)。单击按钮会将您导航到该成员部分。将鼠标悬停在成员类型按钮上将显示该类型的所有成员的弹出菜单,以便快速导航。

Getter 和 Setter 方法

与类配置选项相关的 Getter 和 setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分中,紧挨着它们所作用的配置下方。Getter 和 setter 方法文档将在配置行中找到,以便于参考。

历史记录栏

您的页面历史记录保存在本地存储中,并在顶部标题栏下方显示(使用可用的实际空间)。默认情况下,显示的唯一搜索结果是与您当前查看的产品/版本匹配的页面。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选选项来扩展显示的内容。这将显示历史记录栏中所有产品/版本的所有最近页面。

在历史记录配置菜单中,您还将看到最近访问页面的列表。结果按“当前产品/版本”和“全部”单选选项进行筛选。单击 按钮将清除历史记录栏以及本地存储中保存的历史记录。

如果在历史记录配置菜单中选择了“全部”,则“在历史记录栏中显示产品详细信息”的复选框选项将被启用。选中后,每个历史页面的产品/版本将与页面名称一起显示在历史记录栏中。将光标悬停在历史记录栏中的页面名称上也会将产品/版本显示为工具提示。

搜索和过滤器

可以使用页面顶部的搜索字段搜索 API 文档和指南。

在 API 文档页面上,还有一个过滤器输入字段,用于使用过滤器字符串过滤成员行。除了按字符串过滤外,您还可以按访问级别、继承和只读过滤类成员。这是通过使用页面顶部的复选框完成的。

API 类导航树底部的复选框过滤类列表以包含或排除私有类。

单击空的搜索字段将显示您最近 10 次搜索,以便快速导航。

API 文档类元数据

每个 API 文档页面(Javascript 原始类型页面除外)都有一个与该类相关的元数据菜单视图。此元数据视图将具有以下一项或多项

  • Alternate Name - 一个或多个额外的类名同义词(在 Ext JS 6.0.0 中,Ext.button.Button 类具有 Ext.Button 的备用类名)。备用类名通常为了向后兼容性而维护。
  • Hierarchy - 层次结构视图列出了当前类的继承链,一直到其祖先类,直到根基类。
  • Mixins - 混合到当前类中的类列表
  • Inherited Mixins - 混合到当前类的祖先中的类列表
  • Requires - 实例化类所需定义的所有类
  • Uses - 类在其生命周期中的某些时候可能使用的类列表,但不一定是类最初实例化所必需的
  • Subclasses - 扩展当前类的类

展开和折叠示例和类成员

可运行的示例 (Fiddles) 默认在页面上展开。您可以使用代码块左上角的箭头单独折叠和展开示例代码块。您还可以使用页面右上角的切换按钮切换所有示例的折叠状态。切换所有状态将在页面加载之间记住。

类成员默认在页面上折叠。您可以使用成员行左侧的箭头图标或全局使用右上角的展开/折叠所有切换按钮来展开和折叠成员。

桌面 -vs- 移动视图

在较窄的屏幕或浏览器上查看文档将导致针对较小外形尺寸优化的视图。桌面视图和“移动”视图之间的主要区别在于

  • 全局导航将位于左侧菜单中,可通过汉堡菜单图标访问。菜单包含以下内容(在大多数页面上)
    • 当前产品的名称(作为指向产品着陆页的链接)
    • 用于导航回文档主页的 Sencha 图标
    • 产品菜单下拉按钮
    • API 文档和指南的导航树选项卡
  • 当前上下文导航和工具位于右侧,可通过齿轮图标访问。上下文菜单包含以下内容
    • 全局搜索输入字段
    • (API 文档) “过滤器”选项卡,其中包含成员过滤器、展开/折叠所有示例按钮、展开/折叠所有成员行按钮、访问级别过滤器复选框以及每个成员的计数
    • (API 文档) “相关类”选项卡,其中包含与当前类相关的元数据菜单
    • (指南) 指南的目录

查看类源代码

可以通过单击 API 文档页面顶部的类名来查看类源代码。可以通过单击成员行右侧的“查看源代码”链接来查看类成员的源代码。

WebTestIt


顶部

Page Objects 结构化

“如果在您的测试方法中使用 WebDriver API,那么您就做错了。” - Simon Stewart

Selenium 项目的首席提交者 Simon Stewart 在他对 Selenium 的最初愿景中分享道,Page Objects 是 WebDriver 之上强制性的层。它们两者属于一起,Sencha WebTestIt 的创建就考虑到了这一事实。

为了高效地使用 Sencha WebTestIt,您必须理解 Page Object 模式。

什么是 Page Object?

Page Object 模式是封装的经典示例。它使用特定于应用程序的 API 封装了在 GUI 中查找和操作数据所需的机制。Page Object 的基本经验法则是,它应该允许软件客户端执行和查看人类可以做的任何事情。

尽管名称如此,但不要为每个页面都创建 Page Object。而是为页面上的重要组件创建它们,例如标题、菜单或内容区域。

示例

我们使用我们的 演示商店 作为如何派生 Page Objects 的示例。

我们可以将初始启动页面至少划分为三个 Page Objects

  1. HeaderPo:它可以在每个页面上找到,因此将其提取为 Page Object 是有意义的。
  2. ItemsOverviewPo:此组件包含所有可供销售的商品。
  3. ShoppingCartPo:此购物车摘要从标题中展开,但它包含足够的功能和元素,使其成为自己的 Page Object。

Page Object 操作

现在我们已经将页面划分为 Page Objects,让我们找出如何在测试中使用它们。

Page Object 模式的目的是将应用程序断言 APIWebDriver API 分开。这意味着,测试永远不应直接使用 HTML 元素或 WebDriver,而只应使用公开的(公共)方法,称为操作

这些操作封装了用户交互单元,例如“单击按钮”“登录”“提交表单”,内部使用 WebDriver API 和与 Page Object 关联的元素。

因此,在创建操作方法时,请记住以下最佳实践

  1. 永远不要直接返回元素,而是
    • 如果要使用基本类型的值(字符串、整数、日期等),请返回它们。
    • 当您只是对元素执行操作时,返回 Page Object 实例本身 (this)。
    • 返回另一个 Page Object 以指示上下文切换,例如在单击链接或提交表单后。
    • 这允许您将 Page Object 操作链接在一起,最终得到一个最终的返回值,然后您可以在断言中使用该值。
  2. 不要在 Page Objects 中使用断言,而是
    • 返回元素的相关属性,例如其文本。
    • 或者,将比较值作为参数传递,并返回布尔值。
    • 在测试文件中使用这些结果进行断言。
  3. 好的 Page Object 操作是可重用的,将它们想象成您测试的构建块。

示例

使用上面的 Page Objects,让我们构建一个简单的测试,使用我们刚刚学到的规则。测试应:1. 将一个商品添加到购物车,2. 转到购物车,以及 3. 断言总价是正确的。

注意

此示例使用 Java,但相同的原则适用于 TypeScript 项目。*

  1. 此操作发生在 ItemsOverviewPo 中,并将一个商品添加到购物车。仅将商品添加到购物车不应将我们导航到任何地方,您可能希望在其他测试中的 ItemsOverviewPo 中执行更多操作,因此我们返回 this

    public ItemsOverviewPo addItemToCart() {
        this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.addItemToCartButton)).click();
        return this;
    }
    
  2. 在同一个 Page Object 中,当您单击查看购物车按钮时,您希望进入购物车页面,因此您返回相应的 Page Object 类 CartPo 的新实例

    public CartPo viewCart() {
        this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.viewCartButton)).click();
        return new CartPo(this.driver);
    }
    
  3. 最后,您已准备好验证价格是否显示正确。不要将断言放入 Page Object 操作中。相反,创建一个返回包含总价的元素的文本的方法

    public String getTotalPrice() {
        String totalPriceText = this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.totalPrice)).getText();
        return totalPriceText;
    }
    

    现在您可以在测试中使用这些操作。请注意,由于在我们的操作中返回 Page Object 实例,您如何可以像这样链接操作方法,从而提高测试的可读性

    @Test
    public void checkTotalPrice() {
        // 1. Arrange
        WebDriver driver = getDriver();
        ItemsOverviewPo itemsOverviewPo = new ItemsOverviewPo(driver)
                .open("https://demoshop.webtestit.com");
    
        // 2. Act
        String totalPrice = itemsOverviewPo
                .addItemToCart()
                .viewCart()
                .getTotalPrice();
    
        // 3. Assert
        Assert.assertEquals(totalPrice, "€1,500.00");
    }
    

结论

阅读本文后,您已经了解了 Page Object 模式、如何将复杂的网站划分为各个 Page Objects,以及如何使用最佳实践来构建您的 Page Object 操作。

如果您想了解有关 Page Objects 的更多信息,请务必阅读 Martin Fowler 关于 PageObjects 的文章

WebTestIt