用于 Maestro UI 测试工具的 Swift DSL。

入门项目

如果您已在默认位置安装了 Maestro,则可以打开 StarterProject 并点击运行。一旦您信任了宏并再次点击运行,您应该会看到模拟器启动并在联系人应用中开始添加联系人。

基本用法

导入 MaestroDSL 包,并声明对 MaestroDSLMaestroDSLMacro 的依赖(有关示例,请参阅 StarterProject/Package.swift)。

现在您可以使用顶层 maestroRun 命令来构建要执行的流程。一个向联系人应用添加联系人的流程可能如下所示

import MaestroDSL

try! maestroRun("com.apple.MobileAddressBook") {
    LaunchApp("com.apple.MobileAddressBook")
    
    TapOn(.text("Add"))
    
    TapOn(.id("First name"))
    Input("John")
    
    TapOn(.id("Last name"))
    Input("Appleseed")
    
    TapOn(.text("Done"))
}

提示

为了找到用于选择元素的 selectors,您可以运行 maestro studio 并点击浏览您的应用。

页面对象

在 UI 测试中,通常会引入页面对象来共享逻辑并隐藏了解 selectors id 的细节。在上面的示例中,知道 AddDone 按钮没有 id,而是需要通过 text 查找,并且文本字段具有 id,这是我们想要共享而不是重复的知识。您可以通过创建 @Page 来表示不同的屏幕来实现这一点。对于联系人应用,我们有两个屏幕 - HomePageEditFormPage,所以让我们创建这些页面对象

import MaestroDSL
import MaestroDSLMacro

@Page
struct HomePage {
    @FlowBuilder<HomePage>
    func tapAdd() -> Flow<HomePage> {
        TapOn(.text("Add"))
    }
}

EditFormPage 也类似

import MaestroDSL
import MaestroDSLMacro

@Page
struct EditFormPage {
    @FlowBuilder<EditFormPage>
    func setFirstName(_ name: String) -> Flow<EditFormPage> {
        TapOn(.id("First name"))
        Input(name)
    }

    @FlowBuilder<EditFormPage>
    func setLastName(_ name: String) -> Flow<EditFormPage> {
        TapOn(.id("Last name"))
        Input(name)
    }

    @FlowBuilder<EditFormPage>
    func tapDone() -> Flow<EditFormPage> {
        TapOn(.text("Done"))
    }
}

有了这些,现在的原始流程就可以在不提及标识符的情况下表达出来

import MaestroDSL

try! maestroRun("com.apple.MobileAddressBook") {
    LaunchApp("com.apple.MobileAddressBook")
    
    HomePage {
        $0.tapAdd()
        
        EditFormPage {
            $0.setFirstName("John")
            $0.setLastName("Appleseed")
            $0.tapDone()
        }
    }
}

致谢

最初的想法来自与 @adamcarter93@ebent@saadzulqarnain-at 的集体讨论