使用具有Angular2和.ts规格的量角器时,“ReferenceError:未定义系统”

时间:2021-06-19 01:22:02

I want to do e2e testing on a hello world app in Angular2 with specs written in typescript. However, protractor crashes with the following message:

我想在Angular2中的hello world应用程序上进行e2e测试,并使用typescript编写规范。但是,量角器崩溃时出现以下消息:

Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
[launcher] Error: ReferenceError: System is not defined
    at Object.<anonymous> (C:\Dev\d2ipm\test\e2e\overview.js:1:1)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at C:\Users\%username%\AppData\Roaming\npm\node_modules\protractor\node_modules\jasmine\lib\jasmine.js:63:5
    at Array.forEach (native)
    at Jasmine.loadSpecs (C:\Users\%username%\AppData\Roaming\npm\node_modules\protractor\node_modules\jasmine\lib\jasmine.js:62:18)
[launcher] Process exited with error code 100

Since I use SystemJS as Angular2 suggests by default, System is contained in every compiled .js file, including the test specs. My index.html configures System as suggested in the tutorials, and the app works:

由于默认情况下我使用SystemJS作为Angular2建议,因此System包含在每个已编译的.js文件中,包括测试规范。我的index.html按照教程中的建议配置系统,应用程序可以运行:

    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        },
        globalEvaluationScope: false
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

Running tests written in pure JS works fine. How can I make my test environment see System?

用纯JS编写的运行测试工作正常。如何让我的测试环境看到系统?

1 个解决方案

#1


2  

When you run an e2e test through Protractor, there are actually 2 environments:

当您通过Protractor运行e2e测试时,实际上有两种环境:

  • The first is the environment being tested
    • it runs in a browser,
    • 它在浏览器中运行,

    • said browser is controlled through the "Selenium Webdriver" automation system,
    • 说浏览器是通过“Selenium Webdriver”自动化系统控制的,

    • it loads and execute your whole application as an end-used browser would, including loading the index.html file.
    • 它作为最终使用的浏览器加载并执行整个应用程序,包括加载index.html文件。

  • 第一个是正在测试的环境,它在浏览器中运行,所述浏览器通过“Selenium Webdriver”自动化系统控制,它作为最终使用的浏览器加载并执行整个应用程序,包括加载index.html文件。

  • The second is the environment running the tests themselves
    • In runs in as a local node.js application,
    • 在作为本地node.js应用程序运行时,

    • It uses protractor, which runs Jasmine, which runs the e2e test files
    • 它使用量角器,它运行Jasmine,运行e2e测试文件

    • It controls the browser through Selenium
    • 它通过Selenium控制浏览器

  • 第二个是运行测试本身的环境在作为本地node.js应用程序运行时,它使用量角器,它运行Jasmine,运行e2e测试文件它通过Selenium控制浏览器

Even if you load libraries in your index.html file, the your e2e-spec file won't have access to them. That includes systemjs. This is an issue when the Typescript compiler uses "module": "system"

即使您在index.html文件中加载库,您的e2e-spec文件也无法访问它们。这包括systemjs。当Typescript编译器使用“module”时,这是一个问题:“system”

How to fix it?

One solution is to configure your build process so that the e2e-spec files are compiled with the "module": "commonjs" option. If you want to be able to import files from your web application into the test spec, you would have to compile the whole application twice (though I am not sure there are much use cases where it makes sense to do so).

一种解决方案是配置构建过程,以便使用“module”:“commonjs”选项编译e2e-spec文件。如果您希望能够将Web应用程序中的文件导入到测试规范中,则必须对整个应用程序进行两次编译(尽管我不确定有多少用例可以这样做)。

For example, using gulp

例如,使用gulp

const gulpTypings = require('gulp-typings')
const sourcemaps = require('gulp-sourcemaps')
const ts = require('gulp-typescript')

const tsProject = ts.createProject('tsconfig.json')
const tsProjectE2E = ts.createProject('tsconfig-e2e.json')

const tsFiles = [
  'typings/index.d.ts',
  'app/**/*.ts',
  '!**/*.e2e-spec.ts',
  '!node_modules/**/*'
]

const tsFilesE2E = [
  'typings/index.d.ts',
  'app/**/*.e2e-spec.ts',
  'app/**/*.ts', // You should not need that unless you use your app files in your tests
  '!node_modules/**/*'
]

gulp.task('typings', () => gulp
  .src('./typings.json')
  .pipe(gulpTypings())
)

gulp.task('ts', ['typings'], () => gulp
  .src(tsFiles)
  .pipe(sourcemaps.init())
  .pipe(ts(tsProject))
  .js
  .pipe(sourcemaps.write('.'))
  .pipe(gulp.dest('app'))
)

gulp.task('ts-e2e', ['typings'], () => gulp
  .src(tsFilesE2E)
  .pipe(sourcemaps.init())
  .pipe(ts(tsProjectE2E))
  .js
  .pipe(sourcemaps.write('.'))
  .pipe(gulp.dest('e2e')) // Note that your compiled tests files are put in the e2e/ folder now
)

#1


2  

When you run an e2e test through Protractor, there are actually 2 environments:

当您通过Protractor运行e2e测试时,实际上有两种环境:

  • The first is the environment being tested
    • it runs in a browser,
    • 它在浏览器中运行,

    • said browser is controlled through the "Selenium Webdriver" automation system,
    • 说浏览器是通过“Selenium Webdriver”自动化系统控制的,

    • it loads and execute your whole application as an end-used browser would, including loading the index.html file.
    • 它作为最终使用的浏览器加载并执行整个应用程序,包括加载index.html文件。

  • 第一个是正在测试的环境,它在浏览器中运行,所述浏览器通过“Selenium Webdriver”自动化系统控制,它作为最终使用的浏览器加载并执行整个应用程序,包括加载index.html文件。

  • The second is the environment running the tests themselves
    • In runs in as a local node.js application,
    • 在作为本地node.js应用程序运行时,

    • It uses protractor, which runs Jasmine, which runs the e2e test files
    • 它使用量角器,它运行Jasmine,运行e2e测试文件

    • It controls the browser through Selenium
    • 它通过Selenium控制浏览器

  • 第二个是运行测试本身的环境在作为本地node.js应用程序运行时,它使用量角器,它运行Jasmine,运行e2e测试文件它通过Selenium控制浏览器

Even if you load libraries in your index.html file, the your e2e-spec file won't have access to them. That includes systemjs. This is an issue when the Typescript compiler uses "module": "system"

即使您在index.html文件中加载库,您的e2e-spec文件也无法访问它们。这包括systemjs。当Typescript编译器使用“module”时,这是一个问题:“system”

How to fix it?

One solution is to configure your build process so that the e2e-spec files are compiled with the "module": "commonjs" option. If you want to be able to import files from your web application into the test spec, you would have to compile the whole application twice (though I am not sure there are much use cases where it makes sense to do so).

一种解决方案是配置构建过程,以便使用“module”:“commonjs”选项编译e2e-spec文件。如果您希望能够将Web应用程序中的文件导入到测试规范中,则必须对整个应用程序进行两次编译(尽管我不确定有多少用例可以这样做)。

For example, using gulp

例如,使用gulp

const gulpTypings = require('gulp-typings')
const sourcemaps = require('gulp-sourcemaps')
const ts = require('gulp-typescript')

const tsProject = ts.createProject('tsconfig.json')
const tsProjectE2E = ts.createProject('tsconfig-e2e.json')

const tsFiles = [
  'typings/index.d.ts',
  'app/**/*.ts',
  '!**/*.e2e-spec.ts',
  '!node_modules/**/*'
]

const tsFilesE2E = [
  'typings/index.d.ts',
  'app/**/*.e2e-spec.ts',
  'app/**/*.ts', // You should not need that unless you use your app files in your tests
  '!node_modules/**/*'
]

gulp.task('typings', () => gulp
  .src('./typings.json')
  .pipe(gulpTypings())
)

gulp.task('ts', ['typings'], () => gulp
  .src(tsFiles)
  .pipe(sourcemaps.init())
  .pipe(ts(tsProject))
  .js
  .pipe(sourcemaps.write('.'))
  .pipe(gulp.dest('app'))
)

gulp.task('ts-e2e', ['typings'], () => gulp
  .src(tsFilesE2E)
  .pipe(sourcemaps.init())
  .pipe(ts(tsProjectE2E))
  .js
  .pipe(sourcemaps.write('.'))
  .pipe(gulp.dest('e2e')) // Note that your compiled tests files are put in the e2e/ folder now
)