bencompton / jest-cucumber

Execute Gherkin scenarios in Jest
Apache License 2.0
657 stars 117 forks source link

shared-steps unable to find page instance #91

Open lakshmanp21 opened 4 years ago

lakshmanp21 commented 4 years ago
feature: 
Feature: Upload Feature
    # @test
    Scenario:   I can try common steps
        Given   I am on the landing page ----> this is my common step used in multiple feature files
step_definitions:
import { BrowserTypes } from '../../src/browserTypes';
import * as playwright from 'playwright';

import { loadFeature, defineFeature } from 'jest-cucumber';

import { landing_page } from './shared-steps';

let browser: any;
let page: any;

const feature = loadFeature('./src/features/example.feature');

// Loop over all the supported browsers
for (const browserType of BrowserTypes) {
    defineFeature(feature, (test) => {
        beforeAll(async () => {
            browser = await playwright[browserType].launch({ headless: false }).catch((log: any) => console.log(log));
            page = await browser.newPage().catch((log: any) => console.log(log));
        });
        afterAll(() => {
            // browser.close().catch((log: any) => console.log(log))
        });
        afterEach(async () => {
            // await page.waitFor(3000)
        });
        beforeEach(async () => {
            await page.goto('xxxx.com/', {
                waitUntil: 'networkidle0',
            });
        });

        test('I can try common steps', async ({ given }) => {
            landing_page(given, page);
        });
    });
}
shared-steps.ts

export const landing_page = (given, page) => {
    given(/^I am on the landing page$/, async () => {
        console.log(await page.title());
        expect(await page.title()).toEqual('Sign In');
    });
}
Error:
TypeError: Cannot read property 'title' of undefined

      3 | export const landing_page = (given, page) => {
      4 |     given(/^I am on the landing page$/, async () => {
    > 5 |         console.log(await page.title());
        |                                ^
      6 |         expect(await page.title()).toEqual('Sign In');
      7 |     });
      8 | }
bencompton commented 4 years ago

I think this is an issue with timing of beforeAll / beforeEach and landing_page getting called to declare your given step. It would probably work better if you declare an object reference like scenarioContext below, and then pass that object into your shared step. That way, you can create and destroy the properties of the top-level object as you like in your hooks, but the shared step will always have a reference to the top-level object that won't be changing.

The docs and examples need to be updated, since the currently recommended pattern can be problematic. Implementing #61 would be ideal, I suppose.

for (const browserType of BrowserTypes) {
    defineFeature(feature, (test) => {
        const scenarioContext = {};

        beforeAll(async () => {
            scenarioContext.browser = await playwright[browserType].launch({ headless: false }).catch((log: any) => console.log(log));
            scenarioContext.page = await browser.newPage().catch((log: any) => console.log(log));
        });
        afterAll(() => {
            // scenarioContext.browser.close().catch((log: any) => console.log(log))
        });
        afterEach(async () => {
            // await scenarioContext.page.waitFor(3000)
        });
        beforeEach(async () => {
            await scenarioContext.page.goto('xxxx.com/', {
                waitUntil: 'networkidle0',
            });
        });

        test('I can try common steps', async ({ given }) => {
            landing_page(given, scenarioContext);
        });
    });
}
lakshmanp21 commented 4 years ago

unable to identify the step_definition from shared file, calling the function in steps file @bencompton image

lakshmanp21 commented 3 years ago

@bencompton , tried the above example, didn't work. Any update or insight on this please ?

mainfraame commented 3 years ago

@lakshmanp21 you should check out cucumber-jest. it's a transformer for jest that allows you to use the cucumber api with jest. Because it's using the cucumber js api, it supports declaring step definitions once and they can be used in any feature file.

lakshmanp21 commented 3 years ago

@lakshmanp21 you should check out cucumber-jest. it's a transformer for jest that allows you to use the cucumber api with jest. Because it's using the cucumber js api, it supports declaring step definitions once and they can be used in any feature file.

I am using cucumber-jest as suggested, though the issue (above) exists "dependencies": { "allure-jasmine": "^2.0.0-beta.8", "allure-js-commons": "^2.0.0-beta.8", "codeceptjs": "^2.6.10", "jest": "^26.6.1", "jest-cucumber": "^3.0.0", "playwright": "1.4.0", "ts-jest": "^26.4.3", "typescript": "^3.9.7" }, "devDependencies": { "@fast-csv/parse": "^4.3.3", "@testing-library/jasmine-dom": "^1.1.0", "@types/faker": "^4.1.12", "@types/jest": "^26.0.15", "@types/node": "^14.14.6", "csv-writer": "^1.6.0", "faker": "^4.1.0", "jest-allure": "^0.1.3", "jest-allure2": "^1.2.3", "moment": "^2.28.0" }