在浏览器加载SUT之前,Protractor + Mocha在TypeError中失败

时间:2017-03-16 16:04:57

标签: protractor mocha integration-testing angular-cli

上下文

我正在探索angular2 + angular-cli + typescript。我的目标是确保如果我在打字稿中使用角度应用程序或节点应用程序,我将使用与使用mocha的旧节点应用程序相同的测试技术。为此,我尝试重新配置生成protractor.conf.js的angular-cli以使用mocha而不是jasmine。

问题

如何正确整合angular-cli + mocha +量角器,以便测试将使用量角器实际提供mocha规格有用的浏览器/元素/组件?

我已经将protractor.conf.js更改为使用mocha和chai并且测试完成,但是与量角器组件的所有交互都失败,即element(by.css('app-root h1')).getText()

转换了protractor.conf.js

exports.config = {
  allScriptsTimeout: 11000, // The timeout for a script run on the browser. 
  specs: [
    './e2e/**/*.e2e-spec.ts' // pattern for the test specs
  ],
  baseUrl: 'http://localhost:4200/', // base url of the SUT
  capabilities: {
    'browserName': 'chrome' // browser to use
  },
  directConnect: true, // selenium will not need a server, direct connet to chrome
  framework: 'mocha', // Use mocha instead of jasmine
  mochaOpts: { // Mocha specific options 
    reporter: "spec",
    slow: 3000,
    ui: 'bdd',
    timeout: 30000
  },
  beforeLaunch: function() { // Do all the typescript 
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare: function() {}
};

怀疑

感觉问题是套件在浏览器加载应用程序之前正在执行(并且失败)。这可能是量角器/浏览器的交互,从我理解的应该是不可知的到正在使用的规范。也许这种理解不正确?

示例来源

我在GitHub上有一个运行示例,我用它来测试和比较转换

到目前为止的调查

在命令行node node_modules\protractor\bin\protractor protractor.conf.js --stackTrace --troubleshoot上运行量角器(通过节点)向我们显示该套件已配置并运行truthy测试,跳过测试和实际应用程序测试

套件结果

我们看到truthy测试正在通过,跳过了跳过的测试,并且应用程序测试都失败并出现同样的错误

1 passing 
1 pending
5 failing

 1) A descriptive test name that is irrelevant to the error:
     TypeError: obj.indexOf is not a function
      at include (node_modules\chai\lib\chai\core\assertions.js:228:45)
      at doAsserterAsyncAndAddThen (node_modules\chai-as-promised\lib\chai-as-promised.js:293:29)
      at .<anonymous> (node_modules\chai-as-promised\lib\chai-as-promised.js:271:25)
      at chainableBehavior.method (node_modules\chai\lib\chai\utils\overwriteChainableMethod.js:51:34)
      at assert (node_modules\chai\lib\chai\utils\addChainableMethod.js:84:49)
      at Context.it (e2e\search\search.e2e-spec.ts:14:40)
      at runTest (node_modules\selenium-webdriver\testing\index.js:166:22)
      at node_modules\selenium-webdriver\testing\index.js:187:16
      at new ManagedPromise (node_modules\selenium-webdriver\lib\promise.js:1067:7)
      at controlFlowExecute (node_modules\selenium-webdriver\testing\index.js:186:14)
  From: Task: A descriptive test name that is irrelevant to the error
      at Context.ret (node_modules\selenium-webdriver\testing\index.js:185:10)

似乎会导致TypeError,因为在套件完成之前,应用程序本身似乎没有时间在浏览器中实际加载

- 排除输出

[09:26:33] D/launcher - Running with --troubleshoot
[09:26:33] D/launcher - Protractor version: 5.1.1
[09:26:33] D/launcher - Your base url for tests is http://localhost:4200/
[09:26:33] I/direct - Using ChromeDriver directly...
[09:26:36] D/runner - WebDriver session successfully started with capabilities Capabilities {
  'acceptSslCerts' => true,
  'applicationCacheEnabled' => false,
  'browserConnectionEnabled' => false,
  'browserName' => 'chrome',
  'chrome' => { chromedriverVersion: '2.28.455520 (cc17746adff54984afff480136733114c6b3704b)',
  userDataDir: 'C:\\Users\\abartish\\AppData\\Local\\Temp\\scoped_dir4596_5000' },
  'cssSelectorsEnabled' => true,
  'databaseEnabled' => false,
  'handlesAlerts' => true,
  'hasTouchScreen' => false,
  'javascriptEnabled' => true,
  'locationContextEnabled' => true,
  'mobileEmulationEnabled' => false,
  'nativeEvents' => true,
  'networkConnectionEnabled' => false,
  'pageLoadStrategy' => 'normal',
  'platform' => 'Windows NT',
  'rotatable' => false,
  'takesHeapSnapshot' => true,
  'takesScreenshot' => true,
  'unexpectedAlertBehaviour' => '',
  'version' => '56.0.2924.87',
  'webStorageEnabled' => true }
[09:26:36] D/runner - Running with spec files ./e2e/**/*.e2e-spec.ts

其他信息

有趣的是,如果你使用elementExplorer node node_modules\protractor\bin\protractor protractor.conf.js --stackTrace --troubleshoot --elementExplorer运行量角器,它将不会运行测试,但我们确实看到SUT在启动的浏览器中解析。这个我无法解释。

1 个答案:

答案 0 :(得分:1)

首先,我对Mocha并不熟悉。但是,我可以让你的测试通过。这是你需要做的:

设置依赖项

使用最新和最好的依赖项有时很棒。最新的chai-as-promised对我不起作用。我曾经尝试将Protractor依赖项更新为最新版本的chai和chai-as-promise并运行问题。我不得不降级你的依赖关系并最终使用:

"chai": "~3.5.0",
"chai-as-promised": "~5.3.0",

这些版本与Protractor package.json相同。

使用onPrepare插件

在Protractor运行测试之前设置chai-as-promised:

onPrepare: function() {
  let chai = require('chai');
  let chaiAsPromised = require("chai-as-promised");
  chai.use(chaiAsPromised);
  global.chai = chai;
}

编辑测试:

添加或修改以下内容。

app.e2e-spec.ts

import {RootPage} from './root/root.po';
let expect = global["chai"].expect;

  // change the following lines to have "eventually"
  expect(page.getParagraphText()).to.eventually.contain('Car search POC');

  // if you don't want to use "eventually"
  page.getParagraphText().then(paragraph => {
    expect(paragraph).to.contain('Car search POC');
  });

root.e2e-spec.ts:

let expect = global["chai"].expect;

describe('Home page', () => {

  // change the following lines to have "eventually"
  expect(page.getParagraphText()).to.eventually.include('Car search POC');
  expect(browser.getCurrentUrl()).to.eventually.include(homePage.uri());

home.e2e-spec.ts:

import {RootPage} from './root.po';
import {HomePage} from '../home/home.po';
import {WaitCondition} from '../wait.conditions';
let expect = global["chai"].expect;

  // change the following lines to have "eventually"
  expect(page.getParagraphText()).to.eventually.equal('Car search POC');

  // This line will not work. getInnerHtml has been deprecated by both
  // Protractor and selenium-webdriver.
  //
  // If you want to use something similar, do something like:
  // let i = browser.executeScript("return arguments[0].innerHTML;", element(locator));
  // This is noted in the CHANGELOG under the Protractor 5.0.0 release
  expect(page.getListingContent()).to.exist;

search.e2e-spec.ts

import {SearchPage} from './search.po';
let expect = global["chai"].expect;

  // change the following lines to have "eventually"
  expect(page.getParagraphText()).to.eventually.contain('Car search POC');

控制台输出

以下是运行测试的结果。请注意,“将有内容”失败,因为getInnerHtml()无效。

angular-cli-seed App
  ✓ will do normal tests
  ✓ will display its title

Home page
  ✓ will display its title
  - will have content

root page
  ✓ will display its title
  ✓ will redirect the URL to the home page

search page
  ✓ will display its title


6 passing (5s)
1 pending

这是一个有趣的StackOverflow问题。这很容易回答,因为你包含了一个不起作用的分支。快乐的测试!