【问题标题】:CasperJS doesn't load content injected by Angular routerCasperJS 不加载由 Angular 路由器注入的内容
【发布时间】:2023-06-15 15:35:02
【问题描述】:

我正在 GitHub 上准备一个example project,以配合我正在学习的关于如何为 dockerized 应用程序编写功能测试的课程。该应用程序有一部分是 Angular2 单页应用程序,我正在尝试使用 CasperJS 测试此应用程序(我也尝试过使用 Behat 来解决下面解释的相同问题)。

在 CasperJS 中运行测试时,好像 Angular 中的路由没有为测试加载,我的意思是我可以断言索引模板中的东西存在(例如页面标题)但里面的东西<app-root></app-root> 标签不会为测试加载。

代码

这是索引模板:

<!doctype html>
<html lang="en">
<head
  <meta charset="utf-8">
  <title>TestProject</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <app-root></app-root>
</body>
</html>

测试是:

casper.test.begin('Tests homepage structure', function suite(test) {

    casper.start('http://web', function() {

        // This works because the title is set in the "parent" template.
        test.assertTitle("TestProject", "Title is correct");

        casper.wait(2000);

        // This fails, I'm guessing because the h2 is only in the "child" template,
        // it seems that CasperJS doesn't render the angular2 app correctly
        // and the child route templates are not injected into the page correctly.
        test.assertVisible('h2');
    });

    casper.run(function() {
        test.done();
    });
});

这是测试的输出:

Test file: homepage.js                                                          
# Tests homepage structure
[info] [phantom] Starting...
[info] [phantom] Running suite: 2 steps
PASS Tests homepage structure (NaN test)
[debug] [phantom] opening url: http://web/, HTTP GET
[debug] [phantom] Navigation requested: url=http://web/, type=Other, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "http://web/"
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step anonymous 2/2 http://web/ (HTTP 200)
PASS Title is correct
FAIL Selector is visible
#    type: assertVisible
#    file: homepage.js
#    subject: false
#    selector: "h2"
[info] [phantom] Step anonymous 2/2: done in 178ms.
[info] [phantom] Step _step 3/3 http://web/ (HTTP 200)
[info] [phantom] Step _step 3/3: done in 196ms.
[info] [phantom] wait() finished waiting for 2000ms.
[info] [phantom] Done 3 steps in 2215ms

请注意,这些测试和 web 都在 docker 容器中运行,这就是为什么上面代码中的主机名是“web”而不是 IP。

该应用程序位于 GitHub here。要运行应用程序,请在根目录中执行 docker-compose up 并浏览到 http://127.0.0.1:81/。要运行 CasperJS 测试运行 ./tests/web/run_functional_test.sh,您不需要事先运行 docker-compose up

尝试过的东西

我试图通过在 CasperJS 加载页面时输出任何控制台错误来查看 CasperJS 是否遇到问题,但我没有发现任何可疑之处。

应用程序在浏览器中运行时运行良好,我可以看到路由器注入到索引模板中的内容。

我曾尝试使用resurrectio在Chrome中访问我的页面,点击一些东西然后将此测试直接导出到CasperJS测试文件,这个自动生成的测试由于同样的原因而失败,由注入的内容CasperJS 无法访问路由器。

我曾尝试使用 Behat 和 Selenium 获得类似的结果。这表明问题不在于 CasperJS/PhantomJS(可能是 Angular 设置?)。

问题

我不是 PhantomJS/Selenium 专家,但我知道它们可以渲染 javascript,因此期望 CasperJS 和 Behat 应该能够对 Angular 路由器插入页面的内容运行断言是正常的,我错了吗假设这个?

如果不是,我的测试结果如何?为什么 CasperJS 测试不能针对路由中的模板运行断言?

【问题讨论】:

  • PhantomJS 不是最佳选择,我建议您使用selenium/standalone-chromeselenium/standalone-firefox docker 镜像进行测试。当今天 docker 允许您拥有近乎无头的解决方案时,您不想在无头浏览器上解决问题

标签: angular docker phantomjs casperjs functional-testing


【解决方案1】:

问题归根结底是一个简单的问题,简单的问题通常是那些让你拔头发的问题。

在我的 Web 应用程序中,我使用“127.0.0.1:82”作为 API 的连接字符串。这在本地有效,因为 docker-compose 文件映射了主机的端口 82,但我没有为测试映射端口 82,因此 Web 无法连接到 API。修复是here

我不是 PhantomJS/Selenium 专家,但我知道它们可以渲染 javascript,因此期望 CasperJS 和 Behat 应该能够对 Angular 路由器插入页面的内容运行断言是正常的,我错了吗假设这个?

我的假设当然是正确的。

【讨论】: