使用 Selenium IDE 脚本进行浏览器测试

Selenium IDE脚本测试是 Instana 合成浏览器脚本测试的一种类型。

使用 Selenium IDE 脚本 (也称为辅助脚本) 来模拟用户与 Web 应用程序的交互。

建议您从一个简单的 Selenium IDE脚本开始,具体方法请参阅 “录制 Selenium IDE脚本 ”一节,或者使用示例脚本 Selenium

然后,您可以使用 Instana Synthetic提供的先进功能,例如访问用户凭据、截屏等,具体方法请参阅《 在 Selenium IDE脚本中扩展测试功能 》一文。 如果您想使用 Instana 提供的全局变量(例如) $secure扩展的浏览器测试API (例如 await $browser.takeScreenshot()),可以使用 Instana 的Synthetic-browser-script 本地运行器。 借助此本地运行程序,您可以在本地测试和调试 Selenium IDE脚本,因为 Selenium IDE无法识别这些高级API,也无法在每次测试运行时为您清除Cookie或会话。

录制 Selenium IDE脚本

录制基本脚本

  1. 下载并安装 Selenium 集成开发环境(IDE)。

    Firefox 和Chrome用户可以下载并安装 Selenium 集成开发环境(IDE)。

    • 对于 Firefox 用户,请在浏览器中安装 Firefox 扩展程序。 然后,根据需要重新启动浏览器。

    • 对于 Chrome 用户,请执行以下任一操作:

      注意:Selenium IDE 的 Chrome 扩展程序已不在 Chrome 应用商店中提供。
      • 使用命令行或命令提示符安装 Selenium 集成开发环境。

        npm install -g selenium-ide
        selenium-ide
         

        有关安装说明的更多信息,请参阅 readme 文件

      • 请根据您的操作系统,从 Selenium IDE GitHub 下载 IDE 版本,并在本地运行该应用程序。

        注意:Selenium IDE 应用程序将项目保存为 3.0 格式,而 Synthetic PoP BrowserScript 的播放引擎目前尚不支持该格式。

        为确保兼容性,您必须手动 .side 将文件中的版本号从 3.0 更改为 2.0。

        在 Selenium IDE应用程序中保存项目后,若要手动编辑该 .side 文件,请执行以下步骤:

        1. 在文本编辑器中打开该 .side 文件。

        2. 在文件中找到“版本”字段。 以下示例展示了“版本”字段的外观:

              {
                  "id": "some-id",
                  "version": "3.0",
                    ...
              }
           
        3. 将版本号更改为 2.0。

        4. 保存文件。

  2. 从菜单栏打开 Selenium IDE。 单击 Record a new test in a new project 链接,然后按照指示信息记录脚本。

    在 Selenium IDE 进行记录时,其在脚本中为每个用户操作生成一条命令。

    Selenium

  3. 执行测试操作,在 Google 中搜索 instana 关键字。

    Enter 进入搜索结果页面。 在此页面添加 wait 条件;右键单击搜索图标并选择 Selenium IDE -> Wait For -> Present。 在 Value 属性中输入等待元素显示的超时值,例如 10000 最多可等待 10 秒。

    Selenium

  4. 添加验证测试的断言。 添加 assert 命令;右键单击页面并选择 Selenium IDE -> Assert -> Title

    完成录音后,单击 Selenium IDE 中的 Stop recording 按钮。

    Selenium

  5. 您可以添加指令,如 send keys${KEY_ENTER} 的值,以便在搜索文本区域键入 Enter

    wait for element present 命令的 Value 属性中提供一个超时值,如 10000 以等待条件。 使用与上一步相同的 Target 值来定位搜索文本区域网络元素。 这是确保测试稳定成功运行的重要步骤。 这在浏览器测试领域被称为 显式等待。 在继续执行代码中的下一条命令之前,逻辑会对应用程序的特定条件进行轮询。 如果在指定的超时值之前未满足条件,则会显示超时错误。

    然后测试您的脚本,点击 run

    Selenium

  6. 记录后,将脚本保存到 .side 文件中。

    Selenium

如需更多信息,请参阅 Selenium IDE 入门指南。 完整示例见下节。

建议使用 Instana 中的“合成浏览器脚本 ”本地运行器,在本地测试和调试录制的脚本。 Synthetic-browser-script 本地运行器提供与 Instana Synthetics 相同的运行环境,并可帮助您在每次测试运行前清除 Cookie 或用户配置文件。

然后,您可以在 Instana 上创建一个 .sideSelenium IDE 测试,选择 Create Synthetic Test -> Browser Script Test -> Switch to Advanced Mode,点击 Add Script,并上传 文件。

  • 如果您在 Instana 的测试结果中无法看到时间轴图表。 您可以检查测试 ID 是否在 suites -> tests 属性中。 没有该测试 ID,您的测试将无法执行回放。

    "suites": [{
        "id": "7de135e9-a6c4-4b39-b28a-092bb0d7cbac",
        "name": "Search Instana",
        "persistSession": false,
        "parallel": false,
        "timeout": 300,
        "tests": ["c0283e5a-8cbd-492f-8b3d-f2476f319264"]
    }],
     
  • Instana 仅支持测试套件中的序列化测试,因此 Selenium IDE脚本中的以下属性会被 Instana 浏览器回放引擎覆盖:

    • "persistSession": false
    • "parallel" :false

如何等待某个条件

  • 您可以使用可用的 显式等待命令,等待条件满足后再执行代码中的下一条命令。 显式等待是浏览器测试中的最佳实践。 如果在指定的超时值之前未满足指定条件,则会显示超时错误。 测试失败,提示错误。 最常用的 wait 命令是 wait for element present。 在 value 属性中输入超时值(毫秒)。

    {
        "id": "d13e50bd-f698-4a04-9420-701a21dcde8d",
        "comment": "",
        "command": "waitForElementPresent",
        "target": "id=searchform",
        "targets": [],
        "value": "10000"
    }
     
  • 您可以使用 pause 命令暂停几毫秒。 在下面的示例中,等待时间为 3 秒。

    {
        "id": "60135a5c-6aee-4b9b-86a5-d9d0fa41deb7",
        "comment": "",
        "command": "pause",
        "target": "3000",
        "targets": [],
        "value": ""
    }
     

如何验证测试结果

要自动验证测试结果,您可以使用断言和 Explicit Wait。 如果验证失败,测试结果状态将显示为失败。 您可以使用合成智能警报监控测试失败。

  • 您可以使用 wait for element presentassert element present 或其他 显式等待 命令,在指定超时前等待所需元素出现在用户界面上。 在 wait for 命令的 value 属性中设置超时值。 对于 assert 命令,超时值为 15 秒。
    {
        "id": "e9a3161a-de29-4557-bbf6-9950c1881425",
        "comment": "",
        "command": "assertElementPresent",
        "target": "linkText=About",
        "targets": [],
        "value": ""
    }
     
  • 您可以使用 assert title 命令来验证页面标题。
    {
        "id": "46eb59c2-5fd6-4481-b3e8-eaaddab79a69",
        "comment": "",
        "command": "assertTitle",
        "target": "instana - Google Search",
        "targets": [],
        "value": ""
    }
     
  • 您可以使用 assert text 命令来确认元素文本是否包含所提供的值。 该命令的 value 属性必须与字符串完全匹配。 Selenium IDE 不支持命令的模式匹配。
    {
        "id": "ed733875-5682-4a3b-9a3e-9286f88a62ca",
        "comment": "",
        "command": "assertText",
        "target": "linkText=About",
        "targets": [],
        "value": "About"
    }
     

如何在控制台日志中打印消息

您可以使用 echo 命令在控制台日志中打印日志信息,以帮助您排除故障。

{
    "id": "03e23d25-38e3-4051-81ff-740109350ee8",
    "comment": "",
    "command": "echo",
    "target": "Generate a TOTP token from a TOTP key",
    "targets": [],
    "value": ""
}
 

如何使用 JavaScript 向下滚动

大多数测试用例都需要在页面上滚动,使网页元素成为焦点、可见或可点击。 在 Selenium IDE 脚本中,需要使用 JavaScript 进行滚动。 使用 runScriptexecuteScript 命令实现滚动,如下例所示:

  • 滚动到页面高度的一半:

    {
        "id": "e4d8bc94-cd2c-4648-b64e-952ccfa89aaa",
        "comment": "",
        "command": "runScript",
        "target": "window.scrollTo(0, document.body.scrollHeight/2)",
        "targets": [],
        "value": ""
    }
     
  • 滚动到页面末尾:

    {
        "id": "e4d8bc94-cd2c-4648-b64e-952ccfa89aaa",
        "comment": "",
        "command": "runScript",
        "target": "window.scrollTo(0, document.body.scrollHeight)",
        "targets": [],
        "value": ""
    }
     
  • 滚动到页面开头:

    {
        "id": "e4d8bc94-cd2c-4648-b64e-952ccfa89aaa",
        "comment": "",
        "command": "runScript",
        "target": "window.scrollTo(0, 0)",
        "targets": [],
        "value": ""
    }
     
  • 滚动到网页元素并点击它:

    直到找到该元素,然后滚动到该元素并单击它。

    {
        "id": "d13e50bd-f698-4a04-9420-701a21dcde8d",
        "comment": "",
        "command": "waitForElementPresent",
        "target": "id=pnnext",
        "targets": [],
        "value": "20000"
    },
    {
        "id": "b345d354-1d95-45d0-81ab-7c78695ed040",
        "comment": "",
        "command": "runScript",
        "target": "const el = document.getElementById('pnnext'); el.scrollIntoView(); el.click();",
        "targets": [],
        "value": ""
    }
     
    {
        "id": "d13e50bd-f698-4a04-9420-701a21dcde8d",
        "comment": "",
        "command": "waitForElementPresent",
        "target": "css=#pnnext > span:nth-child(2)",
        "targets": [],
        "value": "20000"
    },
    {
        "id": "b345d354-1d95-45d0-81ab-7c78695ed040",
        "comment": "",
        "command": "runScript",
        "target": "const el = document.querySelector('#pnnext > span:nth-child(2)'); el.scrollIntoView(); el.click();",
        "targets": [],
        "value": ""
    }
     

如何发送密钥

  • 要双击过滤器区域并键入按键,可以使用下面的示例:
    {
        "id": "60135a5c-6aee-4b9b-86a5-d9d0fa41deb1",
        "comment": "",
        "command": "doubleClickAt",
        "target": "id=repos-list-filter-input",
        "targets": [],
        "value": ""
    }, {
        "id": "60135a5c-6aee-4b9b-86a5-d9d0fa41deb1",
        "comment": "",
        "command": "type",
        "target": "id=repos-list-filter-input",
        "targets": [],
        "value": "instana"
    }
     
  • 要在过滤器区域暂停 3 秒后键入 Enter 键,可以使用下面的示例:
    {
        "id": "60135a5c-6aee-4b9b-86a5-d9d0fa41deb2",
        "comment": "",
        "command": "pause",
        "target": "3000",
        "targets": [],
        "value": ""
    }, {
        "id": "d0239041-5bdf-42be-b920-c5055628f161",
        "comment": "",
        "command": "sendKeys",
        "target": "id=repos-list-filter-input",
        "targets": [],
        "value": "${KEY_ENTER}"
    },
     

示例

在下面的示例中,使用 Selenium IDE脚本在搜索引擎中搜索 Instana 等关键词:

{
  "id": "d54cb226-42e2-493a-9965-c05d209da23a",
  "version": "2.0",
  "name": "test-google-search",
  "url": "https://www.google.com",
  "tests": [{
    "id": "c0283e5a-8cbd-492f-8b3d-f2476f319264",
    "name": "search instana",
    "commands": [{
      "id": "cd6aaf21-62f8-4d7f-af0a-5fe8beee8fde",
      "comment": "",
      "command": "open",
      "target": "/",
      "targets": [],
      "value": ""
    }, {
      "id": "f6ef14b9-0f06-4b62-bb29-41c21a298703",
      "comment": "",
      "command": "click",
      "target": "id=APjFqb",
      "targets": [],
      "value": ""
    }, {
      "id": "ed0b72f9-8da9-4413-8088-819b89f1f6dc",
      "comment": "",
      "command": "type",
      "target": "id=APjFqb",
      "targets": [],
      "value": "instana"
    }, {
      "id": "f9746499-1d97-4f83-aa8a-a5419d9e3922",
      "comment": "",
      "command": "sendKeys",
      "target": "id=APjFqb",
      "targets": [],
      "value": "${KEY_ENTER}"
    }, {
      "id": "93939f21-739f-4c84-bb2e-580af6b1bc76",
      "comment": "",
      "command": "waitForElementPresent",
      "target": "css=.zgAlFc svg",
      "targets": [],
      "value": "10000"
    }, {
      "id": "331e3fc1-9baa-4519-9814-3105d6d06937",
      "comment": "",
      "command": "assertTitle",
      "target": "instana - Google Search",
      "targets": [],
      "value": ""
    }]
  }],
  "suites": [{
    "id": "7de135e9-a6c4-4b39-b28a-092bb0d7cbac",
    "name": "Search Instana",
    "persistSession": false,
    "parallel": false,
    "timeout": 300,
    "tests": ["c0283e5a-8cbd-492f-8b3d-f2476f319264"]
  }],
  "urls": ["https://www.google.com/"],
  "plugins": []
}
 

扩展 Selenium IDE脚本的测试功能

Instana 合成浏览器测试比 Selenium IDE 提供更多功能:

  • Instana Synthetic 提供详尽的测试结果,其中包括时间轴图表、 HTTP 归档格式(HAR)文件、屏幕截图、录屏、浏览器日志和控制台日志。

  • Instana Synthetic 提供了更先进的浏览器测试 API 和全局变量。

如果您希望利用 Instana Synthetic 提供的先进浏览器测试 API 和全局变量来修改您的 Selenium IDE 脚本,请参考以下示例。 由于 Selenium IDE无法支持这些高级功能,您需要使用Synthetic-browser-script本地运行器来测试和调试您的脚本。

如何获取用户凭据

  • 访问在 Instana 后端服务器中定义的用户凭据

    要使用 Synthetic Open API 创建凭证,请完成以下步骤:

    1. 请确保您的权限设置正确。
    2. 使用 ` OpenAPI ` 通过传递 `` credentialName 和 `` credentialValue 变量来创建凭据。

    然后,在测试脚本中使用 $secure.credentialName 引用已创建的凭据,例如 $secure.password$secure.username 。 Selenium IDE 脚本中 ${} 属性中的 Value 是指预定义变量,以区别于常量字符串。 $secure.credentialName 如何在 Instana 中访问用户凭据。 硒

    注意: 仅支持 $secure.credentialName 格式。 不支持此 $secure[credentialName] 格式。
    注意: 安全凭据引用 ($secure.credentialName) 将在脚本执行前进行解析。 您必须直接指定凭据名称。 请勿使用变量、字符串拼接或 eval()等方式动态构建引用,因为这些方法不受支持且不会被评估。
    {
        "id": "98b7df8f-ec53-47f9-b7a0-0eedbfc64ff0",
        "comment": "",
        "command": "click",
        "target": "id=email",
        "targets": [],
        "value": ""
    }, {
        "id": "83ae509f-4247-4acc-ab99-46ef4c620f4f",
        "comment": "",
        "command": "type",
        "target": "id=email",
        "targets": [],
        "value": "${$secure.username}"
    }
     
  • 使用密钥生成基于时间的一次性密码 (TOTP),以便使用双因素身份验证(2FA)登录网站。

    {
        "id": "ec51296b-4d16-4167-ac83-ba87f89cc0c7",
        "comment": "Generate a TOTP token from a TOTP key",
        "command": "executeScript",
        "target": "return $browser.generateTOTPToken($secure.totpKey);",
        "targets": [],
        "value": "totpToken"
    }, {
        "id": "3cbc306a-ed33-46bf-9923-92752b0466f2",
        "comment": "",
        "command": "type",
        "target": "id=password",
        "targets": [],
        "value": "${totpToken}"
    }
     

如何截屏

您可以在 Instana 的测试结果详情页面上查看这些截图。

{
    "id": "b49ff289-f041-44f1-836b-ba7e993c3f07",
    "comment": "",
    "command": "executeScript",
    "target": "await $browser.takeScreenshot()",
    "targets": [],
    "value": ""
}
 

如何使用 $synthetic 来访问全局变量

您可以使用 $synthetic.xxxx$secure.xxx$env.xxx 访问全局变量,如下例所示。

要在 JavaScript 的模板字符串语法中使用变量(例如` echo command`),请使用标准的 Node.js 语法,并将变量放入``中 ${}

{
    "id": "da853ea2-7253-4938-ad2d-9272f4c6d3e2",
    "comment": "",
    "command": "echo",
    "target": "tag1's value is ${$synthetic.tag1}",
    "targets": [],
    "value": ""
}
 

如何使用 $attributesAPI 自定义属性

{
    "id": "26438c58-868d-4d6d-9e6f-dbe9d8f373fd",
    "comment": "",
    "command": "executeScript",
    "target": "$attributes.set('regionName', 'green-region');",
    "targets": [],
    "value": ""
}
 

在脚本中由 $attributesAPI 设置的自定义属性,以及在测试定义 customProperties 中由 定义的自定义属性,均可通过 指标 synthetic.tags 在测试结果中访问。 您可以使用该 synthetic.tags 指标来筛选测试结果,或向 “智能警报”自定义负载传递自定义值。 硒

如何调用 Instana 的高级浏览器测试API

  • 使用 Selenium 命令 runScriptexecuteScript 来调用高级浏览器测试 API。

    您可以使用 Selenium 命令 runScriptexecuteScript 来调用 Instana 浏览器测试中的预定义浏览器测试API和全局变量

    executeScriptrunScript 之间的区别在于, executeScript 支持将返回的值存储在变量中。 然后,可以使用 ${xxx} assertecho 变量。 要存储返回值,请使用 return 关键字,并在 value 输入字段中提供一个变量名。

    {
        "id": "ec51296b-4d16-4167-ac83-ba87f89cc0c7",
        "comment": "Generate a TOTP token from a TOTP key",
        "command": "executeScript",
        "target": "return $browser.generateTOTPToken($secure.totpKey);",
        "targets": [],
        "value": "totpToken"
    }, {
        "id": "3cbc306a-ed33-46bf-9923-92752b0466f2",
        "comment": "",
        "command": "echo",
        "target": "Generated TOTO token ${totpToken}",
        "targets": [],
        "value": ""
    }
     
  • 定义环境变量,并在浏览器测试 API 中使用该环境变量。

    {
        "id": "10d09a25-d101-43b0-84df-f22265b7cec6",
        "comment": "",
        "command": "storeJson",
        "target": "{\"proxy\": \"<proxy_server>:8080\", \"noproxy\": \"localhost,google.com,192.168.1.0/24\"}",
        "targets": [],
        "value": "proxyConfig"
    },
    {
        "id": "237bd334-d963-4a73-b9bb-4c31f1dce051",
        "comment": "",
        "command": "runScript",
        "target": "await $browser.setProxy(${proxyConfig.proxy}, ${proxyConfig.noproxy});",
        "targets": [],
        "value": ""
    }
     
  • 滚动到网页元素,然后点击它。

    您可以使用 Instana 浏览器测试工具 API 轻松实现上述滚动操作。 下面的示例实现了 waiting for element presentwaiting for element visiblescrollIntoViewclick 元素的逻辑。 scrollIntoView 函数可以将元素滚动到浏览器窗口的可见区域。

    {
        "id": "b345d354-1d95-45d0-81ab-7c78695ed040",
        "comment": "",
        "command": "runScript",
        "target": "let element = await $browser.waitForAndFindElement(By.xpath(`//a[contains(.,'Customer stories')]`), 30000); await $browser.executeScript(`arguments[0].scrollIntoView()`, element); await $browser.executeScript(`arguments[0].click()`, element)",
        "targets": [],
        "value": ""
    }
     

如何拒绝某些请求

{
    "id": "2e91846e-037b-473d-a977-7fbdfe52d1a4",
    "comment": "",
    "command": "executeScript",
    "target": "await $browser.addHostnamesToDenylist(['ajax.googleapis.com/ajax/libs/jquery']);",
    "targets": [],
    "value": ""
}
 

如何使用 $networkAPI 设置代理

{
    "id": "a418460e-a0a9-4c68-bbd0-fb78d6495e92",
    "comment": "",
    "command": "runScript",
    "target": "await $network.setProxy(${proxyConfig.proxy}, ${proxyConfig.noproxy});",
    "targets": [],
    "value": ""
}