【问题标题】:Executing JavaScript present in a web page through Selenium通过 Selenium 执行网页中的 JavaScript
【发布时间】:2017-07-05 16:22:51
【问题描述】:

我正在编写一个自动脚本,用于填写网页中某人地址的详细信息。请注意,我没有创建此网页。因此,在填写地址时,可以选择插入国家/地区。我检查了这个元素,发现它有一个“

我的问题是我需要确保我输入的国家/地区必须出现在下拉列表中。现在有趣的是:我检查了元素,单击“控制台”并输入以下 JavaScript 方法:

ns.Fields.isFieldValid("FieldName")

仅当值我键入列表中的国家/地区名称时才返回 true,否则返回 false。但是,我尝试通过在 Selenium 中使用以下代码来执行此操作:

FirefoxDriver driver = new FirefoxDriver();
driver.get(URL);
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("ns.Fields.isFieldValid("FieldName");

这给了我一个参考错误,说“ns”没有定义。现在我明白上面的 JS 代码被认为是我编写的新脚本,这里 ns 没有定义,因此我收到了这个错误。

所以我的问题是如何使用网页中已经存在的 JS 来执行代码,因为代码可以在浏览器控制台中运行,但不能通过 selenium 运行。有没有办法让我在 Firefox 的控制台中运行上述代码并从中获取真假结果?

火狐:46.0​​.1

硒:3.4.0

【问题讨论】:

  • 出于好奇,通常当我使用 Selenium 时,我根本不会执行脚本。我知道 Selenium 有一些方法可以等待或检查 DOM 元素的存在。例如,是否有可能知道您要查找的选项的类名?然后,您可以与页面/DOM 进行交互,而不是通过 Selenium 执行 JS 以查找您想要的选项。
  • 不,我不认为这是可能的。你看,当我加载页面时,下拉框中绝对没有任何内容。我开始在文本框中输入的那一刻,选项开始填充。所以我不完全确定国家名称是否在类文件中。从我在那里看到的情况来看,我认为 JS 方法是从 JSON 文件资源中提取详细信息(我不再可用)并选择与我输入的字母匹配的国家。
  • 啊,好的,我明白了。端到端测试应该从用户的角度来测试页面或站点,所以我认为正确的解决方案是使用 Selenium 在框中键入并让页面运行实际搜索。然后,您可以在填充后搜索列表本身。但至于是否存在该选项——这在技术上是一个测试数据的问题,你“应该能够”依赖于知道测试存在的日子。或者你嘲笑它。或者,您可以在页面上运行手动搜索以查看可用于测试的选项类型。
  • @RoboBear 是对的,您不应该依赖内部实现。也就是说,对象ns 在执行命令时尚未创建,或者ns 包含在wrappedJSObject 中。试试return window.wrappedJSObject.ns.Fields.isFieldValid('FieldName')
  • 您的最后一行无效。应该是jse.executeScript("return ns.Fields.isFieldValid('FieldName')");。它需要有一个return,并且您已经嵌套了"s,这会导致问题。将内部双引号更改为单引号,这应该会运行......但不确定它是否真的有效。

标签: javascript java html selenium


【解决方案1】:

免责声明

我创建了一个答案,因为评论太长了,尽管我认为您的问题是 X/Y problem 的一个示例,并且您的问题不够清楚,无法准确回答或无需花费太多精力(我可能确实)并且冒着被否决/近距离投票的风险,因为我的回答与实际主题无关(但我是故意这样做的)。

为什么脚本方法是个坏主意?

以下是脚本编写方法对于验收测试来说不是一个坏主意的一些原因

  • 应用程序可能随时更改

    尤其是你提到的情况:

    请注意,我没有创建此网页。

  • 您调用的方法/函数可能会产生副作用(尽管名称听起来很清楚,但函数在被调用时可能会执行其他操作)

  • 真实用户不会像您使用脚本那样进行交互,您可能会错过

    • 错误或
    • 糟糕的用户体验

(在使用 Selenium 进行非测试自动化时,所有方面也可能适用。)

尝试帮助

让我总结一下我认为目前还不清楚的地方:

  • 该元素的交互效果如何(我会做一些假设)
  • 在交互过程中 DOM 是什么样子的(我会做一些假设)
  • 什么是 Selenium 程序用于:表单提交的自动化/脚本化以大量创建记录或真正的最终用户/验收测试(我假设阅读测试)

但让我开始假设这完全是关于验收测试(许多事情也适用于纯自动化)...

你写道:

我正在编写一个自动脚本,用于填写网页中某人地址的详细信息。 [...] 因此,在填写地址时,可以选择插入国家/地区。我检查了这个元素,发现它有一个“

还有:

所以它基本上是一个下拉菜单,但它会在我键入时填充 [...]

我假设交互看起来像这样:

Country
[|            ]      Step 1 (empty input with cursor)


Country
[B|           ]      Step 2 (letter "B" entered)


Country
[Br|          ]      Step 3 (a proposal box opened)
+-------------+
|Braunschweig |
|Bremen       |
|Brandenburg  |
+-------------+


Country
[Bra|         ]      Step 4 (the proposals limited even more)
+-------------+
|Braunschweig |
|Brandenburg  |
+-------------+

假设:该组合框要么通过<select> element with <option> elements 实现,要么通过<div><ul> 或其他包含列表条目的元素实现。 (这实际上是您应该在问题中澄清的内容。)

假设输入“Braunschweig”时它看起来像这样:

<input type="text" />
<div class="search-proposals country">
    <ul>
        <li>Braunschweig</li>
    </ul>
</div>

我的问题是我需要确保我输入的国家/地区必须出现在下拉列表中。

我不明白你为什么不能只输入国家...

Country
[Zoesville    ]

假设“佐斯维尔”不存在。

因此,提案列表中没有条目。要么是空的

<input type="text" />
<div class="search-proposals country">
    <ul>
    </ul>
</div>

或者根本不存在提案元素:

<input type="text" />

您现在应该能够检测到By.cssSelector(".search-proposals.country li") 的存在。

当然,如果输入的国家/地区正确,应用程序也可能对空的或没有提案列表做出反应。在这种情况下,该提案元素没有给出正确/错误输入的指示/区分。真实用户也同样重要:他们会有糟糕的用户体验。

通常,当输入有效值或至少在聚焦下一个输入时字段模糊时,会出现一些指示,例如绿色检查。这是您可以检查的另一个元素。

在真正的验收测试中,缺少的有效性指示元素值得报告/改进。

但由于这是猜测,到目前为止只有您知道该页面的工作原理,所以我将在此停止。

你的 cmets 上的一些话

在你写的 cmets 中:

[...] 从我看到的情况来看,我认为 JS 方法是从 JSON 文件资源中提取详细信息(我不再可用)并选择与我输入的字母匹配的国家。

和:

[...] 有时,即使在我输入数据后,页面仍在加载,因此有时会跳过 JS 脚本。因此,有时会填充列表,但在极少数情况下,列表根本不会填充,因此实际上无法确定我输入的国家/地区是否真的有效。

当您也不能依赖 UI 时,如何确保 Javascript 方法能够为您提供正确的结果?在我看来:你不能。您应该等待页面完成加载的指示,或者尝试像真实用户那样与它进行交互。

保修

我希望你现在有足够的指导如何在不使用脚本的情况下处理这种情况

如果问题描述更改为八十,我将不会编辑/更新此答案。不过,我考虑添加更新以获取有关上述不清楚点的详细信息。

【讨论】:

  • 感谢您的回答。这很有意义,但没有直接解决我的问题。但是,我从@Florent B 那里得到了答案。wrappedJSObject 做了我想做的事。
猜你喜欢
  • 2015-09-04
  • 2021-06-04
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多