Attach screenshot to cucumber-html-reporter using cucumber-tsflow and protractor

两盒软妹~` 提交于 2021-02-05 08:10:53

问题


After every failed scenario, I would like to attach a screenshot to html report (generated by cucumber-html-reporter, using cucumber-tsflow and protractor. Is that possible?

As far as I understand, I don't have access to the world instance anymore when writing the steps using cucumber-tsflow. Otherwise something like this.attach(screenshot, 'image/png'); would have done the trick.

After googling for a while, I saw some people attaching the screenshot to the scenario like scenario.attach(screenshot);. However, the scenario I get in @after()(hook) is an instance of HookScenarioResult. That interface does not have any method to attach a file to.

I placed a simplified snippet code of the step.ts and conf.ts below. I tried to attach the screenshot in the afterAllScenarios() method with no succes. Hopefully someone can help me out with my problem.

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);
  }
};

回答1:


1 - If you have a custom World you need to make sure that the constructor utilize the attach property. I don't know how it's done with cucumber-tsflow, but cucumberjs which used internally by cucumber-tsflow need the attach parametter like this :

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

2 - We use a custom world in typescript for our Angular E2E test app Here's a cut of the file

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

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

And then in the 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');
});

Also, apparently you have a way to use the world's constructor parameter: https://github.com/timjroberts/cucumber-js-tsflow/issues/16



来源:https://stackoverflow.com/questions/58240414/attach-screenshot-to-cucumber-html-reporter-using-cucumber-tsflow-and-protractor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!