常见问题及解答
在哪里可以找到浏览器测试示例
为什么测试超时设置没有生效
创建浏览器测试时,您可以设置超时值,以确保如果执行时间超过指定时长,测试将失败。 但是,超时设置仅在该值小于默认值 BROWSERSCRIPT_TIMEOUT(默认值为 5 分钟)时才生效。 
为什么在 Selenium 上录制的脚本可能无法在 Instana 上成功运行
Selenium 如果在您的网页浏览器中存在Cookie和浏览历史记录,录制的测试在 Instana 上可能会失败,因为网站上可能无法显示“接受Cookie”等弹出窗口。 为避免此问题,请在创建测试脚本后,使用 Instana Synthetic-browser-script 本地运行器在本地测试您的脚本。
借助 Instana 的合成浏览器脚本 ,您可以执行以下任务:
- 自动清除用户配置文件:尽管您可以使用 Selenium IDE插件在本地成功运行脚本,但由于弹出窗口的原因,这些脚本在 Instana 上可能会失败。 您需要先关闭弹出窗口,然后再执行操作。 通过使用 Synsynthetic-browser-script 本地运行器,将自动清除用户概要文件。 您无需手动从浏览器中清除 cookie。
- 测试 Instana 扩展的浏览器测试 API:如果您想使用 Instana 扩展的浏览器测试 API ,可以使用 Synthetic-browser-script 本地运行器进行测试。 Synthetic-browser-script 本地运行器的运行时与 Instana 上的 Synthetic 浏览器引擎相同。
Selenium IDE 是一款开源记录工具,用于生成 定位器,如 CSS 选择器、XPath、ID 等。 Selenium IDE 可帮助识别网页元素。 不过,它也有以下局限性:
- 要添加显式等待命令、滚动、阴影 DOM 访问等功能,还需要一些手工操作。
- 有时不会报告测试失败,如 元素未附加到页面文档、元素不可交互。 Selenium IDE 有时与脚本运行程序不兼容,这是一个已知问题。
使用由 Instana 提供的 Synthetic-browser-script 本地运行器,在本地测试您的脚本。 使用该工具,您可以看到完整的浏览器用户界面提示,并在测试脚本中执行您的操作,以帮助您调试和排除故障。 如果您有复杂的测试逻辑(例如循环),也可以尝试使用 Instana 上的合成浏览器脚本测试 ,网址为 JavaScript-based。 如何添加手动步骤以支持阴影 DOM 等,请参见本主题的其他章节。
如何解决 “元素不可点击 ”的错误
测试可能会失败,并显示下列其中一条错误消息:
is not clickable at point (285,436) because another element <li> obscures itFailed to execute command clickElement {} element not interactable.
要解决此问题,请移动鼠标以将焦点放在元素上。 您可以使用下列其中一种方法。
向下滚动查看并点击
要滚动以查看并单击,请使用以下 JavaScript 命令:
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);
对于 Selenium IDE 录制的脚本,您可以使用 runScript 或 executeScript 调用 Instana 的扩展 API,以使用相同的 JavaScript 代码:
{
"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": ""
},
对于 Selenium IDE 脚本,请使用本地运行器来回放或测试 Instana 中的高级 API。 例如, $browser.waitForAndFindElement 因为 Selenium 的IDE无法识别它们。 如果您仍想使用 Selenium IDE来运行或测试脚本,可以尝试以下示例中的 JavaScript 代码。 runScript 命令使用 document.querySelector,浏览器可以识别。 有关示例脚本,请参阅 “如何在Google 搜索结果中向下滚动并点击下一页”。
{
"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": ""
}
ActionChains
要移动到元素并单击,请使用 ActionChains:
let element = await $browser.waitForAndFindElement($driver.By.linkText(`Business to business (BtoB) activities`), 10000);
await $browser.actions().move({origin: element}).click().perform();
MouseOver 在 Selenium 的IDE脚本中
有关 Selenium IDE脚本中鼠标悬停功能的更多信息,请参阅 MouseOver 命令。
要在 Selenium IDE 脚本中使用 MouseOver :
{
"id": "2d5c6b52-d2d7-4592-8052-87572a09e58b",
"comment": "",
"command": "mouseOver",
"target": "xpath=//dds-megamenu-category-link[contains(.,'Bridge observability and automated resource management')]",
"targets": [],
"value": ""
},
将按以下代码中所示解析 MouseOver :
await driver.wait(until.elementLocated(By.xpath(`//dds-megamenu-category-link[contains(.,\'Bridge observability and automated resource management\')]`)), configuration.timeout);
await driver.findElement(By.xpath(`//dds-megamenu-category-link[contains(.,\'Bridge observability and automated resource management\')]`))
.then(element => {
return driver.actions({
bridge: true
}).move({
origin: element
}).perform();
});
合理的窗口大小
使用 Selenium IDE 录制脚本时,窗口的大小可能会不正常。 在 Instana 上运行测试时,可能会导致 not clickable at point 或 element not interactable 错误。
要解决这个问题,请尝试以下步骤之一:
- 删除
setWindowSize命令。 Instana 将调整窗口大小。 您的脚本仍可在 Selenium IDE上成功运行。 - 使用 JavaScript 代码设置最大窗口尺寸。 如以下示例所示,使用本地运行程序进行测试:
{
"id": "4f719a79-aa76-4dc8-a18b-7b46523ae0e6",
"comment": "",
"command": "executeScript",
"target": "await $browser.manage().window().maximize();",
"targets": [],
"value": ""
},
如何解决 StaleElementReferenceError 错误
您可能会遇到 StaleElementReferenceError: stale element reference: element is not attached to the page document 错误。 这是一个常见的 Selenium 错误。
当测试脚本引用了一个已不再附加于 DOM 的 Web 元素时,就会出现此错误。在使用 React 或 Vue 等框架的网页中,可能会发生这种情况。 要排除此问题,请参阅示例。
测试定位器能否识别唯一的网页元素
出现这个问题的原因可能是您的定位器会返回多个网页元素,而它无法识别唯一的元素。 定位器可以是 CSS 选择器、XPath、ID 等。 这是 Selenium IDE中属性 Target 中的表达式。 在下面的示例中,CSS 定位器 a[href*='/#/home'] span 返回了多个网页元素,这可能会因元素引用过时而导致测试失败。 要测试定位器,请在浏览器中输入,然后转到更多工具 > 网络开发工具。 一个好的定位器可以突出独特的网络元素。 如果像以下示例所示,出现多个匹配结果,您可以更新或更改定位器。 
要使用 Selenium IDE 选择不同的定位器,请单击 Target 属性。 无论网页元素的位置如何,都应考虑选择一个有意义的定位器。 一个优秀的定位器能够识别出独特的网页元素,无论窗口大小或用户界面位置如何调整。 
元素附加到 DOM 后再次定位该元素
您可以丢弃当前持有的引用并将其替换,可能的方法是在元素附加到 DOM 后再次定位它。
除第 1 项外,网络元素可能因以下任何原因而失效:
- 页面刷新
- DOM 更新
- 网页元素的位置已更改
发生 StaleElementReferenceError 的原因如下:
- HTML 网页上不再存在选定的交互网页元素。
- 选定的网络元素被完全销毁,然后重新创建。
带有 StaleElementReferenceError: 的示例代码
// retrieving an input HTML element from the page
let nameHtmlElement = await $browser.findElement(nameInputBy);
// setting a name in the input element
await nameHtmlElement.sendKeys("John");
// refreshing the page
await $browser.navigate().refresh()
// nameHtmlElement is now stale
// trying to set a new name, but this will throw a StaleElementReferenceException
await nameHtmlElement.sendKeys("Maria");
要解决这个问题,请尝试在使用前再次找到该元素。
// refreshing the page
await $browser.navigate().refresh()
nameHtmlElement = await $browser.findElement(nameInputBy);
await nameHtmlElement.sendKeys("Maria");
一些用户使用 try-catch-retry 解决方案。 您可以在 Instana 上使用重试策略。 如果将重试策略设置为重试两次,则测试失败时最多重试 2 次。 或者您可以搜索 StaleElementReferenceError 以查找浏览器测试领域的更多解决方案,从而在测试脚本代码中解决这个问题。
正在等待页面刷新
如果问题仍未解决,请尝试使用 pause 命令或 await $browser.sleep 等待几秒钟,直到页面或 iframe 刷新。 在定位元素并使用它们之前,请等待页面 "静止",以避免出现过时的元素引用问题。 适当延长 pause 处理时间并采用 InstanaRetry 策略,或许能避免此类问题。 要使用 InstanaRetry 策略,您可以在 Instana 的测试配置页面上设置重试次数,将其设为1或2。 随后,系统将最多运行三次测试,直到测试成功,然后才会将结果发送至 Instana 后端。
// wait 5 seconds OR wait until tab is visible
// click the tab
// wait 5 seconds OR wait until button is visible
// Click button
await $browser.sleep(5000);
{
"id": "75135e0f-5f38-4004-b0f2-fda657d73bb3",
"comment": "",
"command": "pause",
"target": "2000",
"targets": [],
"value": ""
},
在 GitHub 中搜索关键词的方法已在脚本示例中展示。
要解决此 stale element reference 错误,请使用 pause 和 waitForElementPresent 命令:
- 添加
pause命令,等待页面刷新后再切换标签页。 - 添加
waitForEelementPresent命令,等待建议列表出现后再在字段中输入字符。

如何验证测试结果
如何验证测试用例是否成功?
在浏览器测试字段中,使用 Assertions, Explicit WAIT 验证测试结果。 因此,您可以确保网页按预期加载和呈现。 借助 Instana 的浏览器测试功能,您还可以为测试运行生成截图,并查看控制台日志( Selenium 中录制脚本中的 Echo 命令)、浏览器日志以及时间轴图表。
以下命令可能会有所帮助:
{
"id": "938df959-9b65-4ae4-a2f5-59be6188ea5f",
"comment": "This is how to sleep for 5 seconds.",
"command": "pause",
"target": "5000",
"targets": [],
"value": ""
},
{
"id": "2d5c6b52-d2d7-4592-8052-87572a09e58b",
"comment": "This is how to take screenshot",
"command": "executeScript",
"target": "await $browser.takeScreenshot()",
"targets": [],
"value": ""
}
您还可以尝试执行以下断言命令:
{
"id": "46eb59c2-5fd6-4481-b3e8-eaaddab79a69",
"comment": "This is one type of Assertions in browser testing",
"command": "assertTitle",
"target": "instana - Google Search",
"targets": [],
"value": ""
}
如何在浏览器脚本测试中使用 "显式等待"(Explicit Wait)来验证您的测试,请参见下面的示例:
await $browser.waitForAndFindElement($driver.By.xpath(`//h1[contains(text(), 'Websites & mobile apps')]`), 30000)
await $browser.wait($driver.until.titleContains(`Websites – Websites & mobile apps`), 30000);
尝试在录制的侧边文件中添加以下命令:
{
"id": "615cb3e5-fe2a-4859-b0aa-9df52f22028f",
"comment": "This is Explicit Wait in browser testing",
"command": "waitForElementPresent",
"target": "id=mainmenu",
"targets": [],
"value": "30000"
},
{
"id": "03e23d25-38e3-4051-81ff-740109350ee8",
"comment": "This is how to add logging message in console logs",
"command": "echo",
"target": "Verify UI dashboard",
"targets": [],
"value": ""
}
如何切换到框架或iframe
如果 Web 站点使用框架,那么可能会迂到 no such element 错误。
要解决此问题,请使用 $browser.switchTo().frame(id: number | WebElement);切换到机架或 iframe。
要切换到 Instana 浏览器脚本测试的框架或iframe:
let frameElement = await $browser.waitForAndFindElement($driver.By.xpath('//*[contains(@id, "pop-frame")]'), 10000);
await $browser.switchTo().frame(frameElement);
如何查找网页元素
要查找 Web 元素,请参阅 Selenium 中关于定位策略的参考文档。
| 函数 | 描述 |
|---|---|
$browser.waitForAndFindElement($driver.By.id("boxyear"), 1000) |
按标识等待并查找元素,直到元素可见或达到超时值为止 |
$browser.findElements($driver.By.css('select')) |
使用 CSS 选择器在页面上搜索多个元素 |
$browser.findElement($driver.By.linkText("About")) |
通过 linkText 查找元素 |
$browser.findElement($driver.By.xpath('//input[@value='f']')) |
按 XPath 查找元素 |
CSS 选择器的格式为 By.css(element[attribute='attribute-value'])。
XPath 表达式的格式为 By.xpath("//element[@attribute='value']") 或 By.xpath("//*[@attribute='value']")。
要按属性 (例如 <a href="mysite.com"></a>) 查找元素,请运行:
// CSS selector
$driver.By.css(a[href*="example"] )
// XPath expression
$driver.By.xpath("//a[contains(@href,'Electronics')]")
$driver.By.xpath(`//dds-footer-nav-item[contains(.,'Developer education')]`)
要从 Selenium IDE 插件上的缺省定位器进行更改,请单击目标。

如何从下拉列表中选择一个项目
您可以使用 select 命令从下拉列表中选择一个元素。 使用 Value 属性,您可以从一系列选项中选择 label=、value=、id= 或 index= 值。 如果没有提供前缀,则使用 label 进行匹配。 使用 label、value 或 id 代替 index。 否则, Instana 与 Selenium IDE 之间的结果可能无法兼容。
下例显示了如何使用 select 命令在下拉列表中选择 June。 选择 June 选项的方法见第 3、4 和 5 行。 这些方法适用于 Selenium IDE和 Instana。
<select id="month" name="month" class="inline six" onchange="document.cf.typ[1].checked=true">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8" selected="">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>

如何解决 “没有此元素 ”的错误
显式等待是 Selenium 中广为人知的一条最佳实践,旨在避免错误 no such element 并减少等待或休眠时间。 与隐式等待和 $browser.sleep相比,显式等待是首选。
要在 Instana 上使用显式等待,请按照以下示例所示执行命令:
// wait until the title comes out
await $browser.wait($driver.until.titleContains('Year 2023 Calendar'), 10000);
// Call the wait function.
await $browser.wait(function () {
return $browser.getTitle().then(function (title) {
return title.includes("Google");
});
}, 10000);
await $browser.wait(async function () {
const title = await $browser.getTitle();
return title.includes("Google");
}, 10000);
// waitForAndFindElement API
const cookies = await $browser.waitForAndFindElement(
$driver.By.id(`truste-consent-button`),
30000
);
await cookies.click();
在 Selenium IDE 脚本中,可以使用 WAIT 命令,如下例所示。 输入 value 属性的等待时间(毫秒)。
{
"id": "d13e50bd-f698-4a04-9420-701a21dcde8d",
"comment": "",
"command": "waitForElementPresent",
"target": "id=result-stats",
"targets": [
["id=result-stats", "id"],
["css=#result-stats", "css:finder"],
["xpath=//div[@id='result-stats']", "xpath:attributes"],
["xpath=//div[@id='slim_appbar']/div/div", "xpath:idRelative"],
["xpath=//div[7]/div/div/div/div/div", "xpath:position"]
],
"value": "10000"
}
如何使用 Selenium IDE脚本截屏
要调用 Instana 的扩展 API ,请在 Selenium IDE 中运行 或 runScriptexecuteScript 命令。
{
"id": "e781c454-0080-447a-b905-7183443956f3",
"comment": "",
"command": "runScript",
"target": "await $browser.takeScreenshot()",
"targets": [],
"value": ""
}
如何在合成浏览器测试中处理下拉列表
使用 findElement 选择下拉列表中的项,然后单击。
<select id="month" name="month" >
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
...
</select>
// find element by css or xpath
await $browser.findElement($driver.By.css(`#month > option:nth-child(3)`)).click();
await $browser.findElement($driver.By.xpath(`//select[@id='month']/option[3]`)).click();
// wait until element located and do assertion
await $browser.wait($driver.until.elementLocated($driver.By.id("month")), 3000).click();
assert.equal(5, await $browser.findElement($driver.By.id("month")).getAttribute("value"));
await $browser.findElement($driver.By.xpath("//select[@id='month']/option[3]")).click();
assert.equal(3, await $browser.findElement($driver.By.id("month")).getAttribute("value"));
如何处理 Shadow DOM 元素
要测试影子 DOM 元素,请使用 getShadowRoot() 函数。
getShadowRoot() 功能支持 Instana、Synthetic PoP、 Helm、chart 1.1.1 或更高版本。 您必须将 Synthetic PoP 升级至 1.1.1 或更高版本,才能使用 Shadow DOM 交互功能。要使用 getShadowRoot() 函数,请运行以下命令:
let shadowHost = await $browser.waitForAndFindElement(shadowHostSelector, timeout);
let shadowRoot = await shadowHost.getShadowRoot();
let element = await shadowRoot.findElement(elementSelector);
console.log("element text is:", await element.getText(), ", id is:", await element.getId());
或者在 Selenium IDE 中使用 Instana 的高级 API 录制脚本,并使用本地运行器进行测试:
{
"id": "4f602785-2a19-4b5f-a23c-7ae6f6e58d5d",
"comment": "",
"command": "executeScript",
"target": "let shadowHost = await $browser.waitForAndFindElement($driver.By.css(`.field > q2-input`), 10000); let shadowRoot = await shadowHost.getShadowRoot(); let element = await shadowRoot.findElement($driver.By.css(`*[type='text']`)); await element.sendKeys(`user1`); ",
"targets": [],
"value": ""
},
如何通过部分匹配验证页面上的文本
要验证页面上具有部分匹配的文本,您可以通过 XPath 使用 findElement 。
在浏览器脚本测试中验证页面内容
要验证浏览器脚本测试上的页面内容,请执行以下操作:
let element = await $browser.findElement(By.xpath(`//h1[contains(text(), 'Action Result')]`));
console.log("Found element:", await element.getTagName(), ", element text is:", await element.getText());
await $browser.waitForAndFindElement(By.xpath(`//label[contains(text(), 'Action Result')]`), 5000);
console.log(">>>>>>>>>>>>>>>>>>>", "Action Result found");
在 Selenium IDE中验证页面内容的录制脚本测试
要验证 Selenium IDE 记录的脚本测试上的页面内容:
{
"id": "4cbe70ec-48b2-4e57-97cf-6d855fa0f08f",
"comment": "",
"command": "waitForElementVisible",
"target": "//h1[contains(text(), \"Selenium automates\")]",
"targets": [],
"value": "30000"
}

如何登录启用了双因素认证的网站
对于 BrowserScript 和 Selenium SIDE 脚本测试,支持 2FA (双因子认证) 登录到 Web 站点。
完整的测试脚本,请参见 BrowserScript 示例和 Selenium SIDE 示例。
要测试脚本或在本地运行脚本,请将 synb.json 文件中的 url 和 $secure 变量替换为实际值。
要传递 2FA,请完成以下步骤:
- 获取基于时间的一次性密码 (TOTP) 密钥,这是您与 Web 站点之间随机生成的共享密钥,用于创建 TOTP 令牌以通过双因子认证 (2FA) 登录到 Web 站点。 在初始设置 2FA期间,通常以 QR 代码或数字代码的形式向您提供此密钥。 要获取数字代码,请单击双因子认证配置页面上的以下任何帮助链接:
- 无法扫描 QR 代码
- 扫描时发生问题? 请改为输入代码。
- 为保护您的密钥,请通过 Instana 访问 API ,为 TOTP 密钥创建 Synthetic 凭证。
- 在浏览器测试中,请使用浏览器
$browser.generateTOTPToken(key: string)测试工具 API 生成基于时间的TOTP令牌用于输入。- 要将 BrowserScript 用于 2FA 认证:
let totp_token = $browser.generateTOTPToken($secure.totpKey); await findElementByIdAndSendKeys("password", totp_token); - 要将 Selenium SIDE 脚本用于 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}" },
- 要将 BrowserScript 用于 2FA 认证: