使用cucumber-tsflow和量角器将屏幕快照附加到cucumber-html-reporter

时间:2019-10-04 16:51:22

标签: typescript protractor cucumber

在每种失败的情况之后,我想将屏幕截图附加到html报告(由cucumber-html-reporter使用cucumber-tsflowprotractor生成。可以吗?

据我了解,使用cucumber-tsflow编写步骤时,我再也无法访问world实例。否则,像this.attach(screenshot, 'image/png');这样的东西就可以解决问题。

谷歌搜索一段时间后,我看到一些人将屏幕快照附加到诸如scenario.attach(screenshot);之类的场景中。但是,我在@after()(挂钩)中得到的场景是HookScenarioResult的一个实例。该接口没有任何将文件附加到的方法。

我在下面放置了step.ts和conf.ts的简化代码段。我试图将屏幕快照附加到afterAllScenarios()方法中,但没有成功。希望有人可以帮助我解决我的问题。

samplestep-definition.ts

import { binding, given, then, when, before, after } from 'cucumber-tsflow';
import { browser } from 'protractor';
import { expect } from 'chai';
import { HookScenarioResult, Status } from 'cucumber';

import HomePage from './page-objects/home-page';

@binding()
export class HomePageSteps {
    private homePage = new HomePage();

    @before()
    public beforeAllScenarios(): void {
        browser.manage().window().maximize();
    }

    @given(/the user is at the home page/)
    public async givenUserAtHomePage(): Promise<void> {
        await this.homePage.get();
        const actual = await browser.getCurrentUrl();
        const expected = 'https://qaclickacademy.github.io/protocommerce/';
        expect(actual).to.equal(expected);
    }

    @when(/the user enters (.*) in the name field/)
    public async userEntersNameField(input: string): Promise<void> {
        await this.homePage.typeNameAndTab(input);
    }

    @then(/the user should see error message (.*)/)
    public async useShouldSeeErrorMessage(message: string) {
        const errorMessage = await this.homePage.getErrorMessage();
        expect(errorMessage).to.equal(message);
    }

    @after()
    public async afterAllScenarios(scenario: HookScenarioResult): Promise<void> {
        if (scenario.result.status === Status.PASSED) {
            const screenshot = await browser.takeScreenshot();
            // No access to World instance so the code below won't work
            this.attach(screenshot, "image/png");

            // HookScenario has no attach method, so the code below won't work
            scenario.attach(screenshot);
        }
    }
}

cucumber-config.ts

import { Config } from 'protractor';
import * as reporter from 'cucumber-html-reporter';

// An example configuration file
export let config: Config = {
  directConnect: true,
  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),
  capabilities: {
    browserName: 'chrome'
  },
  specs: ['../features/sample.feature'],

  cucumberOpts: {
    format: 'json:./report/cucumber_report.json',
    tags: [
      '@smoketesting'
    ]
  },

  onComplete: () => {
    console.log('on complete called');
    var options = {
      theme: 'bootstrap',
      jsonFile: './report/cucumber_report.json',
      output: './report/cucumber_report.html',
      reportSuiteAsScenarios: true,
      scenarioTimestamp: true,
      launchReport: true,
      metadata: {
        "App Version": "0.3.2"
      }
    };

    reporter.generate(options);
  }
};

2 个答案:

答案 0 :(得分:0)

1-如果您有一个自定义World,则需要确保构造函数使用attach属性。我不知道它是如何用黄瓜tsflow完成的,但是,黄瓜tsflow内部使用的黄瓜js需要这样的附加参数:

function World({ attach }) {
  this.attach = attach
}

2-我们在Angular E2E测试应用程序的打字稿中使用了自定义世界 这是文件的一部分

// world.ts
const { setWorldConstructor } = require('cucumber');

export class World {
  private attach: (buffer: Buffer, mimeType: string) => void;
  constructor({ attach }) {
    this.attach = attach;
  }
}

然后在hook.ts

import { browser } from 'protractor';
import { HookScenarioResult } from 'cucumber';
const { Before, After } = require('cucumber');

// hook.ts
After(async function(scenario: HookScenarioResult) {
  const ss = await browser.takeScreenshot();
  const img = Buffer.alloc(ss.length, ss, 'base64');
  this.attach(img, 'image/png');
});

另外,显然您可以使用世界上的构造函数参数:https://github.com/timjroberts/cucumber-js-tsflow/issues/16

答案 1 :(得分:0)

只需使用类似的东西,设置参数 this: World 并在此处连接,无需自定义代码 从“@cucumber/cucumber”导入{世界};

import { browser } from "protractor";
import { AfterAll, After, Status, World } from "@cucumber/cucumber";
import { setDefaultTimeout } from "@cucumber/cucumber";

setDefaultTimeout(60 * 1000);

After(async function (this: World, scenario) {
  if (scenario.result?.status === Status.PASSED) {
    const screenShot = await browser.takeScreenshot();
    this.attach(screenShot , "image/png");
  }
});